@orkestrel/mcp 0.0.7 → 0.0.9
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 +7 -7
- package/dist/src/browser/index.d.ts +26 -12
- package/dist/src/browser/index.js +43 -17
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +1277 -137
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +1113 -184
- package/dist/src/core/index.d.ts +1113 -184
- package/dist/src/core/index.js +1233 -134
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +361 -68
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +201 -33
- package/dist/src/server/index.d.ts +201 -33
- package/dist/src/server/index.js +352 -70
- package/dist/src/server/index.js.map +1 -1
- package/package.json +10 -10
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
2
2
|
import { EmitterHooks } from '@orkestrel/emitter';
|
|
3
3
|
import { EmitterInterface } from '@orkestrel/emitter';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { JSONValue } from '@orkestrel/contract';
|
|
5
|
+
import { TokenSecret } from '@orkestrel/server';
|
|
6
|
+
import { ToolInterface } from '@orkestrel/tool';
|
|
7
|
+
import { ToolManagerInterface } from '@orkestrel/tool';
|
|
8
|
+
import { ToolResult } from '@orkestrel/tool';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Pipe an {@link MCPTransportInterface} into an {@link MCPClientInterface} — every
|
|
@@ -54,7 +56,11 @@ export declare function bindClient(client: MCPClientInterface, transport: MCPTra
|
|
|
54
56
|
* @remarks
|
|
55
57
|
* `server.handle` already turns a malformed message into a serialized `-32700` /
|
|
56
58
|
* `-32600` reply and a notification into `undefined` (no reply), so this binder adds
|
|
57
|
-
* no parsing of its own. A
|
|
59
|
+
* no parsing of its own. A HELD-OPEN reply arrives as an
|
|
60
|
+
* {@link import('./types.js').MCPTextStream} instead of a string: this is the one place
|
|
61
|
+
* that pumps it, writing each notification in order and then the generator's returned
|
|
62
|
+
* terminating response ({@link sendStream}). A `transport.send` throw or rejection —
|
|
63
|
+
* mid-stream included — is caught and routed
|
|
58
64
|
* to `server.emitter`'s `error` event (never rethrown, never an unhandled rejection);
|
|
59
65
|
* a listener on that event that itself throws is swallowed (the end of the line —
|
|
60
66
|
* the caller's own bug, never this binder's). The returned unbind DETACHES this
|
|
@@ -80,12 +86,134 @@ export declare function bindClient(client: MCPClientInterface, transport: MCPTra
|
|
|
80
86
|
*/
|
|
81
87
|
export declare function bindServer(server: MCPServerInterface, transport: MCPTransportInterface): () => void;
|
|
82
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Map an executed tool's {@link ToolResult} to an MCP {@link MCPCallResult} — the
|
|
91
|
+
* value as structured content plus a backwards-compatible `text` block, or the
|
|
92
|
+
* error as a `text` block.
|
|
93
|
+
*
|
|
94
|
+
* @remarks
|
|
95
|
+
* The {@link ToolManagerInterface} already isolates a thrown tool into a
|
|
96
|
+
* `success: false` result (so the server adds NO try/catch around `execute`):
|
|
97
|
+
* that branch builds an `isError: true` result carrying `result.error`, so the
|
|
98
|
+
* model sees the failure as a tool result it can react to rather than a protocol
|
|
99
|
+
* error; a valued `success: true` branch carries `result.value` unchanged as
|
|
100
|
+
* `structuredContent` and serializes it (via `JSON.stringify`) into one `text`
|
|
101
|
+
* block. A value-less success retains the required empty `content` block and
|
|
102
|
+
* omits `structuredContent`.
|
|
103
|
+
*
|
|
104
|
+
* @param result - The tool's execution outcome
|
|
105
|
+
* @returns The MCP tool-call result
|
|
106
|
+
*/
|
|
107
|
+
export declare function buildCallResult(result: ToolResult): MCPCallResult;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Build the mandatory modern `server/discover` result.
|
|
111
|
+
*
|
|
112
|
+
* @param options - The server identity, instructions, and cache configuration
|
|
113
|
+
* @returns The supported revisions, tools capability, and required modern cache stamps
|
|
114
|
+
*/
|
|
115
|
+
export declare function buildDiscoverResult(options: MCPServerOptions): MCPDiscoverResult;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Build the MCP `initialize` result — the negotiated protocol version, the
|
|
119
|
+
* advertised capabilities, and the server identity.
|
|
120
|
+
*
|
|
121
|
+
* @remarks
|
|
122
|
+
* Version negotiation echoes the client's `requested` version when it is one of the
|
|
123
|
+
* supported legacy revisions. A modern or unsupported request receives the newest
|
|
124
|
+
* supported legacy revision; the client decides whether to continue.
|
|
125
|
+
* `capabilities.tools` is an empty object — this server advertises the tools
|
|
126
|
+
* capability with no sub-options (no list-changed notification yet).
|
|
127
|
+
*
|
|
128
|
+
* @param name - The server name (echoed in `serverInfo`)
|
|
129
|
+
* @param version - The server version (echoed in `serverInfo`)
|
|
130
|
+
* @param requested - The client's requested protocol version (negotiated when supported)
|
|
131
|
+
* @returns The `initialize` result payload
|
|
132
|
+
*/
|
|
133
|
+
export declare function buildInitializeResult(name: string, version: string, requested?: string): Readonly<Record<string, unknown>>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Build a JSON-RPC error {@link JSONRPCResponse} — the `id` echoed, the failure as
|
|
137
|
+
* an `error` object.
|
|
138
|
+
*
|
|
139
|
+
* @param id - The request's id (`null` for a parse / invalid-request error)
|
|
140
|
+
* @param code - One of the reserved JSON-RPC codes (see `./constants.js`)
|
|
141
|
+
* @param message - A short human description of the failure
|
|
142
|
+
* @param data - An OPTIONAL machine-readable payload (omitted from the envelope when absent)
|
|
143
|
+
* @returns The error response envelope
|
|
144
|
+
*/
|
|
145
|
+
export declare function buildJSONRPCError(id: string | number | null, code: number, message: string, data?: unknown): JSONRPCResponse;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Build a JSON-RPC success {@link JSONRPCResponse} — the `id` echoed, the method's
|
|
149
|
+
* value as `result`.
|
|
150
|
+
*
|
|
151
|
+
* @param id - The request's id (`null` only for a parse / invalid-request error)
|
|
152
|
+
* @param result - The method's return value
|
|
153
|
+
* @returns The success response envelope
|
|
154
|
+
*/
|
|
155
|
+
export declare function buildJSONRPCResult(id: string | number | null, result: unknown): JSONRPCResponse;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Stamp a result with the modern complete-result discriminator and server
|
|
159
|
+
* metadata, plus cache fields when the result is cacheable.
|
|
160
|
+
*
|
|
161
|
+
* @remarks
|
|
162
|
+
* This is the single stamping site shared by modern result builders. Supplying
|
|
163
|
+
* `ttl` adds both schema-coupled fields (`ttlMs` and `cacheScope`); omitting it
|
|
164
|
+
* adds neither, which keeps `tools/call` distinct from cacheable results.
|
|
165
|
+
*
|
|
166
|
+
* @param result - The unstamped result payload
|
|
167
|
+
* @param identity - The server identity carried under the reserved `_meta` key
|
|
168
|
+
* @param ttl - Required freshness lifetime for a cacheable result; omit for a non-cacheable result
|
|
169
|
+
* @param scope - The cache visibility, defaulting to `'private'` when `ttl` is supplied
|
|
170
|
+
* @returns A copy of the payload with its modern stamps
|
|
171
|
+
*/
|
|
172
|
+
export declare function buildModernResult<T extends object>(result: T, identity: MCPIdentity, ttl: number, scope?: 'public' | 'private'): T & {
|
|
173
|
+
readonly resultType: 'complete';
|
|
174
|
+
readonly _meta: Readonly<Record<string, unknown>>;
|
|
175
|
+
readonly ttlMs: number;
|
|
176
|
+
readonly cacheScope: 'public' | 'private';
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export declare function buildModernResult<T extends object>(result: T, identity: MCPIdentity): T & {
|
|
180
|
+
readonly resultType: 'complete';
|
|
181
|
+
readonly _meta: Readonly<Record<string, unknown>>;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Build the first notification carrying a subscription id for a listen request.
|
|
186
|
+
*
|
|
187
|
+
* @param notifications - The exact notification filter the server will honour
|
|
188
|
+
* @param id - The `subscriptions/listen` request id
|
|
189
|
+
* @returns The stamped subscription acknowledgement notification
|
|
190
|
+
*/
|
|
191
|
+
export declare function buildSubscriptionAcknowledgement(notifications: SubscriptionFilter, id: string | number): JSONRPCRequest;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Intersect a requested subscription filter with the notification families a server supports.
|
|
195
|
+
*
|
|
196
|
+
* @param requested - The notification families requested by the client
|
|
197
|
+
* @param supported - The notification families the server can actually produce
|
|
198
|
+
* @returns The exact subset the server will honour
|
|
199
|
+
*/
|
|
200
|
+
export declare function buildSubscriptionFilter(requested: SubscriptionFilter, supported: SubscriptionFilter): SubscriptionFilter;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Build the terminating response for a subscription source that closes gracefully.
|
|
204
|
+
*
|
|
205
|
+
* @param id - The `subscriptions/listen` request id
|
|
206
|
+
* @param identity - The server identity included by the modern result stamping site
|
|
207
|
+
* @returns The complete modern result carrying the required subscription id metadata
|
|
208
|
+
*/
|
|
209
|
+
export declare function buildSubscriptionResult(id: string | number, identity: MCPIdentity): JSONRPCResponse;
|
|
210
|
+
|
|
83
211
|
/**
|
|
84
212
|
* Map a {@link ToolManagerInterface}'s definitions to MCP `tools/list` descriptors
|
|
85
213
|
* — renaming `parameters` to the wire's `inputSchema`.
|
|
86
214
|
*
|
|
87
215
|
* @remarks
|
|
88
|
-
* Each {@link import('@orkestrel/
|
|
216
|
+
* Each {@link import('@orkestrel/tool').ToolDefinition} carries through its
|
|
89
217
|
* `name` and (when present) `description`; its open JSON-Schema `parameters`
|
|
90
218
|
* becomes `inputSchema`, defaulting to an empty object schema (`{ type: 'object' }`)
|
|
91
219
|
* when a tool declares none (MCP requires an `inputSchema`).
|
|
@@ -95,22 +223,12 @@ export declare function bindServer(server: MCPServerInterface, transport: MCPTra
|
|
|
95
223
|
*/
|
|
96
224
|
export declare function buildToolDescriptors(manager: ToolManagerInterface): readonly MCPToolDescriptor[];
|
|
97
225
|
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* `result.error` (so the server adds NO try/catch around `execute`): when `error`
|
|
105
|
-
* is present, this builds an `isError: true` result carrying the error text, so the
|
|
106
|
-
* model sees the failure as a tool result it can react to rather than a protocol
|
|
107
|
-
* error; otherwise it serializes `result.value` (via `JSON.stringify`) into one
|
|
108
|
-
* `text` block.
|
|
109
|
-
*
|
|
110
|
-
* @param result - The tool's execution outcome
|
|
111
|
-
* @returns The MCP tool-call result
|
|
112
|
-
*/
|
|
113
|
-
export declare function buildToolResult(result: ToolResult): MCPToolResult;
|
|
226
|
+
/** A successful JSON-RPC response to `tools/call`. */
|
|
227
|
+
export declare interface CallToolResultResponse {
|
|
228
|
+
readonly jsonrpc: '2.0';
|
|
229
|
+
readonly id: string | number;
|
|
230
|
+
readonly result: MCPCallResult | InputRequiredResult;
|
|
231
|
+
}
|
|
114
232
|
|
|
115
233
|
/**
|
|
116
234
|
* The observable events of a {@link ClientTransportInterface} (§13) — the moments the
|
|
@@ -219,7 +337,7 @@ export declare function createDuplexClientTransport(transport: MCPTransportInter
|
|
|
219
337
|
* Create a transport-agnostic Model Context Protocol CLIENT — connects to a REMOTE
|
|
220
338
|
* MCP server over an injected {@link import('./types.js').ClientTransportInterface},
|
|
221
339
|
* runs the `initialize` handshake, and exposes the server's tools as local
|
|
222
|
-
* {@link import('@orkestrel/
|
|
340
|
+
* {@link import('@orkestrel/tool').ToolInterface}s an agent can run.
|
|
223
341
|
*
|
|
224
342
|
* @remarks
|
|
225
343
|
* The egress mirror of {@link createMCPServer}: where the server exposes a local tool
|
|
@@ -227,14 +345,14 @@ export declare function createDuplexClientTransport(transport: MCPTransportInter
|
|
|
227
345
|
* validates and exposes the negotiated protocol, `tools()` lists + wraps the remote
|
|
228
346
|
* tools (each `execute` calls back over the wire),
|
|
229
347
|
* and `call(name, args)` runs a remote `tools/call` (a remote tool failure throws
|
|
230
|
-
* locally, so an agent's {@link import('@orkestrel/
|
|
348
|
+
* locally, so an agent's {@link import('@orkestrel/tool').ToolManagerInterface}
|
|
231
349
|
* isolates it). The transport is injected — a concrete one (the HTTP transport over
|
|
232
350
|
* `fetch`) lives in `@src/server`; the client itself is provider-agnostic. Subscribe
|
|
233
351
|
* to `connect` / `disconnect` / `notification` via `client.on(...)` (or
|
|
234
352
|
* `client.emitter.on(...)`).
|
|
235
353
|
*
|
|
236
|
-
* @param options - `transport` (the carrier; REQUIRED),
|
|
237
|
-
* identity), `timeout` (the per-request deadline), and the reserved `on`
|
|
354
|
+
* @param options - `transport` (the carrier; REQUIRED), an optional `identity`
|
|
355
|
+
* (the client identity), `timeout` (the per-request deadline), and the reserved `on`
|
|
238
356
|
* {@link import('@orkestrel/emitter').EmitterHooks} (see {@link MCPClientOptions})
|
|
239
357
|
* @returns A working {@link MCPClientInterface}
|
|
240
358
|
*
|
|
@@ -255,20 +373,20 @@ export declare function createMCPClient(options: MCPClientOptions): MCPClientInt
|
|
|
255
373
|
|
|
256
374
|
/**
|
|
257
375
|
* Create a transport-agnostic Model Context Protocol server — exposes a live
|
|
258
|
-
* {@link import('@orkestrel/
|
|
376
|
+
* {@link import('@orkestrel/tool').ToolManagerInterface} over JSON-RPC 2.0
|
|
259
377
|
* (`initialize` / `ping` / `tools/list` / `tools/call`).
|
|
260
378
|
*
|
|
261
379
|
* @remarks
|
|
262
380
|
* Pump raw message strings through `handle` (parse → dispatch → serialize) from a
|
|
263
381
|
* transport, or call the typed `dispatch` directly with an already-parsed request.
|
|
264
382
|
* The server is provider-agnostic — JSON-RPC plus the tool registry, with no HTTP
|
|
265
|
-
* and no model. The {@link import('@orkestrel/
|
|
266
|
-
* isolates a thrown tool into a result
|
|
267
|
-
* tool result), so a misbehaving tool never crashes a dispatch. Subscribe to the
|
|
383
|
+
* and no model. The {@link import('@orkestrel/tool').ToolManagerInterface} already
|
|
384
|
+
* isolates a thrown tool into a `success: false` result (surfaced as an MCP
|
|
385
|
+
* `isError: true` tool result), so a misbehaving tool never crashes a dispatch. Subscribe to the
|
|
268
386
|
* `request` event via `server.emitter.on('request', …)` for tracing.
|
|
269
387
|
*
|
|
270
|
-
* @param options - `
|
|
271
|
-
* registry to expose),
|
|
388
|
+
* @param options - `identity` (the server identity), `tools` (the live
|
|
389
|
+
* registry to expose), optional `instructions`, and the reserved `on`
|
|
272
390
|
* {@link import('@orkestrel/emitter').EmitterHooks} (see {@link MCPServerOptions})
|
|
273
391
|
* @returns A working {@link MCPServerInterface}
|
|
274
392
|
*
|
|
@@ -279,7 +397,7 @@ export declare function createMCPClient(options: MCPClientOptions): MCPClientInt
|
|
|
279
397
|
* const tools = createToolManager()
|
|
280
398
|
* tools.add(createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }))
|
|
281
399
|
*
|
|
282
|
-
* const server = createMCPServer({ name: 'calculator', version: '1.0.0', tools })
|
|
400
|
+
* const server = createMCPServer({ identity: { name: 'calculator', version: '1.0.0' }, tools })
|
|
283
401
|
* server.emitter.on('request', (method, id) => log(method, id))
|
|
284
402
|
*
|
|
285
403
|
* // A transport pumps message strings through `handle`:
|
|
@@ -289,34 +407,320 @@ export declare function createMCPClient(options: MCPClientOptions): MCPClientInt
|
|
|
289
407
|
*/
|
|
290
408
|
export declare function createMCPServer(options: MCPServerOptions): MCPServerInterface;
|
|
291
409
|
|
|
410
|
+
/**
|
|
411
|
+
* Default modern result freshness lifetime in milliseconds.
|
|
412
|
+
*
|
|
413
|
+
* @remarks
|
|
414
|
+
* `ttlMs` is required on cacheable results, while zero means immediately stale
|
|
415
|
+
* rather than uncached, so the neutral usable default is one minute.
|
|
416
|
+
*/
|
|
417
|
+
export declare const DEFAULT_MCP_CACHE_TTL = 60000;
|
|
418
|
+
|
|
292
419
|
/** The default client name reported in the MCP `initialize` handshake (`clientInfo.name`). */
|
|
293
420
|
export declare const DEFAULT_MCP_CLIENT_NAME = "taverna";
|
|
294
421
|
|
|
295
422
|
/** The default client version reported in the MCP `initialize` handshake (`clientInfo.version`). */
|
|
296
423
|
export declare const DEFAULT_MCP_CLIENT_VERSION = "1.0.0";
|
|
297
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Secure server bounds used when the matching `limit` option leaf is absent or malformed.
|
|
427
|
+
*
|
|
428
|
+
* @remarks
|
|
429
|
+
* One MiB admits ordinary JSON-RPC requests and substantial tool arguments; 16 KiB admits
|
|
430
|
+
* extension-rich modern metadata and signed multi-round state; four MiB admits substantial
|
|
431
|
+
* JSON tool output without allowing an unconfigured service to serialize arbitrary process
|
|
432
|
+
* memory; 64 metadata keys admits the reserved keys plus many extensions; 128 concurrent
|
|
433
|
+
* streams admits a busy service while bounding retained producers; depth 32 admits ordinary
|
|
434
|
+
* JSON documents while rejecting stack-hostile nesting. Frozen so callers cannot alter the
|
|
435
|
+
* defaults observed by later servers.
|
|
436
|
+
*/
|
|
437
|
+
export declare const DEFAULT_MCP_LIMITS: Readonly<{
|
|
438
|
+
message: 1048576;
|
|
439
|
+
metadata: 16384;
|
|
440
|
+
keys: 64;
|
|
441
|
+
state: 16384;
|
|
442
|
+
content: 4194304;
|
|
443
|
+
subscriptions: 128;
|
|
444
|
+
depth: 32;
|
|
445
|
+
}>;
|
|
446
|
+
|
|
447
|
+
/** The maximum discovery-probe deadline used when a client deadline is configured. */
|
|
448
|
+
export declare const DEFAULT_MCP_PROBE_TIMEOUT = 50;
|
|
449
|
+
|
|
298
450
|
/**
|
|
299
451
|
* The default per-request deadline (ms) an `MCPClient` applies when `options.timeout`
|
|
300
452
|
* is unset — a request the remote server does not answer within it rejects.
|
|
301
453
|
*/
|
|
302
454
|
export declare const DEFAULT_MCP_REQUEST_TIMEOUT = 30000;
|
|
303
455
|
|
|
456
|
+
/** One titled value in a form elicitation's single- or multi-select schema. */
|
|
457
|
+
export declare interface ElicitChoice {
|
|
458
|
+
readonly const: string;
|
|
459
|
+
readonly title: string;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** One restricted primitive schema accepted by MCP form-mode elicitation. */
|
|
463
|
+
export declare type ElicitPrimitiveSchema = {
|
|
464
|
+
readonly type: 'boolean';
|
|
465
|
+
readonly title?: string;
|
|
466
|
+
readonly description?: string;
|
|
467
|
+
readonly default?: boolean;
|
|
468
|
+
} | {
|
|
469
|
+
readonly type: 'number' | 'integer';
|
|
470
|
+
readonly title?: string;
|
|
471
|
+
readonly description?: string;
|
|
472
|
+
readonly minimum?: number;
|
|
473
|
+
readonly maximum?: number;
|
|
474
|
+
readonly default?: number;
|
|
475
|
+
} | {
|
|
476
|
+
readonly type: 'string';
|
|
477
|
+
readonly title?: string;
|
|
478
|
+
readonly description?: string;
|
|
479
|
+
readonly minLength?: number;
|
|
480
|
+
readonly maxLength?: number;
|
|
481
|
+
readonly format?: 'uri' | 'email' | 'date' | 'date-time';
|
|
482
|
+
readonly default?: string;
|
|
483
|
+
readonly enum?: readonly string[];
|
|
484
|
+
readonly enumNames?: readonly string[];
|
|
485
|
+
readonly oneOf?: readonly ElicitChoice[];
|
|
486
|
+
} | {
|
|
487
|
+
readonly type: 'array';
|
|
488
|
+
readonly title?: string;
|
|
489
|
+
readonly description?: string;
|
|
490
|
+
readonly minItems?: number;
|
|
491
|
+
readonly maxItems?: number;
|
|
492
|
+
readonly default?: readonly string[];
|
|
493
|
+
readonly items: {
|
|
494
|
+
readonly type: 'string';
|
|
495
|
+
readonly enum: readonly string[];
|
|
496
|
+
} | {
|
|
497
|
+
readonly anyOf: readonly ElicitChoice[];
|
|
498
|
+
};
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
/** An embedded MCP request asking the client to elicit input from its operator. */
|
|
502
|
+
export declare interface ElicitRequest {
|
|
503
|
+
readonly method: 'elicitation/create';
|
|
504
|
+
readonly params: ElicitRequestParams;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** The restricted top-level object schema carried by a form-mode elicitation request. */
|
|
508
|
+
export declare interface ElicitRequestedSchema extends Readonly<Record<string, unknown>> {
|
|
509
|
+
readonly $schema?: string;
|
|
510
|
+
readonly type: 'object';
|
|
511
|
+
readonly properties: Readonly<Record<string, ElicitPrimitiveSchema>>;
|
|
512
|
+
readonly required?: readonly string[];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** The parameters of a form-mode `elicitation/create` request. */
|
|
516
|
+
export declare interface ElicitRequestFormParams {
|
|
517
|
+
readonly mode?: 'form';
|
|
518
|
+
readonly message: string;
|
|
519
|
+
readonly requestedSchema: ElicitRequestedSchema;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/** The mode-discriminated parameters of an `elicitation/create` request. */
|
|
523
|
+
export declare type ElicitRequestParams = ElicitRequestFormParams | ElicitRequestURLParams;
|
|
524
|
+
|
|
525
|
+
/** The parameters of a URL-mode `elicitation/create` request. */
|
|
526
|
+
export declare interface ElicitRequestURLParams {
|
|
527
|
+
readonly mode: 'url';
|
|
528
|
+
readonly message: string;
|
|
529
|
+
readonly url: string;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/** The result supplied by a client for one embedded {@link ElicitRequest}. */
|
|
533
|
+
export declare interface ElicitResult {
|
|
534
|
+
readonly action: 'accept' | 'decline' | 'cancel';
|
|
535
|
+
readonly content?: Readonly<Record<string, ElicitValue>>;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/** The primitive value shapes accepted in an MCP form elicitation response. */
|
|
539
|
+
export declare type ElicitValue = string | number | boolean | readonly string[];
|
|
540
|
+
|
|
304
541
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
542
|
+
* Infer the wire era for an MCP protocol revision.
|
|
543
|
+
*
|
|
544
|
+
* @param version - The protocol revision to classify
|
|
545
|
+
* @returns `'modern'` for `2026-07-28`, `'legacy'` for either supported legacy
|
|
546
|
+
* revision, or `undefined` when the revision is unsupported
|
|
547
|
+
*/
|
|
548
|
+
export declare function inferEra(version: string): MCPEra | undefined;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Infer the newest supported protocol revision present in a peer's offer.
|
|
552
|
+
*
|
|
553
|
+
* @param offered - The protocol revisions offered by the peer
|
|
554
|
+
* @returns The newest locally supported offered revision, or `undefined`
|
|
555
|
+
*/
|
|
556
|
+
export declare function inferVersion(offered: readonly string[]): MCPVersion | undefined;
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* One embedded multi-round-trip request.
|
|
307
560
|
*
|
|
308
561
|
* @remarks
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
|
|
562
|
+
* This package produces only {@link ElicitRequest}. The deprecated sampling and roots
|
|
563
|
+
* requests remain legal protocol union members and therefore retain their open parameter
|
|
564
|
+
* records here without gaining package-owned producers.
|
|
565
|
+
*/
|
|
566
|
+
export declare type InputRequest = ElicitRequest | {
|
|
567
|
+
readonly method: 'sampling/createMessage';
|
|
568
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
569
|
+
} | {
|
|
570
|
+
readonly method: 'roots/list';
|
|
571
|
+
readonly params?: Readonly<Record<string, unknown>>;
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
/** A server-keyed map of embedded requests the client must fulfil. */
|
|
575
|
+
export declare type InputRequests = Readonly<Record<string, InputRequest>>;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* An incomplete modern result carrying input requests, protected request state, or both.
|
|
313
579
|
*
|
|
314
|
-
* @
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
|
|
580
|
+
* @remarks
|
|
581
|
+
* The two-arm union enforces the protocol's at-least-one-of rule at the type boundary:
|
|
582
|
+
* every value has `inputRequests`, `requestState`, or both.
|
|
583
|
+
*/
|
|
584
|
+
export declare type InputRequiredResult = {
|
|
585
|
+
readonly resultType: 'input_required';
|
|
586
|
+
readonly inputRequests: InputRequests;
|
|
587
|
+
readonly requestState?: string;
|
|
588
|
+
readonly _meta?: Readonly<Record<string, unknown>>;
|
|
589
|
+
} | {
|
|
590
|
+
readonly resultType: 'input_required';
|
|
591
|
+
readonly inputRequests?: InputRequests;
|
|
592
|
+
readonly requestState: string;
|
|
593
|
+
readonly _meta?: Readonly<Record<string, unknown>>;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
/** A map of client results keyed by the corresponding server-assigned input-request key. */
|
|
597
|
+
export declare type InputResponses = Readonly<Record<string, unknown>>;
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Determine whether a value is bounded, cycle-free JSON with safe property names.
|
|
601
|
+
*
|
|
602
|
+
* @remarks
|
|
603
|
+
* Traversal is iterative, ancestor-aware, and contained by {@link attempt}; deep input,
|
|
604
|
+
* cycles, accessors, hostile proxies, `Map`/`Set`, and the prototype-pollution keys
|
|
605
|
+
* `__proto__`, `constructor`, and `prototype` return `false` rather than throwing.
|
|
606
|
+
* The byte count matches `JSON.stringify` without first allocating the serialization.
|
|
607
|
+
*
|
|
608
|
+
* @param value - The unknown value to inspect
|
|
609
|
+
* @param limits - Serialized byte, optional key, and nesting-depth bounds
|
|
610
|
+
* @returns `true` only for safe JSON satisfying every bound
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* isBoundedJSON({ ok: true }, { bytes: 16, keys: 1, depth: 1 }) // true
|
|
615
|
+
* ```
|
|
318
616
|
*/
|
|
319
|
-
export declare function
|
|
617
|
+
export declare function isBoundedJSON<T>(value: T, limits: MCPJSONLimitOptions): value is T & JSONValue;
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Determine whether a value is a string within a UTF-8 byte bound.
|
|
621
|
+
*
|
|
622
|
+
* @param value - The unknown value to inspect
|
|
623
|
+
* @param bytes - The maximum accepted encoded bytes
|
|
624
|
+
* @returns `true` only for a string whose UTF-8 representation fits the bound
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* ```ts
|
|
628
|
+
* isBoundedString('€', 3) // true
|
|
629
|
+
* isBoundedString('€', 2) // false
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
export declare function isBoundedString(value: unknown, bytes: number): value is string;
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Determine whether a value is one restricted primitive form-elicitation schema.
|
|
636
|
+
*
|
|
637
|
+
* @param value - The unknown value to inspect
|
|
638
|
+
* @returns `true` for a supported boolean, numeric, string, or string-array schema
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* ```ts
|
|
642
|
+
* isElicitPrimitiveSchema({ type: 'boolean', default: true }) // true
|
|
643
|
+
* isElicitPrimitiveSchema({ type: 'object' }) // false
|
|
644
|
+
* ```
|
|
645
|
+
*/
|
|
646
|
+
export declare function isElicitPrimitiveSchema(value: unknown): value is ElicitPrimitiveSchema;
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Determine whether a value is an embedded `elicitation/create` request.
|
|
650
|
+
*
|
|
651
|
+
* @param value - The unknown value to inspect
|
|
652
|
+
* @returns `true` when `value` is a form- or URL-mode elicitation request
|
|
653
|
+
*
|
|
654
|
+
* @example
|
|
655
|
+
* ```ts
|
|
656
|
+
* isElicitRequest({
|
|
657
|
+
* method: 'elicitation/create',
|
|
658
|
+
* params: { message: 'Continue?', requestedSchema: { type: 'object', properties: {} } },
|
|
659
|
+
* }) // true
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
export declare function isElicitRequest(value: unknown): value is ElicitRequest;
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Determine whether a value is a form-mode elicitation parameter object.
|
|
666
|
+
*
|
|
667
|
+
* @param value - The unknown value to inspect
|
|
668
|
+
* @returns `true` when `value` has the restricted form elicitation shape
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```ts
|
|
672
|
+
* isElicitRequestFormParams({
|
|
673
|
+
* message: 'Continue?',
|
|
674
|
+
* requestedSchema: { type: 'object', properties: {} },
|
|
675
|
+
* }) // true
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
export declare function isElicitRequestFormParams(value: unknown): value is ElicitRequestFormParams;
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Determine whether a value is a URL-mode elicitation parameter object.
|
|
682
|
+
*
|
|
683
|
+
* @param value - The unknown value to inspect
|
|
684
|
+
* @returns `true` when `value` has the URL elicitation shape
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```ts
|
|
688
|
+
* isElicitRequestURLParams({ mode: 'url', message: 'Authenticate', url: 'https://example.test' })
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
export declare function isElicitRequestURLParams(value: unknown): value is ElicitRequestURLParams;
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Determine whether a value is one elicitation response.
|
|
695
|
+
*
|
|
696
|
+
* @param value - The unknown value to inspect
|
|
697
|
+
* @returns `true` when action/content have the protocol shape
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* ```ts
|
|
701
|
+
* isElicitResult({ action: 'accept', content: { approved: true } }) // true
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
export declare function isElicitResult(value: unknown): value is ElicitResult;
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Determine whether a client capability record declares form-mode elicitation.
|
|
708
|
+
*
|
|
709
|
+
* @remarks
|
|
710
|
+
* The protocol's empty `elicitation` object is the implicit form-only declaration.
|
|
711
|
+
* A non-empty declaration must carry a record-valued `form` member; URL-only support
|
|
712
|
+
* does not authorize a form request. Total over hostile input.
|
|
713
|
+
*
|
|
714
|
+
* @param value - The client capability record to inspect
|
|
715
|
+
* @returns `true` when form-mode elicitation is declared
|
|
716
|
+
*
|
|
717
|
+
* @example
|
|
718
|
+
* ```ts
|
|
719
|
+
* isFormElicitationSupported({ elicitation: {} }) // true — implicit form mode
|
|
720
|
+
* isFormElicitationSupported({ elicitation: { url: {} } }) // false
|
|
721
|
+
* ```
|
|
722
|
+
*/
|
|
723
|
+
export declare function isFormElicitationSupported(value: unknown): boolean;
|
|
320
724
|
|
|
321
725
|
/**
|
|
322
726
|
* Determine whether a parsed value is an MCP `initialize` request — a
|
|
@@ -333,6 +737,50 @@ export declare function initializeResult(name: string, version: string, requeste
|
|
|
333
737
|
*/
|
|
334
738
|
export declare function isInitializeRequest(value: unknown): value is JSONRPCRequest;
|
|
335
739
|
|
|
740
|
+
/**
|
|
741
|
+
* Determine whether a value is one legal embedded multi-round-trip request.
|
|
742
|
+
*
|
|
743
|
+
* @param value - The unknown value to inspect
|
|
744
|
+
* @returns `true` for elicitation, deprecated sampling, or deprecated roots requests
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* isInputRequest({ method: 'roots/list' }) // true — legal but not produced by this package
|
|
749
|
+
* ```
|
|
750
|
+
*/
|
|
751
|
+
export declare function isInputRequest(value: unknown): value is InputRequest;
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Determine whether a value is a server-keyed map of embedded input requests.
|
|
755
|
+
*
|
|
756
|
+
* @param value - The unknown value to inspect
|
|
757
|
+
* @returns `true` when every own value is a legal {@link InputRequest}
|
|
758
|
+
*
|
|
759
|
+
* @example
|
|
760
|
+
* ```ts
|
|
761
|
+
* isInputRequests({ confirm: { method: 'roots/list' } }) // true; maps, never arrays
|
|
762
|
+
* ```
|
|
763
|
+
*/
|
|
764
|
+
export declare function isInputRequests(value: unknown): value is InputRequests;
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Determine whether a value is an MCP input-required result.
|
|
768
|
+
*
|
|
769
|
+
* @remarks
|
|
770
|
+
* Enforces the at-least-one-of rule at runtime: `inputRequests`, `requestState`, or
|
|
771
|
+
* both must be present and valid. Total over hostile input.
|
|
772
|
+
*
|
|
773
|
+
* @param value - The unknown value to inspect
|
|
774
|
+
* @returns `true` when `value` is a valid input-required result
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* ```ts
|
|
778
|
+
* isInputRequiredResult({ resultType: 'input_required', requestState: 'opaque' }) // true
|
|
779
|
+
* isInputRequiredResult({ resultType: 'input_required' }) // false
|
|
780
|
+
* ```
|
|
781
|
+
*/
|
|
782
|
+
export declare function isInputRequiredResult(value: unknown): value is InputRequiredResult;
|
|
783
|
+
|
|
336
784
|
/**
|
|
337
785
|
* Determine whether a parsed value is a {@link JSONRPCMessage} — a request or a
|
|
338
786
|
* response.
|
|
@@ -394,6 +842,29 @@ export declare function isJSONRPCResponse(value: unknown): value is JSONRPCRespo
|
|
|
394
842
|
*/
|
|
395
843
|
export declare function isMCPError(value: unknown): value is MCPError;
|
|
396
844
|
|
|
845
|
+
/**
|
|
846
|
+
* Determine whether a value is a supported {@link MCPVersion}.
|
|
847
|
+
*
|
|
848
|
+
* @param value - The unknown value to inspect
|
|
849
|
+
* @returns `true` when the value is one of {@link SUPPORTED_PROTOCOL_VERSIONS}
|
|
850
|
+
*/
|
|
851
|
+
export declare function isMCPVersion(value: unknown): value is MCPVersion;
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Determine whether a JSON-RPC request uses the modern per-request MCP wire shape.
|
|
855
|
+
*
|
|
856
|
+
* @remarks
|
|
857
|
+
* Presence routes and validity answers: this guard checks only that
|
|
858
|
+
* `params._meta` carries the reserved protocol-version key. The key's value is
|
|
859
|
+
* deliberately not narrowed here, so a present non-string version remains modern
|
|
860
|
+
* and is rejected later by `parseRequestContext` rather than falling through to
|
|
861
|
+
* legacy dispatch. Total over hostile and malformed input.
|
|
862
|
+
*
|
|
863
|
+
* @param value - The already-parsed value to inspect
|
|
864
|
+
* @returns `true` when the value is a request carrying the reserved version key
|
|
865
|
+
*/
|
|
866
|
+
export declare function isModernRequest(value: unknown): value is JSONRPCRequest;
|
|
867
|
+
|
|
397
868
|
/**
|
|
398
869
|
* Determine whether a value is a valid JSON-RPC REQUEST `id` — a string, a number,
|
|
399
870
|
* or absent.
|
|
@@ -416,6 +887,20 @@ export declare function isMCPError(value: unknown): value is MCPError;
|
|
|
416
887
|
*/
|
|
417
888
|
export declare function isRequestId(value: unknown): value is string | number | undefined;
|
|
418
889
|
|
|
890
|
+
/**
|
|
891
|
+
* Determine whether a value is an MCP {@link SubscriptionFilter}.
|
|
892
|
+
*
|
|
893
|
+
* @remarks
|
|
894
|
+
* Every filter field is optional. Boolean notification families accept only booleans, and
|
|
895
|
+
* `resourceSubscriptions` accepts only an array of string URIs. Unknown fields remain open
|
|
896
|
+
* for protocol extensions and are ignored by the built-in subscription matcher. Total over
|
|
897
|
+
* hostile input.
|
|
898
|
+
*
|
|
899
|
+
* @param value - The unknown value to inspect
|
|
900
|
+
* @returns `true` when every recognized filter field has its protocol shape
|
|
901
|
+
*/
|
|
902
|
+
export declare function isSubscriptionFilter(value: unknown): value is SubscriptionFilter;
|
|
903
|
+
|
|
419
904
|
/** JSON-RPC 2.0 reserved error: the method's parameters were invalid. */
|
|
420
905
|
export declare const JSONRPC_INVALID_PARAMS = -32602;
|
|
421
906
|
|
|
@@ -431,18 +916,6 @@ export declare const JSONRPC_PARSE_ERROR = -32700;
|
|
|
431
916
|
/** JSON-RPC 2.0 implementation-defined server error (the `-32000` to `-32099` range). */
|
|
432
917
|
export declare const JSONRPC_SERVER_ERROR = -32000;
|
|
433
918
|
|
|
434
|
-
/**
|
|
435
|
-
* Build a JSON-RPC error {@link JSONRPCResponse} — the `id` echoed, the failure as
|
|
436
|
-
* an `error` object.
|
|
437
|
-
*
|
|
438
|
-
* @param id - The request's id (`null` for a parse / invalid-request error)
|
|
439
|
-
* @param code - One of the reserved JSON-RPC codes (see `./constants.js`)
|
|
440
|
-
* @param message - A short human description of the failure
|
|
441
|
-
* @param data - An OPTIONAL machine-readable payload (omitted from the envelope when absent)
|
|
442
|
-
* @returns The error response envelope
|
|
443
|
-
*/
|
|
444
|
-
export declare function jsonRPCError(id: string | number | null, code: number, message: string, data?: unknown): JSONRPCResponse;
|
|
445
|
-
|
|
446
919
|
/**
|
|
447
920
|
* A JSON-RPC 2.0 error object — the `error` member of a failed
|
|
448
921
|
* {@link JSONRPCResponse}.
|
|
@@ -498,39 +971,99 @@ export declare interface JSONRPCResponse {
|
|
|
498
971
|
}
|
|
499
972
|
|
|
500
973
|
/**
|
|
501
|
-
*
|
|
502
|
-
* value as `result`.
|
|
974
|
+
* Determine whether a produced notification belongs to an honoured subscription filter.
|
|
503
975
|
*
|
|
504
|
-
* @param
|
|
505
|
-
* @param
|
|
506
|
-
* @returns
|
|
976
|
+
* @param notification - The server notification offered by the configured producer
|
|
977
|
+
* @param filter - The filter acknowledged to the client
|
|
978
|
+
* @returns `true` when the notification belongs on this subscription stream
|
|
979
|
+
*/
|
|
980
|
+
export declare function matchesSubscriptionNotification(notification: JSONRPCRequest, filter: SubscriptionFilter): boolean;
|
|
981
|
+
|
|
982
|
+
/** MCP reserved error: required HTTP metadata does not match the request body. */
|
|
983
|
+
export declare const MCP_HEADER_MISMATCH = -32020;
|
|
984
|
+
|
|
985
|
+
/** The legacy fallback anchor used when an initialize request cannot be accepted as modern. */
|
|
986
|
+
export declare const MCP_LEGACY_VERSION: MCPVersion;
|
|
987
|
+
|
|
988
|
+
/** Reserved modern `_meta` key carrying the client's open capability record. */
|
|
989
|
+
export declare const MCP_META_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
|
|
990
|
+
|
|
991
|
+
/** Reserved modern `_meta` key carrying the optional client identity. */
|
|
992
|
+
export declare const MCP_META_CLIENT = "io.modelcontextprotocol/clientInfo";
|
|
993
|
+
|
|
994
|
+
/** Reserved modern `_meta` key carrying the server identity on results. */
|
|
995
|
+
export declare const MCP_META_SERVER = "io.modelcontextprotocol/serverInfo";
|
|
996
|
+
|
|
997
|
+
/** Reserved modern `_meta` key carrying a `subscriptions/listen` request id. */
|
|
998
|
+
export declare const MCP_META_SUBSCRIPTION = "io.modelcontextprotocol/subscriptionId";
|
|
999
|
+
|
|
1000
|
+
/** Reserved modern `_meta` key carrying the request's protocol revision. */
|
|
1001
|
+
export declare const MCP_META_VERSION = "io.modelcontextprotocol/protocolVersion";
|
|
1002
|
+
|
|
1003
|
+
/** MCP reserved error: an operation needs a client capability that was not declared. */
|
|
1004
|
+
export declare const MCP_MISSING_CAPABILITY = -32021;
|
|
1005
|
+
|
|
1006
|
+
/** The modern revision offered by an unpinned client during discovery. */
|
|
1007
|
+
export declare const MCP_MODERN_VERSION: MCPVersion;
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* The revision offered and defaulted to in the legacy `initialize` handshake.
|
|
1011
|
+
*
|
|
1012
|
+
* @remarks
|
|
1013
|
+
* This is deliberately a legacy revision, and the newest one supported. 2026-07-28 is stateless
|
|
1014
|
+
* and defines no `initialize`, so it can never be the handshake's version — a client that offers
|
|
1015
|
+
* it is asking to negotiate a revision with no negotiation.
|
|
507
1016
|
*/
|
|
508
|
-
export declare
|
|
1017
|
+
export declare const MCP_PROTOCOL_VERSION: MCPVersion;
|
|
509
1018
|
|
|
510
|
-
/**
|
|
511
|
-
export declare const
|
|
1019
|
+
/** MCP reserved error: a request names an unsupported protocol revision. */
|
|
1020
|
+
export declare const MCP_UNSUPPORTED_VERSION = -32022;
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* The MCP `tools/call` result — the executed tool's output as `content` blocks,
|
|
1024
|
+
* with `isError` flagging a tool failure.
|
|
1025
|
+
*
|
|
1026
|
+
* @remarks
|
|
1027
|
+
* A success carries the tool's value unchanged as `structuredContent` alongside
|
|
1028
|
+
* its serialized form in one `text` content block. A value-less success omits
|
|
1029
|
+
* `structuredContent`. A tool FAILURE (the `success: false` branch the registry
|
|
1030
|
+
* isolated) carries its `error` text in `content` AND sets `isError: true`, so the
|
|
1031
|
+
* model sees the failure as a tool result it can react to rather than a protocol
|
|
1032
|
+
* error.
|
|
1033
|
+
*/
|
|
1034
|
+
export declare interface MCPCallResult {
|
|
1035
|
+
readonly content: readonly MCPContent[];
|
|
1036
|
+
/** The successful tool value in its original structure; absent when no value was returned. */
|
|
1037
|
+
readonly structuredContent?: unknown;
|
|
1038
|
+
/** `true` when the tool failed — its error text is in `content`. */
|
|
1039
|
+
readonly isError?: boolean;
|
|
1040
|
+
/** The modern result discriminator; absent on a legacy result. */
|
|
1041
|
+
readonly resultType?: 'complete';
|
|
1042
|
+
/** Open modern protocol metadata, including reserved namespaced keys. */
|
|
1043
|
+
readonly _meta?: Readonly<Record<string, unknown>>;
|
|
1044
|
+
}
|
|
512
1045
|
|
|
513
1046
|
/**
|
|
514
1047
|
* A transport-agnostic Model Context Protocol CLIENT — connects to a REMOTE MCP server
|
|
515
|
-
* over an injected {@link ClientTransportInterface},
|
|
516
|
-
* and exposes the server's tools as local {@link ToolInterface}s an agent can run.
|
|
1048
|
+
* over an injected {@link ClientTransportInterface}, negotiates the modern or legacy
|
|
1049
|
+
* wire era, and exposes the server's tools as local {@link ToolInterface}s an agent can run.
|
|
517
1050
|
*
|
|
518
1051
|
* @remarks
|
|
519
1052
|
* - **The mirror of `MCPServer`.** The server DISPATCHES requests over a tool registry;
|
|
520
|
-
* this client ISSUES them over a transport. `connect`
|
|
521
|
-
*
|
|
522
|
-
* lists the remote tools and wraps each as a
|
|
1053
|
+
* this client ISSUES them over a transport. `connect` probes `server/discover` unless
|
|
1054
|
+
* pinned legacy, falls back to `initialize` only for a legacy peer, and exposes the
|
|
1055
|
+
* negotiated `version`; `tools()` lists the remote tools and wraps each as a
|
|
523
1056
|
* local {@link ToolInterface} whose `execute` calls back through `call`; `call` runs a
|
|
524
1057
|
* remote `tools/call` and returns the tool's value (a remote `isError: true` throws
|
|
525
|
-
* locally, so an agent's {@link import('@orkestrel/
|
|
526
|
-
* isolates it into a
|
|
1058
|
+
* locally, so an agent's {@link import('@orkestrel/tool').ToolManagerInterface}
|
|
1059
|
+
* isolates it into a `success: false` result just like a local throw).
|
|
527
1060
|
* - **Request↔response correlation.** Each request is tagged with a monotonic numeric
|
|
528
1061
|
* `id` ({@link #nextId}); a single transport `message` subscription resolves / rejects
|
|
529
1062
|
* the matching {@link #pending} entry by `id`. A message that is NOT a response to a
|
|
530
1063
|
* pending request is a server NOTIFICATION — re-surfaced on the `notification` event.
|
|
531
|
-
* - **Per-request deadline.** `#request`
|
|
532
|
-
*
|
|
533
|
-
*
|
|
1064
|
+
* - **Per-request deadline.** Each `#request` receives its own deadline: ordinary calls use
|
|
1065
|
+
* `this.#timeout`, while an explicitly bounded discovery uses the shorter probe deadline.
|
|
1066
|
+
* `AbortSignal.timeout` (never a raw `setTimeout`) rejects only that pending request.
|
|
534
1067
|
* - **Transport-agnostic.** Imports only core siblings (JSON-RPC + the tool vocabulary);
|
|
535
1068
|
* the concrete transport is injected. Wire fields are narrowed via the contracts
|
|
536
1069
|
* guards (no `as`).
|
|
@@ -540,7 +1073,7 @@ export declare const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
|
540
1073
|
*
|
|
541
1074
|
* @example
|
|
542
1075
|
* ```ts
|
|
543
|
-
* const client = new MCPClient({ transport, name: 'agent', version: '1.0.0' })
|
|
1076
|
+
* const client = new MCPClient({ transport, identity: { name: 'agent', version: '1.0.0' } })
|
|
544
1077
|
* await client.connect()
|
|
545
1078
|
* const tools = await client.tools()
|
|
546
1079
|
* agent.context.tools.add(tools) // the remote tools are now the agent's
|
|
@@ -552,10 +1085,11 @@ export declare class MCPClient implements MCPClientInterface {
|
|
|
552
1085
|
constructor(options: MCPClientOptions);
|
|
553
1086
|
get emitter(): EmitterInterface<MCPClientEventMap>;
|
|
554
1087
|
get connected(): boolean;
|
|
555
|
-
get
|
|
1088
|
+
get version(): MCPVersion | undefined;
|
|
556
1089
|
get transport(): ClientTransportInterface;
|
|
557
1090
|
on<K extends keyof MCPClientEventMap>(event: K, handler: (...args: MCPClientEventMap[K]) => void): void;
|
|
558
1091
|
connect(): Promise<void>;
|
|
1092
|
+
discover(): Promise<MCPDiscoverResult>;
|
|
559
1093
|
disconnect(): Promise<void>;
|
|
560
1094
|
tools(): Promise<readonly ToolInterface[]>;
|
|
561
1095
|
call(name: string, args: Readonly<Record<string, unknown>>): Promise<unknown>;
|
|
@@ -590,20 +1124,21 @@ export declare type MCPClientEventMap = {
|
|
|
590
1124
|
|
|
591
1125
|
/**
|
|
592
1126
|
* A transport-agnostic Model Context Protocol CLIENT — connects to a REMOTE MCP
|
|
593
|
-
* server over an injected {@link ClientTransportInterface},
|
|
594
|
-
*
|
|
1127
|
+
* server over an injected {@link ClientTransportInterface}, negotiates the
|
|
1128
|
+
* modern or legacy wire era, and exposes the server's tools as local
|
|
595
1129
|
* {@link ToolInterface}s an agent can run.
|
|
596
1130
|
*
|
|
597
1131
|
* @remarks
|
|
598
1132
|
* - **The mirror of {@link MCPServerInterface}.** Where the server DISPATCHES requests
|
|
599
|
-
* over a tool registry, the client ISSUES them over a transport: `connect`
|
|
600
|
-
* `
|
|
601
|
-
*
|
|
1133
|
+
* over a tool registry, the client ISSUES them over a transport: `connect` probes
|
|
1134
|
+
* `server/discover` first unless pinned to a legacy revision, falling back to the
|
|
1135
|
+
* legacy `initialize` handshake only when the peer does not speak the modern era.
|
|
1136
|
+
* The negotiated revision is exposed through `version`; `tools()` lists
|
|
602
1137
|
* the remote tools and wraps each as a local {@link ToolInterface} whose `execute`
|
|
603
1138
|
* calls back through `call`; `call(name, args)` runs a remote `tools/call` and
|
|
604
1139
|
* returns the tool's value (a remote tool FAILURE — `isError: true` — throws locally,
|
|
605
|
-
* so the agent's {@link ToolManagerInterface} isolates it into a
|
|
606
|
-
* like a local throw).
|
|
1140
|
+
* so the agent's {@link ToolManagerInterface} isolates it into a `success: false`
|
|
1141
|
+
* result just like a local throw).
|
|
607
1142
|
* - **Request↔response correlation.** Every request is tagged with a monotonic numeric
|
|
608
1143
|
* `id`; the client subscribes to the transport's `message` event and resolves /
|
|
609
1144
|
* rejects the matching pending request by that `id`. A message that is NOT a response
|
|
@@ -620,13 +1155,10 @@ export declare type MCPClientEventMap = {
|
|
|
620
1155
|
*/
|
|
621
1156
|
export declare interface MCPClientInterface {
|
|
622
1157
|
readonly emitter: EmitterInterface<MCPClientEventMap>;
|
|
623
|
-
/** Whether
|
|
1158
|
+
/** Whether era negotiation has completed and the client is connected. */
|
|
624
1159
|
readonly connected: boolean;
|
|
625
|
-
/**
|
|
626
|
-
|
|
627
|
-
* connecting and after {@link disconnect}.
|
|
628
|
-
*/
|
|
629
|
-
readonly protocol: string | undefined;
|
|
1160
|
+
/** The negotiated protocol revision, or `undefined` while disconnected. */
|
|
1161
|
+
readonly version: MCPVersion | undefined;
|
|
630
1162
|
/** The injected transport the client drives the remote server over. */
|
|
631
1163
|
readonly transport: ClientTransportInterface;
|
|
632
1164
|
/**
|
|
@@ -638,19 +1170,29 @@ export declare interface MCPClientInterface {
|
|
|
638
1170
|
*/
|
|
639
1171
|
on<K extends keyof MCPClientEventMap>(event: K, handler: (...args: MCPClientEventMap[K]) => void): void;
|
|
640
1172
|
/**
|
|
641
|
-
* Connect to the remote server — open the transport and
|
|
642
|
-
*
|
|
643
|
-
* `notifications/initialized`.
|
|
1173
|
+
* Connect to the remote server — open the transport and negotiate the modern or
|
|
1174
|
+
* legacy wire era without exposing that choice to the caller.
|
|
644
1175
|
*
|
|
645
1176
|
* @remarks
|
|
646
|
-
* Idempotent — a second `connect` while already connected is a no-op.
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
1177
|
+
* Idempotent — a second `connect` while already connected is a no-op. An unpinned
|
|
1178
|
+
* client probes `server/discover`; a pinned legacy client and a legacy fallback run
|
|
1179
|
+
* `initialize` and send `notifications/initialized`. On success {@link version}
|
|
1180
|
+
* contains a supported revision and the `connect` event fires.
|
|
650
1181
|
*
|
|
651
1182
|
* @returns Resolves once the handshake completes and the client is connected
|
|
652
1183
|
*/
|
|
653
1184
|
connect(): Promise<void>;
|
|
1185
|
+
/**
|
|
1186
|
+
* Discover a modern server's supported revisions and capabilities.
|
|
1187
|
+
*
|
|
1188
|
+
* @remarks
|
|
1189
|
+
* The request carries the modern per-request metadata stamp. Unknown revisions in
|
|
1190
|
+
* the peer's advertisement are ignored because {@link MCPDiscoverResult} exposes
|
|
1191
|
+
* only revisions this client can negotiate.
|
|
1192
|
+
*
|
|
1193
|
+
* @returns The validated modern discovery result
|
|
1194
|
+
*/
|
|
1195
|
+
discover(): Promise<MCPDiscoverResult>;
|
|
654
1196
|
/**
|
|
655
1197
|
* Disconnect from the remote server — reject every pending request and close the
|
|
656
1198
|
* transport.
|
|
@@ -680,11 +1222,11 @@ export declare interface MCPClientInterface {
|
|
|
680
1222
|
* result's `text` content blocks, and either parses the JSON value or throws.
|
|
681
1223
|
*
|
|
682
1224
|
* @remarks
|
|
683
|
-
* The inverse of the server's `
|
|
1225
|
+
* The inverse of the server's `buildCallResult`: a SUCCESS parses the concatenated
|
|
684
1226
|
* `text` as JSON (falling back to the raw string when it is not JSON); a remote tool
|
|
685
1227
|
* FAILURE (`isError: true`) THROWS an `Error` carrying the error text — so an agent's
|
|
686
|
-
* {@link ToolManagerInterface} isolates the remote failure into a
|
|
687
|
-
* exactly as it would a local tool throw.
|
|
1228
|
+
* {@link ToolManagerInterface} isolates the remote failure into a `success: false`
|
|
1229
|
+
* result exactly as it would a local tool throw.
|
|
688
1230
|
*
|
|
689
1231
|
* @param name - The remote tool's name
|
|
690
1232
|
* @param args - The arguments record forwarded as the call's `arguments`
|
|
@@ -695,15 +1237,18 @@ export declare interface MCPClientInterface {
|
|
|
695
1237
|
|
|
696
1238
|
/**
|
|
697
1239
|
* Options for `createMCPClient` — the {@link ClientTransportInterface} to drive, the
|
|
698
|
-
* client
|
|
1240
|
+
* optional client {@link MCPIdentity}, the per-request `timeout`, and the reserved
|
|
699
1241
|
* `on` hooks (§8).
|
|
700
1242
|
*
|
|
701
1243
|
* @remarks
|
|
702
1244
|
* - `transport` — the carrier the client drives a remote MCP server over (REQUIRED;
|
|
703
1245
|
* a concrete one from `src/server/mcp`, or an in-process loopback).
|
|
704
|
-
* - `
|
|
705
|
-
*
|
|
706
|
-
*
|
|
1246
|
+
* - `identity` — identifies the client in the `initialize` handshake (`clientInfo`);
|
|
1247
|
+
* defaults to {@link import('./constants.js').DEFAULT_MCP_CLIENT_NAME} /
|
|
1248
|
+
* {@link import('./constants.js').DEFAULT_MCP_CLIENT_VERSION}.
|
|
1249
|
+
* - `capabilities` — the open client-capability record carried by every modern
|
|
1250
|
+
* request; defaults to an empty record when the modern client implementation lands.
|
|
1251
|
+
* - `version` — an optional protocol pin; absence lets the modern client negotiate.
|
|
707
1252
|
* - `timeout` — the per-request deadline in milliseconds: a `tools/list` / `tools/call`
|
|
708
1253
|
* / `initialize` that the server does not answer within it REJECTS (the pending
|
|
709
1254
|
* request is settled by an `AbortSignal.timeout(timeout)` deadline — never a raw
|
|
@@ -717,18 +1262,47 @@ export declare interface MCPClientOptions {
|
|
|
717
1262
|
/** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
|
|
718
1263
|
readonly error?: EmitterErrorHandler;
|
|
719
1264
|
readonly transport: ClientTransportInterface;
|
|
720
|
-
readonly
|
|
721
|
-
|
|
1265
|
+
readonly identity?: MCPIdentity;
|
|
1266
|
+
/** The open client-capability record carried by modern requests. */
|
|
1267
|
+
readonly capabilities?: Readonly<Record<string, unknown>>;
|
|
1268
|
+
/** An optional protocol revision pin; absence permits negotiation. */
|
|
1269
|
+
readonly version?: MCPVersion;
|
|
722
1270
|
/** The per-request deadline in milliseconds (default {@link import('./constants.js').DEFAULT_MCP_REQUEST_TIMEOUT}). */
|
|
723
1271
|
readonly timeout?: number;
|
|
724
1272
|
}
|
|
725
1273
|
|
|
726
|
-
/** One content item of an MCP {@link
|
|
1274
|
+
/** One content item of an MCP {@link MCPCallResult} — a `text` block carrying the tool's output. */
|
|
727
1275
|
export declare interface MCPContent {
|
|
728
1276
|
readonly type: 'text';
|
|
729
1277
|
readonly text: string;
|
|
730
1278
|
}
|
|
731
1279
|
|
|
1280
|
+
/** The mandatory modern `server/discover` result. */
|
|
1281
|
+
export declare interface MCPDiscoverResult {
|
|
1282
|
+
readonly supportedVersions: readonly MCPVersion[];
|
|
1283
|
+
readonly capabilities: Readonly<Record<string, unknown>>;
|
|
1284
|
+
readonly resultType: 'complete';
|
|
1285
|
+
readonly ttlMs: number;
|
|
1286
|
+
readonly cacheScope: 'public' | 'private';
|
|
1287
|
+
readonly instructions?: string;
|
|
1288
|
+
readonly _meta?: Readonly<Record<string, unknown>>;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
/** Per-request execution options every dispatched handler receives. */
|
|
1292
|
+
export declare interface MCPDispatchOptions {
|
|
1293
|
+
/** Aborts when the bound transport can observe that the caller's request has ended. */
|
|
1294
|
+
readonly signal?: AbortSignal;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/** One consumer-requested form elicitation, before MCP assigns its map key and signs state. */
|
|
1298
|
+
export declare interface MCPElicitation {
|
|
1299
|
+
readonly request: ElicitRequestFormParams;
|
|
1300
|
+
readonly state?: string;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
/** The wire era selected by an MCP request's structure. */
|
|
1304
|
+
export declare type MCPEra = 'modern' | 'legacy';
|
|
1305
|
+
|
|
732
1306
|
/**
|
|
733
1307
|
* A remote Model Context Protocol JSON-RPC error, preserving its machine-readable
|
|
734
1308
|
* numeric code and optional structured context.
|
|
@@ -737,13 +1311,19 @@ export declare interface MCPContent {
|
|
|
737
1311
|
* {@link MCPClient} throws this error only for a remote JSON-RPC `error` response.
|
|
738
1312
|
* Local lifecycle and transport conditions such as disconnects and request timeouts
|
|
739
1313
|
* remain plain `Error`s. `context` carries the response's optional `error.data`
|
|
740
|
-
* unchanged and is `undefined` when the peer omitted it.
|
|
1314
|
+
* unchanged and is `undefined` when the peer omitted it. This includes the modern
|
|
1315
|
+
* reserved paths: `-32020` carries no context, `-32021` may carry
|
|
1316
|
+
* `requiredCapabilities`, and `-32022` carries the peer's `supported` revisions and
|
|
1317
|
+
* `requested` revision for negotiation recovery.
|
|
741
1318
|
*
|
|
742
1319
|
* @example
|
|
743
1320
|
* ```ts
|
|
744
|
-
* const error = new MCPError('
|
|
745
|
-
*
|
|
746
|
-
*
|
|
1321
|
+
* const error = new MCPError('Unsupported protocol version', -32022, {
|
|
1322
|
+
* supported: ['2026-07-28'],
|
|
1323
|
+
* requested: '2024-11-05',
|
|
1324
|
+
* })
|
|
1325
|
+
* error.code // -32022
|
|
1326
|
+
* error.context // { supported: ['2026-07-28'], requested: '2024-11-05' }
|
|
747
1327
|
* ```
|
|
748
1328
|
*/
|
|
749
1329
|
export declare class MCPError extends Error {
|
|
@@ -760,6 +1340,188 @@ export declare class MCPError extends Error {
|
|
|
760
1340
|
constructor(message: string, code: number, context?: unknown);
|
|
761
1341
|
}
|
|
762
1342
|
|
|
1343
|
+
/** The identity (`name` / `version`) of an MCP server or client. */
|
|
1344
|
+
export declare interface MCPIdentity {
|
|
1345
|
+
readonly name: string;
|
|
1346
|
+
readonly version: string;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/** The call-in-hand context supplied to an {@link MCPInputHandler}. */
|
|
1350
|
+
export declare interface MCPInputContext {
|
|
1351
|
+
readonly request: JSONRPCRequest;
|
|
1352
|
+
readonly name: string;
|
|
1353
|
+
readonly arguments: Readonly<Record<string, unknown>>;
|
|
1354
|
+
readonly response?: ElicitResult;
|
|
1355
|
+
readonly state?: string;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* Decide whether the current `tools/call` needs operator input.
|
|
1360
|
+
*
|
|
1361
|
+
* @param context - The original call plus a verified response/state on a retry
|
|
1362
|
+
* @param options - The per-request execution options
|
|
1363
|
+
* @returns A form elicitation to send, or `undefined` to continue into the tool registry
|
|
1364
|
+
*/
|
|
1365
|
+
export declare type MCPInputHandler = (context: MCPInputContext, options: MCPDispatchOptions) => MCPElicitation | undefined | Promise<MCPElicitation | undefined>;
|
|
1366
|
+
|
|
1367
|
+
/** Consumer policy for the server's multi-round-trip input mechanism. */
|
|
1368
|
+
export declare interface MCPInputOptions {
|
|
1369
|
+
/** HMAC secret or `[current, ...older]` rotation list used by `signToken` / `verifyToken`. */
|
|
1370
|
+
readonly secret: TokenSecret;
|
|
1371
|
+
/** Token lifetime in milliseconds; required so MCP never invents an expiry policy. */
|
|
1372
|
+
readonly ttl: number;
|
|
1373
|
+
/** Resolve the authenticated principal for the call in hand. */
|
|
1374
|
+
readonly principal: MCPPrincipalHandler;
|
|
1375
|
+
/** Decide whether the call needs a form elicitation, including on verified retries. */
|
|
1376
|
+
readonly elicit: MCPInputHandler;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/** The integrity-protected payload carried inside an opaque `requestState` token. */
|
|
1380
|
+
export declare interface MCPInputState {
|
|
1381
|
+
readonly principal: string;
|
|
1382
|
+
readonly ttl: number;
|
|
1383
|
+
readonly origin: string | number;
|
|
1384
|
+
readonly key: string;
|
|
1385
|
+
readonly name: string;
|
|
1386
|
+
readonly state?: string;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/** Limits applied by {@link isBoundedJSON} to one JSON value. */
|
|
1390
|
+
export declare interface MCPJSONLimitOptions {
|
|
1391
|
+
/** Maximum serialized UTF-8 bytes. */
|
|
1392
|
+
readonly bytes: number;
|
|
1393
|
+
/** Maximum total enumerable keys; omitted when bytes alone bound breadth. */
|
|
1394
|
+
readonly keys?: number;
|
|
1395
|
+
/** Maximum array/object nesting depth. */
|
|
1396
|
+
readonly depth: number;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/** Configurable hostile-input and live-resource bounds for an MCP server. */
|
|
1400
|
+
export declare interface MCPLimitOptions {
|
|
1401
|
+
/** Maximum UTF-8 bytes accepted by the raw string boundary. */
|
|
1402
|
+
readonly message?: number;
|
|
1403
|
+
/** Maximum serialized UTF-8 bytes accepted in one `_meta` value. */
|
|
1404
|
+
readonly metadata?: number;
|
|
1405
|
+
/** Maximum total enumerable keys accepted across one `_meta` value. */
|
|
1406
|
+
readonly keys?: number;
|
|
1407
|
+
/** Maximum UTF-8 bytes accepted in one protected `requestState`. */
|
|
1408
|
+
readonly state?: number;
|
|
1409
|
+
/** Maximum serialized UTF-8 bytes accepted from one produced tool content value. */
|
|
1410
|
+
readonly content?: number;
|
|
1411
|
+
/** Maximum simultaneously live built-in subscription streams. */
|
|
1412
|
+
readonly subscriptions?: number;
|
|
1413
|
+
/** Maximum nesting depth accepted by bounded JSON values. */
|
|
1414
|
+
readonly depth?: number;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/**
|
|
1418
|
+
* The MCP `tools/list` result — tool descriptors plus optional modern result
|
|
1419
|
+
* stamps.
|
|
1420
|
+
*
|
|
1421
|
+
* @remarks
|
|
1422
|
+
* The wire field names remain verbatim. A modern result requires `resultType`,
|
|
1423
|
+
* `ttlMs`, and `cacheScope`; they remain optional here because the same result
|
|
1424
|
+
* shape also models the unstamped legacy response.
|
|
1425
|
+
*/
|
|
1426
|
+
export declare interface MCPListResult {
|
|
1427
|
+
readonly tools: readonly MCPToolDescriptor[];
|
|
1428
|
+
readonly resultType?: 'complete';
|
|
1429
|
+
readonly ttlMs?: number;
|
|
1430
|
+
readonly cacheScope?: 'public' | 'private';
|
|
1431
|
+
readonly _meta?: Readonly<Record<string, unknown>>;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* One modern method, registered on the seam that dispatches it.
|
|
1436
|
+
*
|
|
1437
|
+
* @remarks
|
|
1438
|
+
* `undefined` answers nothing (the notification arm); an {@link MCPStream} holds the
|
|
1439
|
+
* request open. `options.signal` aborts when the caller's request ends — what a handler
|
|
1440
|
+
* does with it is the handler's decision, never this package's.
|
|
1441
|
+
*
|
|
1442
|
+
* @param request - The parsed modern request being dispatched
|
|
1443
|
+
* @param options - The per-request execution options (see {@link MCPDispatchOptions})
|
|
1444
|
+
* @returns The terminating response, a held-open {@link MCPStream}, or `undefined` for no answer
|
|
1445
|
+
*/
|
|
1446
|
+
export declare type MCPMethodHandler = (request: JSONRPCRequest, options: MCPDispatchOptions) => Promise<JSONRPCResponse | MCPStream | undefined>;
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* The modern method registry an {@link import('./types.js').MCPServerInterface}
|
|
1450
|
+
* dispatches through — a name-keyed store of {@link MCPMethodHandler}s that owns its
|
|
1451
|
+
* map rather than exposing one.
|
|
1452
|
+
*
|
|
1453
|
+
* @remarks
|
|
1454
|
+
* - **One seam.** The server registers its built-in modern methods here at construction
|
|
1455
|
+
* and resolves EVERY modern method from here, so a consumer's method and a built-in
|
|
1456
|
+
* are the same kind of thing on the same path.
|
|
1457
|
+
* - **Registration is a write, not a merge.** `add` under a name already present
|
|
1458
|
+
* REPLACES it, which is how a consumer overrides a built-in; there is no precedence
|
|
1459
|
+
* rule to remember.
|
|
1460
|
+
* - **A narrower contract than a `Map`.** Callers register and resolve; they cannot
|
|
1461
|
+
* iterate, clear, or otherwise reach the server's internal state through it.
|
|
1462
|
+
*
|
|
1463
|
+
* @example
|
|
1464
|
+
* ```ts
|
|
1465
|
+
* const methods = new MCPMethodManager()
|
|
1466
|
+
* methods.add('tools/list', async (request) => buildJSONRPCResult(request.id ?? null, { tools: [] }))
|
|
1467
|
+
* methods.method('tools/list') // the handler
|
|
1468
|
+
* methods.method('tools/nope') // undefined → the dispatch branch answers -32601
|
|
1469
|
+
* ```
|
|
1470
|
+
*/
|
|
1471
|
+
export declare class MCPMethodManager implements MCPMethodManagerInterface {
|
|
1472
|
+
#private;
|
|
1473
|
+
add(name: string, handler: MCPMethodHandler): void;
|
|
1474
|
+
method(name: string): MCPMethodHandler | undefined;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* The modern method registry an {@link MCPServerInterface} dispatches through — the ONE
|
|
1479
|
+
* seam carrying both the built-in methods and any method a consumer adds.
|
|
1480
|
+
*
|
|
1481
|
+
* @remarks
|
|
1482
|
+
* `server/discover`, `tools/list`, `tools/call`, and `subscriptions/listen` are registered here at construction,
|
|
1483
|
+
* so they travel the SAME path as every later method: there is no second dispatch route
|
|
1484
|
+
* and no precedence puzzle. `add` under an existing name REPLACES that method — a
|
|
1485
|
+
* consumer overriding a built-in is an ordinary registration, not a special case. A name
|
|
1486
|
+
* with no handler is not an error state to model: {@link method} answers `undefined` and
|
|
1487
|
+
* the dispatch branch turns that into `-32601`.
|
|
1488
|
+
*/
|
|
1489
|
+
export declare interface MCPMethodManagerInterface {
|
|
1490
|
+
/**
|
|
1491
|
+
* Register one modern method — replacing any handler already under that name.
|
|
1492
|
+
*
|
|
1493
|
+
* @param name - The JSON-RPC method name to answer (e.g. `'tools/call'`)
|
|
1494
|
+
* @param handler - The handler dispatched for that method
|
|
1495
|
+
*/
|
|
1496
|
+
add(name: string, handler: MCPMethodHandler): void;
|
|
1497
|
+
/**
|
|
1498
|
+
* Find the handler registered for one method name.
|
|
1499
|
+
*
|
|
1500
|
+
* @param name - The JSON-RPC method name to resolve
|
|
1501
|
+
* @returns The registered handler, or `undefined` when the method is unregistered
|
|
1502
|
+
*/
|
|
1503
|
+
method(name: string): MCPMethodHandler | undefined;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
/** Derive the deployment-authenticated principal bound into signed request state. */
|
|
1507
|
+
export declare type MCPPrincipalHandler = (request: JSONRPCRequest) => string | Promise<string>;
|
|
1508
|
+
|
|
1509
|
+
/**
|
|
1510
|
+
* The validated per-request context projected from a modern request's reserved
|
|
1511
|
+
* `_meta` keys.
|
|
1512
|
+
*
|
|
1513
|
+
* @remarks
|
|
1514
|
+
* `version` remains a string so a syntactically valid but unsupported revision
|
|
1515
|
+
* reaches the dedicated unsupported-version path. `capabilities` is an open wire
|
|
1516
|
+
* record; `identity` is optional because client information is recommended but
|
|
1517
|
+
* not required.
|
|
1518
|
+
*/
|
|
1519
|
+
export declare interface MCPRequestContext {
|
|
1520
|
+
readonly version: string;
|
|
1521
|
+
readonly capabilities: Readonly<Record<string, unknown>>;
|
|
1522
|
+
readonly identity?: MCPIdentity;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
763
1525
|
/**
|
|
764
1526
|
* A transport-agnostic Model Context Protocol server — dispatches JSON-RPC 2.0
|
|
765
1527
|
* requests over a live {@link ToolManagerInterface}, with NO transport coupling.
|
|
@@ -771,14 +1533,15 @@ export declare class MCPError extends Error {
|
|
|
771
1533
|
* `JSON.parse`s the raw message (a failure → a `-32700` response), narrows it to
|
|
772
1534
|
* a request (a non-request → a `-32600` response), dispatches, and serializes the
|
|
773
1535
|
* response back to a string (`undefined` for a notification).
|
|
774
|
-
* - **
|
|
775
|
-
* the
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
*
|
|
1536
|
+
* - **Dual-era dispatch.** A request carrying the reserved modern version key uses
|
|
1537
|
+
* modern metadata validation and the registered method seam. Every other request
|
|
1538
|
+
* uses the legacy `initialize` / `ping` / `tools/list` / `tools/call` switch. The
|
|
1539
|
+
* wire era is selected per request and never stored.
|
|
1540
|
+
* - **One modern seam.** `server/discover`, `tools/list`, `tools/call`, and
|
|
1541
|
+
* `subscriptions/listen` are
|
|
1542
|
+
* registered on `methods` at construction and resolved from it on every dispatch —
|
|
1543
|
+
* the same path a later method or a consumer's own takes, with an unregistered
|
|
1544
|
+
* method still answering `-32601`.
|
|
782
1545
|
* - **Provider-agnostic.** Imports only core siblings — JSON-RPC + the tool registry,
|
|
783
1546
|
* no HTTP, no model. Wire fields are narrowed via the contracts guards (no `as`).
|
|
784
1547
|
* - **Observable (§13).** The owned `emitter` fires `request` at the top of every
|
|
@@ -789,7 +1552,7 @@ export declare class MCPError extends Error {
|
|
|
789
1552
|
* ```ts
|
|
790
1553
|
* const tools = createToolManager()
|
|
791
1554
|
* tools.add(createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }))
|
|
792
|
-
* const server = new MCPServer({ name: 'demo', version: '1.0.0', tools })
|
|
1555
|
+
* const server = new MCPServer({ identity: { name: 'demo', version: '1.0.0' }, tools })
|
|
793
1556
|
* await server.handle('{"jsonrpc":"2.0","method":"ping","id":1}') // '{"jsonrpc":"2.0","id":1,"result":{}}'
|
|
794
1557
|
* ```
|
|
795
1558
|
*/
|
|
@@ -797,10 +1560,10 @@ export declare class MCPServer implements MCPServerInterface {
|
|
|
797
1560
|
#private;
|
|
798
1561
|
constructor(options: MCPServerOptions);
|
|
799
1562
|
get emitter(): EmitterInterface<MCPServerEventMap>;
|
|
800
|
-
get
|
|
801
|
-
get
|
|
802
|
-
dispatch(request: JSONRPCRequest): Promise<JSONRPCResponse | undefined>;
|
|
803
|
-
handle(message: string): Promise<string | undefined>;
|
|
1563
|
+
get identity(): MCPIdentity;
|
|
1564
|
+
get methods(): MCPMethodManagerInterface;
|
|
1565
|
+
dispatch(request: JSONRPCRequest, options?: MCPDispatchOptions): Promise<JSONRPCResponse | MCPStream | undefined>;
|
|
1566
|
+
handle(message: string, options?: MCPDispatchOptions): Promise<string | MCPTextStream | undefined>;
|
|
804
1567
|
}
|
|
805
1568
|
|
|
806
1569
|
/**
|
|
@@ -809,16 +1572,16 @@ export declare class MCPServer implements MCPServerInterface {
|
|
|
809
1572
|
* via `server.emitter.on`.
|
|
810
1573
|
*
|
|
811
1574
|
* @remarks
|
|
812
|
-
* `request` fires at the TOP of every `dispatch` with the method
|
|
813
|
-
*
|
|
814
|
-
* observer sees every inbound call. Listener isolation is the emitter's (§13): a
|
|
1575
|
+
* `request` fires at the TOP of every `dispatch` with the method, correlating id
|
|
1576
|
+
* (`null` for a notification), and structurally selected wire era, BEFORE the
|
|
1577
|
+
* method runs — so an observer sees every inbound call. Listener isolation is the emitter's (§13): a
|
|
815
1578
|
* listener throw is routed to the emitter's `error` handler (the `error` option),
|
|
816
1579
|
* never onto this map, so a buggy observer can never corrupt a dispatch. Declared as
|
|
817
1580
|
* a `type` alias (§4.5) so the type-literal satisfies `EventMap` structurally.
|
|
818
1581
|
*/
|
|
819
1582
|
export declare type MCPServerEventMap = {
|
|
820
|
-
/** A request is being dispatched — its
|
|
821
|
-
readonly request: readonly [method: string, id: string | number | null];
|
|
1583
|
+
/** A request is being dispatched — its method, correlating id, and structural wire era. */
|
|
1584
|
+
readonly request: readonly [method: string, id: string | number | null, era: MCPEra];
|
|
822
1585
|
/**
|
|
823
1586
|
* A transport-level fault surfaced while a bound {@link MCPTransportInterface} was
|
|
824
1587
|
* piping a reply out (a `send` throw or rejection from {@link bindServer}). A DOMAIN
|
|
@@ -827,26 +1590,26 @@ export declare type MCPServerEventMap = {
|
|
|
827
1590
|
readonly error: readonly [error: unknown];
|
|
828
1591
|
};
|
|
829
1592
|
|
|
830
|
-
/** The server identity echoed in the MCP `initialize` result's `serverInfo`. */
|
|
831
|
-
export declare interface MCPServerInfo {
|
|
832
|
-
readonly name: string;
|
|
833
|
-
readonly version: string;
|
|
834
|
-
}
|
|
835
|
-
|
|
836
1593
|
/**
|
|
837
1594
|
* A transport-agnostic Model Context Protocol server — dispatches JSON-RPC 2.0
|
|
838
|
-
* requests (
|
|
1595
|
+
* requests (the fixed legacy methods plus the modern subscription method) over a live
|
|
839
1596
|
* {@link ToolManagerInterface}, with NO transport coupling (a transport layer
|
|
840
1597
|
* pumps strings through `handle`).
|
|
841
1598
|
*
|
|
842
1599
|
* @remarks
|
|
843
1600
|
* - **Two entry points.** `dispatch(request)` is the TYPED core: it takes an
|
|
844
1601
|
* already-parsed {@link JSONRPCRequest}, runs the method, and resolves a
|
|
845
|
-
* {@link JSONRPCResponse} — or
|
|
846
|
-
* `id`). `handle(message)` is the
|
|
847
|
-
* message, narrows it to a request,
|
|
848
|
-
*
|
|
849
|
-
*
|
|
1602
|
+
* {@link JSONRPCResponse} — or an {@link MCPStream} for a held-open modern method, or
|
|
1603
|
+
* `undefined` for a NOTIFICATION (a request with no `id`). `handle(message)` is the
|
|
1604
|
+
* STRING boundary: it `JSON.parse`s the raw message, narrows it to a request,
|
|
1605
|
+
* dispatches, and serializes the answer back to a string (or an {@link MCPTextStream},
|
|
1606
|
+
* the same sequence already serialized) — turning a parse failure into a `-32700`
|
|
1607
|
+
* response and a non-request into a `-32600` response, and returning `undefined` for a
|
|
1608
|
+
* notification.
|
|
1609
|
+
* - **One method seam.** Every modern method — the built-in `server/discover` /
|
|
1610
|
+
* `tools/list` / `tools/call` / `subscriptions/listen` included — is registered on `methods` and dispatched
|
|
1611
|
+
* from it, so a method added later travels the identical path and an unregistered one
|
|
1612
|
+
* still answers `-32601`.
|
|
850
1613
|
* - **Provider-agnostic.** Imports only core siblings; it speaks JSON-RPC + the
|
|
851
1614
|
* tool registry, with no HTTP, no model, and no backend coupling.
|
|
852
1615
|
* - **Observable (§13).** The owned `emitter` ({@link MCPServerEventMap}) fires
|
|
@@ -855,57 +1618,120 @@ export declare interface MCPServerInfo {
|
|
|
855
1618
|
*/
|
|
856
1619
|
export declare interface MCPServerInterface {
|
|
857
1620
|
readonly emitter: EmitterInterface<MCPServerEventMap>;
|
|
858
|
-
readonly
|
|
859
|
-
|
|
1621
|
+
readonly identity: MCPIdentity;
|
|
1622
|
+
/** The modern method registry this server dispatches through (built-ins included). */
|
|
1623
|
+
readonly methods: MCPMethodManagerInterface;
|
|
860
1624
|
/**
|
|
861
|
-
* Dispatch an already-parsed request — run its method and resolve the
|
|
862
|
-
*
|
|
1625
|
+
* Dispatch an already-parsed request — run its method and resolve the answer, or
|
|
1626
|
+
* `undefined` for a notification (a request with no `id`).
|
|
1627
|
+
*
|
|
1628
|
+
* @remarks
|
|
1629
|
+
* A held-open modern method answers with an {@link MCPStream} instead of a response:
|
|
1630
|
+
* narrow the two apart with `Symbol.asyncIterator in result`. `options` is optional,
|
|
1631
|
+
* so a caller that cannot abort simply never supplies one.
|
|
863
1632
|
*
|
|
864
1633
|
* @param request - The parsed JSON-RPC request to dispatch
|
|
865
|
-
* @
|
|
1634
|
+
* @param options - Per-request execution options (see {@link MCPDispatchOptions})
|
|
1635
|
+
* @returns The response, a held-open {@link MCPStream}, or `undefined` for a notification
|
|
866
1636
|
*/
|
|
867
|
-
dispatch(request: JSONRPCRequest): Promise<JSONRPCResponse | undefined>;
|
|
1637
|
+
dispatch(request: JSONRPCRequest, options?: MCPDispatchOptions): Promise<JSONRPCResponse | MCPStream | undefined>;
|
|
868
1638
|
/**
|
|
869
|
-
* Handle a raw message string — parse it, dispatch, and serialize the
|
|
1639
|
+
* Handle a raw message string — parse it, dispatch, and serialize the answer.
|
|
870
1640
|
*
|
|
871
1641
|
* @remarks
|
|
872
1642
|
* A `JSON.parse` failure resolves a serialized `-32700` (Parse error) response;
|
|
873
1643
|
* a parsed value that is not a valid request resolves a serialized `-32600`
|
|
874
|
-
* (Invalid Request) response; a notification resolves `undefined` (no response).
|
|
1644
|
+
* (Invalid Request) response; a notification resolves `undefined` (no response). A
|
|
1645
|
+
* held-open method resolves an {@link MCPTextStream} — the typed stream's mirror,
|
|
1646
|
+
* already serialized — so a transport writes each message with no second parse.
|
|
875
1647
|
*
|
|
876
1648
|
* @param message - The raw JSON-RPC message string
|
|
877
|
-
* @
|
|
1649
|
+
* @param options - Per-request execution options (see {@link MCPDispatchOptions})
|
|
1650
|
+
* @returns The serialized response string, an {@link MCPTextStream}, or `undefined` for a notification
|
|
878
1651
|
*/
|
|
879
|
-
handle(message: string): Promise<string | undefined>;
|
|
1652
|
+
handle(message: string, options?: MCPDispatchOptions): Promise<string | MCPTextStream | undefined>;
|
|
880
1653
|
}
|
|
881
1654
|
|
|
882
1655
|
/**
|
|
883
|
-
* Options for `createMCPServer` — the server
|
|
884
|
-
*
|
|
1656
|
+
* Options for `createMCPServer` — the server {@link MCPIdentity}, the live
|
|
1657
|
+
* {@link ToolManagerInterface} it exposes, optional `instructions`, and the
|
|
885
1658
|
* reserved `on` hooks (§8).
|
|
886
1659
|
*
|
|
887
1660
|
* @remarks
|
|
888
|
-
* `
|
|
889
|
-
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
1661
|
+
* `identity` identifies the server in the `initialize` handshake (`serverInfo`).
|
|
1662
|
+
* `tools` is the live registry the server dispatches `tools/list` / `tools/call`
|
|
1663
|
+
* over — its `definitions()` advertise the tools and its `execute()` runs a call
|
|
1664
|
+
* (the manager already isolates a tool throw into a `success: false` result, so
|
|
1665
|
+
* the server adds none). `instructions` is the optional human guidance exposed
|
|
1666
|
+
* by `server/discover`. `cache` configures the modern cache stamps: `ttl` is the
|
|
1667
|
+
* freshness lifetime in milliseconds and `scope` defaults to `'private'`. `on`
|
|
1668
|
+
* is the §8 reserved key: initial listeners for the server's
|
|
1669
|
+
* {@link MCPServerEventMap}, wired at construction. `input` enables modern
|
|
1670
|
+
* `tools/call` multi-round trips: the consumer decides when input is needed and
|
|
1671
|
+
* supplies principal/signing/TTL policy, while MCP assigns the request key and
|
|
1672
|
+
* owns the protected wire round trip. `limit` configures the server's hostile-input
|
|
1673
|
+
* and live-subscription bounds; every omitted leaf uses {@link DEFAULT_MCP_LIMITS}.
|
|
896
1674
|
*/
|
|
897
1675
|
export declare interface MCPServerOptions {
|
|
898
1676
|
readonly on?: EmitterHooks<MCPServerEventMap>;
|
|
899
1677
|
/** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
|
|
900
1678
|
readonly error?: EmitterErrorHandler;
|
|
901
|
-
readonly
|
|
902
|
-
readonly version: string;
|
|
1679
|
+
readonly identity: MCPIdentity;
|
|
903
1680
|
/** The live tool registry the server exposes over `tools/list` / `tools/call`. */
|
|
904
1681
|
readonly tools: ToolManagerInterface;
|
|
905
|
-
/**
|
|
906
|
-
readonly
|
|
1682
|
+
/** Optional human guidance exposed by `server/discover`. */
|
|
1683
|
+
readonly instructions?: string;
|
|
1684
|
+
/** Modern cache stamps; omitted values use the protocol-safe defaults. */
|
|
1685
|
+
readonly cache?: {
|
|
1686
|
+
readonly ttl?: number;
|
|
1687
|
+
readonly scope?: 'public' | 'private';
|
|
1688
|
+
};
|
|
1689
|
+
/** Optional multi-round-trip input mechanism; all signing and expiry policy is consumer-supplied. */
|
|
1690
|
+
readonly input?: MCPInputOptions;
|
|
1691
|
+
/** Optional event-driven producer for the modern `subscriptions/listen` method. */
|
|
1692
|
+
readonly subscription?: MCPSubscriptionOptions;
|
|
1693
|
+
/** Hostile-input and live-resource bounds; omitted leaves use secure defaults. */
|
|
1694
|
+
readonly limit?: MCPLimitOptions;
|
|
907
1695
|
}
|
|
908
1696
|
|
|
1697
|
+
/**
|
|
1698
|
+
* A held-open modern result: each `yield` is a notification (a {@link JSONRPCRequest}
|
|
1699
|
+
* with no `id`); the `return` value is the terminating response.
|
|
1700
|
+
*
|
|
1701
|
+
* @remarks
|
|
1702
|
+
* Held-open closure is a RESULT in the modern revision, not an out-of-band event, so it
|
|
1703
|
+
* arrives where a result arrives — the generator's `return`. Consuming a stream and
|
|
1704
|
+
* consuming a unary response therefore end the same way, and a transport narrows the two
|
|
1705
|
+
* apart at ONE point (`Symbol.asyncIterator in result`), at the place that already pumps
|
|
1706
|
+
* messages onto the wire.
|
|
1707
|
+
*/
|
|
1708
|
+
export declare type MCPStream = AsyncGenerator<JSONRPCRequest, JSONRPCResponse>;
|
|
1709
|
+
|
|
1710
|
+
/**
|
|
1711
|
+
* Produce notifications for one honoured `subscriptions/listen` filter.
|
|
1712
|
+
*
|
|
1713
|
+
* @remarks
|
|
1714
|
+
* The producer parks on its own event source while idle and ends its iterable to close the
|
|
1715
|
+
* subscription gracefully. `options.signal` is the per-request cancellation signal; a
|
|
1716
|
+
* producer that needs cancellation observes it directly rather than polling.
|
|
1717
|
+
*
|
|
1718
|
+
* @param notifications - The requested filter intersected with the server's supported filter
|
|
1719
|
+
* @param options - The per-request execution options
|
|
1720
|
+
* @returns An event-driven source of server notifications
|
|
1721
|
+
*/
|
|
1722
|
+
export declare type MCPSubscriptionHandler = (notifications: SubscriptionFilter, options: MCPDispatchOptions) => AsyncIterable<JSONRPCRequest> | Promise<AsyncIterable<JSONRPCRequest>>;
|
|
1723
|
+
|
|
1724
|
+
/** Configuration for the server's built-in `subscriptions/listen` method. */
|
|
1725
|
+
export declare interface MCPSubscriptionOptions {
|
|
1726
|
+
/** The notification filter this server can actually honour. */
|
|
1727
|
+
readonly notifications: SubscriptionFilter;
|
|
1728
|
+
/** Open the producer for one honoured filter. */
|
|
1729
|
+
readonly listen: MCPSubscriptionHandler;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
/** The string-boundary mirror of {@link MCPStream} — the same sequence, already serialized. */
|
|
1733
|
+
export declare type MCPTextStream = AsyncGenerator<string, string>;
|
|
1734
|
+
|
|
909
1735
|
/**
|
|
910
1736
|
* One entry of the MCP `tools/list` result — a tool's `name`, optional
|
|
911
1737
|
* `description`, and its JSON-Schema `inputSchema`.
|
|
@@ -921,22 +1747,6 @@ export declare interface MCPToolDescriptor {
|
|
|
921
1747
|
readonly inputSchema: Readonly<Record<string, unknown>>;
|
|
922
1748
|
}
|
|
923
1749
|
|
|
924
|
-
/**
|
|
925
|
-
* The MCP `tools/call` result — the executed tool's output as `content` blocks,
|
|
926
|
-
* with `isError` flagging a tool failure.
|
|
927
|
-
*
|
|
928
|
-
* @remarks
|
|
929
|
-
* A success carries the tool's value serialized into one `text` content block; a
|
|
930
|
-
* tool FAILURE (the `ToolResult.error` the registry isolated) carries the error
|
|
931
|
-
* text in `content` AND sets `isError: true`, so the model sees the failure as a
|
|
932
|
-
* tool result it can react to rather than a protocol error.
|
|
933
|
-
*/
|
|
934
|
-
export declare interface MCPToolResult {
|
|
935
|
-
readonly content: readonly MCPContent[];
|
|
936
|
-
/** `true` when the tool failed — its error text is in `content`. */
|
|
937
|
-
readonly isError?: boolean;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
1750
|
/**
|
|
941
1751
|
* A duplex message channel an environment face provides to the pure engine — the
|
|
942
1752
|
* one port `bindServer` and `bindClient` (`./helpers.js`) pipe an
|
|
@@ -962,6 +1772,9 @@ export declare interface MCPTransportInterface {
|
|
|
962
1772
|
readonly close: () => void | Promise<void>;
|
|
963
1773
|
}
|
|
964
1774
|
|
|
1775
|
+
/** A protocol revision supported by this MCP package. */
|
|
1776
|
+
export declare type MCPVersion = '2026-07-28' | '2025-11-25' | '2025-06-18';
|
|
1777
|
+
|
|
965
1778
|
/**
|
|
966
1779
|
* Narrow an already-parsed value to a {@link JSONRPCMessage}, or `undefined` when
|
|
967
1780
|
* it is not one.
|
|
@@ -984,16 +1797,132 @@ export declare interface MCPTransportInterface {
|
|
|
984
1797
|
*/
|
|
985
1798
|
export declare function parseJSONRPCMessage(value: unknown): JSONRPCMessage | undefined;
|
|
986
1799
|
|
|
1800
|
+
/**
|
|
1801
|
+
* Parse the verified value embedded in an opaque signed `requestState` token.
|
|
1802
|
+
*
|
|
1803
|
+
* @remarks
|
|
1804
|
+
* This parser does not verify the HMAC; {@link import('@orkestrel/server').verifyToken}
|
|
1805
|
+
* performs that boundary first and returns the JSON string parsed here. The protected
|
|
1806
|
+
* payload binds the authenticated principal, token lifetime, originating request id,
|
|
1807
|
+
* server-assigned input key, tool name, and optional consumer state. Total over malformed
|
|
1808
|
+
* or hostile input.
|
|
1809
|
+
*
|
|
1810
|
+
* @param value - The HMAC-verified token value to parse
|
|
1811
|
+
* @returns The protected input state, or `undefined` when malformed
|
|
1812
|
+
*
|
|
1813
|
+
* @example
|
|
1814
|
+
* ```ts
|
|
1815
|
+
* parseMCPInputState('{"principal":"user-1","ttl":1000,"origin":1,"key":"k","name":"reply"}')
|
|
1816
|
+
* // { principal: 'user-1', ttl: 1000, origin: 1, key: 'k', name: 'reply' }
|
|
1817
|
+
* ```
|
|
1818
|
+
*/
|
|
1819
|
+
export declare function parseMCPInputState(value: unknown): MCPInputState | undefined;
|
|
1820
|
+
|
|
1821
|
+
/**
|
|
1822
|
+
* Parse the reserved modern request metadata into an {@link MCPRequestContext}.
|
|
1823
|
+
*
|
|
1824
|
+
* @remarks
|
|
1825
|
+
* This is the validity step after {@link isModernRequest}: a defined result can
|
|
1826
|
+
* only come from a guard-positive request, while a guard-positive request returns
|
|
1827
|
+
* `undefined` exactly when its required modern metadata is malformed. The version
|
|
1828
|
+
* must be a string but need not be supported; unsupported strings belong to the
|
|
1829
|
+
* dedicated protocol-version error path. Client identity is optional, but when
|
|
1830
|
+
* present it must carry string `name` and `version` members. Total over hostile and
|
|
1831
|
+
* malformed input.
|
|
1832
|
+
*
|
|
1833
|
+
* @param value - The already-parsed request candidate to coerce
|
|
1834
|
+
* @returns The validated modern request context, or `undefined`
|
|
1835
|
+
*/
|
|
1836
|
+
export declare function parseRequestContext(value: unknown): MCPRequestContext | undefined;
|
|
1837
|
+
|
|
1838
|
+
/**
|
|
1839
|
+
* Pump an {@link MCPTextStream} onto a transport — every notification in order, then the
|
|
1840
|
+
* terminating response.
|
|
1841
|
+
*
|
|
1842
|
+
* @remarks
|
|
1843
|
+
* The generator's `return` value is a message like any other on the wire: it is sent
|
|
1844
|
+
* LAST and closes the exchange. Sends are awaited one at a time so the transport
|
|
1845
|
+
* receives the sequence in the order the method produced it.
|
|
1846
|
+
*
|
|
1847
|
+
* @param stream - The serialized held-open result to write out
|
|
1848
|
+
* @param transport - The duplex channel to write each message to
|
|
1849
|
+
* @returns Resolves once the terminating response has been sent
|
|
1850
|
+
*
|
|
1851
|
+
* @example
|
|
1852
|
+
* ```ts
|
|
1853
|
+
* const answer = await server.handle(message)
|
|
1854
|
+
* if (typeof answer !== 'string') await sendStream(answer, transport)
|
|
1855
|
+
* ```
|
|
1856
|
+
*/
|
|
1857
|
+
export declare function sendStream(stream: MCPTextStream, transport: MCPTransportInterface): Promise<void>;
|
|
1858
|
+
|
|
1859
|
+
/**
|
|
1860
|
+
* Serialize a typed {@link MCPStream} into its string mirror — each yielded
|
|
1861
|
+
* notification and the terminating response, already `JSON.stringify`d.
|
|
1862
|
+
*
|
|
1863
|
+
* @remarks
|
|
1864
|
+
* The string-boundary half of the held-open arm: `handle` returns this so a transport
|
|
1865
|
+
* writes each message with no second parse, exactly as it writes a unary reply string.
|
|
1866
|
+
* The terminating response arrives as the returned generator's OWN `return` value, so a
|
|
1867
|
+
* consumer distinguishes "one more notification" from "this is the answer" without a
|
|
1868
|
+
* sentinel.
|
|
1869
|
+
*
|
|
1870
|
+
* @param stream - The typed held-open result to serialize
|
|
1871
|
+
* @returns The same sequence with every message serialized to a string
|
|
1872
|
+
*
|
|
1873
|
+
* @example
|
|
1874
|
+
* ```ts
|
|
1875
|
+
* const text = serializeStream(stream)
|
|
1876
|
+
* for (let next = await text.next(); ; next = await text.next()) {
|
|
1877
|
+
* if (next.done === true) return next.value // the terminating response, serialized
|
|
1878
|
+
* log(next.value) // one serialized notification
|
|
1879
|
+
* }
|
|
1880
|
+
* ```
|
|
1881
|
+
*/
|
|
1882
|
+
export declare function serializeStream(stream: MCPStream): MCPTextStream;
|
|
1883
|
+
|
|
1884
|
+
/**
|
|
1885
|
+
* Stamp a subscription notification with the request id reserved for its held-open stream.
|
|
1886
|
+
*
|
|
1887
|
+
* @param notification - The notification to copy and stamp
|
|
1888
|
+
* @param id - The `subscriptions/listen` request id
|
|
1889
|
+
* @returns The stamped notification, preserving its other params and metadata
|
|
1890
|
+
*/
|
|
1891
|
+
export declare function stampSubscriptionNotification(notification: JSONRPCRequest, id: string | number): JSONRPCRequest;
|
|
1892
|
+
|
|
1893
|
+
/** The notification families a client may opt in to on a `subscriptions/listen` stream. */
|
|
1894
|
+
export declare interface SubscriptionFilter {
|
|
1895
|
+
/** Receive `notifications/tools/list_changed` when the server produces it. */
|
|
1896
|
+
readonly toolsListChanged?: boolean;
|
|
1897
|
+
/** Receive `notifications/prompts/list_changed` when the server produces it. */
|
|
1898
|
+
readonly promptsListChanged?: boolean;
|
|
1899
|
+
/** Receive `notifications/resources/list_changed` when the server produces it. */
|
|
1900
|
+
readonly resourcesListChanged?: boolean;
|
|
1901
|
+
/** Receive `notifications/resources/updated` for these resource URIs. */
|
|
1902
|
+
readonly resourceSubscriptions?: readonly string[];
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
/** The terminating result returned when a `subscriptions/listen` stream closes gracefully. */
|
|
1906
|
+
export declare interface SubscriptionsListenResult {
|
|
1907
|
+
readonly resultType: 'complete';
|
|
1908
|
+
readonly _meta: SubscriptionsListenResultMetaObject;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
/** The required metadata on a graceful `subscriptions/listen` result. */
|
|
1912
|
+
export declare interface SubscriptionsListenResultMetaObject extends Readonly<Record<string, unknown>> {
|
|
1913
|
+
/** The JSON-RPC id of the `subscriptions/listen` request whose stream is closing. */
|
|
1914
|
+
readonly 'io.modelcontextprotocol/subscriptionId': string | number;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
987
1917
|
/**
|
|
988
1918
|
* The MCP protocol revisions this server can negotiate.
|
|
989
1919
|
*
|
|
990
1920
|
* @remarks
|
|
991
1921
|
* `initialize` echoes the client's requested `protocolVersion` when it appears in
|
|
992
|
-
* this list
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
* JSON-RPC messages.
|
|
1922
|
+
* this list. Frozen in client-preference and discovery-advertisement order. The
|
|
1923
|
+
* package does not advertise `2025-03-26` because that revision mandates JSON-RPC
|
|
1924
|
+
* batching, while this package accepts only individual JSON-RPC messages.
|
|
996
1925
|
*/
|
|
997
|
-
export declare const SUPPORTED_PROTOCOL_VERSIONS: readonly
|
|
1926
|
+
export declare const SUPPORTED_PROTOCOL_VERSIONS: readonly MCPVersion[];
|
|
998
1927
|
|
|
999
1928
|
export { }
|