feat(mcp): contracts, capability stats migration and MCP SDK dependency
- contracts/mcp.ts: capability stats/tools, MCP server status/config schemas, mcpToolVisible - api.ts: GET /capabilities/stats, GET /capabilities/tools, GET /mcp/status, PATCH /mcp/config - migration 0039: mcp_server_config single row + audit_event capability index - deno.json: npm:@modelcontextprotocol/[email protected].1 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
efb5d206c1
commit
73ee3c6614
8 files changed
+294
-10
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import type { Kysely } from "kysely";
|
||||
import { dropTables, execDdl } from "../src/migration-helpers.ts";
|
||||
|
||||
// AG-1 对外 MCP 服务端与能力统计:
|
||||
// - mcp_server_config:单行配置(启用开关、允许连接的 API Key;null = 所有未撤销的 Key)。
|
||||
// - 能力调用统计直接汇总 audit_event(capability.invoke / capability.denied 覆盖读写全部能力,
|
||||
// capability_invocation 只记有副作用的调用);补一条按能力 + 时间的部分索引。
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`
|
||||
create table mcp_server_config (
|
||||
id integer primary key default 1 check (id = 1),
|
||||
enabled boolean not null default true,
|
||||
allowed_api_key_ids text[],
|
||||
updated_by text,
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
insert into mcp_server_config (id) values (1);
|
||||
|
||||
create index if not exists audit_event_capability_idx on audit_event (target_id, at)
|
||||
where target_type = 'capability';
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 同上
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`drop index if exists audit_event_capability_idx;
|
||||
${dropTables(["mcp_server_config"])}`,
|
||||
);
|
||||
}
|
||||
@@ -868,6 +868,14 @@ export interface MediaAssetTable {
|
||||
download_task_id: string | null;
|
||||
}
|
||||
|
||||
export interface McpServerConfigTable {
|
||||
id: Generated<number>;
|
||||
enabled: Generated<boolean>;
|
||||
allowed_api_key_ids: string[] | null;
|
||||
updated_by: string | null;
|
||||
updated_at: GeneratedTimestamptz;
|
||||
}
|
||||
|
||||
export interface MediaEntityTable {
|
||||
id: Generated<string>;
|
||||
kind: MediaEntityKind;
|
||||
@@ -1623,6 +1631,7 @@ export interface DB {
|
||||
library_root: LibraryRootTable;
|
||||
login_attempt: LoginAttemptTable;
|
||||
media_asset: MediaAssetTable;
|
||||
mcp_server_config: McpServerConfigTable;
|
||||
media_entity: MediaEntityTable;
|
||||
media_server_instance: MediaServerInstanceTable;
|
||||
metadata_field: MetadataFieldTable;
|
||||
@@ -1772,6 +1781,9 @@ export type LoginAttemptUpdate = Updateable<LoginAttemptTable>;
|
||||
export type MediaAssetRow = Selectable<MediaAssetTable>;
|
||||
export type NewMediaAsset = Insertable<MediaAssetTable>;
|
||||
export type MediaAssetUpdate = Updateable<MediaAssetTable>;
|
||||
export type McpServerConfigRow = Selectable<McpServerConfigTable>;
|
||||
export type NewMcpServerConfig = Insertable<McpServerConfigTable>;
|
||||
export type McpServerConfigUpdate = Updateable<McpServerConfigTable>;
|
||||
export type MediaEntityRow = Selectable<MediaEntityTable>;
|
||||
export type NewMediaEntity = Insertable<MediaEntityTable>;
|
||||
export type MediaEntityUpdate = Updateable<MediaEntityTable>;
|
||||
|
||||
@@ -109,6 +109,8 @@ const EXPECTED_TABLES = [
|
||||
// W9-I 进程心跳(0034)
|
||||
"process_heartbeat",
|
||||
"process_heartbeat_sample",
|
||||
// AG-1 MCP 服务端配置(0039)
|
||||
"mcp_server_config",
|
||||
// C1-B 恢复码 / Passkey / WebAuthn 挑战(0037)
|
||||
"admin_recovery_code",
|
||||
"admin_passkey",
|
||||
@@ -132,6 +134,8 @@ const NON_ENTITY_TABLES = [
|
||||
// 进程心跳:instance_id 主键 / 只追加的采样
|
||||
"process_heartbeat",
|
||||
"process_heartbeat_sample",
|
||||
// 单行配置(id = 1)
|
||||
"mcp_server_config",
|
||||
// 一次性凭据:只记创建 / 用掉的时间
|
||||
"admin_recovery_code",
|
||||
"webauthn_challenge",
|
||||
|
||||
Reference in new issue
Block a user