@nifrajs/mcp 2.14.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/agent-descriptor.d.ts +29 -0
- package/dist/agent-descriptor.d.ts.map +1 -0
- package/dist/agent-descriptor.js +31 -0
- package/dist/agent-descriptor.js.map +1 -0
- package/dist/http.d.ts +11 -8
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +131 -18
- package/dist/http.js.map +1 -1
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js.map +1 -1
- package/package.json +12 -2
- package/src/agent-descriptor.ts +51 -0
- package/src/http.ts +155 -19
- package/src/server.ts +5 -0
package/README.md
CHANGED
|
@@ -24,6 +24,10 @@ Mount `mcp.fetch` at `POST /mcp`. The package also exposes the JSON-RPC protocol
|
|
|
24
24
|
layers directly, plus `defineMcpWidget` and the React adapter for tool results that render UI in MCP
|
|
25
25
|
hosts.
|
|
26
26
|
|
|
27
|
+
Clients that include `text/event-stream` in `Accept` receive progress notifications as they happen,
|
|
28
|
+
followed by the final JSON-RPC response in the same stream. An SSE `GET /mcp` opens a cancellable
|
|
29
|
+
server-message connection; a plain `GET /mcp` remains a health page.
|
|
30
|
+
|
|
27
31
|
## For AI agents
|
|
28
32
|
|
|
29
33
|
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-descriptor adapter for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* An MCP tool is built from the same core {@link ToolContract} the runtime already validates and
|
|
5
|
+
* enforces, so its descriptor is the identical content-free projection the core tool adapter
|
|
6
|
+
* produces - same name, same schema digest, same required capabilities - distinguished only by the
|
|
7
|
+
* `mcp-tool` kind. That parity is what lets a host reason about a capability once, whether it is
|
|
8
|
+
* reached in-process or over the MCP transport.
|
|
9
|
+
*
|
|
10
|
+
* This module is the only place `@nifrajs/mcp` depends on `@nifrajs/agent`, and it is reached solely
|
|
11
|
+
* through the optional `@nifrajs/mcp/agent-descriptor` subpath. The base MCP import path never loads
|
|
12
|
+
* it, so the agent edge stays opt-in and the dependency direction (`mcp -> agent`, never the reverse)
|
|
13
|
+
* is preserved.
|
|
14
|
+
*/
|
|
15
|
+
import { type CapabilityDescriptor, type IsolationClass } from "@nifrajs/agent/registry";
|
|
16
|
+
import type { ToolContract } from "@nifrajs/core/tool-contract";
|
|
17
|
+
export interface McpDescriptorOptions {
|
|
18
|
+
readonly version?: string;
|
|
19
|
+
readonly isolation?: IsolationClass;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Project one MCP-facing tool contract into a `mcp-tool` capability descriptor. The digest is taken
|
|
23
|
+
* over the tool's own input schema, so it matches the core tool descriptor for the same contract.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mcpToolDescriptor<Input, Output>(tool: ToolContract<Input, Output>, options?: McpDescriptorOptions): Promise<CapabilityDescriptor>;
|
|
26
|
+
/** Project a set of MCP tool contracts, preserving order. Compose the result into a snapshot to dedupe. */
|
|
27
|
+
export declare function mcpToolDescriptors<Input, Output>(tools: readonly ToolContract<Input, Output>[], options?: McpDescriptorOptions): Promise<readonly CapabilityDescriptor[]>;
|
|
28
|
+
export type { CapabilityDescriptor, IsolationClass };
|
|
29
|
+
//# sourceMappingURL=agent-descriptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-descriptor.d.ts","sourceRoot":"","sources":["../src/agent-descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;CACpC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAC7C,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAM/B;AAED,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAC9C,KAAK,EAAE,SAAS,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAC7C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAE1C;AAED,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-descriptor adapter for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* An MCP tool is built from the same core {@link ToolContract} the runtime already validates and
|
|
5
|
+
* enforces, so its descriptor is the identical content-free projection the core tool adapter
|
|
6
|
+
* produces - same name, same schema digest, same required capabilities - distinguished only by the
|
|
7
|
+
* `mcp-tool` kind. That parity is what lets a host reason about a capability once, whether it is
|
|
8
|
+
* reached in-process or over the MCP transport.
|
|
9
|
+
*
|
|
10
|
+
* This module is the only place `@nifrajs/mcp` depends on `@nifrajs/agent`, and it is reached solely
|
|
11
|
+
* through the optional `@nifrajs/mcp/agent-descriptor` subpath. The base MCP import path never loads
|
|
12
|
+
* it, so the agent edge stays opt-in and the dependency direction (`mcp -> agent`, never the reverse)
|
|
13
|
+
* is preserved.
|
|
14
|
+
*/
|
|
15
|
+
import { descriptorFromTool, } from "@nifrajs/agent/registry";
|
|
16
|
+
/**
|
|
17
|
+
* Project one MCP-facing tool contract into a `mcp-tool` capability descriptor. The digest is taken
|
|
18
|
+
* over the tool's own input schema, so it matches the core tool descriptor for the same contract.
|
|
19
|
+
*/
|
|
20
|
+
export function mcpToolDescriptor(tool, options = {}) {
|
|
21
|
+
return descriptorFromTool(tool, {
|
|
22
|
+
kind: "mcp-tool",
|
|
23
|
+
...(options.version === undefined ? {} : { version: options.version }),
|
|
24
|
+
...(options.isolation === undefined ? {} : { isolation: options.isolation }),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Project a set of MCP tool contracts, preserving order. Compose the result into a snapshot to dedupe. */
|
|
28
|
+
export function mcpToolDescriptors(tools, options = {}) {
|
|
29
|
+
return Promise.all(tools.map((tool) => mcpToolDescriptor(tool, options)));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=agent-descriptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-descriptor.js","sourceRoot":"","sources":["../src/agent-descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAEL,kBAAkB,GAEnB,MAAM,yBAAyB,CAAA;AAQhC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAiC,EACjC,UAAgC,EAAE;IAElC,OAAO,kBAAkB,CAAC,IAAI,EAAE;QAC9B,IAAI,EAAE,UAAU;QAChB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACtE,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;KAC7E,CAAC,CAAA;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,kBAAkB,CAChC,KAA6C,EAC7C,UAAgC,EAAE;IAElC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;AAC3E,CAAC"}
|
package/dist/http.d.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* The transport core shared by every HTTP host of an MCP server - the dev/docs MCP in `@nifrajs/cli`
|
|
3
3
|
* (`nifra docs-mcp`), the site's edge worker, and a nifra app mounting `POST /mcp` via
|
|
4
4
|
* {@link ./server.ts}. {@link respondMcpHttp} is a plain Web `fetch` handler: POST a JSON-RPC body →
|
|
5
|
-
* JSON-RPC response
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* JSON-RPC response (or an SSE stream when the client accepts `text/event-stream`); GET is a health page
|
|
6
|
+
* or a cancellable SSE stream; OPTIONS is the CORS preflight. It never throws - a bad body becomes a
|
|
7
|
+
* JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources / prompts /
|
|
8
|
+
* the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
|
|
8
9
|
*/
|
|
9
10
|
import { type JsonRpcRequest, type McpServerFeatures, type McpTool } from "./protocol.js";
|
|
10
11
|
export interface McpHttpOptions {
|
|
@@ -28,11 +29,13 @@ export interface McpHttpOptions {
|
|
|
28
29
|
readonly authorizeMessage?: (message: JsonRpcRequest, request: Request) => boolean | Promise<boolean>;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
|
-
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
|
|
32
|
-
* response
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
32
|
+
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → a JSON-RPC
|
|
33
|
+
* response, or an SSE stream carrying progress notifications and the final response when the client
|
|
34
|
+
* accepts `text/event-stream`; GET → a health page or a cancellable SSE stream; OPTIONS → CORS preflight.
|
|
35
|
+
* Never throws - a bad body becomes a JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that
|
|
36
|
+
* mirrors its method/name/version into headers is validated against the body before dispatch and gets spec
|
|
37
|
+
* HTTP statuses; legacy requests are served unchanged. The dispatch is the shared, transport-agnostic
|
|
38
|
+
* {@link handleRpc}.
|
|
36
39
|
*/
|
|
37
40
|
export declare function respondMcpHttp(request: Request, tools: McpTool[], serverInfo: {
|
|
38
41
|
name: string;
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAGL,KAAK,cAAc,EAGnB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAGb,MAAM,eAAe,CAAA;AAiDtB,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IACrC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAC1B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,OAAO,KACb,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAChC;AAkOD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,EAAE,EAChB,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAoFnB"}
|
package/dist/http.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* The transport core shared by every HTTP host of an MCP server - the dev/docs MCP in `@nifrajs/cli`
|
|
3
3
|
* (`nifra docs-mcp`), the site's edge worker, and a nifra app mounting `POST /mcp` via
|
|
4
4
|
* {@link ./server.ts}. {@link respondMcpHttp} is a plain Web `fetch` handler: POST a JSON-RPC body →
|
|
5
|
-
* JSON-RPC response
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* JSON-RPC response (or an SSE stream when the client accepts `text/event-stream`); GET is a health page
|
|
6
|
+
* or a cancellable SSE stream; OPTIONS is the CORS preflight. It never throws - a bad body becomes a
|
|
7
|
+
* JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources / prompts /
|
|
8
|
+
* the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
|
|
8
9
|
*/
|
|
9
10
|
import { handleRpc, MCP_ERROR, modernVersionOf, rpcError, } from "./protocol.js";
|
|
10
11
|
// Headers on every response. `access-control-allow-headers` lists the request headers a browser MCP client
|
|
@@ -38,6 +39,9 @@ function corsFor(request, allowedOrigins) {
|
|
|
38
39
|
}
|
|
39
40
|
const DEFAULT_MAX_BODY_BYTES = 1_000_000;
|
|
40
41
|
const TEXT_DECODER = new TextDecoder();
|
|
42
|
+
const TEXT_ENCODER = new TextEncoder();
|
|
43
|
+
const SSE_CONTENT_TYPE = "text/event-stream; charset=utf-8";
|
|
44
|
+
const SSE_KEEP_ALIVE_MS = 15_000;
|
|
41
45
|
/** Invalid byte caps make `total > maxBytes` fail open (especially for `NaN`). Reject configuration
|
|
42
46
|
* before any request body is read so MCP cannot silently lose its memory bound. */
|
|
43
47
|
function assertByteLimit(value) {
|
|
@@ -45,6 +49,103 @@ function assertByteLimit(value) {
|
|
|
45
49
|
throw new RangeError("MCP maxBodyBytes must be a non-negative safe integer");
|
|
46
50
|
}
|
|
47
51
|
}
|
|
52
|
+
function acceptsEventStream(request) {
|
|
53
|
+
return (request.headers.get("accept") ?? "").toLowerCase().includes("text/event-stream");
|
|
54
|
+
}
|
|
55
|
+
function eventStreamResponse(request, headers, run, keepAliveMs = 0) {
|
|
56
|
+
const abortController = new AbortController();
|
|
57
|
+
let closed = false;
|
|
58
|
+
let controller;
|
|
59
|
+
let resolveClosed = () => { };
|
|
60
|
+
const closedPromise = new Promise((resolve) => {
|
|
61
|
+
resolveClosed = resolve;
|
|
62
|
+
});
|
|
63
|
+
let onRequestAbort;
|
|
64
|
+
let heartbeat;
|
|
65
|
+
const teardown = () => {
|
|
66
|
+
if (heartbeat !== undefined)
|
|
67
|
+
clearInterval(heartbeat);
|
|
68
|
+
if (request.signal !== undefined && onRequestAbort !== undefined) {
|
|
69
|
+
request.signal.removeEventListener("abort", onRequestAbort);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const finish = (closeController) => {
|
|
73
|
+
if (closed)
|
|
74
|
+
return;
|
|
75
|
+
closed = true;
|
|
76
|
+
teardown();
|
|
77
|
+
abortController.abort();
|
|
78
|
+
resolveClosed();
|
|
79
|
+
if (closeController) {
|
|
80
|
+
try {
|
|
81
|
+
controller?.close();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// The consumer may have canceled the stream between the check and close.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const write = (frame) => {
|
|
89
|
+
if (closed)
|
|
90
|
+
return;
|
|
91
|
+
try {
|
|
92
|
+
controller?.enqueue(TEXT_ENCODER.encode(frame));
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
finish(false);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const stream = {
|
|
99
|
+
signal: abortController.signal,
|
|
100
|
+
closed: closedPromise,
|
|
101
|
+
send(message) {
|
|
102
|
+
write(`data: ${JSON.stringify(message)}\n\n`);
|
|
103
|
+
},
|
|
104
|
+
comment(value = "") {
|
|
105
|
+
write(`: ${value.replace(/[\r\n]/g, "")}\n\n`);
|
|
106
|
+
},
|
|
107
|
+
close() {
|
|
108
|
+
finish(true);
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
const body = new ReadableStream({
|
|
112
|
+
start(nextController) {
|
|
113
|
+
controller = nextController;
|
|
114
|
+
if (request.signal.aborted) {
|
|
115
|
+
finish(true);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
onRequestAbort = () => finish(true);
|
|
119
|
+
request.signal.addEventListener("abort", onRequestAbort, { once: true });
|
|
120
|
+
if (keepAliveMs > 0) {
|
|
121
|
+
heartbeat = setInterval(() => stream.comment(), keepAliveMs);
|
|
122
|
+
heartbeat.unref?.();
|
|
123
|
+
}
|
|
124
|
+
void (async () => run(stream))().then(() => stream.close(), (error) => {
|
|
125
|
+
if (closed)
|
|
126
|
+
return;
|
|
127
|
+
try {
|
|
128
|
+
controller?.error(error instanceof Error ? error : new Error("mcp_sse_failed"));
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
finish(false);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
cancel() {
|
|
136
|
+
finish(false);
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
return new Response(body, {
|
|
140
|
+
status: 200,
|
|
141
|
+
headers: {
|
|
142
|
+
...headers,
|
|
143
|
+
"content-type": SSE_CONTENT_TYPE,
|
|
144
|
+
"cache-control": "no-cache, no-transform",
|
|
145
|
+
"x-accel-buffering": "no",
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
48
149
|
function parseContentLength(value) {
|
|
49
150
|
if (value.length === 0)
|
|
50
151
|
return undefined;
|
|
@@ -149,11 +250,13 @@ function modernErrorStatus(response) {
|
|
|
149
250
|
return code === -32601 ? 404 : 200;
|
|
150
251
|
}
|
|
151
252
|
/**
|
|
152
|
-
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
|
|
153
|
-
* response
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
253
|
+
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → a JSON-RPC
|
|
254
|
+
* response, or an SSE stream carrying progress notifications and the final response when the client
|
|
255
|
+
* accepts `text/event-stream`; GET → a health page or a cancellable SSE stream; OPTIONS → CORS preflight.
|
|
256
|
+
* Never throws - a bad body becomes a JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that
|
|
257
|
+
* mirrors its method/name/version into headers is validated against the body before dispatch and gets spec
|
|
258
|
+
* HTTP statuses; legacy requests are served unchanged. The dispatch is the shared, transport-agnostic
|
|
259
|
+
* {@link handleRpc}.
|
|
157
260
|
*/
|
|
158
261
|
export async function respondMcpHttp(request, tools, serverInfo, options = {}) {
|
|
159
262
|
const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
|
|
@@ -167,14 +270,14 @@ export async function respondMcpHttp(request, tools, serverInfo, options = {}) {
|
|
|
167
270
|
if (request.method === "OPTIONS")
|
|
168
271
|
return new Response(null, { status: 204, headers: cors });
|
|
169
272
|
if (request.method === "GET") {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
});
|
|
273
|
+
if (acceptsEventStream(request)) {
|
|
274
|
+
// Keep the GET side of Streamable HTTP usable for clients that open a server-message channel. This
|
|
275
|
+
// transport has no durable session store, so the public seam is a cancellable keep-alive stream;
|
|
276
|
+
// request-scoped progress still travels on the POST stream below.
|
|
277
|
+
return eventStreamResponse(request, { allow: "POST, GET", ...cors }, async (stream) => {
|
|
278
|
+
stream.comment("connected");
|
|
279
|
+
await stream.closed;
|
|
280
|
+
}, SSE_KEEP_ALIVE_MS);
|
|
178
281
|
}
|
|
179
282
|
return new Response(options.health ??
|
|
180
283
|
"MCP server - POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call).", { headers: { "content-type": "text/plain; charset=utf-8", ...cors } });
|
|
@@ -215,9 +318,19 @@ export async function respondMcpHttp(request, tools, serverInfo, options = {}) {
|
|
|
215
318
|
if (headerError !== null)
|
|
216
319
|
return Response.json(headerError, { status: 400, headers });
|
|
217
320
|
}
|
|
218
|
-
const
|
|
219
|
-
signal: request.signal,
|
|
321
|
+
const dispatch = (stream) => handleRpc(message, tools, serverInfo, options.features ?? {}, {
|
|
322
|
+
signal: stream?.signal ?? request.signal,
|
|
323
|
+
...(stream !== undefined ? { sendNotification: stream.send } : {}),
|
|
220
324
|
});
|
|
325
|
+
if (acceptsEventStream(request)) {
|
|
326
|
+
return eventStreamResponse(request, headers, async (stream) => {
|
|
327
|
+
const response = await dispatch(stream);
|
|
328
|
+
if (response !== null)
|
|
329
|
+
stream.send(response);
|
|
330
|
+
stream.close();
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
const response = await dispatch();
|
|
221
334
|
// A notification (no id) yields null - acknowledge with 202 Accepted and no body (Streamable-HTTP).
|
|
222
335
|
if (response === null)
|
|
223
336
|
return new Response(null, { status: 202, headers });
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -62,6 +62,11 @@ export interface McpServer {
|
|
|
62
62
|
fetch(request: Request, overrides?: Pick<McpHttpOptions, "authorizeMessage">): Promise<Response>;
|
|
63
63
|
/** Dispatch one JSON-RPC message directly (no HTTP) - for headless verification and unit tests. */
|
|
64
64
|
handle(message: JsonRpcRequest): Promise<JsonRpcResponse | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Release server-owned resources, when the implementation has any (for example a database worker).
|
|
67
|
+
* Calling it more than once is safe. The base MCP server has nothing to release and omits this hook.
|
|
68
|
+
*/
|
|
69
|
+
readonly close?: () => Promise<void>;
|
|
65
70
|
}
|
|
66
71
|
export declare function createMcpServer(opts: CreateMcpServerOptions): McpServer;
|
|
67
72
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,WAAW,CAAA;AAC/D,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAEb,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IACnC,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,sDAAsD;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,wGAAwG;IACxG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;uEACmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAC1B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,OAAO,KACb,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACtD,qGAAqG;IACrG,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,kBAAkB,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChG,mGAAmG;IACnG,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,WAAW,CAAA;AAC/D,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAEb,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IACnC,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IACvC,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,sDAAsD;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,wGAAwG;IACxG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;uEACmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAC1B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,OAAO,KACb,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACtD,qGAAqG;IACrG,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,kBAAkB,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChG,mGAAmG;IACnG,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IAChE;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,SAAS,CA8BvE"}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAuB,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/D,OAAO,EACL,SAAS,EAOT,OAAO,GACR,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAuB,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/D,OAAO,EACL,SAAS,EAOT,OAAO,GACR,MAAM,eAAe,CAAA;AAmDtB,MAAM,UAAU,eAAe,CAAC,IAA4B;IAC1D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;IAClC,sGAAsG;IACtG,gDAAgD;IAChD,MAAM,SAAS,GAAkB,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAA;IAC/F,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IAC7D,MAAM,QAAQ,GAAsB;QAClC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChF,CAAA;IACD,OAAO;QACL,KAAK;QACL,QAAQ;QACR,UAAU;QACV,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAC5B,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE;YACzC,QAAQ;YACR,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3F,GAAG,CAAC,SAAS,EAAE,gBAAgB,KAAK,SAAS;gBAC3C,CAAC,CAAC,EAAE,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,EAAE;gBAClD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;QACJ,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC;KACrE,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Build MCP servers - and MCP Apps (interactive `ui://` widgets, SEP-1865) - for a nifra app. The transport-agnostic JSON-RPC core (also used by `@nifrajs/cli`'s dev MCP), a Streamable-HTTP handler you mount at `POST /mcp`, and `defineMcpWidget`/`defineMcpTool` for tool results that render real UI in MCP hosts.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
"bun": "./src/react.ts",
|
|
45
45
|
"types": "./dist/react.d.ts",
|
|
46
46
|
"default": "./dist/react.js"
|
|
47
|
+
},
|
|
48
|
+
"./agent-descriptor": {
|
|
49
|
+
"bun": "./src/agent-descriptor.ts",
|
|
50
|
+
"types": "./dist/agent-descriptor.d.ts",
|
|
51
|
+
"default": "./dist/agent-descriptor.js"
|
|
47
52
|
}
|
|
48
53
|
},
|
|
49
54
|
"files": [
|
|
@@ -59,14 +64,19 @@
|
|
|
59
64
|
"access": "public"
|
|
60
65
|
},
|
|
61
66
|
"peerDependencies": {
|
|
62
|
-
"@nifrajs/
|
|
67
|
+
"@nifrajs/agent": "^3.2.0",
|
|
68
|
+
"@nifrajs/core": "^3.2.0"
|
|
63
69
|
},
|
|
64
70
|
"peerDependenciesMeta": {
|
|
71
|
+
"@nifrajs/agent": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
65
74
|
"@nifrajs/core": {
|
|
66
75
|
"optional": true
|
|
67
76
|
}
|
|
68
77
|
},
|
|
69
78
|
"devDependencies": {
|
|
79
|
+
"@nifrajs/agent": "workspace:*",
|
|
70
80
|
"@nifrajs/core": "workspace:*",
|
|
71
81
|
"react": "19.2.7"
|
|
72
82
|
},
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-descriptor adapter for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* An MCP tool is built from the same core {@link ToolContract} the runtime already validates and
|
|
5
|
+
* enforces, so its descriptor is the identical content-free projection the core tool adapter
|
|
6
|
+
* produces - same name, same schema digest, same required capabilities - distinguished only by the
|
|
7
|
+
* `mcp-tool` kind. That parity is what lets a host reason about a capability once, whether it is
|
|
8
|
+
* reached in-process or over the MCP transport.
|
|
9
|
+
*
|
|
10
|
+
* This module is the only place `@nifrajs/mcp` depends on `@nifrajs/agent`, and it is reached solely
|
|
11
|
+
* through the optional `@nifrajs/mcp/agent-descriptor` subpath. The base MCP import path never loads
|
|
12
|
+
* it, so the agent edge stays opt-in and the dependency direction (`mcp -> agent`, never the reverse)
|
|
13
|
+
* is preserved.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
type CapabilityDescriptor,
|
|
18
|
+
descriptorFromTool,
|
|
19
|
+
type IsolationClass,
|
|
20
|
+
} from "@nifrajs/agent/registry"
|
|
21
|
+
import type { ToolContract } from "@nifrajs/core/tool-contract"
|
|
22
|
+
|
|
23
|
+
export interface McpDescriptorOptions {
|
|
24
|
+
readonly version?: string
|
|
25
|
+
readonly isolation?: IsolationClass
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Project one MCP-facing tool contract into a `mcp-tool` capability descriptor. The digest is taken
|
|
30
|
+
* over the tool's own input schema, so it matches the core tool descriptor for the same contract.
|
|
31
|
+
*/
|
|
32
|
+
export function mcpToolDescriptor<Input, Output>(
|
|
33
|
+
tool: ToolContract<Input, Output>,
|
|
34
|
+
options: McpDescriptorOptions = {},
|
|
35
|
+
): Promise<CapabilityDescriptor> {
|
|
36
|
+
return descriptorFromTool(tool, {
|
|
37
|
+
kind: "mcp-tool",
|
|
38
|
+
...(options.version === undefined ? {} : { version: options.version }),
|
|
39
|
+
...(options.isolation === undefined ? {} : { isolation: options.isolation }),
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Project a set of MCP tool contracts, preserving order. Compose the result into a snapshot to dedupe. */
|
|
44
|
+
export function mcpToolDescriptors<Input, Output>(
|
|
45
|
+
tools: readonly ToolContract<Input, Output>[],
|
|
46
|
+
options: McpDescriptorOptions = {},
|
|
47
|
+
): Promise<readonly CapabilityDescriptor[]> {
|
|
48
|
+
return Promise.all(tools.map((tool) => mcpToolDescriptor(tool, options)))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type { CapabilityDescriptor, IsolationClass }
|
package/src/http.ts
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
* The transport core shared by every HTTP host of an MCP server - the dev/docs MCP in `@nifrajs/cli`
|
|
3
3
|
* (`nifra docs-mcp`), the site's edge worker, and a nifra app mounting `POST /mcp` via
|
|
4
4
|
* {@link ./server.ts}. {@link respondMcpHttp} is a plain Web `fetch` handler: POST a JSON-RPC body →
|
|
5
|
-
* JSON-RPC response
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* JSON-RPC response (or an SSE stream when the client accepts `text/event-stream`); GET is a health page
|
|
6
|
+
* or a cancellable SSE stream; OPTIONS is the CORS preflight. It never throws - a bad body becomes a
|
|
7
|
+
* JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources / prompts /
|
|
8
|
+
* the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import {
|
|
11
12
|
handleRpc,
|
|
13
|
+
type JsonRpcNotification,
|
|
12
14
|
type JsonRpcRequest,
|
|
13
15
|
type JsonRpcResponse,
|
|
14
16
|
MCP_ERROR,
|
|
@@ -53,6 +55,9 @@ function corsFor(
|
|
|
53
55
|
|
|
54
56
|
const DEFAULT_MAX_BODY_BYTES = 1_000_000
|
|
55
57
|
const TEXT_DECODER = new TextDecoder()
|
|
58
|
+
const TEXT_ENCODER = new TextEncoder()
|
|
59
|
+
const SSE_CONTENT_TYPE = "text/event-stream; charset=utf-8"
|
|
60
|
+
const SSE_KEEP_ALIVE_MS = 15_000
|
|
56
61
|
|
|
57
62
|
/** Invalid byte caps make `total > maxBytes` fail open (especially for `NaN`). Reject configuration
|
|
58
63
|
* before any request body is read so MCP cannot silently lose its memory bound. */
|
|
@@ -86,6 +91,120 @@ export interface McpHttpOptions {
|
|
|
86
91
|
) => boolean | Promise<boolean>
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
interface EventStreamControl {
|
|
95
|
+
readonly signal: AbortSignal
|
|
96
|
+
readonly closed: Promise<void>
|
|
97
|
+
send(message: JsonRpcNotification | JsonRpcResponse): void
|
|
98
|
+
comment(value?: string): void
|
|
99
|
+
close(): void
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function acceptsEventStream(request: Request): boolean {
|
|
103
|
+
return (request.headers.get("accept") ?? "").toLowerCase().includes("text/event-stream")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function eventStreamResponse(
|
|
107
|
+
request: Request,
|
|
108
|
+
headers: Record<string, string>,
|
|
109
|
+
run: (stream: EventStreamControl) => void | Promise<void>,
|
|
110
|
+
keepAliveMs = 0,
|
|
111
|
+
): Response {
|
|
112
|
+
const abortController = new AbortController()
|
|
113
|
+
let closed = false
|
|
114
|
+
let controller: ReadableStreamDefaultController<Uint8Array> | undefined
|
|
115
|
+
let resolveClosed: () => void = () => {}
|
|
116
|
+
const closedPromise = new Promise<void>((resolve) => {
|
|
117
|
+
resolveClosed = resolve
|
|
118
|
+
})
|
|
119
|
+
let onRequestAbort: (() => void) | undefined
|
|
120
|
+
let heartbeat: ReturnType<typeof setInterval> | undefined
|
|
121
|
+
|
|
122
|
+
const teardown = (): void => {
|
|
123
|
+
if (heartbeat !== undefined) clearInterval(heartbeat)
|
|
124
|
+
if (request.signal !== undefined && onRequestAbort !== undefined) {
|
|
125
|
+
request.signal.removeEventListener("abort", onRequestAbort)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const finish = (closeController: boolean): void => {
|
|
130
|
+
if (closed) return
|
|
131
|
+
closed = true
|
|
132
|
+
teardown()
|
|
133
|
+
abortController.abort()
|
|
134
|
+
resolveClosed()
|
|
135
|
+
if (closeController) {
|
|
136
|
+
try {
|
|
137
|
+
controller?.close()
|
|
138
|
+
} catch {
|
|
139
|
+
// The consumer may have canceled the stream between the check and close.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const write = (frame: string): void => {
|
|
145
|
+
if (closed) return
|
|
146
|
+
try {
|
|
147
|
+
controller?.enqueue(TEXT_ENCODER.encode(frame))
|
|
148
|
+
} catch {
|
|
149
|
+
finish(false)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const stream: EventStreamControl = {
|
|
154
|
+
signal: abortController.signal,
|
|
155
|
+
closed: closedPromise,
|
|
156
|
+
send(message) {
|
|
157
|
+
write(`data: ${JSON.stringify(message)}\n\n`)
|
|
158
|
+
},
|
|
159
|
+
comment(value = "") {
|
|
160
|
+
write(`: ${value.replace(/[\r\n]/g, "")}\n\n`)
|
|
161
|
+
},
|
|
162
|
+
close() {
|
|
163
|
+
finish(true)
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const body = new ReadableStream<Uint8Array>({
|
|
168
|
+
start(nextController) {
|
|
169
|
+
controller = nextController
|
|
170
|
+
if (request.signal.aborted) {
|
|
171
|
+
finish(true)
|
|
172
|
+
return
|
|
173
|
+
}
|
|
174
|
+
onRequestAbort = () => finish(true)
|
|
175
|
+
request.signal.addEventListener("abort", onRequestAbort, { once: true })
|
|
176
|
+
if (keepAliveMs > 0) {
|
|
177
|
+
heartbeat = setInterval(() => stream.comment(), keepAliveMs)
|
|
178
|
+
;(heartbeat as { unref?: () => void }).unref?.()
|
|
179
|
+
}
|
|
180
|
+
void (async () => run(stream))().then(
|
|
181
|
+
() => stream.close(),
|
|
182
|
+
(error: unknown) => {
|
|
183
|
+
if (closed) return
|
|
184
|
+
try {
|
|
185
|
+
controller?.error(error instanceof Error ? error : new Error("mcp_sse_failed"))
|
|
186
|
+
} finally {
|
|
187
|
+
finish(false)
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
)
|
|
191
|
+
},
|
|
192
|
+
cancel() {
|
|
193
|
+
finish(false)
|
|
194
|
+
},
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
return new Response(body, {
|
|
198
|
+
status: 200,
|
|
199
|
+
headers: {
|
|
200
|
+
...headers,
|
|
201
|
+
"content-type": SSE_CONTENT_TYPE,
|
|
202
|
+
"cache-control": "no-cache, no-transform",
|
|
203
|
+
"x-accel-buffering": "no",
|
|
204
|
+
},
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
89
208
|
function parseContentLength(value: string): number | undefined {
|
|
90
209
|
if (value.length === 0) return undefined
|
|
91
210
|
let length = 0
|
|
@@ -197,11 +316,13 @@ function modernErrorStatus(response: JsonRpcResponse): number {
|
|
|
197
316
|
}
|
|
198
317
|
|
|
199
318
|
/**
|
|
200
|
-
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
|
|
201
|
-
* response
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
319
|
+
* Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → a JSON-RPC
|
|
320
|
+
* response, or an SSE stream carrying progress notifications and the final response when the client
|
|
321
|
+
* accepts `text/event-stream`; GET → a health page or a cancellable SSE stream; OPTIONS → CORS preflight.
|
|
322
|
+
* Never throws - a bad body becomes a JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that
|
|
323
|
+
* mirrors its method/name/version into headers is validated against the body before dispatch and gets spec
|
|
324
|
+
* HTTP statuses; legacy requests are served unchanged. The dispatch is the shared, transport-agnostic
|
|
325
|
+
* {@link handleRpc}.
|
|
205
326
|
*/
|
|
206
327
|
export async function respondMcpHttp(
|
|
207
328
|
request: Request,
|
|
@@ -219,14 +340,19 @@ export async function respondMcpHttp(
|
|
|
219
340
|
}
|
|
220
341
|
if (request.method === "OPTIONS") return new Response(null, { status: 204, headers: cors })
|
|
221
342
|
if (request.method === "GET") {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
343
|
+
if (acceptsEventStream(request)) {
|
|
344
|
+
// Keep the GET side of Streamable HTTP usable for clients that open a server-message channel. This
|
|
345
|
+
// transport has no durable session store, so the public seam is a cancellable keep-alive stream;
|
|
346
|
+
// request-scoped progress still travels on the POST stream below.
|
|
347
|
+
return eventStreamResponse(
|
|
348
|
+
request,
|
|
349
|
+
{ allow: "POST, GET", ...cors },
|
|
350
|
+
async (stream) => {
|
|
351
|
+
stream.comment("connected")
|
|
352
|
+
await stream.closed
|
|
353
|
+
},
|
|
354
|
+
SSE_KEEP_ALIVE_MS,
|
|
355
|
+
)
|
|
230
356
|
}
|
|
231
357
|
return new Response(
|
|
232
358
|
options.health ??
|
|
@@ -269,9 +395,19 @@ export async function respondMcpHttp(
|
|
|
269
395
|
const headerError = modernHeaderMismatch(request, message, bodyVersion)
|
|
270
396
|
if (headerError !== null) return Response.json(headerError, { status: 400, headers })
|
|
271
397
|
}
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
398
|
+
const dispatch = (stream?: EventStreamControl): Promise<JsonRpcResponse | null> =>
|
|
399
|
+
handleRpc(message, tools, serverInfo, options.features ?? {}, {
|
|
400
|
+
signal: stream?.signal ?? request.signal,
|
|
401
|
+
...(stream !== undefined ? { sendNotification: stream.send } : {}),
|
|
402
|
+
})
|
|
403
|
+
if (acceptsEventStream(request)) {
|
|
404
|
+
return eventStreamResponse(request, headers, async (stream) => {
|
|
405
|
+
const response = await dispatch(stream)
|
|
406
|
+
if (response !== null) stream.send(response)
|
|
407
|
+
stream.close()
|
|
408
|
+
})
|
|
409
|
+
}
|
|
410
|
+
const response = await dispatch()
|
|
275
411
|
// A notification (no id) yields null - acknowledge with 202 Accepted and no body (Streamable-HTTP).
|
|
276
412
|
if (response === null) return new Response(null, { status: 202, headers })
|
|
277
413
|
// Modern requests carry spec HTTP statuses (400 version/header, 404 unknown method); legacy stays 200.
|
package/src/server.ts
CHANGED
|
@@ -74,6 +74,11 @@ export interface McpServer {
|
|
|
74
74
|
fetch(request: Request, overrides?: Pick<McpHttpOptions, "authorizeMessage">): Promise<Response>
|
|
75
75
|
/** Dispatch one JSON-RPC message directly (no HTTP) - for headless verification and unit tests. */
|
|
76
76
|
handle(message: JsonRpcRequest): Promise<JsonRpcResponse | null>
|
|
77
|
+
/**
|
|
78
|
+
* Release server-owned resources, when the implementation has any (for example a database worker).
|
|
79
|
+
* Calling it more than once is safe. The base MCP server has nothing to release and omits this hook.
|
|
80
|
+
*/
|
|
81
|
+
readonly close?: () => Promise<void>
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
export function createMcpServer(opts: CreateMcpServerOptions): McpServer {
|