@nifrajs/mcp 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/http.d.ts CHANGED
@@ -14,11 +14,19 @@ export interface McpHttpOptions {
14
14
  readonly features?: McpServerFeatures;
15
15
  /** Shown on the GET health page so each host can describe itself. */
16
16
  readonly health?: string;
17
+ /**
18
+ * Origin allowlist for the DNS-rebinding guard. Omit (the default) to allow any origin - the right
19
+ * choice for a public, unauthenticated docs server that can't enumerate its browser clients' origins.
20
+ * Set it (e.g. a localhost origin for a hardened local host) to reject any other browser origin with 403.
21
+ */
22
+ readonly allowedOrigins?: readonly string[];
17
23
  }
18
24
  /**
19
25
  * Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
20
26
  * response; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
21
- * JSON-RPC parse error. The dispatch is the shared, transport-agnostic {@link handleRpc}.
27
+ * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
28
+ * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
29
+ * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
22
30
  */
23
31
  export declare function respondMcpHttp(request: Request, tools: McpTool[], serverInfo: {
24
32
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAEb,MAAM,eAAe,CAAA;AAWtB,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;CACzB;AAuDD;;;;GAIG;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,CAgCnB"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,OAAO,EAGb,MAAM,eAAe,CAAA;AAsCtB,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;CAC5C;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,CA0DnB"}
package/dist/http.js CHANGED
@@ -6,12 +6,36 @@
6
6
  * becomes a JSON-RPC parse error. Pass the tools (and optional {@link McpServerFeatures} for resources /
7
7
  * prompts / the MCP Apps `ui://` widgets) so each host supplies its own corpus/source behind one core.
8
8
  */
9
- import { handleRpc, rpcError, } from "./protocol.js";
10
- const CORS = {
11
- "access-control-allow-origin": "*",
9
+ import { handleRpc, MCP_ERROR, modernVersionOf, rpcError, } from "./protocol.js";
10
+ // Headers on every response. `access-control-allow-headers` lists the request headers a browser MCP client
11
+ // (claude.ai, ChatGPT) actually sends: `mcp-protocol-version` (required per POST since 2025-06-18),
12
+ // `mcp-method`/`mcp-name` (the 2026-07-28 request-metadata mirror), `authorization` (OAuth-protected hosts),
13
+ // plus `accept`/`last-event-id`. Omit any and the CORS preflight fails, so the connector never loads.
14
+ const CORS_BASE = {
12
15
  "access-control-allow-methods": "POST, GET, OPTIONS",
13
- "access-control-allow-headers": "content-type",
16
+ "access-control-allow-headers": "content-type, authorization, mcp-protocol-version, mcp-session-id, mcp-method, mcp-name, accept, last-event-id",
17
+ "access-control-expose-headers": "mcp-protocol-version, mcp-session-id",
18
+ "access-control-max-age": "86400",
14
19
  };
20
+ /**
21
+ * Resolve the CORS/Origin headers for one request against the host's `allowedOrigins` policy, or `null`
22
+ * when the request's `Origin` is present but not allowed - the caller then answers 403, per the
23
+ * Streamable-HTTP DNS-rebinding rule ("Servers MUST validate the `Origin` header ... respond with 403").
24
+ * With no policy (the default) every origin is allowed and reflected as `*` - correct for a public,
25
+ * secret-free, unauthenticated server, whose browser clients send arbitrary origins we can't enumerate.
26
+ */
27
+ function corsFor(request, allowedOrigins) {
28
+ if (allowedOrigins === undefined)
29
+ return { ...CORS_BASE, "access-control-allow-origin": "*" };
30
+ const origin = request.headers.get("origin");
31
+ // A caller with no Origin (curl, server-to-server) can't mount a DNS-rebinding attack - allow it.
32
+ if (origin === null)
33
+ return { ...CORS_BASE, vary: "Origin" };
34
+ if (allowedOrigins.includes(origin)) {
35
+ return { ...CORS_BASE, "access-control-allow-origin": origin, vary: "Origin" };
36
+ }
37
+ return null;
38
+ }
15
39
  const DEFAULT_MAX_BODY_BYTES = 1_000_000;
16
40
  const TEXT_DECODER = new TextDecoder();
17
41
  function parseContentLength(value) {
@@ -67,22 +91,89 @@ async function readJsonBounded(request, maxBytes) {
67
91
  return { ok: false, status: 400 };
68
92
  }
69
93
  }
94
+ const SENTINEL_PREFIX = "=?base64?";
95
+ const SENTINEL_SUFFIX = "?=";
96
+ /** Decode the Streamable-HTTP `=?base64?...?=` header sentinel (used when a name/uri isn't header-safe).
97
+ * A plain value passes through; a malformed sentinel is returned as-is so validation still fails closed. */
98
+ function decodeSentinel(value) {
99
+ if (value === null)
100
+ return null;
101
+ if (!value.startsWith(SENTINEL_PREFIX) || !value.endsWith(SENTINEL_SUFFIX))
102
+ return value;
103
+ const encoded = value.slice(SENTINEL_PREFIX.length, value.length - SENTINEL_SUFFIX.length);
104
+ try {
105
+ return TEXT_DECODER.decode(Uint8Array.from(atob(encoded), (ch) => ch.charCodeAt(0)));
106
+ }
107
+ catch {
108
+ return value;
109
+ }
110
+ }
111
+ /** Validate a modern (2026-07-28) request's mirrored headers against its body: `MCP-Protocol-Version`,
112
+ * `Mcp-Method`, and - for name-bearing methods - `Mcp-Name` MUST match, else a `HeaderMismatch` the caller
113
+ * returns as 400. Stops an intermediary from routing on a header while the server acts on a different body. */
114
+ function modernHeaderMismatch(request, message, bodyVersion) {
115
+ const rid = message.id ?? null;
116
+ const headerVersion = request.headers.get("mcp-protocol-version");
117
+ if (headerVersion === null || headerVersion !== bodyVersion) {
118
+ return rpcError(rid, MCP_ERROR.HEADER_MISMATCH, "MCP-Protocol-Version header missing or mismatched");
119
+ }
120
+ const method = typeof message.method === "string" ? message.method : "";
121
+ const headerMethod = request.headers.get("mcp-method");
122
+ if (headerMethod === null || headerMethod !== method) {
123
+ return rpcError(rid, MCP_ERROR.HEADER_MISMATCH, "Mcp-Method header missing or mismatched");
124
+ }
125
+ if (method === "tools/call" || method === "resources/read" || method === "prompts/get") {
126
+ const bodyName = method === "resources/read" ? message.params?.uri : message.params?.name;
127
+ const headerName = decodeSentinel(request.headers.get("mcp-name"));
128
+ if (headerName === null || typeof bodyName !== "string" || headerName !== bodyName) {
129
+ return rpcError(rid, MCP_ERROR.HEADER_MISMATCH, "Mcp-Name header missing or mismatched");
130
+ }
131
+ }
132
+ return null;
133
+ }
134
+ /** HTTP status for a modern request's dispatch result: 400 for version/header errors, 404 for an unknown
135
+ * method, 200 otherwise (in-band tool errors are ordinary JSON-RPC results and stay 200). */
136
+ function modernErrorStatus(response) {
137
+ if (!("error" in response))
138
+ return 200;
139
+ const { code } = response.error;
140
+ if (code === MCP_ERROR.UNSUPPORTED_VERSION || code === MCP_ERROR.HEADER_MISMATCH)
141
+ return 400;
142
+ return code === -32601 ? 404 : 200;
143
+ }
70
144
  /**
71
145
  * Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
72
146
  * response; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
73
- * JSON-RPC parse error. The dispatch is the shared, transport-agnostic {@link handleRpc}.
147
+ * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
148
+ * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
149
+ * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
74
150
  */
75
151
  export async function respondMcpHttp(request, tools, serverInfo, options = {}) {
152
+ const cors = corsFor(request, options.allowedOrigins);
153
+ if (cors === null) {
154
+ // Origin present but not allowlisted: reject before the body is ever read (DNS-rebinding guard). No
155
+ // `id` (no request parsed) and no CORS headers - a disallowed origin gets nothing to work with.
156
+ return Response.json(rpcError(null, -32600, "origin not allowed"), { status: 403 });
157
+ }
76
158
  if (request.method === "OPTIONS")
77
- return new Response(null, { status: 204, headers: CORS });
159
+ return new Response(null, { status: 204, headers: cors });
78
160
  if (request.method === "GET") {
161
+ // The 2026-07-28 revision removed the GET SSE stream; a client probing for it (`Accept:
162
+ // text/event-stream`) gets 405 so its transport fallback fires. A plain browser/monitor GET still
163
+ // gets the human-readable health page.
164
+ if ((request.headers.get("accept") ?? "").includes("text/event-stream")) {
165
+ return new Response("event stream not supported", {
166
+ status: 405,
167
+ headers: { allow: "POST, GET", ...cors },
168
+ });
169
+ }
79
170
  return new Response(options.health ??
80
- "MCP server - POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call).", { headers: { "content-type": "text/plain; charset=utf-8", ...CORS } });
171
+ "MCP server - POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call).", { headers: { "content-type": "text/plain; charset=utf-8", ...cors } });
81
172
  }
82
173
  if (request.method !== "POST") {
83
174
  return new Response("method not allowed", {
84
175
  status: 405,
85
- headers: { allow: "POST, GET", ...CORS },
176
+ headers: { allow: "POST, GET", ...cors },
86
177
  });
87
178
  }
88
179
  const parsed = await readJsonBounded(request, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES);
@@ -90,18 +181,30 @@ export async function respondMcpHttp(request, tools, serverInfo, options = {}) {
90
181
  if (parsed.status === 413) {
91
182
  return Response.json(rpcError(null, -32000, "payload too large"), {
92
183
  status: 413,
93
- headers: CORS,
184
+ headers: cors,
94
185
  });
95
186
  }
96
- return Response.json(rpcError(null, -32700, "parse error"), { status: 400, headers: CORS });
187
+ return Response.json(rpcError(null, -32700, "parse error"), { status: 400, headers: cors });
97
188
  }
98
189
  const message = parsed.value;
190
+ const bodyVersion = modernVersionOf(message.params);
191
+ // Mirror the protocol version back for intermediaries (SHOULD, 2025-06-18+); absent is fine.
192
+ const echoVersion = request.headers.get("mcp-protocol-version");
193
+ const headers = echoVersion !== null ? { ...cors, "mcp-protocol-version": echoVersion } : cors;
194
+ if (bodyVersion !== undefined) {
195
+ // Modern request: header/body mirror MUST agree. Reject divergence with 400 before dispatch.
196
+ const headerError = modernHeaderMismatch(request, message, bodyVersion);
197
+ if (headerError !== null)
198
+ return Response.json(headerError, { status: 400, headers });
199
+ }
99
200
  const response = await handleRpc(message, tools, serverInfo, options.features ?? {}, {
100
201
  signal: request.signal,
101
202
  });
102
- // A notification (no id) yields null - acknowledge with 204, no body.
203
+ // A notification (no id) yields null - acknowledge with 202 Accepted and no body (Streamable-HTTP).
103
204
  if (response === null)
104
- return new Response(null, { status: 204, headers: CORS });
105
- return Response.json(response, { headers: CORS });
205
+ return new Response(null, { status: 202, headers });
206
+ // Modern requests carry spec HTTP statuses (400 version/header, 404 unknown method); legacy stays 200.
207
+ const status = bodyVersion !== undefined ? modernErrorStatus(response) : 200;
208
+ return Response.json(response, { status, headers });
106
209
  }
107
210
  //# sourceMappingURL=http.js.map
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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"}
@@ -9,7 +9,20 @@
9
9
  * for the widget to render, and `initialize` advertises the `io.modelcontextprotocol/ui` extension. All of
10
10
  * it is additive - a tool whose handler returns a plain `string` behaves exactly as before.
11
11
  */
12
- export declare const PROTOCOL_VERSION = "2024-11-05";
12
+ /** The protocol revision this server advertises by default. A handshake-era version - the HTTP transport
13
+ * still uses `initialize`; current clients reach it through their backward-compatibility fallback.
14
+ * `initialize` echoes the client's own requested version instead when it's one this server also speaks
15
+ * ({@link SUPPORTED_PROTOCOL_VERSIONS}). */
16
+ export declare const PROTOCOL_VERSION = "2025-06-18";
17
+ /** The stateless per-request revision (2026-07-28+). A request carrying its version in `_meta`
18
+ * (`io.modelcontextprotocol/protocolVersion`) is served in modern mode; an `initialize` request stays
19
+ * legacy. This server is dual-era: `handleRpc` answers both on the same dispatch, per request. */
20
+ export declare const MODERN_PROTOCOL_VERSION = "2026-07-28";
21
+ /** MCP-reserved JSON-RPC error codes (2026-07-28 error-code policy carves out -32020..-32099 for the spec). */
22
+ export declare const MCP_ERROR: {
23
+ readonly HEADER_MISMATCH: -32020;
24
+ readonly UNSUPPORTED_VERSION: -32022;
25
+ };
13
26
  /** The MIME type a UI resource MUST use so a host recognizes it as an MCP App widget (SEP-1865). */
14
27
  export declare const UI_MIME = "text/html;profile=mcp-app";
15
28
  /** The `capabilities.extensions` key advertising UI support in the `initialize` result (SEP-1865). */
@@ -96,6 +109,9 @@ export interface McpServerFeatures {
96
109
  readonly ui?: {
97
110
  readonly mimeTypes?: readonly string[];
98
111
  };
112
+ /** Natural-language guidance for LLMs on how to use this server. Surfaced in the modern
113
+ * `server/discover` result (2026-07-28); legacy `initialize` does not carry it. */
114
+ readonly instructions?: string;
99
115
  }
100
116
  export interface JsonRpcRequest {
101
117
  readonly jsonrpc?: string;
@@ -118,10 +134,11 @@ export type JsonRpcResponse = {
118
134
  error: {
119
135
  code: number;
120
136
  message: string;
137
+ data?: unknown;
121
138
  };
122
139
  };
123
140
  export declare const rpcResult: (id: JsonRpcId, value: unknown) => JsonRpcResponse;
124
- export declare const rpcError: (id: JsonRpcId, code: number, message: string) => JsonRpcResponse;
141
+ export declare const rpcError: (id: JsonRpcId, code: number, message: string, data?: unknown) => JsonRpcResponse;
125
142
  export interface McpProtocolState {
126
143
  readonly activeRequests: Map<string, AbortController>;
127
144
  }
@@ -131,6 +148,9 @@ export interface McpProtocolOptions {
131
148
  readonly sendNotification?: (notification: JsonRpcNotification) => void;
132
149
  }
133
150
  export declare function createMcpProtocolState(): McpProtocolState;
151
+ /** The protocol version a modern (2026-07-28+) request declares in `_meta`, or `undefined` for a legacy
152
+ * request. Its presence is what puts the dispatch in modern mode for that one request. */
153
+ export declare function modernVersionOf(params: Record<string, unknown> | undefined): string | undefined;
134
154
  /**
135
155
  * Dispatch one JSON-RPC message against the given tools. Returns the response, or `null` for a
136
156
  * notification (no reply). Tool errors are reported in-band (`isError`) so the agent can react to them.
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/protocol.js CHANGED
@@ -9,7 +9,27 @@
9
9
  * for the widget to render, and `initialize` advertises the `io.modelcontextprotocol/ui` extension. All of
10
10
  * it is additive - a tool whose handler returns a plain `string` behaves exactly as before.
11
11
  */
12
- export const PROTOCOL_VERSION = "2024-11-05";
12
+ /** The protocol revision this server advertises by default. A handshake-era version - the HTTP transport
13
+ * still uses `initialize`; current clients reach it through their backward-compatibility fallback.
14
+ * `initialize` echoes the client's own requested version instead when it's one this server also speaks
15
+ * ({@link SUPPORTED_PROTOCOL_VERSIONS}). */
16
+ export const PROTOCOL_VERSION = "2025-06-18";
17
+ /** The handshake-era revisions this server speaks. `initialize` echoes the client's requested
18
+ * `protocolVersion` when it's in this set (the smoothest negotiation), else answers {@link PROTOCOL_VERSION}. */
19
+ const SUPPORTED_PROTOCOL_VERSIONS = new Set([
20
+ "2024-11-05",
21
+ "2025-03-26",
22
+ "2025-06-18",
23
+ "2025-11-25",
24
+ ]);
25
+ /** The stateless per-request revision (2026-07-28+). A request carrying its version in `_meta`
26
+ * (`io.modelcontextprotocol/protocolVersion`) is served in modern mode; an `initialize` request stays
27
+ * legacy. This server is dual-era: `handleRpc` answers both on the same dispatch, per request. */
28
+ export const MODERN_PROTOCOL_VERSION = "2026-07-28";
29
+ /** MCP-reserved JSON-RPC error codes (2026-07-28 error-code policy carves out -32020..-32099 for the spec). */
30
+ export const MCP_ERROR = { HEADER_MISMATCH: -32020, UNSUPPORTED_VERSION: -32022 };
31
+ const META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
32
+ const META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
13
33
  /** The MIME type a UI resource MUST use so a host recognizes it as an MCP App widget (SEP-1865). */
14
34
  export const UI_MIME = "text/html;profile=mcp-app";
15
35
  /** The `capabilities.extensions` key advertising UI support in the `initialize` result (SEP-1865). */
@@ -19,10 +39,10 @@ export const rpcResult = (id, value) => ({
19
39
  id,
20
40
  result: value,
21
41
  });
22
- export const rpcError = (id, code, message) => ({
42
+ export const rpcError = (id, code, message, data) => ({
23
43
  jsonrpc: "2.0",
24
44
  id,
25
- error: { code, message },
45
+ error: data !== undefined ? { code, message, data } : { code, message },
26
46
  });
27
47
  export function createMcpProtocolState() {
28
48
  return { activeRequests: new Map() };
@@ -32,11 +52,20 @@ function requestKey(id) {
32
52
  return `s:${id}`;
33
53
  return typeof id === "number" && Number.isFinite(id) ? `n:${id}` : undefined;
34
54
  }
35
- function progressTokenOf(params) {
55
+ function metaObject(params) {
36
56
  const meta = params?._meta;
37
- if (typeof meta !== "object" || meta === null || Array.isArray(meta))
38
- return undefined;
39
- const token = meta.progressToken;
57
+ return typeof meta === "object" && meta !== null && !Array.isArray(meta)
58
+ ? meta
59
+ : undefined;
60
+ }
61
+ /** The protocol version a modern (2026-07-28+) request declares in `_meta`, or `undefined` for a legacy
62
+ * request. Its presence is what puts the dispatch in modern mode for that one request. */
63
+ export function modernVersionOf(params) {
64
+ const version = metaObject(params)?.[META_PROTOCOL_VERSION];
65
+ return typeof version === "string" ? version : undefined;
66
+ }
67
+ function progressTokenOf(params) {
68
+ const token = metaObject(params)?.progressToken;
40
69
  return typeof token === "string" || (typeof token === "number" && Number.isFinite(token))
41
70
  ? token
42
71
  : undefined;
@@ -70,6 +99,22 @@ function compactDescription(description) {
70
99
  return sentence;
71
100
  return `${sentence.slice(0, 117).trimEnd()}...`;
72
101
  }
102
+ /** Freshness hint for the static docs corpus - a modern client MAY cache list/read results this long. */
103
+ const DEFAULT_CACHE_TTL_MS = 3_600_000;
104
+ /** Wrap a result in the 2026-07-28 completion envelope: `resultType`, a self-identifying `serverInfo`
105
+ * under `_meta`, and - for the cacheable list/read methods - a public freshness hint. Legacy results skip
106
+ * this entirely and keep their exact pre-2026-07-28 shape. */
107
+ function withEnvelope(value, serverInfo, cacheable) {
108
+ const existingMeta = typeof value._meta === "object" && value._meta !== null && !Array.isArray(value._meta)
109
+ ? value._meta
110
+ : undefined;
111
+ return {
112
+ ...value,
113
+ resultType: "complete",
114
+ _meta: { ...(existingMeta ?? {}), [META_SERVER_INFO]: serverInfo },
115
+ ...(cacheable ? { ttlMs: DEFAULT_CACHE_TTL_MS, cacheScope: "public" } : {}),
116
+ };
117
+ }
73
118
  /** Normalize a handler's return into the `tools/call` result object. A `string` becomes a single text
74
119
  * block (base-MCP behavior, unchanged); a {@link McpToolResult} passes `content`/`structuredContent`
75
120
  * through, and inherits the tool descriptor's `_meta` (the `ui.resourceUri` link) when it sets none. */
@@ -99,10 +144,29 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
99
144
  const resources = features.resources ?? [];
100
145
  const prompts = features.prompts ?? [];
101
146
  const state = options.state ?? createMcpProtocolState();
147
+ // A request that declares its version in `_meta` is a modern (2026-07-28+) request. We speak exactly one
148
+ // modern revision; any other declared version is rejected so the client can retry with a supported one.
149
+ const requestedVersion = modernVersionOf(params);
150
+ const isModern = requestedVersion !== undefined;
151
+ if (isModern && requestedVersion !== MODERN_PROTOCOL_VERSION) {
152
+ return rpcError(rid, MCP_ERROR.UNSUPPORTED_VERSION, "Unsupported protocol version", {
153
+ supported: [MODERN_PROTOCOL_VERSION],
154
+ requested: requestedVersion,
155
+ });
156
+ }
157
+ // Modern results carry the completion envelope; legacy results keep their exact prior shape. Every data
158
+ // case returns through `reply` so the one `isModern` decision drives the whole response shape.
159
+ const reply = (value, cacheable = false) => rpcResult(rid, isModern ? withEnvelope(value, serverInfo, cacheable) : value);
102
160
  switch (method) {
103
- case "initialize":
161
+ case "initialize": {
162
+ // Handshake version negotiation: answer with the client's requested version when we speak it too,
163
+ // otherwise our default. The client then decides whether our answer is acceptable.
164
+ const requested = params?.protocolVersion;
165
+ const protocolVersion = typeof requested === "string" && SUPPORTED_PROTOCOL_VERSIONS.has(requested)
166
+ ? requested
167
+ : PROTOCOL_VERSION;
104
168
  return rpcResult(rid, {
105
- protocolVersion: PROTOCOL_VERSION,
169
+ protocolVersion,
106
170
  capabilities: {
107
171
  tools: {},
108
172
  ...(resources.length > 0 ? { resources: {} } : {}),
@@ -117,6 +181,26 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
117
181
  },
118
182
  serverInfo,
119
183
  });
184
+ }
185
+ case "server/discover":
186
+ // The modern capability/identity probe (replaces `initialize` for 2026-07-28 clients). Always
187
+ // enveloped and cacheable - it is a modern-only RPC.
188
+ return rpcResult(rid, withEnvelope({
189
+ supportedVersions: [MODERN_PROTOCOL_VERSION],
190
+ capabilities: {
191
+ tools: {},
192
+ ...(resources.length > 0 ? { resources: {} } : {}),
193
+ ...(prompts.length > 0 ? { prompts: {} } : {}),
194
+ ...(features.ui !== undefined
195
+ ? {
196
+ extensions: {
197
+ [UI_EXTENSION_KEY]: { mimeTypes: features.ui.mimeTypes ?? [UI_MIME] },
198
+ },
199
+ }
200
+ : {}),
201
+ },
202
+ ...(features.instructions !== undefined ? { instructions: features.instructions } : {}),
203
+ }, serverInfo, true));
120
204
  case "notifications/initialized":
121
205
  return null;
122
206
  case "notifications/cancelled": {
@@ -128,7 +212,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
128
212
  case "ping":
129
213
  return rpcResult(rid, {});
130
214
  case "tools/list":
131
- return rpcResult(rid, params?.compact === true
215
+ return reply(params?.compact === true
132
216
  ? {
133
217
  tools: tools.map((t) => ({
134
218
  name: t.name,
@@ -143,13 +227,13 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
143
227
  ...(t.annotations !== undefined ? { annotations: t.annotations } : {}),
144
228
  ...(t._meta !== undefined ? { _meta: t._meta } : {}),
145
229
  })),
146
- });
230
+ }, true);
147
231
  case "tools/describe": {
148
232
  const name = params?.name;
149
233
  const tool = tools.find((t) => t.name === name);
150
234
  if (!tool)
151
235
  return rpcError(rid, -32602, `unknown tool: ${String(name)}`);
152
- return rpcResult(rid, {
236
+ return reply({
153
237
  tool: {
154
238
  name: tool.name,
155
239
  description: tool.description,
@@ -203,17 +287,17 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
203
287
  if (controller.signal.aborted)
204
288
  throw new DOMException("cancelled", "AbortError");
205
289
  reportProgress(1, 1);
206
- return rpcResult(rid, toolCallResult(result, tool));
290
+ return reply(toolCallResult(result, tool));
207
291
  }
208
292
  catch (err) {
209
293
  if (controller.signal.aborted) {
210
- return rpcResult(rid, {
294
+ return reply({
211
295
  content: [{ type: "text", text: abortMessage(controller.signal) }],
212
296
  isError: true,
213
297
  });
214
298
  }
215
299
  const msg = err instanceof Error ? err.message : String(err);
216
- return rpcResult(rid, { content: [{ type: "text", text: `Error: ${msg}` }], isError: true });
300
+ return reply({ content: [{ type: "text", text: `Error: ${msg}` }], isError: true });
217
301
  }
218
302
  finally {
219
303
  cleanupAbort();
@@ -223,7 +307,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
223
307
  }
224
308
  }
225
309
  case "resources/list":
226
- return rpcResult(rid, {
310
+ return reply({
227
311
  resources: resources.map((r) => ({
228
312
  uri: r.uri,
229
313
  name: r.name,
@@ -231,7 +315,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
231
315
  ...(r.mimeType !== undefined ? { mimeType: r.mimeType } : {}),
232
316
  ...(r._meta !== undefined ? { _meta: r._meta } : {}),
233
317
  })),
234
- });
318
+ }, true);
235
319
  case "resources/read": {
236
320
  const uri = params?.uri;
237
321
  const resource = resources.find((r) => r.uri === uri);
@@ -239,7 +323,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
239
323
  return rpcError(rid, -32602, `unknown resource: ${String(uri)}`);
240
324
  try {
241
325
  const content = await resource.read();
242
- return rpcResult(rid, {
326
+ return reply({
243
327
  contents: [
244
328
  {
245
329
  uri: resource.uri,
@@ -248,7 +332,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
248
332
  ...(resource._meta !== undefined ? { _meta: resource._meta } : {}),
249
333
  },
250
334
  ],
251
- });
335
+ }, true);
252
336
  }
253
337
  catch {
254
338
  // Don't surface the raw read error - it can leak a filesystem path. Return a generic message.
@@ -256,13 +340,13 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
256
340
  }
257
341
  }
258
342
  case "prompts/list":
259
- return rpcResult(rid, {
343
+ return reply({
260
344
  prompts: prompts.map((p) => ({
261
345
  name: p.name,
262
346
  description: p.description,
263
347
  ...(p.arguments !== undefined ? { arguments: p.arguments } : {}),
264
348
  })),
265
- });
349
+ }, true);
266
350
  case "prompts/get": {
267
351
  const name = params?.name;
268
352
  const prompt = prompts.find((p) => p.name === name);
@@ -270,7 +354,7 @@ export async function handleRpc(message, tools, serverInfo, features = {}, optio
270
354
  return rpcError(rid, -32602, `unknown prompt: ${String(name)}`);
271
355
  const args = params?.arguments ?? {};
272
356
  try {
273
- return rpcResult(rid, {
357
+ return reply({
274
358
  description: prompt.description,
275
359
  messages: await prompt.handler(args),
276
360
  });
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -34,6 +34,11 @@ export interface CreateMcpServerOptions {
34
34
  readonly health?: string;
35
35
  /** Max JSON-RPC body size in bytes (default 1 MB). */
36
36
  readonly maxBodyBytes?: number;
37
+ /** Natural-language guidance for LLMs, surfaced in the modern `server/discover` result (2026-07-28). */
38
+ readonly instructions?: string;
39
+ /** Origin allowlist for the DNS-rebinding guard. Omit to allow any origin; set it to reject other
40
+ * browser origins with 403 (e.g. a hardened, non-public mount). */
41
+ readonly allowedOrigins?: readonly string[];
37
42
  }
38
43
  export interface McpServer {
39
44
  readonly tools: McpTool[];
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,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;CAC/B;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,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC1C,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,CAwBvE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,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;CAC5C;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,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC1C,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,CA0BvE"}
package/dist/server.js CHANGED
@@ -32,6 +32,7 @@ export function createMcpServer(opts) {
32
32
  ...(resources.length > 0 ? { resources } : {}),
33
33
  ...(opts.prompts !== undefined ? { prompts: opts.prompts } : {}),
34
34
  ...(widgets.length > 0 ? { ui: { mimeTypes: [UI_MIME] } } : {}),
35
+ ...(opts.instructions !== undefined ? { instructions: opts.instructions } : {}),
35
36
  };
36
37
  return {
37
38
  tools,
@@ -41,6 +42,7 @@ export function createMcpServer(opts) {
41
42
  features,
42
43
  ...(opts.health !== undefined ? { health: opts.health } : {}),
43
44
  ...(opts.maxBodyBytes !== undefined ? { maxBodyBytes: opts.maxBodyBytes } : {}),
45
+ ...(opts.allowedOrigins !== undefined ? { allowedOrigins: opts.allowedOrigins } : {}),
44
46
  }),
45
47
  handle: (message) => handleRpc(message, tools, serverInfo, features),
46
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EACL,SAAS,EAOT,OAAO,GACR,MAAM,eAAe,CAAA;AA4BtB,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;KAChE,CAAA;IACD,OAAO;QACL,KAAK;QACL,QAAQ;QACR,UAAU;QACV,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,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;SAChF,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,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EACL,SAAS,EAOT,OAAO,GACR,MAAM,eAAe,CAAA;AAiCtB,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,EAAE,CACjB,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;SACtF,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.0",
3
+ "version": "2.5.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",
package/src/http.ts CHANGED
@@ -10,15 +10,45 @@
10
10
  import {
11
11
  handleRpc,
12
12
  type JsonRpcRequest,
13
+ type JsonRpcResponse,
14
+ MCP_ERROR,
13
15
  type McpServerFeatures,
14
16
  type McpTool,
17
+ modernVersionOf,
15
18
  rpcError,
16
19
  } from "./protocol.ts"
17
20
 
18
- const CORS: Record<string, string> = {
19
- "access-control-allow-origin": "*",
21
+ // Headers on every response. `access-control-allow-headers` lists the request headers a browser MCP client
22
+ // (claude.ai, ChatGPT) actually sends: `mcp-protocol-version` (required per POST since 2025-06-18),
23
+ // `mcp-method`/`mcp-name` (the 2026-07-28 request-metadata mirror), `authorization` (OAuth-protected hosts),
24
+ // plus `accept`/`last-event-id`. Omit any and the CORS preflight fails, so the connector never loads.
25
+ const CORS_BASE: Record<string, string> = {
20
26
  "access-control-allow-methods": "POST, GET, OPTIONS",
21
- "access-control-allow-headers": "content-type",
27
+ "access-control-allow-headers":
28
+ "content-type, authorization, mcp-protocol-version, mcp-session-id, mcp-method, mcp-name, accept, last-event-id",
29
+ "access-control-expose-headers": "mcp-protocol-version, mcp-session-id",
30
+ "access-control-max-age": "86400",
31
+ }
32
+
33
+ /**
34
+ * Resolve the CORS/Origin headers for one request against the host's `allowedOrigins` policy, or `null`
35
+ * when the request's `Origin` is present but not allowed - the caller then answers 403, per the
36
+ * Streamable-HTTP DNS-rebinding rule ("Servers MUST validate the `Origin` header ... respond with 403").
37
+ * With no policy (the default) every origin is allowed and reflected as `*` - correct for a public,
38
+ * secret-free, unauthenticated server, whose browser clients send arbitrary origins we can't enumerate.
39
+ */
40
+ function corsFor(
41
+ request: Request,
42
+ allowedOrigins: readonly string[] | undefined,
43
+ ): Record<string, string> | null {
44
+ if (allowedOrigins === undefined) return { ...CORS_BASE, "access-control-allow-origin": "*" }
45
+ const origin = request.headers.get("origin")
46
+ // A caller with no Origin (curl, server-to-server) can't mount a DNS-rebinding attack - allow it.
47
+ if (origin === null) return { ...CORS_BASE, vary: "Origin" }
48
+ if (allowedOrigins.includes(origin)) {
49
+ return { ...CORS_BASE, "access-control-allow-origin": origin, vary: "Origin" }
50
+ }
51
+ return null
22
52
  }
23
53
 
24
54
  const DEFAULT_MAX_BODY_BYTES = 1_000_000
@@ -31,6 +61,12 @@ export interface McpHttpOptions {
31
61
  readonly features?: McpServerFeatures
32
62
  /** Shown on the GET health page so each host can describe itself. */
33
63
  readonly health?: string
64
+ /**
65
+ * Origin allowlist for the DNS-rebinding guard. Omit (the default) to allow any origin - the right
66
+ * choice for a public, unauthenticated docs server that can't enumerate its browser clients' origins.
67
+ * Set it (e.g. a localhost origin for a hardened local host) to reject any other browser origin with 403.
68
+ */
69
+ readonly allowedOrigins?: readonly string[]
34
70
  }
35
71
 
36
72
  function parseContentLength(value: string): number | undefined {
@@ -86,10 +122,69 @@ async function readJsonBounded(
86
122
  }
87
123
  }
88
124
 
125
+ const SENTINEL_PREFIX = "=?base64?"
126
+ const SENTINEL_SUFFIX = "?="
127
+
128
+ /** Decode the Streamable-HTTP `=?base64?...?=` header sentinel (used when a name/uri isn't header-safe).
129
+ * A plain value passes through; a malformed sentinel is returned as-is so validation still fails closed. */
130
+ function decodeSentinel(value: string | null): string | null {
131
+ if (value === null) return null
132
+ if (!value.startsWith(SENTINEL_PREFIX) || !value.endsWith(SENTINEL_SUFFIX)) return value
133
+ const encoded = value.slice(SENTINEL_PREFIX.length, value.length - SENTINEL_SUFFIX.length)
134
+ try {
135
+ return TEXT_DECODER.decode(Uint8Array.from(atob(encoded), (ch) => ch.charCodeAt(0)))
136
+ } catch {
137
+ return value
138
+ }
139
+ }
140
+
141
+ /** Validate a modern (2026-07-28) request's mirrored headers against its body: `MCP-Protocol-Version`,
142
+ * `Mcp-Method`, and - for name-bearing methods - `Mcp-Name` MUST match, else a `HeaderMismatch` the caller
143
+ * returns as 400. Stops an intermediary from routing on a header while the server acts on a different body. */
144
+ function modernHeaderMismatch(
145
+ request: Request,
146
+ message: JsonRpcRequest,
147
+ bodyVersion: string,
148
+ ): JsonRpcResponse | null {
149
+ const rid = message.id ?? null
150
+ const headerVersion = request.headers.get("mcp-protocol-version")
151
+ if (headerVersion === null || headerVersion !== bodyVersion) {
152
+ return rpcError(
153
+ rid,
154
+ MCP_ERROR.HEADER_MISMATCH,
155
+ "MCP-Protocol-Version header missing or mismatched",
156
+ )
157
+ }
158
+ const method = typeof message.method === "string" ? message.method : ""
159
+ const headerMethod = request.headers.get("mcp-method")
160
+ if (headerMethod === null || headerMethod !== method) {
161
+ return rpcError(rid, MCP_ERROR.HEADER_MISMATCH, "Mcp-Method header missing or mismatched")
162
+ }
163
+ if (method === "tools/call" || method === "resources/read" || method === "prompts/get") {
164
+ const bodyName = method === "resources/read" ? message.params?.uri : message.params?.name
165
+ const headerName = decodeSentinel(request.headers.get("mcp-name"))
166
+ if (headerName === null || typeof bodyName !== "string" || headerName !== bodyName) {
167
+ return rpcError(rid, MCP_ERROR.HEADER_MISMATCH, "Mcp-Name header missing or mismatched")
168
+ }
169
+ }
170
+ return null
171
+ }
172
+
173
+ /** HTTP status for a modern request's dispatch result: 400 for version/header errors, 404 for an unknown
174
+ * method, 200 otherwise (in-band tool errors are ordinary JSON-RPC results and stay 200). */
175
+ function modernErrorStatus(response: JsonRpcResponse): number {
176
+ if (!("error" in response)) return 200
177
+ const { code } = response.error
178
+ if (code === MCP_ERROR.UNSUPPORTED_VERSION || code === MCP_ERROR.HEADER_MISMATCH) return 400
179
+ return code === -32601 ? 404 : 200
180
+ }
181
+
89
182
  /**
90
183
  * Handle one MCP request over HTTP against the given `tools`/`features`. POST a JSON-RPC body → JSON-RPC
91
184
  * response; GET → a plain-text health page; OPTIONS → CORS preflight. Never throws - a bad body becomes a
92
- * JSON-RPC parse error. The dispatch is the shared, transport-agnostic {@link handleRpc}.
185
+ * JSON-RPC parse error. Dual-era: a modern (2026-07-28) POST that mirrors its method/name/version into
186
+ * headers is validated against the body before dispatch and gets spec HTTP statuses; legacy requests are
187
+ * served unchanged. The dispatch is the shared, transport-agnostic {@link handleRpc}.
93
188
  */
94
189
  export async function respondMcpHttp(
95
190
  request: Request,
@@ -97,18 +192,33 @@ export async function respondMcpHttp(
97
192
  serverInfo: { name: string; version: string },
98
193
  options: McpHttpOptions = {},
99
194
  ): Promise<Response> {
100
- if (request.method === "OPTIONS") return new Response(null, { status: 204, headers: CORS })
195
+ const cors = corsFor(request, options.allowedOrigins)
196
+ if (cors === null) {
197
+ // Origin present but not allowlisted: reject before the body is ever read (DNS-rebinding guard). No
198
+ // `id` (no request parsed) and no CORS headers - a disallowed origin gets nothing to work with.
199
+ return Response.json(rpcError(null, -32600, "origin not allowed"), { status: 403 })
200
+ }
201
+ if (request.method === "OPTIONS") return new Response(null, { status: 204, headers: cors })
101
202
  if (request.method === "GET") {
203
+ // The 2026-07-28 revision removed the GET SSE stream; a client probing for it (`Accept:
204
+ // text/event-stream`) gets 405 so its transport fallback fires. A plain browser/monitor GET still
205
+ // gets the human-readable health page.
206
+ if ((request.headers.get("accept") ?? "").includes("text/event-stream")) {
207
+ return new Response("event stream not supported", {
208
+ status: 405,
209
+ headers: { allow: "POST, GET", ...cors },
210
+ })
211
+ }
102
212
  return new Response(
103
213
  options.health ??
104
214
  "MCP server - POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call).",
105
- { headers: { "content-type": "text/plain; charset=utf-8", ...CORS } },
215
+ { headers: { "content-type": "text/plain; charset=utf-8", ...cors } },
106
216
  )
107
217
  }
108
218
  if (request.method !== "POST") {
109
219
  return new Response("method not allowed", {
110
220
  status: 405,
111
- headers: { allow: "POST, GET", ...CORS },
221
+ headers: { allow: "POST, GET", ...cors },
112
222
  })
113
223
  }
114
224
  const parsed = await readJsonBounded(request, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES)
@@ -116,16 +226,27 @@ export async function respondMcpHttp(
116
226
  if (parsed.status === 413) {
117
227
  return Response.json(rpcError(null, -32000, "payload too large"), {
118
228
  status: 413,
119
- headers: CORS,
229
+ headers: cors,
120
230
  })
121
231
  }
122
- return Response.json(rpcError(null, -32700, "parse error"), { status: 400, headers: CORS })
232
+ return Response.json(rpcError(null, -32700, "parse error"), { status: 400, headers: cors })
123
233
  }
124
234
  const message = parsed.value as JsonRpcRequest
235
+ const bodyVersion = modernVersionOf(message.params)
236
+ // Mirror the protocol version back for intermediaries (SHOULD, 2025-06-18+); absent is fine.
237
+ const echoVersion = request.headers.get("mcp-protocol-version")
238
+ const headers = echoVersion !== null ? { ...cors, "mcp-protocol-version": echoVersion } : cors
239
+ if (bodyVersion !== undefined) {
240
+ // Modern request: header/body mirror MUST agree. Reject divergence with 400 before dispatch.
241
+ const headerError = modernHeaderMismatch(request, message, bodyVersion)
242
+ if (headerError !== null) return Response.json(headerError, { status: 400, headers })
243
+ }
125
244
  const response = await handleRpc(message, tools, serverInfo, options.features ?? {}, {
126
245
  signal: request.signal,
127
246
  })
128
- // A notification (no id) yields null - acknowledge with 204, no body.
129
- if (response === null) return new Response(null, { status: 204, headers: CORS })
130
- return Response.json(response, { headers: CORS })
247
+ // A notification (no id) yields null - acknowledge with 202 Accepted and no body (Streamable-HTTP).
248
+ if (response === null) return new Response(null, { status: 202, headers })
249
+ // Modern requests carry spec HTTP statuses (400 version/header, 404 unknown method); legacy stays 200.
250
+ const status = bodyVersion !== undefined ? modernErrorStatus(response) : 200
251
+ return Response.json(response, { status, headers })
131
252
  }
package/src/protocol.ts CHANGED
@@ -10,7 +10,28 @@
10
10
  * it is additive - a tool whose handler returns a plain `string` behaves exactly as before.
11
11
  */
12
12
 
13
- export const PROTOCOL_VERSION = "2024-11-05"
13
+ /** The protocol revision this server advertises by default. A handshake-era version - the HTTP transport
14
+ * still uses `initialize`; current clients reach it through their backward-compatibility fallback.
15
+ * `initialize` echoes the client's own requested version instead when it's one this server also speaks
16
+ * ({@link SUPPORTED_PROTOCOL_VERSIONS}). */
17
+ export const PROTOCOL_VERSION = "2025-06-18"
18
+ /** The handshake-era revisions this server speaks. `initialize` echoes the client's requested
19
+ * `protocolVersion` when it's in this set (the smoothest negotiation), else answers {@link PROTOCOL_VERSION}. */
20
+ const SUPPORTED_PROTOCOL_VERSIONS = new Set([
21
+ "2024-11-05",
22
+ "2025-03-26",
23
+ "2025-06-18",
24
+ "2025-11-25",
25
+ ])
26
+
27
+ /** The stateless per-request revision (2026-07-28+). A request carrying its version in `_meta`
28
+ * (`io.modelcontextprotocol/protocolVersion`) is served in modern mode; an `initialize` request stays
29
+ * legacy. This server is dual-era: `handleRpc` answers both on the same dispatch, per request. */
30
+ export const MODERN_PROTOCOL_VERSION = "2026-07-28"
31
+ /** MCP-reserved JSON-RPC error codes (2026-07-28 error-code policy carves out -32020..-32099 for the spec). */
32
+ export const MCP_ERROR = { HEADER_MISMATCH: -32020, UNSUPPORTED_VERSION: -32022 } as const
33
+ const META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion"
34
+ const META_SERVER_INFO = "io.modelcontextprotocol/serverInfo"
14
35
 
15
36
  /** The MIME type a UI resource MUST use so a host recognizes it as an MCP App widget (SEP-1865). */
16
37
  export const UI_MIME = "text/html;profile=mcp-app"
@@ -103,6 +124,9 @@ export interface McpServerFeatures {
103
124
  /** Advertise the MCP Apps UI extension in `initialize`. Present when the server serves `ui://` widgets;
104
125
  * `mimeTypes` defaults to `[UI_MIME]`. */
105
126
  readonly ui?: { readonly mimeTypes?: readonly string[] }
127
+ /** Natural-language guidance for LLMs on how to use this server. Surfaced in the modern
128
+ * `server/discover` result (2026-07-28); legacy `initialize` does not carry it. */
129
+ readonly instructions?: string
106
130
  }
107
131
 
108
132
  export interface JsonRpcRequest {
@@ -120,17 +144,22 @@ export interface JsonRpcNotification {
120
144
 
121
145
  export type JsonRpcResponse =
122
146
  | { jsonrpc: "2.0"; id: JsonRpcId; result: unknown }
123
- | { jsonrpc: "2.0"; id: JsonRpcId; error: { code: number; message: string } }
147
+ | { jsonrpc: "2.0"; id: JsonRpcId; error: { code: number; message: string; data?: unknown } }
124
148
 
125
149
  export const rpcResult = (id: JsonRpcId, value: unknown): JsonRpcResponse => ({
126
150
  jsonrpc: "2.0",
127
151
  id,
128
152
  result: value,
129
153
  })
130
- export const rpcError = (id: JsonRpcId, code: number, message: string): JsonRpcResponse => ({
154
+ export const rpcError = (
155
+ id: JsonRpcId,
156
+ code: number,
157
+ message: string,
158
+ data?: unknown,
159
+ ): JsonRpcResponse => ({
131
160
  jsonrpc: "2.0",
132
161
  id,
133
- error: { code, message },
162
+ error: data !== undefined ? { code, message, data } : { code, message },
134
163
  })
135
164
 
136
165
  export interface McpProtocolState {
@@ -152,10 +181,24 @@ function requestKey(id: unknown): string | undefined {
152
181
  return typeof id === "number" && Number.isFinite(id) ? `n:${id}` : undefined
153
182
  }
154
183
 
155
- function progressTokenOf(params: Record<string, unknown> | undefined): ProgressToken | undefined {
184
+ function metaObject(
185
+ params: Record<string, unknown> | undefined,
186
+ ): Record<string, unknown> | undefined {
156
187
  const meta = params?._meta
157
- if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return undefined
158
- const token = (meta as Record<string, unknown>).progressToken
188
+ return typeof meta === "object" && meta !== null && !Array.isArray(meta)
189
+ ? (meta as Record<string, unknown>)
190
+ : undefined
191
+ }
192
+
193
+ /** The protocol version a modern (2026-07-28+) request declares in `_meta`, or `undefined` for a legacy
194
+ * request. Its presence is what puts the dispatch in modern mode for that one request. */
195
+ export function modernVersionOf(params: Record<string, unknown> | undefined): string | undefined {
196
+ const version = metaObject(params)?.[META_PROTOCOL_VERSION]
197
+ return typeof version === "string" ? version : undefined
198
+ }
199
+
200
+ function progressTokenOf(params: Record<string, unknown> | undefined): ProgressToken | undefined {
201
+ const token = metaObject(params)?.progressToken
159
202
  return typeof token === "string" || (typeof token === "number" && Number.isFinite(token))
160
203
  ? token
161
204
  : undefined
@@ -191,6 +234,29 @@ function compactDescription(description: string): string {
191
234
  return `${sentence.slice(0, 117).trimEnd()}...`
192
235
  }
193
236
 
237
+ /** Freshness hint for the static docs corpus - a modern client MAY cache list/read results this long. */
238
+ const DEFAULT_CACHE_TTL_MS = 3_600_000
239
+
240
+ /** Wrap a result in the 2026-07-28 completion envelope: `resultType`, a self-identifying `serverInfo`
241
+ * under `_meta`, and - for the cacheable list/read methods - a public freshness hint. Legacy results skip
242
+ * this entirely and keep their exact pre-2026-07-28 shape. */
243
+ function withEnvelope(
244
+ value: Record<string, unknown>,
245
+ serverInfo: { name: string; version: string },
246
+ cacheable: boolean,
247
+ ): Record<string, unknown> {
248
+ const existingMeta =
249
+ typeof value._meta === "object" && value._meta !== null && !Array.isArray(value._meta)
250
+ ? (value._meta as Record<string, unknown>)
251
+ : undefined
252
+ return {
253
+ ...value,
254
+ resultType: "complete",
255
+ _meta: { ...(existingMeta ?? {}), [META_SERVER_INFO]: serverInfo },
256
+ ...(cacheable ? { ttlMs: DEFAULT_CACHE_TTL_MS, cacheScope: "public" } : {}),
257
+ }
258
+ }
259
+
194
260
  /** Normalize a handler's return into the `tools/call` result object. A `string` becomes a single text
195
261
  * block (base-MCP behavior, unchanged); a {@link McpToolResult} passes `content`/`structuredContent`
196
262
  * through, and inherits the tool descriptor's `_meta` (the `ui.resourceUri` link) when it sets none. */
@@ -228,10 +294,32 @@ export async function handleRpc(
228
294
  const prompts = features.prompts ?? []
229
295
  const state = options.state ?? createMcpProtocolState()
230
296
 
297
+ // A request that declares its version in `_meta` is a modern (2026-07-28+) request. We speak exactly one
298
+ // modern revision; any other declared version is rejected so the client can retry with a supported one.
299
+ const requestedVersion = modernVersionOf(params)
300
+ const isModern = requestedVersion !== undefined
301
+ if (isModern && requestedVersion !== MODERN_PROTOCOL_VERSION) {
302
+ return rpcError(rid, MCP_ERROR.UNSUPPORTED_VERSION, "Unsupported protocol version", {
303
+ supported: [MODERN_PROTOCOL_VERSION],
304
+ requested: requestedVersion,
305
+ })
306
+ }
307
+ // Modern results carry the completion envelope; legacy results keep their exact prior shape. Every data
308
+ // case returns through `reply` so the one `isModern` decision drives the whole response shape.
309
+ const reply = (value: Record<string, unknown>, cacheable = false): JsonRpcResponse =>
310
+ rpcResult(rid, isModern ? withEnvelope(value, serverInfo, cacheable) : value)
311
+
231
312
  switch (method) {
232
- case "initialize":
313
+ case "initialize": {
314
+ // Handshake version negotiation: answer with the client's requested version when we speak it too,
315
+ // otherwise our default. The client then decides whether our answer is acceptable.
316
+ const requested = params?.protocolVersion
317
+ const protocolVersion =
318
+ typeof requested === "string" && SUPPORTED_PROTOCOL_VERSIONS.has(requested)
319
+ ? requested
320
+ : PROTOCOL_VERSION
233
321
  return rpcResult(rid, {
234
- protocolVersion: PROTOCOL_VERSION,
322
+ protocolVersion,
235
323
  capabilities: {
236
324
  tools: {},
237
325
  ...(resources.length > 0 ? { resources: {} } : {}),
@@ -246,6 +334,33 @@ export async function handleRpc(
246
334
  },
247
335
  serverInfo,
248
336
  })
337
+ }
338
+ case "server/discover":
339
+ // The modern capability/identity probe (replaces `initialize` for 2026-07-28 clients). Always
340
+ // enveloped and cacheable - it is a modern-only RPC.
341
+ return rpcResult(
342
+ rid,
343
+ withEnvelope(
344
+ {
345
+ supportedVersions: [MODERN_PROTOCOL_VERSION],
346
+ capabilities: {
347
+ tools: {},
348
+ ...(resources.length > 0 ? { resources: {} } : {}),
349
+ ...(prompts.length > 0 ? { prompts: {} } : {}),
350
+ ...(features.ui !== undefined
351
+ ? {
352
+ extensions: {
353
+ [UI_EXTENSION_KEY]: { mimeTypes: features.ui.mimeTypes ?? [UI_MIME] },
354
+ },
355
+ }
356
+ : {}),
357
+ },
358
+ ...(features.instructions !== undefined ? { instructions: features.instructions } : {}),
359
+ },
360
+ serverInfo,
361
+ true,
362
+ ),
363
+ )
249
364
  case "notifications/initialized":
250
365
  return null
251
366
  case "notifications/cancelled": {
@@ -256,8 +371,7 @@ export async function handleRpc(
256
371
  case "ping":
257
372
  return rpcResult(rid, {})
258
373
  case "tools/list":
259
- return rpcResult(
260
- rid,
374
+ return reply(
261
375
  params?.compact === true
262
376
  ? {
263
377
  tools: tools.map((t) => ({
@@ -274,12 +388,13 @@ export async function handleRpc(
274
388
  ...(t._meta !== undefined ? { _meta: t._meta } : {}),
275
389
  })),
276
390
  },
391
+ true,
277
392
  )
278
393
  case "tools/describe": {
279
394
  const name = params?.name
280
395
  const tool = tools.find((t) => t.name === name)
281
396
  if (!tool) return rpcError(rid, -32602, `unknown tool: ${String(name)}`)
282
- return rpcResult(rid, {
397
+ return reply({
283
398
  tool: {
284
399
  name: tool.name,
285
400
  description: tool.description,
@@ -331,16 +446,16 @@ export async function handleRpc(
331
446
  })
332
447
  if (controller.signal.aborted) throw new DOMException("cancelled", "AbortError")
333
448
  reportProgress(1, 1)
334
- return rpcResult(rid, toolCallResult(result, tool))
449
+ return reply(toolCallResult(result, tool))
335
450
  } catch (err) {
336
451
  if (controller.signal.aborted) {
337
- return rpcResult(rid, {
452
+ return reply({
338
453
  content: [{ type: "text", text: abortMessage(controller.signal) }],
339
454
  isError: true,
340
455
  })
341
456
  }
342
457
  const msg = err instanceof Error ? err.message : String(err)
343
- return rpcResult(rid, { content: [{ type: "text", text: `Error: ${msg}` }], isError: true })
458
+ return reply({ content: [{ type: "text", text: `Error: ${msg}` }], isError: true })
344
459
  } finally {
345
460
  cleanupAbort()
346
461
  if (key !== undefined && state.activeRequests.get(key) === controller) {
@@ -349,51 +464,60 @@ export async function handleRpc(
349
464
  }
350
465
  }
351
466
  case "resources/list":
352
- return rpcResult(rid, {
353
- resources: resources.map((r) => ({
354
- uri: r.uri,
355
- name: r.name,
356
- ...(r.description !== undefined ? { description: r.description } : {}),
357
- ...(r.mimeType !== undefined ? { mimeType: r.mimeType } : {}),
358
- ...(r._meta !== undefined ? { _meta: r._meta } : {}),
359
- })),
360
- })
467
+ return reply(
468
+ {
469
+ resources: resources.map((r) => ({
470
+ uri: r.uri,
471
+ name: r.name,
472
+ ...(r.description !== undefined ? { description: r.description } : {}),
473
+ ...(r.mimeType !== undefined ? { mimeType: r.mimeType } : {}),
474
+ ...(r._meta !== undefined ? { _meta: r._meta } : {}),
475
+ })),
476
+ },
477
+ true,
478
+ )
361
479
  case "resources/read": {
362
480
  const uri = params?.uri
363
481
  const resource = resources.find((r) => r.uri === uri)
364
482
  if (!resource) return rpcError(rid, -32602, `unknown resource: ${String(uri)}`)
365
483
  try {
366
484
  const content = await resource.read()
367
- return rpcResult(rid, {
368
- contents: [
369
- {
370
- uri: resource.uri,
371
- mimeType: content.mimeType ?? resource.mimeType ?? "text/plain",
372
- text: content.text,
373
- ...(resource._meta !== undefined ? { _meta: resource._meta } : {}),
374
- },
375
- ],
376
- })
485
+ return reply(
486
+ {
487
+ contents: [
488
+ {
489
+ uri: resource.uri,
490
+ mimeType: content.mimeType ?? resource.mimeType ?? "text/plain",
491
+ text: content.text,
492
+ ...(resource._meta !== undefined ? { _meta: resource._meta } : {}),
493
+ },
494
+ ],
495
+ },
496
+ true,
497
+ )
377
498
  } catch {
378
499
  // Don't surface the raw read error - it can leak a filesystem path. Return a generic message.
379
500
  return rpcError(rid, -32000, `failed to read resource: ${String(uri)}`)
380
501
  }
381
502
  }
382
503
  case "prompts/list":
383
- return rpcResult(rid, {
384
- prompts: prompts.map((p) => ({
385
- name: p.name,
386
- description: p.description,
387
- ...(p.arguments !== undefined ? { arguments: p.arguments } : {}),
388
- })),
389
- })
504
+ return reply(
505
+ {
506
+ prompts: prompts.map((p) => ({
507
+ name: p.name,
508
+ description: p.description,
509
+ ...(p.arguments !== undefined ? { arguments: p.arguments } : {}),
510
+ })),
511
+ },
512
+ true,
513
+ )
390
514
  case "prompts/get": {
391
515
  const name = params?.name
392
516
  const prompt = prompts.find((p) => p.name === name)
393
517
  if (!prompt) return rpcError(rid, -32602, `unknown prompt: ${String(name)}`)
394
518
  const args = (params?.arguments as Record<string, unknown>) ?? {}
395
519
  try {
396
- return rpcResult(rid, {
520
+ return reply({
397
521
  description: prompt.description,
398
522
  messages: await prompt.handler(args),
399
523
  })
package/src/server.ts CHANGED
@@ -46,6 +46,11 @@ export interface CreateMcpServerOptions {
46
46
  readonly health?: string
47
47
  /** Max JSON-RPC body size in bytes (default 1 MB). */
48
48
  readonly maxBodyBytes?: number
49
+ /** Natural-language guidance for LLMs, surfaced in the modern `server/discover` result (2026-07-28). */
50
+ readonly instructions?: string
51
+ /** Origin allowlist for the DNS-rebinding guard. Omit to allow any origin; set it to reject other
52
+ * browser origins with 403 (e.g. a hardened, non-public mount). */
53
+ readonly allowedOrigins?: readonly string[]
49
54
  }
50
55
 
51
56
  export interface McpServer {
@@ -69,6 +74,7 @@ export function createMcpServer(opts: CreateMcpServerOptions): McpServer {
69
74
  ...(resources.length > 0 ? { resources } : {}),
70
75
  ...(opts.prompts !== undefined ? { prompts: opts.prompts } : {}),
71
76
  ...(widgets.length > 0 ? { ui: { mimeTypes: [UI_MIME] } } : {}),
77
+ ...(opts.instructions !== undefined ? { instructions: opts.instructions } : {}),
72
78
  }
73
79
  return {
74
80
  tools,
@@ -79,6 +85,7 @@ export function createMcpServer(opts: CreateMcpServerOptions): McpServer {
79
85
  features,
80
86
  ...(opts.health !== undefined ? { health: opts.health } : {}),
81
87
  ...(opts.maxBodyBytes !== undefined ? { maxBodyBytes: opts.maxBodyBytes } : {}),
88
+ ...(opts.allowedOrigins !== undefined ? { allowedOrigins: opts.allowedOrigins } : {}),
82
89
  }),
83
90
  handle: (message) => handleRpc(message, tools, serverInfo, features),
84
91
  }