feat(AI接入): 内置 MCP 服务与个人 Token 管理
Docker Build and Push / build-image (push) Successful in 4m34s

- 新增 /api/mcp (Streamable HTTP) 与 41 个工具: 项目/看板列/任务/清单/打卡; - 新增 McpToken 模型与迁移, DB 仅存 SHA-256 哈希, token 绑定用户; - 新增 /api/mcp-tokens 增删改查, 支持独立命名 (如 R1); - 「我的」页新增 AI 接入 (MCP) 区块: 地址复制/新建/一次性展示/删除; - 补充 docs/MCP.md 与样式
This commit is contained in:
jif2.zhang
2026-11-09 10:41:08 +08:00
parent fa172d8974
commit ec6c9c7677
26 changed files with 3763 additions and 12 deletions
File diff suppressed because one or more lines are too long
+92 -2
View File
@@ -408,7 +408,8 @@ export const ModelName = {
BoardColumn: 'BoardColumn',
Task: 'Task',
TaskMember: 'TaskMember',
TaskTag: 'TaskTag'
TaskTag: 'TaskTag',
McpToken: 'McpToken'
} as const
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
@@ -424,7 +425,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
omit: GlobalOmitOptions
}
meta: {
modelProps: "user" | "article" | "news" | "alert" | "serverNode" | "serverNodeHistory" | "serviceCheck" | "econ_SowInventory" | "scraperCache" | "mihomeAccount" | "mihomeHome" | "mihomeDevice" | "mihomeEnvSample" | "mihomeEnvHour" | "habit" | "checkIn" | "checkList" | "checkListItem" | "checkListTemplate" | "project" | "projectMember" | "boardColumn" | "task" | "taskMember" | "taskTag"
modelProps: "user" | "article" | "news" | "alert" | "serverNode" | "serverNodeHistory" | "serviceCheck" | "econ_SowInventory" | "scraperCache" | "mihomeAccount" | "mihomeHome" | "mihomeDevice" | "mihomeEnvSample" | "mihomeEnvHour" | "habit" | "checkIn" | "checkList" | "checkListItem" | "checkListTemplate" | "project" | "projectMember" | "boardColumn" | "task" | "taskMember" | "taskTag" | "mcpToken"
txIsolationLevel: TransactionIsolationLevel
}
model: {
@@ -2278,6 +2279,80 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
}
}
}
McpToken: {
payload: Prisma.$McpTokenPayload<ExtArgs>
fields: Prisma.McpTokenFieldRefs
operations: {
findUnique: {
args: Prisma.McpTokenFindUniqueArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload> | null
}
findUniqueOrThrow: {
args: Prisma.McpTokenFindUniqueOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
findFirst: {
args: Prisma.McpTokenFindFirstArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload> | null
}
findFirstOrThrow: {
args: Prisma.McpTokenFindFirstOrThrowArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
findMany: {
args: Prisma.McpTokenFindManyArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>[]
}
create: {
args: Prisma.McpTokenCreateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
createMany: {
args: Prisma.McpTokenCreateManyArgs<ExtArgs>
result: BatchPayload
}
createManyAndReturn: {
args: Prisma.McpTokenCreateManyAndReturnArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>[]
}
delete: {
args: Prisma.McpTokenDeleteArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
update: {
args: Prisma.McpTokenUpdateArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
deleteMany: {
args: Prisma.McpTokenDeleteManyArgs<ExtArgs>
result: BatchPayload
}
updateMany: {
args: Prisma.McpTokenUpdateManyArgs<ExtArgs>
result: BatchPayload
}
updateManyAndReturn: {
args: Prisma.McpTokenUpdateManyAndReturnArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>[]
}
upsert: {
args: Prisma.McpTokenUpsertArgs<ExtArgs>
result: runtime.Types.Utils.PayloadToResult<Prisma.$McpTokenPayload>
}
aggregate: {
args: Prisma.McpTokenAggregateArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.AggregateMcpToken>
}
groupBy: {
args: Prisma.McpTokenGroupByArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.McpTokenGroupByOutputType>[]
}
count: {
args: Prisma.McpTokenCountArgs<ExtArgs>
result: runtime.Types.Utils.Optional<Prisma.McpTokenCountAggregateOutputType> | number
}
}
}
}
} & {
other: {
@@ -2715,6 +2790,20 @@ export const TaskTagScalarFieldEnum = {
export type TaskTagScalarFieldEnum = (typeof TaskTagScalarFieldEnum)[keyof typeof TaskTagScalarFieldEnum]
export const McpTokenScalarFieldEnum = {
id: 'id',
userId: 'userId',
name: 'name',
prefix: 'prefix',
tokenHash: 'tokenHash',
lastUsedAt: 'lastUsedAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type McpTokenScalarFieldEnum = (typeof McpTokenScalarFieldEnum)[keyof typeof McpTokenScalarFieldEnum]
export const SortOrder = {
asc: 'asc',
desc: 'desc'
@@ -2979,6 +3068,7 @@ export type GlobalOmitConfig = {
task?: Prisma.TaskOmit
taskMember?: Prisma.TaskMemberOmit
taskTag?: Prisma.TaskTagOmit
mcpToken?: Prisma.McpTokenOmit
}
/* Types for Logging */
@@ -75,7 +75,8 @@ export const ModelName = {
BoardColumn: 'BoardColumn',
Task: 'Task',
TaskMember: 'TaskMember',
TaskTag: 'TaskTag'
TaskTag: 'TaskTag',
McpToken: 'McpToken'
} as const
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
@@ -492,6 +493,20 @@ export const TaskTagScalarFieldEnum = {
export type TaskTagScalarFieldEnum = (typeof TaskTagScalarFieldEnum)[keyof typeof TaskTagScalarFieldEnum]
export const McpTokenScalarFieldEnum = {
id: 'id',
userId: 'userId',
name: 'name',
prefix: 'prefix',
tokenHash: 'tokenHash',
lastUsedAt: 'lastUsedAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type McpTokenScalarFieldEnum = (typeof McpTokenScalarFieldEnum)[keyof typeof McpTokenScalarFieldEnum]
export const SortOrder = {
asc: 'asc',
desc: 'desc'