@creezio/mcp-facade 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +420 -0
  2. package/dist/.creezio-src-hash.json +4 -0
  3. package/dist/admin/adapters.d.ts +10 -0
  4. package/dist/admin/adapters.d.ts.map +1 -0
  5. package/dist/admin/adapters.js +21 -0
  6. package/dist/admin/adapters.js.map +1 -0
  7. package/dist/admin/http-routes.d.ts +11 -0
  8. package/dist/admin/http-routes.d.ts.map +1 -0
  9. package/dist/admin/http-routes.js +66 -0
  10. package/dist/admin/http-routes.js.map +1 -0
  11. package/dist/admin/index.d.ts +12 -0
  12. package/dist/admin/index.d.ts.map +1 -0
  13. package/dist/admin/index.js +8 -0
  14. package/dist/admin/index.js.map +1 -0
  15. package/dist/admin/mcp-admin.d.ts +165 -0
  16. package/dist/admin/mcp-admin.d.ts.map +1 -0
  17. package/dist/admin/mcp-admin.js +419 -0
  18. package/dist/admin/mcp-admin.js.map +1 -0
  19. package/dist/admin/tool-policy-guard.d.ts +106 -0
  20. package/dist/admin/tool-policy-guard.d.ts.map +1 -0
  21. package/dist/admin/tool-policy-guard.js +187 -0
  22. package/dist/admin/tool-policy-guard.js.map +1 -0
  23. package/dist/admin/types.d.ts +62 -0
  24. package/dist/admin/types.d.ts.map +1 -0
  25. package/dist/admin/types.js +6 -0
  26. package/dist/admin/types.js.map +1 -0
  27. package/dist/brand-facade.d.ts +41 -0
  28. package/dist/brand-facade.d.ts.map +1 -0
  29. package/dist/brand-facade.js +67 -0
  30. package/dist/brand-facade.js.map +1 -0
  31. package/dist/core-tools.d.ts +22 -0
  32. package/dist/core-tools.d.ts.map +1 -0
  33. package/dist/core-tools.js +93 -0
  34. package/dist/core-tools.js.map +1 -0
  35. package/dist/dyn-import.d.ts +13 -0
  36. package/dist/dyn-import.d.ts.map +1 -0
  37. package/dist/dyn-import.js +2 -0
  38. package/dist/dyn-import.js.map +1 -0
  39. package/dist/facade.d.ts +40 -0
  40. package/dist/facade.d.ts.map +1 -0
  41. package/dist/facade.js +334 -0
  42. package/dist/facade.js.map +1 -0
  43. package/dist/hono-bind.d.ts +48 -0
  44. package/dist/hono-bind.d.ts.map +1 -0
  45. package/dist/hono-bind.js +70 -0
  46. package/dist/hono-bind.js.map +1 -0
  47. package/dist/hono-proxy.d.ts +63 -0
  48. package/dist/hono-proxy.d.ts.map +1 -0
  49. package/dist/hono-proxy.js +185 -0
  50. package/dist/hono-proxy.js.map +1 -0
  51. package/dist/index.d.ts +32 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +23 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/jwt.d.ts +20 -0
  56. package/dist/jwt.d.ts.map +1 -0
  57. package/dist/jwt.js +84 -0
  58. package/dist/jwt.js.map +1 -0
  59. package/dist/module-ops-tools.d.ts +43 -0
  60. package/dist/module-ops-tools.d.ts.map +1 -0
  61. package/dist/module-ops-tools.js +301 -0
  62. package/dist/module-ops-tools.js.map +1 -0
  63. package/dist/namespace.d.ts +23 -0
  64. package/dist/namespace.d.ts.map +1 -0
  65. package/dist/namespace.js +51 -0
  66. package/dist/namespace.js.map +1 -0
  67. package/dist/oauth/cors-policy.d.ts +3 -0
  68. package/dist/oauth/cors-policy.d.ts.map +1 -0
  69. package/dist/oauth/cors-policy.js +25 -0
  70. package/dist/oauth/cors-policy.js.map +1 -0
  71. package/dist/oauth/hono-app.d.ts +18 -0
  72. package/dist/oauth/hono-app.d.ts.map +1 -0
  73. package/dist/oauth/hono-app.js +175 -0
  74. package/dist/oauth/hono-app.js.map +1 -0
  75. package/dist/oauth/index.d.ts +9 -0
  76. package/dist/oauth/index.d.ts.map +1 -0
  77. package/dist/oauth/index.js +6 -0
  78. package/dist/oauth/index.js.map +1 -0
  79. package/dist/oauth/rate-limit.d.ts +11 -0
  80. package/dist/oauth/rate-limit.d.ts.map +1 -0
  81. package/dist/oauth/rate-limit.js +32 -0
  82. package/dist/oauth/rate-limit.js.map +1 -0
  83. package/dist/oauth/routes.d.ts +8 -0
  84. package/dist/oauth/routes.d.ts.map +1 -0
  85. package/dist/oauth/routes.js +671 -0
  86. package/dist/oauth/routes.js.map +1 -0
  87. package/dist/oauth/store.d.ts +113 -0
  88. package/dist/oauth/store.d.ts.map +1 -0
  89. package/dist/oauth/store.js +390 -0
  90. package/dist/oauth/store.js.map +1 -0
  91. package/dist/oauth/types.d.ts +97 -0
  92. package/dist/oauth/types.d.ts.map +1 -0
  93. package/dist/oauth/types.js +5 -0
  94. package/dist/oauth/types.js.map +1 -0
  95. package/dist/open-external-tab-host-tools.d.ts +67 -0
  96. package/dist/open-external-tab-host-tools.d.ts.map +1 -0
  97. package/dist/open-external-tab-host-tools.js +92 -0
  98. package/dist/open-external-tab-host-tools.js.map +1 -0
  99. package/dist/policy.d.ts +59 -0
  100. package/dist/policy.d.ts.map +1 -0
  101. package/dist/policy.js +88 -0
  102. package/dist/policy.js.map +1 -0
  103. package/dist/runtime.d.ts +22 -0
  104. package/dist/runtime.d.ts.map +1 -0
  105. package/dist/runtime.js +20 -0
  106. package/dist/runtime.js.map +1 -0
  107. package/dist/types.d.ts +163 -0
  108. package/dist/types.d.ts.map +1 -0
  109. package/dist/types.js +2 -0
  110. package/dist/types.js.map +1 -0
  111. package/dist-cjs/admin/adapters.js +27 -0
  112. package/dist-cjs/admin/adapters.js.map +1 -0
  113. package/dist-cjs/admin/http-routes.js +69 -0
  114. package/dist-cjs/admin/http-routes.js.map +1 -0
  115. package/dist-cjs/admin/index.js +40 -0
  116. package/dist-cjs/admin/index.js.map +1 -0
  117. package/dist-cjs/admin/mcp-admin.js +441 -0
  118. package/dist-cjs/admin/mcp-admin.js.map +1 -0
  119. package/dist-cjs/admin/tool-policy-guard.js +193 -0
  120. package/dist-cjs/admin/tool-policy-guard.js.map +1 -0
  121. package/dist-cjs/admin/types.js +7 -0
  122. package/dist-cjs/admin/types.js.map +1 -0
  123. package/dist-cjs/brand-facade.js +70 -0
  124. package/dist-cjs/brand-facade.js.map +1 -0
  125. package/dist-cjs/core-tools.js +97 -0
  126. package/dist-cjs/core-tools.js.map +1 -0
  127. package/dist-cjs/dyn-import.js +5 -0
  128. package/dist-cjs/dyn-import.js.map +1 -0
  129. package/dist-cjs/facade.js +337 -0
  130. package/dist-cjs/facade.js.map +1 -0
  131. package/dist-cjs/hono-bind.js +74 -0
  132. package/dist-cjs/hono-bind.js.map +1 -0
  133. package/dist-cjs/hono-proxy.js +189 -0
  134. package/dist-cjs/hono-proxy.js.map +1 -0
  135. package/dist-cjs/index.js +120 -0
  136. package/dist-cjs/index.js.map +1 -0
  137. package/dist-cjs/jwt.js +91 -0
  138. package/dist-cjs/jwt.js.map +1 -0
  139. package/dist-cjs/module-ops-tools.js +308 -0
  140. package/dist-cjs/module-ops-tools.js.map +1 -0
  141. package/dist-cjs/namespace.js +56 -0
  142. package/dist-cjs/namespace.js.map +1 -0
  143. package/dist-cjs/oauth/cors-policy.js +29 -0
  144. package/dist-cjs/oauth/cors-policy.js.map +1 -0
  145. package/dist-cjs/oauth/hono-app.js +178 -0
  146. package/dist-cjs/oauth/hono-app.js.map +1 -0
  147. package/dist-cjs/oauth/index.js +48 -0
  148. package/dist-cjs/oauth/index.js.map +1 -0
  149. package/dist-cjs/oauth/rate-limit.js +37 -0
  150. package/dist-cjs/oauth/rate-limit.js.map +1 -0
  151. package/dist-cjs/oauth/routes.js +674 -0
  152. package/dist-cjs/oauth/routes.js.map +1 -0
  153. package/dist-cjs/oauth/store.js +418 -0
  154. package/dist-cjs/oauth/store.js.map +1 -0
  155. package/dist-cjs/oauth/types.js +6 -0
  156. package/dist-cjs/oauth/types.js.map +1 -0
  157. package/dist-cjs/open-external-tab-host-tools.js +96 -0
  158. package/dist-cjs/open-external-tab-host-tools.js.map +1 -0
  159. package/dist-cjs/package.json +3 -0
  160. package/dist-cjs/policy.js +93 -0
  161. package/dist-cjs/policy.js.map +1 -0
  162. package/dist-cjs/runtime.js +24 -0
  163. package/dist-cjs/runtime.js.map +1 -0
  164. package/dist-cjs/types.js +3 -0
  165. package/dist-cjs/types.js.map +1 -0
  166. package/package.json +92 -0
  167. package/ui/index.ts +5 -0
  168. package/ui/mcp-admin-client.tsx +270 -0
  169. package/ui/primitives/badge.tsx +37 -0
  170. package/ui/primitives/button.tsx +44 -0
  171. package/ui/primitives/card.tsx +44 -0
  172. package/ui/primitives/cn.ts +6 -0
  173. package/ui/primitives/input.tsx +19 -0
  174. package/ui/primitives/tabs.tsx +51 -0
