@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.
- package/README.md +420 -0
- package/dist/.creezio-src-hash.json +4 -0
- package/dist/admin/adapters.d.ts +10 -0
- package/dist/admin/adapters.d.ts.map +1 -0
- package/dist/admin/adapters.js +21 -0
- package/dist/admin/adapters.js.map +1 -0
- package/dist/admin/http-routes.d.ts +11 -0
- package/dist/admin/http-routes.d.ts.map +1 -0
- package/dist/admin/http-routes.js +66 -0
- package/dist/admin/http-routes.js.map +1 -0
- package/dist/admin/index.d.ts +12 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +8 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/mcp-admin.d.ts +165 -0
- package/dist/admin/mcp-admin.d.ts.map +1 -0
- package/dist/admin/mcp-admin.js +419 -0
- package/dist/admin/mcp-admin.js.map +1 -0
- package/dist/admin/tool-policy-guard.d.ts +106 -0
- package/dist/admin/tool-policy-guard.d.ts.map +1 -0
- package/dist/admin/tool-policy-guard.js +187 -0
- package/dist/admin/tool-policy-guard.js.map +1 -0
- package/dist/admin/types.d.ts +62 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +6 -0
- package/dist/admin/types.js.map +1 -0
- package/dist/brand-facade.d.ts +41 -0
- package/dist/brand-facade.d.ts.map +1 -0
- package/dist/brand-facade.js +67 -0
- package/dist/brand-facade.js.map +1 -0
- package/dist/core-tools.d.ts +22 -0
- package/dist/core-tools.d.ts.map +1 -0
- package/dist/core-tools.js +93 -0
- package/dist/core-tools.js.map +1 -0
- package/dist/dyn-import.d.ts +13 -0
- package/dist/dyn-import.d.ts.map +1 -0
- package/dist/dyn-import.js +2 -0
- package/dist/dyn-import.js.map +1 -0
- package/dist/facade.d.ts +40 -0
- package/dist/facade.d.ts.map +1 -0
- package/dist/facade.js +334 -0
- package/dist/facade.js.map +1 -0
- package/dist/hono-bind.d.ts +48 -0
- package/dist/hono-bind.d.ts.map +1 -0
- package/dist/hono-bind.js +70 -0
- package/dist/hono-bind.js.map +1 -0
- package/dist/hono-proxy.d.ts +63 -0
- package/dist/hono-proxy.d.ts.map +1 -0
- package/dist/hono-proxy.js +185 -0
- package/dist/hono-proxy.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +20 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +84 -0
- package/dist/jwt.js.map +1 -0
- package/dist/module-ops-tools.d.ts +43 -0
- package/dist/module-ops-tools.d.ts.map +1 -0
- package/dist/module-ops-tools.js +301 -0
- package/dist/module-ops-tools.js.map +1 -0
- package/dist/namespace.d.ts +23 -0
- package/dist/namespace.d.ts.map +1 -0
- package/dist/namespace.js +51 -0
- package/dist/namespace.js.map +1 -0
- package/dist/oauth/cors-policy.d.ts +3 -0
- package/dist/oauth/cors-policy.d.ts.map +1 -0
- package/dist/oauth/cors-policy.js +25 -0
- package/dist/oauth/cors-policy.js.map +1 -0
- package/dist/oauth/hono-app.d.ts +18 -0
- package/dist/oauth/hono-app.d.ts.map +1 -0
- package/dist/oauth/hono-app.js +175 -0
- package/dist/oauth/hono-app.js.map +1 -0
- package/dist/oauth/index.d.ts +9 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/index.js +6 -0
- package/dist/oauth/index.js.map +1 -0
- package/dist/oauth/rate-limit.d.ts +11 -0
- package/dist/oauth/rate-limit.d.ts.map +1 -0
- package/dist/oauth/rate-limit.js +32 -0
- package/dist/oauth/rate-limit.js.map +1 -0
- package/dist/oauth/routes.d.ts +8 -0
- package/dist/oauth/routes.d.ts.map +1 -0
- package/dist/oauth/routes.js +671 -0
- package/dist/oauth/routes.js.map +1 -0
- package/dist/oauth/store.d.ts +113 -0
- package/dist/oauth/store.d.ts.map +1 -0
- package/dist/oauth/store.js +390 -0
- package/dist/oauth/store.js.map +1 -0
- package/dist/oauth/types.d.ts +97 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/types.js +5 -0
- package/dist/oauth/types.js.map +1 -0
- package/dist/open-external-tab-host-tools.d.ts +67 -0
- package/dist/open-external-tab-host-tools.d.ts.map +1 -0
- package/dist/open-external-tab-host-tools.js +92 -0
- package/dist/open-external-tab-host-tools.js.map +1 -0
- package/dist/policy.d.ts +59 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +88 -0
- package/dist/policy.js.map +1 -0
- package/dist/runtime.d.ts +22 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +20 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +163 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist-cjs/admin/adapters.js +27 -0
- package/dist-cjs/admin/adapters.js.map +1 -0
- package/dist-cjs/admin/http-routes.js +69 -0
- package/dist-cjs/admin/http-routes.js.map +1 -0
- package/dist-cjs/admin/index.js +40 -0
- package/dist-cjs/admin/index.js.map +1 -0
- package/dist-cjs/admin/mcp-admin.js +441 -0
- package/dist-cjs/admin/mcp-admin.js.map +1 -0
- package/dist-cjs/admin/tool-policy-guard.js +193 -0
- package/dist-cjs/admin/tool-policy-guard.js.map +1 -0
- package/dist-cjs/admin/types.js +7 -0
- package/dist-cjs/admin/types.js.map +1 -0
- package/dist-cjs/brand-facade.js +70 -0
- package/dist-cjs/brand-facade.js.map +1 -0
- package/dist-cjs/core-tools.js +97 -0
- package/dist-cjs/core-tools.js.map +1 -0
- package/dist-cjs/dyn-import.js +5 -0
- package/dist-cjs/dyn-import.js.map +1 -0
- package/dist-cjs/facade.js +337 -0
- package/dist-cjs/facade.js.map +1 -0
- package/dist-cjs/hono-bind.js +74 -0
- package/dist-cjs/hono-bind.js.map +1 -0
- package/dist-cjs/hono-proxy.js +189 -0
- package/dist-cjs/hono-proxy.js.map +1 -0
- package/dist-cjs/index.js +120 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/jwt.js +91 -0
- package/dist-cjs/jwt.js.map +1 -0
- package/dist-cjs/module-ops-tools.js +308 -0
- package/dist-cjs/module-ops-tools.js.map +1 -0
- package/dist-cjs/namespace.js +56 -0
- package/dist-cjs/namespace.js.map +1 -0
- package/dist-cjs/oauth/cors-policy.js +29 -0
- package/dist-cjs/oauth/cors-policy.js.map +1 -0
- package/dist-cjs/oauth/hono-app.js +178 -0
- package/dist-cjs/oauth/hono-app.js.map +1 -0
- package/dist-cjs/oauth/index.js +48 -0
- package/dist-cjs/oauth/index.js.map +1 -0
- package/dist-cjs/oauth/rate-limit.js +37 -0
- package/dist-cjs/oauth/rate-limit.js.map +1 -0
- package/dist-cjs/oauth/routes.js +674 -0
- package/dist-cjs/oauth/routes.js.map +1 -0
- package/dist-cjs/oauth/store.js +418 -0
- package/dist-cjs/oauth/store.js.map +1 -0
- package/dist-cjs/oauth/types.js +6 -0
- package/dist-cjs/oauth/types.js.map +1 -0
- package/dist-cjs/open-external-tab-host-tools.js +96 -0
- package/dist-cjs/open-external-tab-host-tools.js.map +1 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/policy.js +93 -0
- package/dist-cjs/policy.js.map +1 -0
- package/dist-cjs/runtime.js +24 -0
- package/dist-cjs/runtime.js.map +1 -0
- package/dist-cjs/types.js +3 -0
- package/dist-cjs/types.js.map +1 -0
- package/package.json +92 -0
- package/ui/index.ts +5 -0
- package/ui/mcp-admin-client.tsx +270 -0
- package/ui/primitives/badge.tsx +37 -0
- package/ui/primitives/button.tsx +44 -0
- package/ui/primitives/card.tsx +44 -0
- package/ui/primitives/cn.ts +6 -0
- package/ui/primitives/input.tsx +19 -0
- package/ui/primitives/tabs.tsx +51 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Génération des tools MCP depuis les opérations de module (SoT).
|
|
3
|
+
* Handler = requête synthétique vers le même mount HTTP — zéro 2e implémentation.
|
|
4
|
+
*/
|
|
5
|
+
import { entityOperationsFromSpec, resolveOperationHttpPath, } from "@creezio/api-kernel";
|
|
6
|
+
import { dynImport } from "./dyn-import.js";
|
|
7
|
+
import { verifyAccessToken } from "./oauth/store.js";
|
|
8
|
+
/**
|
|
9
|
+
* Access token OAuth MCP (HS256 MCP_JWT_SECRET — ChatGPT & co) → session
|
|
10
|
+
* plateforme mintée pour le user du consentement (`uid`). Les gardes marque
|
|
11
|
+
* (`requireSession`) ne connaissent que les JWT session AUTH_SECRET : sans
|
|
12
|
+
* cette conversion, tout tool `module.*` répond 401 malgré un OAuth valide.
|
|
13
|
+
* Fail-closed : uid absent/inconnu ou stores indisponibles → null (le 401
|
|
14
|
+
* métier reste la réponse).
|
|
15
|
+
*/
|
|
16
|
+
async function mintSessionFromMcpAccessToken(token) {
|
|
17
|
+
let userId = "";
|
|
18
|
+
try {
|
|
19
|
+
const payload = await verifyAccessToken(token);
|
|
20
|
+
userId = (payload?.user_id || "").trim();
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null; // adapters OAuth non configurés (façade standalone)
|
|
24
|
+
}
|
|
25
|
+
if (!userId)
|
|
26
|
+
return null;
|
|
27
|
+
try {
|
|
28
|
+
const [authMod, tasksMod] = await Promise.all([
|
|
29
|
+
dynImport("@creezio/auth"),
|
|
30
|
+
dynImport("@creezio/tasks"),
|
|
31
|
+
]);
|
|
32
|
+
if (!authMod.createSessionToken)
|
|
33
|
+
return null;
|
|
34
|
+
const users = tasksMod.getTasksBrandConfig?.()?.users;
|
|
35
|
+
let user = null;
|
|
36
|
+
try {
|
|
37
|
+
const found = users?.list().find((u) => u.id === userId && u.active !== false) ??
|
|
38
|
+
null;
|
|
39
|
+
if (found) {
|
|
40
|
+
user = {
|
|
41
|
+
id: found.id,
|
|
42
|
+
username: found.username,
|
|
43
|
+
role: found.role === "owner" ? "owner" : found.role || "collaborator",
|
|
44
|
+
permissions: [...(found.permissions || [])],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* store users indisponible → fallback owner ci-dessous */
|
|
50
|
+
}
|
|
51
|
+
if (!user) {
|
|
52
|
+
try {
|
|
53
|
+
const owner = users?.getOwner?.() ?? null;
|
|
54
|
+
if (owner && owner.id === userId) {
|
|
55
|
+
user = {
|
|
56
|
+
id: owner.id,
|
|
57
|
+
username: owner.username,
|
|
58
|
+
role: "owner",
|
|
59
|
+
permissions: [...(owner.permissions || [])],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* fail-closed */
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!user)
|
|
68
|
+
return null;
|
|
69
|
+
return await authMod.createSessionToken({ user });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Cookie + Authorization pour `requireSession` sur la req synthétique. */
|
|
76
|
+
async function headersFromActor(actor) {
|
|
77
|
+
const headers = {};
|
|
78
|
+
if (actor?.headers) {
|
|
79
|
+
for (const [key, value] of Object.entries(actor.headers)) {
|
|
80
|
+
if (value == null || value === "")
|
|
81
|
+
continue;
|
|
82
|
+
headers[key.toLowerCase()] = String(value);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const raw = (actor?.bearerToken || "").trim();
|
|
86
|
+
if (raw) {
|
|
87
|
+
const token = raw.replace(/^Bearer\s+/i, "").trim();
|
|
88
|
+
if (token && !headers.authorization) {
|
|
89
|
+
headers.authorization = `Bearer ${token}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Bearer JWT : si c'est un access token OAuth MCP, le convertir en
|
|
93
|
+
// session plateforme mintée (sinon inchangé — JWT session déjà valide).
|
|
94
|
+
const authz = (headers.authorization || "")
|
|
95
|
+
.replace(/^Bearer\s+/i, "")
|
|
96
|
+
.trim();
|
|
97
|
+
if (authz && authz.split(".").length === 3) {
|
|
98
|
+
const minted = await mintSessionFromMcpAccessToken(authz);
|
|
99
|
+
if (minted)
|
|
100
|
+
headers.authorization = `Bearer ${minted}`;
|
|
101
|
+
}
|
|
102
|
+
return Object.keys(headers).length ? headers : undefined;
|
|
103
|
+
}
|
|
104
|
+
function interpolatePath(template, args) {
|
|
105
|
+
const used = new Set();
|
|
106
|
+
const path = template.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, (_, name) => {
|
|
107
|
+
used.add(name);
|
|
108
|
+
const value = args[name];
|
|
109
|
+
return encodeURIComponent(value == null ? "" : String(value));
|
|
110
|
+
});
|
|
111
|
+
return { path, used };
|
|
112
|
+
}
|
|
113
|
+
function asQuery(rest) {
|
|
114
|
+
const query = {};
|
|
115
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
116
|
+
if (value == null)
|
|
117
|
+
continue;
|
|
118
|
+
if (Array.isArray(value)) {
|
|
119
|
+
query[key] = value.map((v) => String(v)).join(",");
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (typeof value === "object")
|
|
123
|
+
continue;
|
|
124
|
+
query[key] = String(value);
|
|
125
|
+
}
|
|
126
|
+
return query;
|
|
127
|
+
}
|
|
128
|
+
function defaultInputSchema(op) {
|
|
129
|
+
if (op.inputSchema && typeof op.inputSchema === "object") {
|
|
130
|
+
return op.inputSchema;
|
|
131
|
+
}
|
|
132
|
+
const params = [
|
|
133
|
+
...normalizePath(op.path).matchAll(/:([A-Za-z_][A-Za-z0-9_]*)/g),
|
|
134
|
+
].map((m) => m[1]);
|
|
135
|
+
const properties = {};
|
|
136
|
+
for (const name of params)
|
|
137
|
+
properties[name] = { type: "string" };
|
|
138
|
+
return {
|
|
139
|
+
type: "object",
|
|
140
|
+
properties,
|
|
141
|
+
required: params,
|
|
142
|
+
additionalProperties: true,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function normalizePath(path) {
|
|
146
|
+
const raw = String(path || "").trim();
|
|
147
|
+
if (!raw || raw === "/")
|
|
148
|
+
return "/";
|
|
149
|
+
return raw.startsWith("/") ? raw : `/${raw}`;
|
|
150
|
+
}
|
|
151
|
+
function restArgs(args, used) {
|
|
152
|
+
const rest = {};
|
|
153
|
+
for (const [key, value] of Object.entries(args)) {
|
|
154
|
+
if (used.has(key))
|
|
155
|
+
continue;
|
|
156
|
+
rest[key] = value;
|
|
157
|
+
}
|
|
158
|
+
return rest;
|
|
159
|
+
}
|
|
160
|
+
function responseToToolResult(res) {
|
|
161
|
+
if (res.status >= 400) {
|
|
162
|
+
const body = res.body;
|
|
163
|
+
return {
|
|
164
|
+
ok: false,
|
|
165
|
+
error: (body && typeof body === "object" && body.error) ||
|
|
166
|
+
`http_${res.status}`,
|
|
167
|
+
content: res.body,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return { ok: true, content: res.body };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Génère un tool MCP par op — `module.<id>.<op.id>`.
|
|
174
|
+
* Handler = requête synthétique (method/path/body) vers le même
|
|
175
|
+
* `ApiMount.handle` via `invokeMount` (typiquement `api.handle`) —
|
|
176
|
+
* zéro 2ᵉ implémentation métier.
|
|
177
|
+
*/
|
|
178
|
+
export function generateModuleToolsFromOperations(moduleId, ops, invokeMount, options = {}) {
|
|
179
|
+
const mountId = options.mountId || moduleId;
|
|
180
|
+
const space = options.space || "module";
|
|
181
|
+
const tools = [];
|
|
182
|
+
for (const op of ops) {
|
|
183
|
+
const template = resolveOperationHttpPath(space, mountId, op.path);
|
|
184
|
+
tools.push({
|
|
185
|
+
name: `module.${mountId}.${op.id}`,
|
|
186
|
+
description: op.description,
|
|
187
|
+
space: "module",
|
|
188
|
+
ownerId: moduleId,
|
|
189
|
+
inputSchema: defaultInputSchema(op),
|
|
190
|
+
...(op.roles?.length ? { defaultRoles: op.roles } : {}),
|
|
191
|
+
mcpPublishDefault: op.mcpPublishDefault === true,
|
|
192
|
+
requiredScope: op.method === "GET" ? "crm:read" : op.permission || "crm:write",
|
|
193
|
+
handler: async (args, actor) => {
|
|
194
|
+
const { path, used } = interpolatePath(template, args);
|
|
195
|
+
const rest = restArgs(args, used);
|
|
196
|
+
const method = op.method;
|
|
197
|
+
const headers = await headersFromActor(actor);
|
|
198
|
+
const req = {
|
|
199
|
+
method,
|
|
200
|
+
path,
|
|
201
|
+
...(headers ? { headers } : {}),
|
|
202
|
+
...(method === "GET"
|
|
203
|
+
? { query: asQuery(rest) }
|
|
204
|
+
: { body: rest }),
|
|
205
|
+
};
|
|
206
|
+
return responseToToolResult(await invokeMount(req));
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return tools;
|
|
211
|
+
}
|
|
212
|
+
function toolsFromListedOps(api, listed, spaces) {
|
|
213
|
+
const byMount = new Map();
|
|
214
|
+
for (const { space, mountId, op } of listed) {
|
|
215
|
+
if (!spaces.has(space))
|
|
216
|
+
continue;
|
|
217
|
+
const cur = byMount.get(mountId);
|
|
218
|
+
if (cur) {
|
|
219
|
+
cur.ops.push(op);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
byMount.set(mountId, { space, ops: [op] });
|
|
223
|
+
}
|
|
224
|
+
const invokeMount = (req) => api.handle(req);
|
|
225
|
+
const out = [];
|
|
226
|
+
for (const [mountId, { space, ops }] of byMount) {
|
|
227
|
+
out.push(...generateModuleToolsFromOperations(mountId, ops, invokeMount, {
|
|
228
|
+
mountId,
|
|
229
|
+
space,
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Tools `module.*` générés depuis `api.listOperations()` (space module).
|
|
236
|
+
* SoT runtime — `BrandModuleDef.mcpTools` n'existe plus.
|
|
237
|
+
*/
|
|
238
|
+
export function generateModuleToolsFromListedOps(api, listed) {
|
|
239
|
+
return toolsFromListedOps(api, listed ?? api.listOperations(), new Set(["module"]));
|
|
240
|
+
}
|
|
241
|
+
/** Tools générés depuis les mounts déjà enregistrés sur le kernel. */
|
|
242
|
+
export function generateModuleToolsFromMountedOps(api, mounts) {
|
|
243
|
+
if (!mounts) {
|
|
244
|
+
return toolsFromListedOps(api, api.listOperations(), new Set(["module", "platform"]));
|
|
245
|
+
}
|
|
246
|
+
const out = [];
|
|
247
|
+
for (const mount of mounts) {
|
|
248
|
+
if (mount.space !== "module" && mount.space !== "platform")
|
|
249
|
+
continue;
|
|
250
|
+
if (!mount.operations?.length)
|
|
251
|
+
continue;
|
|
252
|
+
out.push(...generateModuleToolsFromOperations(mount.id, mount.operations, (req) => api.handle(req), { mountId: mount.id, space: mount.space }));
|
|
253
|
+
}
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Discovery runtime : uniquement `listOperations()` (space module).
|
|
258
|
+
* `extraTools` = hook apps (health, JWT) — pas de `mcpTools` manuscrit.
|
|
259
|
+
*/
|
|
260
|
+
export function discoverModuleToolsFromKernel(api, extraTools = []) {
|
|
261
|
+
const generated = generateModuleToolsFromListedOps(api);
|
|
262
|
+
if (!extraTools.length)
|
|
263
|
+
return generated;
|
|
264
|
+
const seen = new Set(generated.map((t) => t.name));
|
|
265
|
+
return [...generated, ...extraTools.filter((t) => !seen.has(t.name))];
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Discovery kit-side : SoT = `api.listOperations()` (space module).
|
|
269
|
+
* Fallback : ops des BrandModuleDef (EntitySpec CRUD + apiMounts) si le
|
|
270
|
+
* kernel n'a pas encore les mounts. Pas de champ `mcpTools`.
|
|
271
|
+
*/
|
|
272
|
+
export function discoverModuleToolsFromBrandModules(modules, api) {
|
|
273
|
+
const fromKernel = generateModuleToolsFromListedOps(api);
|
|
274
|
+
if (fromKernel.length)
|
|
275
|
+
return fromKernel;
|
|
276
|
+
const generated = [];
|
|
277
|
+
const invoke = (req) => api.handle(req);
|
|
278
|
+
for (const mod of modules) {
|
|
279
|
+
const seenOp = new Set();
|
|
280
|
+
for (const [mountId, spec] of Object.entries(mod.entitySpecs ?? {})) {
|
|
281
|
+
const ops = entityOperationsFromSpec(spec);
|
|
282
|
+
for (const op of ops)
|
|
283
|
+
seenOp.add(`${mountId}:${op.id}`);
|
|
284
|
+
generated.push(...generateModuleToolsFromOperations(mod.id, ops, invoke, {
|
|
285
|
+
mountId,
|
|
286
|
+
space: "module",
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
for (const [mountId, mount] of Object.entries(mod.apiMounts ?? {})) {
|
|
290
|
+
const extras = (mount.operations ?? []).filter((op) => !seenOp.has(`${mountId}:${op.id}`));
|
|
291
|
+
if (!extras.length)
|
|
292
|
+
continue;
|
|
293
|
+
generated.push(...generateModuleToolsFromOperations(mod.id, extras, invoke, {
|
|
294
|
+
mountId,
|
|
295
|
+
space: "module",
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return generated;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=module-ops-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-ops-tools.js","sourceRoot":"","sources":["../src/module-ops-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namespacing H4 — core.* / creezio.* · module.<owner>.* · plugin.<owner>.*
|
|
3
|
+
*/
|
|
4
|
+
import type { McpToolSpace } from "./types.js";
|
|
5
|
+
export type ParsedToolName = {
|
|
6
|
+
space: McpToolSpace;
|
|
7
|
+
ownerId?: string;
|
|
8
|
+
rest: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Parse un nom de tool namespacé. Retourne null si le format est invalide
|
|
12
|
+
* pour la couche attendue.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseNamespacedToolName(name: string): ParsedToolName | null;
|
|
15
|
+
/**
|
|
16
|
+
* Vérifie qu'un tool déclaré respecte le préfixe de sa `space`.
|
|
17
|
+
* Les alias legacy (snake_case historique) ne passent pas ici — ils
|
|
18
|
+
* passent par `registerAlias`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertNamespacedToolName(space: McpToolSpace, name: string, ownerId?: string): void;
|
|
21
|
+
/** True si le nom ressemble à un alias legacy (hors namespace H4). */
|
|
22
|
+
export declare function isLegacyAliasName(name: string): boolean;
|
|
23
|
+
//# sourceMappingURL=namespace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../src/namespace.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAc3E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAsBN;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namespacing H4 — core.* / creezio.* · module.<owner>.* · plugin.<owner>.*
|
|
3
|
+
*/
|
|
4
|
+
const OWNER_RE = /^[a-z][a-z0-9_-]{0,62}$/;
|
|
5
|
+
/**
|
|
6
|
+
* Parse un nom de tool namespacé. Retourne null si le format est invalide
|
|
7
|
+
* pour la couche attendue.
|
|
8
|
+
*/
|
|
9
|
+
export function parseNamespacedToolName(name) {
|
|
10
|
+
if (!name || typeof name !== "string")
|
|
11
|
+
return null;
|
|
12
|
+
if (name.startsWith("creezio.") || name.startsWith("core.")) {
|
|
13
|
+
return { space: "core", rest: name.replace(/^(creezio|core)\./, "") };
|
|
14
|
+
}
|
|
15
|
+
const mod = /^module\.([a-z][a-z0-9_-]{0,62})\.(.+)$/.exec(name);
|
|
16
|
+
if (mod) {
|
|
17
|
+
return { space: "module", ownerId: mod[1], rest: mod[2] };
|
|
18
|
+
}
|
|
19
|
+
const plug = /^plugin\.([a-z][a-z0-9_-]{0,62})\.(.+)$/.exec(name);
|
|
20
|
+
if (plug) {
|
|
21
|
+
return { space: "plugin", ownerId: plug[1], rest: plug[2] };
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Vérifie qu'un tool déclaré respecte le préfixe de sa `space`.
|
|
27
|
+
* Les alias legacy (snake_case historique) ne passent pas ici — ils
|
|
28
|
+
* passent par `registerAlias`.
|
|
29
|
+
*/
|
|
30
|
+
export function assertNamespacedToolName(space, name, ownerId) {
|
|
31
|
+
const parsed = parseNamespacedToolName(name);
|
|
32
|
+
if (!parsed) {
|
|
33
|
+
throw new Error(`mcp_namespace_invalid: « ${name} » doit être core.*/creezio.* | module.<id>.* | plugin.<id>.*`);
|
|
34
|
+
}
|
|
35
|
+
if (parsed.space !== space) {
|
|
36
|
+
throw new Error(`mcp_namespace_mismatch: « ${name} » parse comme ${parsed.space}, déclaré ${space}`);
|
|
37
|
+
}
|
|
38
|
+
if (space === "module" || space === "plugin") {
|
|
39
|
+
if (!ownerId || !OWNER_RE.test(ownerId)) {
|
|
40
|
+
throw new Error(`mcp_owner_invalid: ownerId requis pour space=${space}`);
|
|
41
|
+
}
|
|
42
|
+
if (parsed.ownerId !== ownerId) {
|
|
43
|
+
throw new Error(`mcp_owner_mismatch: nom « ${name} » owner=${parsed.ownerId}, déclaré ${ownerId}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** True si le nom ressemble à un alias legacy (hors namespace H4). */
|
|
48
|
+
export function isLegacyAliasName(name) {
|
|
49
|
+
return parseNamespacedToolName(name) === null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace.js","sourceRoot":"","sources":["../src/namespace.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,EAAE,CAAC;IACxE,CAAC;IACD,MAAM,GAAG,GAAG,yCAAyC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,yCAAyC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAmB,EACnB,IAAY,EACZ,OAAgB;IAEhB,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,+DAA+D,CAChG,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,kBAAkB,MAAM,CAAC,KAAK,aAAa,KAAK,EAAE,CACpF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,gDAAgD,KAAK,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,YAAY,MAAM,CAAC,OAAO,aAAa,OAAO,EAAE,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,uBAAuB,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors-policy.d.ts","sourceRoot":"","sources":["../../src/oauth/cors-policy.ts"],"names":[],"mappings":"AAQA,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAY3C;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAK3D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveMcpPublicUrl } from "./store.js";
|
|
2
|
+
const SAFE_DEFAULTS = [
|
|
3
|
+
"https://chatgpt.com",
|
|
4
|
+
"https://chat.openai.com",
|
|
5
|
+
"https://claude.ai",
|
|
6
|
+
];
|
|
7
|
+
export function mcpCorsAllowlist() {
|
|
8
|
+
const configured = (process.env.MCP_CORS_ORIGINS || "")
|
|
9
|
+
.split(",")
|
|
10
|
+
.map((origin) => origin.trim().replace(/\/+$/, ""))
|
|
11
|
+
.filter(Boolean);
|
|
12
|
+
const publicUrl = resolveMcpPublicUrl();
|
|
13
|
+
return Array.from(new Set([
|
|
14
|
+
...(configured.length ? configured : SAFE_DEFAULTS),
|
|
15
|
+
...(publicUrl ? [publicUrl] : []),
|
|
16
|
+
]));
|
|
17
|
+
}
|
|
18
|
+
export function resolveMcpCorsOrigin(origin) {
|
|
19
|
+
// Requêtes serveur-à-serveur et loopback sans Origin.
|
|
20
|
+
if (!origin)
|
|
21
|
+
return "*";
|
|
22
|
+
const normalized = origin.replace(/\/+$/, "");
|
|
23
|
+
return mcpCorsAllowlist().includes(normalized) ? origin : "";
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cors-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors-policy.js","sourceRoot":"","sources":["../../src/oauth/cors-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,aAAa,GAAG;IACpB,qBAAqB;IACrB,yBAAyB;IACzB,mBAAmB;CACpB,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC9B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;SACpD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;SAClD,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IACxC,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,GAAG,CAAC;QACN,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAClC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,sDAAsD;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IACxB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,OAAO,gBAAgB,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory Hono `/mcp` + OAuth — SoT kit (équivalent fonctionnel server/mcp/app.ts).
|
|
3
|
+
* Transport Streamable HTTP et buildMcpServer restent injectés par la marque.
|
|
4
|
+
*/
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
import type { CreateMcpHonoAppOptions } from "./types.js";
|
|
7
|
+
type McpAppEnv = {
|
|
8
|
+
Variables: {
|
|
9
|
+
mcpAuth: {
|
|
10
|
+
authType: "api_key" | "oauth";
|
|
11
|
+
clientId: string;
|
|
12
|
+
userId: string | null;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function createMcpHonoApp(options: CreateMcpHonoAppOptions): Hono<McpAppEnv>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=hono-app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-app.d.ts","sourceRoot":"","sources":["../../src/oauth/hono-app.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,KAAK,SAAS,GAAG;IACf,SAAS,EAAE;QACT,OAAO,EAAE;YACP,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;YAC9B,QAAQ,EAAE,MAAM,CAAC;YACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;SACvB,CAAC;KACH,CAAC;CACH,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,CAuMlF"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory Hono `/mcp` + OAuth — SoT kit (équivalent fonctionnel server/mcp/app.ts).
|
|
3
|
+
* Transport Streamable HTTP et buildMcpServer restent injectés par la marque.
|
|
4
|
+
*/
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
import { cors } from "hono/cors";
|
|
7
|
+
import { clientCanAuthenticate } from "../admin/mcp-admin.js";
|
|
8
|
+
import { getClient, isMcpPublicUrlRequiredError, mcpBaseUrl, verifyAccessToken, } from "./store.js";
|
|
9
|
+
import { checkMcpRateLimit, rateLimitHeaders } from "./rate-limit.js";
|
|
10
|
+
import { resolveMcpCorsOrigin } from "./cors-policy.js";
|
|
11
|
+
export function createMcpHonoApp(options) {
|
|
12
|
+
const mcpApp = new Hono();
|
|
13
|
+
const rateLimit = options.mcpRateLimit?.limit ?? 120;
|
|
14
|
+
const rateWindow = options.mcpRateLimit?.windowMs ?? 60_000;
|
|
15
|
+
const resolveCors = options.resolveCorsOrigin ?? resolveMcpCorsOrigin;
|
|
16
|
+
if (options.ensureSchema) {
|
|
17
|
+
mcpApp.use("*", async (_c, next) => {
|
|
18
|
+
options.ensureSchema?.();
|
|
19
|
+
await next();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
mcpApp.use("*", cors({
|
|
23
|
+
origin: resolveCors,
|
|
24
|
+
allowMethods: ["GET", "POST", "DELETE", "OPTIONS"],
|
|
25
|
+
allowHeaders: [
|
|
26
|
+
"Authorization",
|
|
27
|
+
"Content-Type",
|
|
28
|
+
"Mcp-Session-Id",
|
|
29
|
+
"MCP-Protocol-Version",
|
|
30
|
+
],
|
|
31
|
+
exposeHeaders: ["Mcp-Session-Id", "WWW-Authenticate"],
|
|
32
|
+
maxAge: 86400,
|
|
33
|
+
}));
|
|
34
|
+
mcpApp.route("/", options.oauthRoutes);
|
|
35
|
+
if (options.mcpMiddleware) {
|
|
36
|
+
mcpApp.use("/mcp", options.mcpMiddleware);
|
|
37
|
+
}
|
|
38
|
+
function tunnelRequired() {
|
|
39
|
+
return new Response(JSON.stringify({
|
|
40
|
+
error: "temporarily_unavailable",
|
|
41
|
+
error_description: "tunnel requis — configurez l'accès mobile (APP_PUBLIC_URL / MCP_PUBLIC_URL)",
|
|
42
|
+
}), { status: 503, headers: { "Content-Type": "application/json" } });
|
|
43
|
+
}
|
|
44
|
+
function unauthorized(description, opts) {
|
|
45
|
+
const headers = {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
};
|
|
48
|
+
if (opts?.publicMeta !== false) {
|
|
49
|
+
try {
|
|
50
|
+
const meta = `${mcpBaseUrl()}/.well-known/oauth-protected-resource/mcp`;
|
|
51
|
+
headers["WWW-Authenticate"] =
|
|
52
|
+
`Bearer resource_metadata="${meta}", ` +
|
|
53
|
+
`error="invalid_token", error_description="${description}"`;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
if (!isMcpPublicUrlRequiredError(e))
|
|
57
|
+
throw e;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return new Response(JSON.stringify({
|
|
61
|
+
jsonrpc: "2.0",
|
|
62
|
+
error: { code: -32001, message: `Unauthorized: ${description}` },
|
|
63
|
+
id: null,
|
|
64
|
+
}), { status: 401, headers });
|
|
65
|
+
}
|
|
66
|
+
mcpApp.all("/mcp", async (c) => {
|
|
67
|
+
const auth = c.req.header("authorization") || "";
|
|
68
|
+
const token = auth.replace(/^Bearer\s+/i, "").trim();
|
|
69
|
+
if (!token || token === auth) {
|
|
70
|
+
return unauthorized("Bearer token manquant");
|
|
71
|
+
}
|
|
72
|
+
const apiKeyAuth = options.apiKeyAuth;
|
|
73
|
+
if (apiKeyAuth && token.startsWith(apiKeyAuth.prefix)) {
|
|
74
|
+
const key = apiKeyAuth.verify(token);
|
|
75
|
+
if (!key) {
|
|
76
|
+
return unauthorized("clé API invalide ou révoquée", {
|
|
77
|
+
publicMeta: false,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const rate = checkMcpRateLimit(`mcp:api-key:${key.id}`, rateLimit, rateWindow);
|
|
81
|
+
for (const [name, value] of Object.entries(rateLimitHeaders(rate))) {
|
|
82
|
+
c.header(name, value);
|
|
83
|
+
}
|
|
84
|
+
if (!rate.ok) {
|
|
85
|
+
return c.json({
|
|
86
|
+
error: "rate_limit_exceeded",
|
|
87
|
+
error_description: "Limite MCP atteinte",
|
|
88
|
+
}, 429);
|
|
89
|
+
}
|
|
90
|
+
const userId = apiKeyAuth.resolveUserId?.(key) ?? key.user_id ?? null;
|
|
91
|
+
c.set("mcpAuth", {
|
|
92
|
+
authType: "api_key",
|
|
93
|
+
clientId: `api-key:${key.id}`,
|
|
94
|
+
userId,
|
|
95
|
+
});
|
|
96
|
+
const server = await options.buildMcpServer({
|
|
97
|
+
userId,
|
|
98
|
+
clientId: `api-key:${key.id}`,
|
|
99
|
+
scopes: key.scopes,
|
|
100
|
+
});
|
|
101
|
+
const transport = options.createTransport();
|
|
102
|
+
await server.connect(transport);
|
|
103
|
+
try {
|
|
104
|
+
return await transport.handleRequest(c);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
queueMicrotask(() => {
|
|
108
|
+
transport.close().catch(() => { });
|
|
109
|
+
server.close().catch(() => { });
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
mcpBaseUrl();
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
if (isMcpPublicUrlRequiredError(e))
|
|
118
|
+
return tunnelRequired();
|
|
119
|
+
throw e;
|
|
120
|
+
}
|
|
121
|
+
const payload = await verifyAccessToken(token);
|
|
122
|
+
if (!payload) {
|
|
123
|
+
return unauthorized("token invalide ou expiré");
|
|
124
|
+
}
|
|
125
|
+
let clientOk = false;
|
|
126
|
+
try {
|
|
127
|
+
clientOk = clientCanAuthenticate(payload.client_id);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Admin adapters absents : fallback store (filtre enabled/revoked).
|
|
131
|
+
clientOk = Boolean(getClient(payload.client_id));
|
|
132
|
+
}
|
|
133
|
+
if (!clientOk) {
|
|
134
|
+
return unauthorized("client OAuth désactivé ou révoqué");
|
|
135
|
+
}
|
|
136
|
+
const rate = checkMcpRateLimit(`mcp:oauth:${payload.client_id}`, rateLimit, rateWindow);
|
|
137
|
+
for (const [name, value] of Object.entries(rateLimitHeaders(rate))) {
|
|
138
|
+
c.header(name, value);
|
|
139
|
+
}
|
|
140
|
+
if (!rate.ok) {
|
|
141
|
+
return c.json({
|
|
142
|
+
error: "rate_limit_exceeded",
|
|
143
|
+
error_description: "Limite MCP atteinte",
|
|
144
|
+
}, 429);
|
|
145
|
+
}
|
|
146
|
+
c.set("mcpAuth", {
|
|
147
|
+
authType: "oauth",
|
|
148
|
+
clientId: payload.client_id,
|
|
149
|
+
userId: payload.user_id,
|
|
150
|
+
});
|
|
151
|
+
const server = await options.buildMcpServer({
|
|
152
|
+
userId: payload.user_id,
|
|
153
|
+
clientId: payload.client_id,
|
|
154
|
+
scopes: payload.scope,
|
|
155
|
+
});
|
|
156
|
+
const transport = options.createTransport();
|
|
157
|
+
await server.connect(transport);
|
|
158
|
+
try {
|
|
159
|
+
return await transport.handleRequest(c);
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
queueMicrotask(() => {
|
|
163
|
+
transport.close().catch(() => { });
|
|
164
|
+
server.close().catch(() => { });
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
mcpApp.notFound((c) => c.json({ error: "Route inconnue" }, 404));
|
|
169
|
+
mcpApp.onError((err, c) => {
|
|
170
|
+
console.error("[mcp]", err);
|
|
171
|
+
return c.json({ error: err instanceof Error ? err.message : "Erreur serveur" }, 500);
|
|
172
|
+
});
|
|
173
|
+
return mcpApp;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=hono-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-app.js","sourceRoot":"","sources":["../../src/oauth/hono-app.ts"],"names":[],"mappings":"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"}
|