@mcpolyglot/core 0.1.0 → 0.3.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/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/oauth.test.d.ts +2 -0
- package/dist/__tests__/oauth.test.d.ts.map +1 -0
- package/dist/__tests__/oauth.test.js +158 -0
- package/dist/__tests__/oauth.test.js.map +1 -0
- package/dist/__tests__/pipeline.test.d.ts +2 -0
- package/dist/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline.test.js +179 -0
- package/dist/__tests__/pipeline.test.js.map +1 -0
- package/dist/__tests__/streamable-http.test.d.ts +2 -0
- package/dist/__tests__/streamable-http.test.d.ts.map +1 -0
- package/dist/__tests__/streamable-http.test.js +105 -0
- package/dist/__tests__/streamable-http.test.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +41 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +91 -36
- package/dist/server.js.map +1 -1
- package/dist/tool.d.ts +12 -3
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js.map +1 -1
- package/dist/transport.d.ts +5 -2
- package/dist/transport.d.ts.map +1 -1
- package/dist/transports/oauth.d.ts +56 -0
- package/dist/transports/oauth.d.ts.map +1 -0
- package/dist/transports/oauth.js +65 -0
- package/dist/transports/oauth.js.map +1 -0
- package/dist/transports/stdio.d.ts +1 -1
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +2 -2
- package/dist/transports/stdio.js.map +1 -1
- package/dist/transports/streamable-http.d.ts +52 -4
- package/dist/transports/streamable-http.d.ts.map +1 -1
- package/dist/transports/streamable-http.js +136 -26
- package/dist/transports/streamable-http.js.map +1 -1
- package/package.json +4 -4
package/dist/server.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { randomUUID, createHash } from 'node:crypto';
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
3
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
-
import {
|
|
4
|
+
import { z } from 'zod';
|
|
5
5
|
import { DEFAULT_SCOPES, } from './tool.js';
|
|
6
|
-
import { McpolyglotError,
|
|
6
|
+
import { McpolyglotError, TimeoutError } from './errors.js';
|
|
7
7
|
/**
|
|
8
8
|
* MCP server that wires connectors + security hooks + a transport.
|
|
9
9
|
*
|
|
@@ -29,11 +29,12 @@ import { McpolyglotError, ScopeError, TimeoutError } from './errors.js';
|
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
export class McpolyglotServer {
|
|
32
|
-
|
|
32
|
+
info;
|
|
33
33
|
tools = new Map();
|
|
34
34
|
connectors;
|
|
35
35
|
perEntity;
|
|
36
36
|
scopes;
|
|
37
|
+
agents;
|
|
37
38
|
security;
|
|
38
39
|
sessionId = randomUUID();
|
|
39
40
|
logger;
|
|
@@ -44,38 +45,51 @@ export class McpolyglotServer {
|
|
|
44
45
|
this.scopes = new Set(opts.scopes ?? DEFAULT_SCOPES);
|
|
45
46
|
this.security = opts.security;
|
|
46
47
|
this.logger = opts.logger ?? makeNoopLogger();
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
49
|
-
|
|
48
|
+
this.agents = new Map((opts.agents ?? []).map((a) => [a.id, { ...a, tools: new Map() }]));
|
|
49
|
+
this.info = { name: opts.name ?? 'mcpolyglot', version: opts.version ?? '0.0.1' };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A fresh MCP protocol server bound to this instance's tools and pipeline. Stdio makes one;
|
|
53
|
+
* the stateless HTTP transport makes one per request (the SDK forbids reusing either).
|
|
54
|
+
*/
|
|
55
|
+
createMcpServer() {
|
|
56
|
+
const server = new Server(this.info, { capabilities: { tools: {} } });
|
|
57
|
+
server.setRequestHandler(ListToolsRequestSchema, async (_req, extra) => ({
|
|
58
|
+
tools: Array.from(this.caller(server, extra).tools.values()).map((t) => ({
|
|
50
59
|
name: t.name,
|
|
51
60
|
description: t.description,
|
|
52
|
-
inputSchema:
|
|
61
|
+
inputSchema: z.toJSONSchema(t.inputSchema, { target: 'draft-7' }),
|
|
53
62
|
})),
|
|
54
63
|
}));
|
|
55
|
-
|
|
56
|
-
const
|
|
64
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
65
|
+
const caller = this.caller(server, extra);
|
|
66
|
+
const def = caller.tools.get(req.params.name);
|
|
57
67
|
if (!def) {
|
|
58
68
|
throw new McpolyglotError('tool.not_found', `Unknown tool: ${req.params.name}`);
|
|
59
69
|
}
|
|
60
|
-
const internal = await this.executeTool(def, req.params.arguments ?? {});
|
|
70
|
+
const internal = await this.executeTool(def, req.params.arguments ?? {}, caller);
|
|
61
71
|
return toMcpResult(internal);
|
|
62
72
|
});
|
|
73
|
+
return server;
|
|
63
74
|
}
|
|
64
75
|
async start(transport) {
|
|
65
|
-
for (const c of this.
|
|
76
|
+
for (const c of this.allConnectors())
|
|
66
77
|
await c.init({ logger: this.logger });
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
for (const c of this.connectors) {
|
|
79
|
+
for (const tool of this.toolsOf(c))
|
|
80
|
+
registerTool(this.tools, tool);
|
|
81
|
+
}
|
|
82
|
+
for (const a of this.agents.values()) {
|
|
83
|
+
for (const c of a.connectors) {
|
|
84
|
+
for (const tool of this.toolsOf(c)) {
|
|
85
|
+
// Agents only see tools their scopes fully cover.
|
|
86
|
+
if (tool.scopes.every((s) => a.scopes.includes(s)))
|
|
87
|
+
registerTool(a.tools, tool);
|
|
74
88
|
}
|
|
75
89
|
}
|
|
76
90
|
}
|
|
77
91
|
this.transport = transport;
|
|
78
|
-
await transport.start(this.
|
|
92
|
+
await transport.start(() => this.createMcpServer());
|
|
79
93
|
this.logger.info('mcpolyglot.started', {
|
|
80
94
|
sessionId: this.sessionId,
|
|
81
95
|
transport: transport.kind,
|
|
@@ -84,51 +98,76 @@ export class McpolyglotServer {
|
|
|
84
98
|
}
|
|
85
99
|
async stop() {
|
|
86
100
|
await this.transport?.stop();
|
|
87
|
-
for (const c of this.
|
|
101
|
+
for (const c of this.allConnectors()) {
|
|
88
102
|
await c.close();
|
|
89
103
|
}
|
|
90
|
-
await this.server.close();
|
|
91
104
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
105
|
+
allConnectors() {
|
|
106
|
+
return new Set([...this.connectors, ...[...this.agents.values()].flatMap((a) => a.connectors)]);
|
|
107
|
+
}
|
|
108
|
+
toolsOf(c) {
|
|
109
|
+
const cfg = this.perEntity[c.id];
|
|
110
|
+
return [...c.listPrimitiveTools(), ...(cfg?.enabled ? c.generatePerEntityTools(cfg) : [])];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Who is calling. Only `authInfo` set by our HTTP transport identifies an agent; headers
|
|
114
|
+
* and clientInfo are client-asserted and only used as an audit label when it's absent.
|
|
115
|
+
*/
|
|
116
|
+
caller(server, extra) {
|
|
117
|
+
const agent = extra.authInfo ? this.agents.get(extra.authInfo.clientId) : undefined;
|
|
118
|
+
if (agent) {
|
|
119
|
+
return {
|
|
120
|
+
agentId: agent.id,
|
|
121
|
+
scopes: new Set(agent.scopes),
|
|
122
|
+
tools: agent.tools,
|
|
123
|
+
rateKey: `agent:${agent.id}`,
|
|
124
|
+
};
|
|
95
125
|
}
|
|
96
|
-
|
|
126
|
+
const header = extra.requestInfo?.headers['x-mcpolyglot-agent'];
|
|
127
|
+
return {
|
|
128
|
+
agentId: (Array.isArray(header) ? header[0] : header) ?? server.getClientVersion()?.name,
|
|
129
|
+
scopes: this.scopes,
|
|
130
|
+
tools: this.tools,
|
|
131
|
+
rateKey: this.sessionId,
|
|
132
|
+
};
|
|
97
133
|
}
|
|
98
134
|
/**
|
|
99
135
|
* Fixed pipeline: scope check → rate limit → timeout → handler →
|
|
100
136
|
* redaction → size cap → untrusted-wrap → audit log → response.
|
|
101
137
|
* Connectors cannot bypass.
|
|
102
138
|
*/
|
|
103
|
-
async executeTool(def, rawArgs) {
|
|
139
|
+
async executeTool(def, rawArgs, caller) {
|
|
140
|
+
const { agentId, scopes } = caller;
|
|
104
141
|
const started = Date.now();
|
|
105
142
|
const argsHash = hashArgs(rawArgs);
|
|
106
143
|
let result;
|
|
107
144
|
let errorEntry;
|
|
145
|
+
let decision = 'allow';
|
|
146
|
+
let release = undefined;
|
|
108
147
|
try {
|
|
109
148
|
// 1. scope check
|
|
110
|
-
this.security.hooks.checkScopes(def.name, def.scopes,
|
|
149
|
+
this.security.hooks.checkScopes(def.name, def.scopes, scopes);
|
|
111
150
|
// 2. rate limit
|
|
112
|
-
await this.security.hooks.checkRateLimit(def.name,
|
|
151
|
+
release = await this.security.hooks.checkRateLimit(def.name, caller.rateKey);
|
|
113
152
|
// 3. timeout
|
|
114
153
|
const ac = new AbortController();
|
|
115
154
|
const timer = setTimeout(() => ac.abort(), this.security.defaultLimits.timeoutMs);
|
|
116
155
|
const ctx = {
|
|
117
156
|
sessionId: this.sessionId,
|
|
118
|
-
scopes
|
|
157
|
+
scopes,
|
|
119
158
|
signal: ac.signal,
|
|
120
159
|
limits: this.security.defaultLimits,
|
|
121
160
|
logger: this.logger,
|
|
122
161
|
};
|
|
162
|
+
// Race the handler against the timer: a handler that ignores `signal` (a sync driver,
|
|
163
|
+
// a hung socket) must still not hold the call open past the limit.
|
|
164
|
+
const timedOut = new Promise((_, reject) => ac.signal.addEventListener('abort', () => reject(new TimeoutError(`Tool ${def.name} exceeded ${ctx.limits.timeoutMs}ms`))));
|
|
123
165
|
try {
|
|
124
166
|
const parsed = def.inputSchema.parse(rawArgs);
|
|
125
|
-
result = await def.handler(parsed, ctx);
|
|
167
|
+
result = await Promise.race([def.handler(parsed, ctx), timedOut]);
|
|
126
168
|
}
|
|
127
169
|
finally {
|
|
128
170
|
clearTimeout(timer);
|
|
129
|
-
if (ac.signal.aborted && !result) {
|
|
130
|
-
throw new TimeoutError(`Tool ${def.name} exceeded ${ctx.limits.timeoutMs}ms`);
|
|
131
|
-
}
|
|
132
171
|
}
|
|
133
172
|
// 4. redaction
|
|
134
173
|
const redacted = this.security.hooks.redact(def.name, result);
|
|
@@ -147,9 +186,12 @@ export class McpolyglotServer {
|
|
|
147
186
|
catch (err) {
|
|
148
187
|
const e = err;
|
|
149
188
|
errorEntry = { code: e.code ?? 'internal_error', message: e.message };
|
|
150
|
-
|
|
189
|
+
decision = err instanceof McpolyglotError && isPolicyRejection(err.code) ? 'deny' : 'error';
|
|
190
|
+
// Policy rejections (scope, read-only, rate limit, timeout) are tool errors the model
|
|
191
|
+
// can read and correct, not protocol failures.
|
|
192
|
+
if (err instanceof McpolyglotError && isPolicyRejection(err.code)) {
|
|
151
193
|
return {
|
|
152
|
-
content: [{ type: 'text', text: e.message }],
|
|
194
|
+
content: [{ type: 'text', text: `${err.code}: ${e.message}` }],
|
|
153
195
|
isError: true,
|
|
154
196
|
metadata: { durationMs: Date.now() - started },
|
|
155
197
|
};
|
|
@@ -157,12 +199,16 @@ export class McpolyglotServer {
|
|
|
157
199
|
throw err;
|
|
158
200
|
}
|
|
159
201
|
finally {
|
|
202
|
+
release?.();
|
|
160
203
|
await this.security.hooks.audit({
|
|
161
204
|
ts: new Date().toISOString(),
|
|
162
205
|
sessionId: this.sessionId,
|
|
206
|
+
...(agentId ? { agentId } : {}),
|
|
163
207
|
tool: def.name,
|
|
208
|
+
decision,
|
|
209
|
+
...(errorEntry ? { reason: errorEntry.message } : {}),
|
|
164
210
|
argsHash,
|
|
165
|
-
scopes: Array.from(
|
|
211
|
+
scopes: Array.from(scopes),
|
|
166
212
|
durationMs: Date.now() - started,
|
|
167
213
|
rows: result?.metadata?.rows,
|
|
168
214
|
truncated: result?.metadata?.truncated,
|
|
@@ -172,6 +218,9 @@ export class McpolyglotServer {
|
|
|
172
218
|
}
|
|
173
219
|
}
|
|
174
220
|
}
|
|
221
|
+
function isPolicyRejection(code) {
|
|
222
|
+
return code.startsWith('forbidden.') || code === 'rate_limited' || code === 'timeout';
|
|
223
|
+
}
|
|
175
224
|
function hashArgs(args) {
|
|
176
225
|
return createHash('sha256')
|
|
177
226
|
.update(JSON.stringify(args ?? {}))
|
|
@@ -197,4 +246,10 @@ function makeNoopLogger() {
|
|
|
197
246
|
error: () => { },
|
|
198
247
|
};
|
|
199
248
|
}
|
|
249
|
+
function registerTool(map, tool) {
|
|
250
|
+
if (map.has(tool.name)) {
|
|
251
|
+
throw new McpolyglotError('tool.duplicate', `Duplicate tool name: ${tool.name}`);
|
|
252
|
+
}
|
|
253
|
+
map.set(tool.name, tool);
|
|
254
|
+
}
|
|
200
255
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/tool.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Loose Zod schema type used as the default bound on `ToolDefinition` /
|
|
4
|
+
* `ToolHandler`. We deliberately type the output as `any` so a connector
|
|
5
|
+
* defining `inputSchema: z.object({ name: z.string() })` can write
|
|
6
|
+
* `handler: ({ name }) => ...` without an explicit generic — the destructure
|
|
7
|
+
* remains permissive while runtime parsing still enforces the schema.
|
|
8
|
+
*/
|
|
9
|
+
export type AnyZodSchema = z.ZodType<any>;
|
|
10
|
+
export type ZodInfer<S extends AnyZodSchema> = z.infer<S>;
|
|
2
11
|
/** Every scope mcpolyglot understands. New scopes must be added here so the Zod config schema accepts them. */
|
|
3
12
|
export declare const ALL_SCOPES: readonly ["schema:read", "tables:read", "tables:write", "query:raw", "http:call"];
|
|
4
13
|
/** A capability a tool requires from the calling session. Checked by `ScopeGuard`. */
|
|
@@ -55,7 +64,7 @@ export interface ToolExecCtx {
|
|
|
55
64
|
* Handler signature for a tool. Args are pre-validated against `ToolDefinition.inputSchema`,
|
|
56
65
|
* so the function receives a parsed, typed value — no defensive validation needed.
|
|
57
66
|
*/
|
|
58
|
-
export type ToolHandler<S extends
|
|
67
|
+
export type ToolHandler<S extends AnyZodSchema = AnyZodSchema> = (args: ZodInfer<S>, ctx: ToolExecCtx) => Promise<ToolResult>;
|
|
59
68
|
/**
|
|
60
69
|
* The contract every connector returns from `listPrimitiveTools()` /
|
|
61
70
|
* `generatePerEntityTools()`. The `handler` is the only point where the connector
|
|
@@ -75,7 +84,7 @@ export type ToolHandler<S extends ZodTypeAny = ZodTypeAny> = (args: ZodInfer<S>,
|
|
|
75
84
|
* };
|
|
76
85
|
* ```
|
|
77
86
|
*/
|
|
78
|
-
export interface ToolDefinition<S extends
|
|
87
|
+
export interface ToolDefinition<S extends AnyZodSchema = AnyZodSchema> {
|
|
79
88
|
/** Globally-unique tool name. By convention: `<connector.id>.<verb>`. */
|
|
80
89
|
name: string;
|
|
81
90
|
/** Human-readable description shown to the model in `tools/list`. */
|
package/dist/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
|
package/dist/tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAaA,+GAA+G;AAC/G,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,aAAa;IACb,aAAa;IACb,cAAc;IACd,WAAW;IACX,WAAW;CACH,CAAC;AAKX,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAqB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC"}
|
package/dist/transport.d.ts
CHANGED
|
@@ -6,8 +6,11 @@ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface Transport {
|
|
8
8
|
readonly kind: 'stdio' | 'http';
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Start accepting traffic. `createServer` returns a fresh MCP server wired to the tool
|
|
11
|
+
* pipeline; call it once per connection (stdio: once; stateless HTTP: per request).
|
|
12
|
+
*/
|
|
13
|
+
start(createServer: () => Server): Promise<void>;
|
|
11
14
|
/** Stop accepting traffic and close any underlying sockets. Must be idempotent. */
|
|
12
15
|
stop(): Promise<void>;
|
|
13
16
|
}
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,mFAAmF;IACnF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type JWTPayload } from 'jose';
|
|
2
|
+
export interface OAuthVerifierOptions {
|
|
3
|
+
/** OIDC issuer URL. Required. Token `iss` must match exactly. */
|
|
4
|
+
issuer: string;
|
|
5
|
+
/** Expected `aud` claim. Required. */
|
|
6
|
+
audience: string;
|
|
7
|
+
/**
|
|
8
|
+
* JWKS endpoint. If omitted, defaults to `${issuer}/.well-known/jwks.json`,
|
|
9
|
+
* which matches the convention used by Auth0, Okta, Keycloak, AWS Cognito,
|
|
10
|
+
* and most other OIDC providers.
|
|
11
|
+
*/
|
|
12
|
+
jwksUri?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Allowed clock skew, in seconds, when checking `exp` / `nbf`. Defaults to 30s
|
|
15
|
+
* — enough to absorb NTP drift between issuer and verifier without weakening
|
|
16
|
+
* expiry semantics.
|
|
17
|
+
*/
|
|
18
|
+
clockToleranceSeconds?: number;
|
|
19
|
+
}
|
|
20
|
+
/** Successful verification carries the subject and the full payload. */
|
|
21
|
+
export interface OAuthVerifyOk {
|
|
22
|
+
ok: true;
|
|
23
|
+
sub?: string;
|
|
24
|
+
payload: JWTPayload;
|
|
25
|
+
}
|
|
26
|
+
/** Failed verification carries a stable reason code suitable for logs / 401s. */
|
|
27
|
+
export interface OAuthVerifyErr {
|
|
28
|
+
ok: false;
|
|
29
|
+
/**
|
|
30
|
+
* Stable, machine-readable reason. Mapped from the `code` jose throws
|
|
31
|
+
* (e.g. `ERR_JWT_EXPIRED`) so callers can render `error_description`
|
|
32
|
+
* without leaking stack traces.
|
|
33
|
+
*/
|
|
34
|
+
reason: string;
|
|
35
|
+
}
|
|
36
|
+
export type OAuthVerifyResult = OAuthVerifyOk | OAuthVerifyErr;
|
|
37
|
+
export interface OAuthVerifier {
|
|
38
|
+
/** Validate a Bearer token's signature, issuer, audience, and timing. */
|
|
39
|
+
verify(token: string): Promise<OAuthVerifyResult>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build an OAuth bearer-token verifier backed by a remote JWKS. The JWKS is
|
|
43
|
+
* fetched on first use and cached / rotated by `jose` automatically (default
|
|
44
|
+
* 10-minute cooldown, 30-second timeout). Verification enforces:
|
|
45
|
+
*
|
|
46
|
+
* - signature against a JWKS-resolved key
|
|
47
|
+
* - `iss` exact-match
|
|
48
|
+
* - `aud` exact-match
|
|
49
|
+
* - `exp` / `nbf` within `clockToleranceSeconds`
|
|
50
|
+
*
|
|
51
|
+
* The verifier is intentionally minimal: scope mapping (e.g. translating an
|
|
52
|
+
* OAuth `scope` claim into the mcpolyglot scope set) is the caller's job, not
|
|
53
|
+
* the transport's. The transport's only contract is "the bearer is valid".
|
|
54
|
+
*/
|
|
55
|
+
export declare function createOAuthVerifier(opts: OAuthVerifierOptions): OAuthVerifier;
|
|
56
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/transports/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,UAAU,EAAwB,MAAM,MAAM,CAAC;AAE5F,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,KAAK,CAAC;IACV;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,cAAc,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CAmB7E"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Build an OAuth bearer-token verifier backed by a remote JWKS. The JWKS is
|
|
4
|
+
* fetched on first use and cached / rotated by `jose` automatically (default
|
|
5
|
+
* 10-minute cooldown, 30-second timeout). Verification enforces:
|
|
6
|
+
*
|
|
7
|
+
* - signature against a JWKS-resolved key
|
|
8
|
+
* - `iss` exact-match
|
|
9
|
+
* - `aud` exact-match
|
|
10
|
+
* - `exp` / `nbf` within `clockToleranceSeconds`
|
|
11
|
+
*
|
|
12
|
+
* The verifier is intentionally minimal: scope mapping (e.g. translating an
|
|
13
|
+
* OAuth `scope` claim into the mcpolyglot scope set) is the caller's job, not
|
|
14
|
+
* the transport's. The transport's only contract is "the bearer is valid".
|
|
15
|
+
*/
|
|
16
|
+
export function createOAuthVerifier(opts) {
|
|
17
|
+
const jwksUri = opts.jwksUri ?? defaultJwksUri(opts.issuer);
|
|
18
|
+
const jwks = createRemoteJWKSet(new URL(jwksUri));
|
|
19
|
+
const clockTolerance = opts.clockToleranceSeconds ?? 30;
|
|
20
|
+
return {
|
|
21
|
+
async verify(token) {
|
|
22
|
+
try {
|
|
23
|
+
const result = await jwtVerify(token, jwks, {
|
|
24
|
+
issuer: opts.issuer,
|
|
25
|
+
audience: opts.audience,
|
|
26
|
+
clockTolerance,
|
|
27
|
+
});
|
|
28
|
+
return { ok: true, sub: result.payload.sub, payload: result.payload };
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
return { ok: false, reason: classifyError(e) };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Strip a trailing slash from issuer before joining the JWKS path. */
|
|
37
|
+
function defaultJwksUri(issuer) {
|
|
38
|
+
return `${issuer.replace(/\/$/, '')}/.well-known/jwks.json`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Map `jose` errors and other failures to a small, stable set of reason
|
|
42
|
+
* strings. Anything we don't recognize collapses to `invalid_token` so we
|
|
43
|
+
* never leak verifier internals into a 401 response.
|
|
44
|
+
*/
|
|
45
|
+
function classifyError(e) {
|
|
46
|
+
if (typeof e === 'object' && e !== null && 'code' in e) {
|
|
47
|
+
const code = String(e.code);
|
|
48
|
+
switch (code) {
|
|
49
|
+
case 'ERR_JWT_EXPIRED':
|
|
50
|
+
return 'token_expired';
|
|
51
|
+
case 'ERR_JWT_CLAIM_VALIDATION_FAILED':
|
|
52
|
+
return 'claim_validation_failed';
|
|
53
|
+
case 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED':
|
|
54
|
+
return 'signature_invalid';
|
|
55
|
+
case 'ERR_JWKS_NO_MATCHING_KEY':
|
|
56
|
+
return 'unknown_key';
|
|
57
|
+
case 'ERR_JWKS_TIMEOUT':
|
|
58
|
+
return 'jwks_unavailable';
|
|
59
|
+
default:
|
|
60
|
+
return 'invalid_token';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return 'invalid_token';
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/transports/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAyC,MAAM,MAAM,CAAC;AA8C5F;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA0B;IAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAExD,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,KAAa;YACxB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAoB,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;oBAC3D,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,cAAc;iBACf,CAAC,CAAC;gBACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACxE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,wBAAwB,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,CAAE,CAAuB,CAAC,IAAI,CAAC,CAAC;QACnD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,iBAAiB;gBACpB,OAAO,eAAe,CAAC;YACzB,KAAK,iCAAiC;gBACpC,OAAO,yBAAyB,CAAC;YACnC,KAAK,uCAAuC;gBAC1C,OAAO,mBAAmB,CAAC;YAC7B,KAAK,0BAA0B;gBAC7B,OAAO,aAAa,CAAC;YACvB,KAAK,kBAAkB;gBACrB,OAAO,kBAAkB,CAAC;YAC5B;gBACE,OAAO,eAAe,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -3,7 +3,7 @@ import type { Transport } from '../transport.js';
|
|
|
3
3
|
export declare class StdioTransport implements Transport {
|
|
4
4
|
readonly kind: "stdio";
|
|
5
5
|
private inner?;
|
|
6
|
-
start(
|
|
6
|
+
start(createServer: () => Server): Promise<void>;
|
|
7
7
|
stop(): Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=stdio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,KAAK,CAAC,CAAuB;IAE/B,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,KAAK,CAAC,CAAuB;IAE/B,KAAK,CAAC,YAAY,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI5B"}
|
package/dist/transports/stdio.js
CHANGED
|
@@ -2,9 +2,9 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
2
2
|
export class StdioTransport {
|
|
3
3
|
kind = 'stdio';
|
|
4
4
|
inner;
|
|
5
|
-
async start(
|
|
5
|
+
async start(createServer) {
|
|
6
6
|
this.inner = new StdioServerTransport();
|
|
7
|
-
await
|
|
7
|
+
await createServer().connect(this.inner);
|
|
8
8
|
}
|
|
9
9
|
async stop() {
|
|
10
10
|
await this.inner?.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAIjF,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,OAAgB,CAAC;IACzB,KAAK,CAAwB;IAErC,KAAK,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAIjF,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,OAAgB,CAAC;IACzB,KAAK,CAAwB;IAErC,KAAK,CAAC,KAAK,CAAC,YAA0B;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACxC,MAAM,YAAY,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -1,9 +1,44 @@
|
|
|
1
1
|
import type { Server as McpServer } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
2
|
import type { Transport } from '../transport.js';
|
|
3
|
+
import { type OAuthVerifierOptions } from './oauth.js';
|
|
4
|
+
/** Bearer-token mode: a fixed shared secret on the `Authorization` header. */
|
|
5
|
+
export interface BearerAuthOptions {
|
|
6
|
+
kind: 'bearer';
|
|
7
|
+
/** Pre-shared bearer token. Auto-generated if omitted. */
|
|
8
|
+
token?: string;
|
|
9
|
+
}
|
|
10
|
+
/** OAuth mode: signature + claim verification against a JWKS. */
|
|
11
|
+
export interface OAuthAuthOptions extends OAuthVerifierOptions {
|
|
12
|
+
kind: 'oauth';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Per-agent tokens: each bearer token is sha256-hashed and matched against the agents'
|
|
16
|
+
* stored hashes. The matched agent id reaches request handlers as `authInfo.clientId`.
|
|
17
|
+
*/
|
|
18
|
+
export interface AgentsAuthOptions {
|
|
19
|
+
kind: 'agents';
|
|
20
|
+
agents: ReadonlyArray<{
|
|
21
|
+
id: string;
|
|
22
|
+
tokens: ReadonlyArray<{
|
|
23
|
+
hash: string;
|
|
24
|
+
revoked?: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export type HttpAuthOptions = BearerAuthOptions | OAuthAuthOptions | AgentsAuthOptions;
|
|
3
29
|
export interface StreamableHttpTransportOptions {
|
|
4
30
|
host: string;
|
|
5
31
|
port: number;
|
|
6
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Auth strategy. Defaults to `{ kind: 'bearer' }` (auto-generated token)
|
|
34
|
+
* for back-compat with the original API.
|
|
35
|
+
*/
|
|
36
|
+
auth?: HttpAuthOptions;
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated Pass `auth: { kind: 'bearer', token }` instead. Retained so
|
|
39
|
+
* existing callers (and the CLI's `--http` flag without OAuth config)
|
|
40
|
+
* keep working unchanged.
|
|
41
|
+
*/
|
|
7
42
|
bearerToken?: string;
|
|
8
43
|
/** Where to log server startup banner / auth-failure events. Stderr by default. */
|
|
9
44
|
logger?: {
|
|
@@ -13,16 +48,29 @@ export interface StreamableHttpTransportOptions {
|
|
|
13
48
|
}
|
|
14
49
|
export declare class StreamableHttpTransport implements Transport {
|
|
15
50
|
readonly kind: "http";
|
|
16
|
-
|
|
51
|
+
/** Bearer token in use, or `undefined` when running in OAuth mode. */
|
|
52
|
+
readonly bearerToken: string | undefined;
|
|
53
|
+
readonly authKind: 'bearer' | 'oauth' | 'agents';
|
|
17
54
|
private readonly host;
|
|
18
55
|
private readonly port;
|
|
56
|
+
private readonly auth;
|
|
19
57
|
private readonly logger;
|
|
20
|
-
private
|
|
58
|
+
private newServer?;
|
|
21
59
|
private httpServer?;
|
|
22
60
|
constructor(opts: StreamableHttpTransportOptions);
|
|
23
|
-
start(
|
|
61
|
+
start(newServer: () => McpServer): Promise<void>;
|
|
24
62
|
stop(): Promise<void>;
|
|
25
63
|
private handle;
|
|
26
64
|
private checkAuth;
|
|
27
65
|
}
|
|
66
|
+
/** sha256 hex of a bearer token — the only form an agent token is ever stored in. */
|
|
67
|
+
export declare function hashToken(token: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Compare the token's hash against every stored hash with `timingSafeEqual`, without
|
|
70
|
+
* stopping at the first match, so timing doesn't reveal which (or whether an) entry hit.
|
|
71
|
+
*/
|
|
72
|
+
export declare function matchAgent(hashes: readonly {
|
|
73
|
+
agentId: string;
|
|
74
|
+
hash: Buffer;
|
|
75
|
+
}[], token: string): string | undefined;
|
|
28
76
|
//# sourceMappingURL=streamable-http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamable-http.d.ts","sourceRoot":"","sources":["../../src/transports/streamable-http.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"streamable-http.d.ts","sourceRoot":"","sources":["../../src/transports/streamable-http.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAErF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEhG,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC5D,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;QACpB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,aAAa,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KAC5D,CAAC,CAAC;CACJ;AAED,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEvF,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QAC9D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;KAC/D,CAAC;CACH;AAOD,qBAAa,uBAAwB,YAAW,SAAS;IACvD,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAChC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwD;IAC/E,OAAO,CAAC,SAAS,CAAC,CAAkB;IACpC,OAAO,CAAC,UAAU,CAAC,CAAa;gBAEpB,IAAI,EAAE,8BAA8B;IAc1C,KAAK,CAAC,SAAS,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDhD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAQb,MAAM;YA0CN,SAAS;CA6BxB;AAqDD,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EACpD,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CASpB"}
|