@nifrajs/mcp 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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; GET is a health page; OPTIONS is the CORS preflight. It never throws - a bad body
6
- * becomes a JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources /
7
- * prompts / the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
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; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
33
- * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
34
- * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
35
- * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
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;
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,cAAc,EAGnB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAGb,MAAM,eAAe,CAAA;AA8CtB,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;AAgHD;;;;;;GAMG;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,CAqEnB"}
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; GET is a health page; OPTIONS is the CORS preflight. It never throws - a bad body
6
- * becomes a JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources /
7
- * prompts / the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
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; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
154
- * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
155
- * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
156
- * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
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
- // The 2026-07-28 revision removed the GET SSE stream; a client probing for it (`Accept:
171
- // text/event-stream`) gets 405 so its transport fallback fires. A plain browser/monitor GET still
172
- // gets the human-readable health page.
173
- if ((request.headers.get("accept") ?? "").includes("text/event-stream")) {
174
- return new Response("event stream not supported", {
175
- status: 405,
176
- headers: { allow: "POST, GET", ...cors },
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 response = await handleRpc(message, tools, serverInfo, options.features ?? {}, {
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
@@ -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;CACjE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,SAAS,CA8BvE"}
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"}
@@ -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;AA8CtB,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"}
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": "3.1.0",
3
+ "version": "3.3.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/core": "^3.1.0"
67
+ "@nifrajs/agent": "^3.3.0",
68
+ "@nifrajs/core": "^3.3.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; GET is a health page; OPTIONS is the CORS preflight. It never throws - a bad body
6
- * becomes a JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources /
7
- * prompts / the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
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; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
202
- * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
203
- * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
204
- * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
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
- // The 2026-07-28 revision removed the GET SSE stream; a client probing for it (`Accept:
223
- // text/event-stream`) gets 405 so its transport fallback fires. A plain browser/monitor GET still
224
- // gets the human-readable health page.
225
- if ((request.headers.get("accept") ?? "").includes("text/event-stream")) {
226
- return new Response("event stream not supported", {
227
- status: 405,
228
- headers: { allow: "POST, GET", ...cors },
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 response = await handleRpc(message, tools, serverInfo, options.features ?? {}, {
273
- signal: request.signal,
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 {