@@ -0,0 +1,165 @@
1
+ import type { McpToolDefinition } from "./types.js";
2
+ export type { McpToolDefinition } from "./types.js";
3
+ export declare function ensureMcpAdminSchema(): void;
4
+ /**
5
+ * Seed permissif (INSERT OR IGNORE) de policies pour des tools hors registre
6
+ * adapters — ex. tools de `facade.listTools()` quand la garde M2 est activée
7
+ * sur une façade marque. Ne modifie JAMAIS une policy existante.
8
+ */
9
+ export declare function seedMcpToolPolicies(tools: Array<Pick<McpToolDefinition, "name"> & Partial<Pick<McpToolDefinition, "requiredScope" | "defaultRoles" | "mcpPublishDefault">>>): void;
10
+ export type McpToolPolicy = McpToolDefinition & {
11
+ enabled: boolean;
12
+ allowedRoles: string[];
13
+ allowedScopes: string[];
14
+ updatedAt: string | null;
15
+ };
16
+ export declare function listMcpToolPolicies(): McpToolPolicy[];
17
+ export declare function getMcpToolPolicy(name: string): McpToolPolicy | null;
18
+ /**
19
+ * Noms désactivés PAR L'ADMIN (`enabled=0` ET `admin_override=1`).
20
+ *
21
+ * Les lignes `enabled=0` seedées par défaut (`mcpPublishDefault=false` —
22
+ * ex. toute op module sans opt-in publish, cf.
23
+ * `generateModuleToolsFromOperations`) ne comptent PAS : elles signifient
24
+ * « non publié par défaut aux clients MCP externes », pas « désactivé » —
25
+ * les masquer vidait `listTools`/`GET /mcp` des tools métier (régression
26
+ * 0.17.1, vue par les gates module des marques). Admin non câblé / erreur
27
+ * DB → ensemble vide (pas de filtre).
28
+ */
29
+ export declare function disabledMcpToolPolicyNames(): Set<string>;
30
+ /** Retire de `listTools` les tools (et alias) désactivés en admin MCP. */
31
+ export declare function filterListedToolsByEnabledPolicy<T extends {
32
+ name: string;
33
+ aliasOf?: string;
34
+ }>(tools: T[], aliases?: Record<string, string>): T[];
35
+ export declare function updateMcpToolPolicy(name: string, input: {
36
+ enabled?: boolean;
37
+ allowedRoles?: string[];
38
+ allowedScopes?: string[];
39
+ }): McpToolPolicy | null;
40
+ export type McpAdminClient = {
41
+ client_id: string;
42
+ client_name: string | null;
43
+ redirect_uris: string[];
44
+ token_endpoint_auth_method: string;
45
+ scope: string | null;
46
+ created_at: string;
47
+ enabled: boolean;
48
+ revoked_at: string | null;
49
+ last_used_at: string | null;
50
+ active_refresh_tokens: number;
51
+ };
52
+ export declare function listMcpClients(): McpAdminClient[];
53
+ export declare function setMcpClientEnabled(clientId: string, enabled: boolean): boolean;
54
+ export declare function revokeMcpClient(clientId: string): boolean;
55
+ export declare function rotateMcpClientSecret(clientId: string): {
56
+ clientSecret: string;
57
+ } | null;
58
+ export declare function clientCanAuthenticate(clientId: string): boolean;
59
+ export declare function touchMcpClient(clientId: string): void;
60
+ export declare function mcpAdminStatus(): {
61
+ ready: boolean;
62
+ publicUrl: string | null;
63
+ mcpUrl: string | null;
64
+ oauthReady: boolean;
65
+ jwtConfigured: boolean;
66
+ toolCount: number;
67
+ enabledToolCount: number;
68
+ clientCount: number;
69
+ enabledClientCount: number;
70
+ };
71
+ export declare function mcpDiagnostics(): {
72
+ status: {
73
+ ready: boolean;
74
+ publicUrl: string | null;
75
+ mcpUrl: string | null;
76
+ oauthReady: boolean;
77
+ jwtConfigured: boolean;
78
+ toolCount: number;
79
+ enabledToolCount: number;
80
+ clientCount: number;
81
+ enabledClientCount: number;
82
+ };
83
+ checks: {
84
+ id: string;
85
+ ok: boolean;
86
+ message: string;
87
+ }[];
88
+ healthy: boolean;
89
+ };
90
+ export declare function mcpMetrics(): {
91
+ window: string;
92
+ requests: number;
93
+ errors: number;
94
+ errorRate: number;
95
+ averageDurationMs: number;
96
+ p95DurationMs: number | undefined;
97
+ byTool: {
98
+ [k: string]: number;
99
+ };
100
+ };
101
+ export declare function auditMcpAdmin(event: string, options?: {
102
+ actor?: string | null;
103
+ clientId?: string | null;
104
+ toolName?: string | null;
105
+ outcome?: string;
106
+ detail?: unknown;
107
+ }): void;
108
+ export declare function listMcpAuditLogs(limit?: number): unknown[];
109
+ export declare function pruneMcpAuditLogs(retentionDays?: number): number;
110
+ export declare function exportMcpDiagnostics(): {
111
+ generatedAt: string;
112
+ diagnostics: {
113
+ status: {
114
+ ready: boolean;
115
+ publicUrl: string | null;
116
+ mcpUrl: string | null;
117
+ oauthReady: boolean;
118
+ jwtConfigured: boolean;
119
+ toolCount: number;
120
+ enabledToolCount: number;
121
+ clientCount: number;
122
+ enabledClientCount: number;
123
+ };
124
+ checks: {
125
+ id: string;
126
+ ok: boolean;
127
+ message: string;
128
+ }[];
129
+ healthy: boolean;
130
+ };
131
+ metrics: {
132
+ window: string;
133
+ requests: number;
134
+ errors: number;
135
+ errorRate: number;
136
+ averageDurationMs: number;
137
+ p95DurationMs: number | undefined;
138
+ byTool: {
139
+ [k: string]: number;
140
+ };
141
+ };
142
+ tools: {
143
+ name: string;
144
+ enabled: boolean;
145
+ requiredScope: string;
146
+ allowedRoles: string[];
147
+ allowedScopes: string[];
148
+ }[];
149
+ clients: {
150
+ idPrefix: string;
151
+ name: string | null;
152
+ redirectHosts: string[];
153
+ scope: string | null;
154
+ enabled: boolean;
155
+ revoked: boolean;
156
+ lastUsedAt: string | null;
157
+ }[];
158
+ auditRetentionDays: number;
159
+ configuration: {
160
+ corsConfigured: boolean;
161
+ publicUrlConfigured: boolean;
162
+ jwtConfigured: boolean;
163
+ };
164
+ };
165
+ //# sourceMappingURL=mcp-admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-admin.d.ts","sourceRoot":"","sources":["../../src/admin/mcp-admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,419 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { getMcpAdminAdapters } from "./adapters.js";
3
+ function getDb() {
4
+ return getMcpAdminAdapters().getDb();
5
+ }
6
+ function getWriteDb() {
7
+ return getMcpAdminAdapters().getWriteDb();
8
+ }
9
+ function tableExists(name) {
10
+ return getMcpAdminAdapters().tableExists(name);
11
+ }
12
+ function MCP_TOOL_REGISTRY() {
13
+ return getMcpAdminAdapters().listTools();
14
+ }
15
+ function mcpOauthReady() {
16
+ return getMcpAdminAdapters().mcpOauthReady();
17
+ }
18
+ function resolveMcpPublicUrl() {
19
+ return getMcpAdminAdapters().resolveMcpPublicUrl();
20
+ }
21
+ function listRequestLogs(opts) {
22
+ const fn = getMcpAdminAdapters().listRequestLogs;
23
+ return fn ? fn(opts) : { logs: [] };
24
+ }
25
+ let schemaEnsured = false;
26
+ /** Rôles acceptés dans les policies (adapters, défaut historique). */
27
+ function policyRoleNames() {
28
+ return getMcpAdminAdapters().policyRoleNames || ["owner", "collaborator"];
29
+ }
30
+ /** Scopes acceptés dans les policies (adapters, défaut historique). */
31
+ function policyScopeNames() {
32
+ return (getMcpAdminAdapters().policyScopeNames || [
33
+ "crm",
34
+ "crm:read",
35
+ "crm:write",
36
+ "full",
37
+ ]);
38
+ }
39
+ function hasColumn(table, column) {
40
+ if (!tableExists(table))
41
+ return false;
42
+ return getDb()
43
+ .prepare(`PRAGMA table_info("${table.replaceAll('"', '""')}")`)
44
+ .all().some((item) => item.name === column);
45
+ }
46
+ export function ensureMcpAdminSchema() {
47
+ if (schemaEnsured)
48
+ return;
49
+ const db = getWriteDb();
50
+ if (tableExists("mcp_oauth_clients")) {
51
+ if (!hasColumn("mcp_oauth_clients", "enabled")) {
52
+ db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1`);
53
+ }
54
+ if (!hasColumn("mcp_oauth_clients", "revoked_at")) {
55
+ db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN revoked_at TEXT`);
56
+ }
57
+ if (!hasColumn("mcp_oauth_clients", "last_used_at")) {
58
+ db.exec(`ALTER TABLE mcp_oauth_clients ADD COLUMN last_used_at TEXT`);
59
+ }
60
+ }
61
+ if (tableExists("mcp_tool_policies") &&
62
+ !hasColumn("mcp_tool_policies", "admin_override")) {
63
+ db.exec(`ALTER TABLE mcp_tool_policies ADD COLUMN admin_override INTEGER NOT NULL DEFAULT 0`);
64
+ }
65
+ db.exec(`
66
+ CREATE TABLE IF NOT EXISTS mcp_tool_policies (
67
+ tool_name TEXT PRIMARY KEY,
68
+ enabled INTEGER NOT NULL DEFAULT 1,
69
+ allowed_roles TEXT NOT NULL DEFAULT 'owner,collaborator',
70
+ allowed_scopes TEXT NOT NULL DEFAULT '',
71
+ -- 1 si l'admin a explicitement fixé enabled (updateMcpToolPolicy) —
72
+ -- distingue une désactivation admin du seed par défaut
73
+ -- (mcpPublishDefault=false → enabled=0 « non publié par défaut »).
74
+ admin_override INTEGER NOT NULL DEFAULT 0,
75
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
76
+ );
77
+ CREATE TABLE IF NOT EXISTS mcp_audit_logs (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
80
+ event TEXT NOT NULL,
81
+ actor TEXT,
82
+ client_id TEXT,
83
+ tool_name TEXT,
84
+ outcome TEXT NOT NULL DEFAULT 'ok',
85
+ detail_json TEXT
86
+ );
87
+ CREATE INDEX IF NOT EXISTS idx_mcp_audit_created ON mcp_audit_logs(created_at);
88
+ `);
89
+ const insert = db.prepare(`INSERT OR IGNORE INTO mcp_tool_policies
90
+ (tool_name, enabled, allowed_roles, allowed_scopes)
91
+ VALUES (?, ?, ?, ?)`);
92
+ const seedFn = () => {
93
+ for (const tool of MCP_TOOL_REGISTRY()) {
94
+ const roles = (tool.defaultRoles || policyRoleNames()).join(",");
95
+ const enabled = tool.mcpPublishDefault === false ? 0 : 1;
96
+ insert.run(tool.name, enabled, roles, tool.requiredScope);
97
+ }
98
+ };
99
+ if (db.transaction)
100
+ db.transaction(seedFn)();
101
+ else
102
+ seedFn();
103
+ pruneMcpAuditLogs();
104
+ schemaEnsured = true;
105
+ }
106
+ /**
107
+ * Seed permissif (INSERT OR IGNORE) de policies pour des tools hors registre
108
+ * adapters — ex. tools de `facade.listTools()` quand la garde M2 est activée
109
+ * sur une façade marque. Ne modifie JAMAIS une policy existante.
110
+ */
111
+ export function seedMcpToolPolicies(tools) {
112
+ ensureMcpAdminSchema();
113
+ const db = getWriteDb();
114
+ const insert = db.prepare(`INSERT OR IGNORE INTO mcp_tool_policies
115
+ (tool_name, enabled, allowed_roles, allowed_scopes)
116
+ VALUES (?, ?, ?, ?)`);
117
+ const run = () => {
118
+ for (const tool of tools) {
119
+ if (!tool?.name)
120
+ continue;
121
+ const roles = (tool.defaultRoles || policyRoleNames()).join(",");
122
+ const enabled = tool.mcpPublishDefault === false ? 0 : 1;
123
+ insert.run(tool.name, enabled, roles, tool.requiredScope || "");
124
+ }
125
+ };
126
+ if (db.transaction)
127
+ db.transaction(run)();
128
+ else
129
+ run();
130
+ }
131
+ export function listMcpToolPolicies() {
132
+ ensureMcpAdminSchema();
133
+ const rows = getDb()
134
+ .prepare(`SELECT tool_name, enabled, allowed_roles, allowed_scopes, updated_at
135
+ FROM mcp_tool_policies`)
136
+ .all();
137
+ const policy = new Map(rows.map((row) => [row.tool_name, row]));
138
+ return MCP_TOOL_REGISTRY().map((tool) => {
139
+ const row = policy.get(tool.name);
140
+ const defaultEnabled = tool.mcpPublishDefault !== false;
141
+ return {
142
+ ...tool,
143
+ enabled: row ? row.enabled !== 0 : defaultEnabled,
144
+ allowedRoles: (row?.allowed_roles || policyRoleNames().join(","))
145
+ .split(",")
146
+ .filter(Boolean),
147
+ allowedScopes: (row?.allowed_scopes || tool.requiredScope).split(/[\s,]+/).filter(Boolean),
148
+ updatedAt: row?.updated_at || null,
149
+ };
150
+ });
151
+ }
152
+ export function getMcpToolPolicy(name) {
153
+ return listMcpToolPolicies().find((tool) => tool.name === name) || null;
154
+ }
155
+ /**
156
+ * Noms désactivés PAR L'ADMIN (`enabled=0` ET `admin_override=1`).
157
+ *
158
+ * Les lignes `enabled=0` seedées par défaut (`mcpPublishDefault=false` —
159
+ * ex. toute op module sans opt-in publish, cf.
160
+ * `generateModuleToolsFromOperations`) ne comptent PAS : elles signifient
161
+ * « non publié par défaut aux clients MCP externes », pas « désactivé » —
162
+ * les masquer vidait `listTools`/`GET /mcp` des tools métier (régression
163
+ * 0.17.1, vue par les gates module des marques). Admin non câblé / erreur
164
+ * DB → ensemble vide (pas de filtre).
165
+ */
166
+ export function disabledMcpToolPolicyNames() {
167
+ try {
168
+ ensureMcpAdminSchema();
169
+ const rows = getDb()
170
+ .prepare(`SELECT tool_name FROM mcp_tool_policies
171
+ WHERE enabled = 0 AND admin_override = 1`)
172
+ .all();
173
+ return new Set(rows.map((row) => row.tool_name));
174
+ }
175
+ catch {
176
+ return new Set();
177
+ }
178
+ }
179
+ /** Retire de `listTools` les tools (et alias) désactivés en admin MCP. */
180
+ export function filterListedToolsByEnabledPolicy(tools, aliases = {}) {
181
+ const disabled = disabledMcpToolPolicyNames();
182
+ if (disabled.size === 0)
183
+ return tools;
184
+ for (const [alias, canonical] of Object.entries(aliases)) {
185
+ if (disabled.has(alias))
186
+ disabled.add(canonical);
187
+ if (disabled.has(canonical))
188
+ disabled.add(alias);
189
+ }
190
+ return tools.filter((tool) => !disabled.has(tool.name) &&
191
+ !(tool.aliasOf && disabled.has(tool.aliasOf)));
192
+ }
193
+ export function updateMcpToolPolicy(name, input) {
194
+ ensureMcpAdminSchema();
195
+ if (!MCP_TOOL_REGISTRY().some((tool) => tool.name === name))
196
+ return null;
197
+ const current = getMcpToolPolicy(name);
198
+ // Rôles/scopes acceptés : injectés par la marque via les adapters
199
+ // (défauts = comportement historique TempoFlow, zéro breaking change).
200
+ const roles = (input.allowedRoles || current.allowedRoles).filter((role) => policyRoleNames().includes(role));
201
+ const scopes = (input.allowedScopes || current.allowedScopes).filter((scope) => policyScopeNames().includes(scope));
202
+ // `admin_override` ne se pose QUE sur une action explicite sur `enabled`
203
+ // (une édition rôles/scopes ne requalifie pas un seed par défaut en
204
+ // désactivation admin) — consommé par disabledMcpToolPolicyNames().
205
+ getWriteDb()
206
+ .prepare(`UPDATE mcp_tool_policies
207
+ SET enabled = ?, allowed_roles = ?, allowed_scopes = ?,
208
+ admin_override = MAX(admin_override, ?),
209
+ updated_at = datetime('now')
210
+ WHERE tool_name = ?`)
211
+ .run((input.enabled ?? current.enabled) ? 1 : 0, roles.join(","), scopes.join(","), input.enabled === undefined ? 0 : 1, name);
212
+ auditMcpAdmin("tool_policy_updated", {
213
+ toolName: name,
214
+ detail: { enabled: input.enabled ?? current.enabled, roles, scopes },
215
+ });
216
+ return getMcpToolPolicy(name);
217
+ }
218
+ export function listMcpClients() {
219
+ ensureMcpAdminSchema();
220
+ if (!mcpOauthReady())
221
+ return [];
222
+ const rows = getDb()
223
+ .prepare(`SELECT c.client_id, c.client_name, c.redirect_uris,
224
+ c.token_endpoint_auth_method, c.scope, c.created_at,
225
+ c.enabled, c.revoked_at, c.last_used_at,
226
+ SUM(CASE WHEN r.revoked_at IS NULL AND r.expires_at > unixepoch() THEN 1 ELSE 0 END)
227
+ AS active_refresh_tokens
228
+ FROM mcp_oauth_clients c
229
+ LEFT JOIN mcp_oauth_refresh_tokens r ON r.client_id = c.client_id
230
+ GROUP BY c.client_id
231
+ ORDER BY c.created_at DESC`)
232
+ .all();
233
+ return rows.map((row) => ({
234
+ ...row,
235
+ enabled: row.enabled !== 0 && !row.revoked_at,
236
+ redirect_uris: safeStringArray(row.redirect_uris),
237
+ active_refresh_tokens: Number(row.active_refresh_tokens || 0),
238
+ }));
239
+ }
240
+ function safeStringArray(raw) {
241
+ try {
242
+ const parsed = JSON.parse(raw);
243
+ return Array.isArray(parsed) ? parsed.map(String) : [];
244
+ }
245
+ catch {
246
+ return [];
247
+ }
248
+ }
249
+ export function setMcpClientEnabled(clientId, enabled) {
250
+ ensureMcpAdminSchema();
251
+ const result = getWriteDb()
252
+ .prepare(`UPDATE mcp_oauth_clients SET enabled = ? WHERE client_id = ? AND revoked_at IS NULL`)
253
+ .run(enabled ? 1 : 0, clientId);
254
+ if (result.changes) {
255
+ if (!enabled)
256
+ revokeClientTokens(clientId);
257
+ auditMcpAdmin(enabled ? "client_enabled" : "client_disabled", { clientId });
258
+ }
259
+ return result.changes > 0;
260
+ }
261
+ export function revokeMcpClient(clientId) {
262
+ ensureMcpAdminSchema();
263
+ const result = getWriteDb()
264
+ .prepare(`UPDATE mcp_oauth_clients
265
+ SET enabled = 0, revoked_at = COALESCE(revoked_at, datetime('now'))
266
+ WHERE client_id = ?`)
267
+ .run(clientId);
268
+ revokeClientTokens(clientId);
269
+ if (result.changes)
270
+ auditMcpAdmin("client_revoked", { clientId });
271
+ return result.changes > 0;
272
+ }
273
+ export function rotateMcpClientSecret(clientId) {
274
+ ensureMcpAdminSchema();
275
+ const client = getDb()
276
+ .prepare(`SELECT token_endpoint_auth_method, revoked_at
277
+ FROM mcp_oauth_clients WHERE client_id = ?`)
278
+ .get(clientId);
279
+ if (!client || client.revoked_at || client.token_endpoint_auth_method === "none")
280
+ return null;
281
+ const clientSecret = randomBytes(32).toString("base64url");
282
+ const hash = createHash("sha256").update(clientSecret, "utf8").digest("hex");
283
+ getWriteDb()
284
+ .prepare(`UPDATE mcp_oauth_clients SET client_secret_hash = ? WHERE client_id = ?`)
285
+ .run(hash, clientId);
286
+ revokeClientTokens(clientId);
287
+ auditMcpAdmin("client_secret_rotated", { clientId });
288
+ return { clientSecret };
289
+ }
290
+ function revokeClientTokens(clientId) {
291
+ getWriteDb()
292
+ .prepare(`UPDATE mcp_oauth_refresh_tokens
293
+ SET revoked_at = COALESCE(revoked_at, unixepoch())
294
+ WHERE client_id = ?`)
295
+ .run(clientId);
296
+ }
297
+ export function clientCanAuthenticate(clientId) {
298
+ ensureMcpAdminSchema();
299
+ const row = getDb()
300
+ .prepare(`SELECT enabled, revoked_at FROM mcp_oauth_clients WHERE client_id = ?`)
301
+ .get(clientId);
302
+ return Boolean(row && row.enabled !== 0 && !row.revoked_at);
303
+ }
304
+ export function touchMcpClient(clientId) {
305
+ ensureMcpAdminSchema();
306
+ getWriteDb()
307
+ .prepare(`UPDATE mcp_oauth_clients SET last_used_at = datetime('now') WHERE client_id = ?`)
308
+ .run(clientId);
309
+ }
310
+ export function mcpAdminStatus() {
311
+ const publicUrl = resolveMcpPublicUrl();
312
+ const clients = listMcpClients();
313
+ const tools = listMcpToolPolicies();
314
+ return {
315
+ ready: mcpOauthReady(),
316
+ publicUrl,
317
+ mcpUrl: publicUrl ? `${publicUrl}/mcp` : null,
318
+ oauthReady: mcpOauthReady(),
319
+ jwtConfigured: Boolean(process.env.MCP_JWT_SECRET),
320
+ toolCount: tools.length,
321
+ enabledToolCount: tools.filter((tool) => tool.enabled).length,
322
+ clientCount: clients.length,
323
+ enabledClientCount: clients.filter((client) => client.enabled).length,
324
+ };
325
+ }
326
+ export function mcpDiagnostics() {
327
+ const status = mcpAdminStatus();
328
+ const checks = [
329
+ { id: "oauth_schema", ok: status.oauthReady, message: "Tables OAuth MCP" },
330
+ { id: "jwt_secret", ok: status.jwtConfigured, message: "Secret JWT MCP configuré" },
331
+ { id: "public_url", ok: Boolean(status.publicUrl), message: "URL publique / tunnel" },
332
+ { id: "tools", ok: status.enabledToolCount > 0, message: "Au moins un tool actif" },
333
+ ];
334
+ return { status, checks, healthy: checks.every((check) => check.ok) };
335
+ }
336
+ export function mcpMetrics() {
337
+ const logs = listRequestLogs({ source: "mcp", limit: 1000 }).logs;
338
+ const errors = logs.filter((log) => log.status >= 400 || log.detail.ok === false);
339
+ const durations = logs.map((log) => log.durationMs).sort((a, b) => a - b);
340
+ return {
341
+ window: "process",
342
+ requests: logs.length,
343
+ errors: errors.length,
344
+ errorRate: logs.length ? errors.length / logs.length : 0,
345
+ averageDurationMs: logs.length
346
+ ? Math.round(logs.reduce((sum, log) => sum + log.durationMs, 0) / logs.length)
347
+ : 0,
348
+ p95DurationMs: durations.length
349
+ ? durations[Math.min(durations.length - 1, Math.floor(durations.length * 0.95))]
350
+ : 0,
351
+ byTool: Object.fromEntries(MCP_TOOL_REGISTRY().map((tool) => [
352
+ tool.name,
353
+ logs.filter((log) => log.detail.tool === tool.name).length,
354
+ ])),
355
+ };
356
+ }
357
+ export function auditMcpAdmin(event, options = {}) {
358
+ ensureMcpAdminSchema();
359
+ getWriteDb()
360
+ .prepare(`INSERT INTO mcp_audit_logs
361
+ (event, actor, client_id, tool_name, outcome, detail_json)
362
+ VALUES (?, ?, ?, ?, ?, ?)`)
363
+ .run(event, options.actor || null, options.clientId || null, options.toolName || null, options.outcome || "ok", options.detail == null ? null : JSON.stringify(options.detail));
364
+ }
365
+ export function listMcpAuditLogs(limit = 200) {
366
+ ensureMcpAdminSchema();
367
+ return getDb()
368
+ .prepare(`SELECT id, created_at, event, actor, client_id, tool_name, outcome, detail_json
369
+ FROM mcp_audit_logs ORDER BY id DESC LIMIT ?`)
370
+ .all(Math.min(1000, Math.max(1, limit)));
371
+ }
372
+ export function pruneMcpAuditLogs(retentionDays = Number(process.env.MCP_AUDIT_RETENTION_DAYS || 30)) {
373
+ if (!tableExists("mcp_audit_logs"))
374
+ return 0;
375
+ const days = Number.isFinite(retentionDays)
376
+ ? Math.min(365, Math.max(1, Math.floor(retentionDays)))
377
+ : 30;
378
+ return getWriteDb()
379
+ .prepare(`DELETE FROM mcp_audit_logs WHERE created_at < datetime('now', ?)`)
380
+ .run(`-${days} days`).changes;
381
+ }
382
+ export function exportMcpDiagnostics() {
383
+ const clients = listMcpClients().map((client) => ({
384
+ idPrefix: client.client_id.slice(0, 12),
385
+ name: client.client_name,
386
+ redirectHosts: client.redirect_uris.map((uri) => {
387
+ try {
388
+ return new URL(uri).host;
389
+ }
390
+ catch {
391
+ return "invalid";
392
+ }
393
+ }),
394
+ scope: client.scope,
395
+ enabled: client.enabled,
396
+ revoked: Boolean(client.revoked_at),
397
+ lastUsedAt: client.last_used_at,
398
+ }));
399
+ return {
400
+ generatedAt: new Date().toISOString(),
401
+ diagnostics: mcpDiagnostics(),
402
+ metrics: mcpMetrics(),
403
+ tools: listMcpToolPolicies().map((tool) => ({
404
+ name: tool.name,
405
+ enabled: tool.enabled,
406
+ requiredScope: tool.requiredScope,
407
+ allowedRoles: tool.allowedRoles,
408
+ allowedScopes: tool.allowedScopes,
409
+ })),
410
+ clients,
411
+ auditRetentionDays: Number(process.env.MCP_AUDIT_RETENTION_DAYS || 30),
412
+ configuration: {
413
+ corsConfigured: Boolean(process.env.MCP_CORS_ORIGINS?.trim()),
414
+ publicUrlConfigured: Boolean(resolveMcpPublicUrl()),
415
+ jwtConfigured: Boolean(process.env.MCP_JWT_SECRET),
416
+ },
417
+ };
418
+ }
419
+ //# sourceMappingURL=mcp-admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-admin.js","sourceRoot":"","sources":["../../src/admin/mcp-admin.ts"],"names":[],"mappings":"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"}