@ni-c/mcp-hub 0.9.2 → 0.11.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +619 -0
  2. package/README.md +189 -64
  3. package/dist/admin.js +232 -8
  4. package/dist/admin.js.map +1 -1
  5. package/dist/auth/address.js +89 -0
  6. package/dist/auth/address.js.map +1 -0
  7. package/dist/auth/api-tokens.js +27 -0
  8. package/dist/auth/api-tokens.js.map +1 -0
  9. package/dist/auth/cimd.js +367 -0
  10. package/dist/auth/cimd.js.map +1 -0
  11. package/dist/auth/consent-page.js +4 -7
  12. package/dist/auth/consent-page.js.map +1 -1
  13. package/dist/auth/headers.js +22 -1
  14. package/dist/auth/headers.js.map +1 -1
  15. package/dist/auth/login-page.js +4 -7
  16. package/dist/auth/login-page.js.map +1 -1
  17. package/dist/auth/oidc/adapter.js +135 -0
  18. package/dist/auth/oidc/adapter.js.map +1 -0
  19. package/dist/auth/oidc/interactions.js +187 -0
  20. package/dist/auth/oidc/interactions.js.map +1 -0
  21. package/dist/auth/oidc/mount.js +144 -0
  22. package/dist/auth/oidc/mount.js.map +1 -0
  23. package/dist/auth/oidc/provider.js +440 -0
  24. package/dist/auth/oidc/provider.js.map +1 -0
  25. package/dist/auth/oidc/quirks.js +234 -0
  26. package/dist/auth/oidc/quirks.js.map +1 -0
  27. package/dist/auth/oidc/verifier.js +121 -0
  28. package/dist/auth/oidc/verifier.js.map +1 -0
  29. package/dist/auth/page.js +22 -0
  30. package/dist/auth/page.js.map +1 -1
  31. package/dist/auth/pinned-fetch.js +129 -0
  32. package/dist/auth/pinned-fetch.js.map +1 -0
  33. package/dist/auth/protected-resource.js +41 -0
  34. package/dist/auth/protected-resource.js.map +1 -0
  35. package/dist/auth/rate-limit.js +156 -0
  36. package/dist/auth/rate-limit.js.map +1 -0
  37. package/dist/auth/redirect-uri.js +90 -0
  38. package/dist/auth/redirect-uri.js.map +1 -0
  39. package/dist/auth/registration.js +146 -0
  40. package/dist/auth/registration.js.map +1 -0
  41. package/dist/auth/session.js +43 -0
  42. package/dist/auth/session.js.map +1 -0
  43. package/dist/auth/signed-token.js +49 -0
  44. package/dist/auth/signed-token.js.map +1 -0
  45. package/dist/auth/store.js +516 -5
  46. package/dist/auth/store.js.map +1 -1
  47. package/dist/auth/text.js +51 -0
  48. package/dist/auth/text.js.map +1 -0
  49. package/dist/config.js +184 -5
  50. package/dist/config.js.map +1 -1
  51. package/dist/docker-proxy/policy.js +1 -0
  52. package/dist/docker-proxy/policy.js.map +1 -1
  53. package/dist/docker-proxy/server.js +1 -0
  54. package/dist/docker-proxy/server.js.map +1 -1
  55. package/dist/elicitation.js +0 -0
  56. package/dist/elicitation.js.map +1 -0
  57. package/dist/forward.js +0 -0
  58. package/dist/forward.js.map +1 -0
  59. package/dist/health.js +22 -3
  60. package/dist/health.js.map +1 -1
  61. package/dist/hub.js +337 -29
  62. package/dist/hub.js.map +1 -1
  63. package/dist/index.js +218 -23
  64. package/dist/index.js.map +1 -1
  65. package/dist/limits.js +13 -1
  66. package/dist/limits.js.map +1 -1
  67. package/dist/mcp-limits.js +14 -2
  68. package/dist/mcp-limits.js.map +1 -1
  69. package/dist/proxy.js +262 -34
  70. package/dist/proxy.js.map +1 -1
  71. package/dist/stdio.js +97 -7
  72. package/dist/stdio.js.map +1 -1
  73. package/dist/subscriptions.js +236 -0
  74. package/dist/subscriptions.js.map +1 -0
  75. package/dist/supervisor.js +472 -28
  76. package/dist/supervisor.js.map +1 -1
  77. package/dist/timings.js +61 -0
  78. package/dist/timings.js.map +1 -0
  79. package/dist/tool-filter.js +59 -0
  80. package/dist/tool-filter.js.map +1 -0
  81. package/dist/transports/docker.js.map +1 -1
  82. package/dist/transports/stream.js +33 -20
  83. package/dist/transports/stream.js.map +1 -1
  84. package/dist/upstream/auth.js +435 -0
  85. package/dist/upstream/auth.js.map +1 -0
  86. package/dist/upstream/login.js +94 -0
  87. package/dist/upstream/login.js.map +1 -0
  88. package/dist/upstream/provider.js +286 -0
  89. package/dist/upstream/provider.js.map +1 -0
  90. package/dist/upstream/routes.js +97 -0
  91. package/dist/upstream/routes.js.map +1 -0
  92. package/package.json +23 -7
  93. package/dist/auth/provider.js +0 -380
  94. package/dist/auth/provider.js.map +0 -1
  95. package/dist/auth/routes.js +0 -223
  96. package/dist/auth/routes.js.map +0 -1
package/dist/proxy.js CHANGED
@@ -1,25 +1,64 @@
1
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
3
- import { CallToolRequestSchema, CallToolResultSchema, CompleteRequestSchema, CompleteResultSchema, GetPromptRequestSchema, GetPromptResultSchema, ListPromptsRequestSchema, ListPromptsResultSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ListToolsRequestSchema, ListToolsResultSchema, ReadResourceRequestSchema, ReadResourceResultSchema } from '@modelcontextprotocol/sdk/types.js';
1
+ import { CompleteResultSchema, GetPromptResultSchema, ListPromptsResultSchema, ListResourcesResultSchema, ListResourceTemplatesResultSchema, ListToolsResultSchema, ReadResourceResultSchema } from '@modelcontextprotocol/core';
2
+ import { NodeStreamableHTTPServerTransport, toNodeHandler, toWebRequest } from '@modelcontextprotocol/node';
3
+ import { Server, ProtocolError, ProtocolErrorCode, createMcpHandler, isInputRequiredResult, isLegacyRequest } from '@modelcontextprotocol/server';
4
4
  import { ABSOLUTE_CALL_OPTIONS, assertForwardedResultSize } from './mcp-limits.js';
5
+ import { filterTools, loggableToolName, toolAllowed } from './tool-filter.js';
6
+ import { forwardToolCall } from './forward.js';
7
+ import { KEEPALIVE_MS, MAX_STREAM_MS, MAX_SUBSCRIPTIONS, MAX_SUBSCRIPTION_URIS, SubscriptionRegistry, isListenRequest, parseListenFilter, subscriptionsAllowed } from './subscriptions.js';
8
+ /**
9
+ * The revision each era puts on the wire.
10
+ *
11
+ * Only ever read to *tell* somebody which one they are on; nothing branches on
12
+ * the string. `Era` stays the type everything else is written against, because
13
+ * a revision date is a fact about the wire and an era is a fact about
14
+ * behaviour, and the code cares about the second one.
15
+ */
16
+ export const REVISION = { modern: '2026-07-28', legacy: '2025-11-25' };
5
17
  /**
6
18
  * The child's capabilities minus what this proxy does not actually serve.
7
19
  *
8
- * resources.subscribe is dropped: there is no Subscribe handler below, so a
9
- * client that believed the advertisement got -32601 at call time. Announcing
10
- * only what we answer is the difference between a missing feature and a lie.
20
+ * The rule is one sentence: announce only what we answer. Three claims are
21
+ * decided here, and each used to be decided the other way.
22
+ *
23
+ * `listChanged` and `resources.subscribe` now survive — but only on the era
24
+ * that carries them. A 2026-07-28 client opens a `subscriptions/listen` stream
25
+ * and the hub delivers on it; a 2025 client would need `resources/subscribe`
26
+ * and an unsolicited server-to-client channel, and gets neither, so it is told
27
+ * neither. The 2025 side is the behaviour that shipped before, now stated
28
+ * rather than assumed.
29
+ *
30
+ * `logging` goes on both eras. `logging/setLevel` has no handler and never
31
+ * had one, so a client that believed the advertisement got a -32601 at call
32
+ * time — the exact shape of the bug `resources.subscribe` used to have. On
33
+ * 2026-07-28 the level is per-request `_meta` and there is no RPC to implement;
34
+ * carrying `notifications/message` is a separate piece of work, and until it
35
+ * exists the honest answer is silence.
11
36
  *
12
- * listChanged deliberately stays. Forwarding server-initiated messages needs
13
- * per-client session state, which the stateless transport exists to avoid, so
14
- * the notification never arrives — but a client waiting for one that never
15
- * comes is no worse off than a client that was never told. It is listed under
16
- * the known gaps in the documentation instead.
37
+ * A server whose operator set `subscriptions: "off"` is treated exactly like a
38
+ * 2025 connection here. Withdrawing the delivery without withdrawing the claim
39
+ * would just recreate the lie one config key lower down.
17
40
  */
18
- function advertisedCapabilities(capabilities) {
19
- const caps = { ...(capabilities ?? {}) };
41
+ function advertisedCapabilities(capabilities, era, allowed) {
42
+ const caps = { ...capabilities };
43
+ delete caps.logging;
44
+ const pushes = era === 'modern' && allowed;
45
+ // `listChanged: false` and an absent key mean the same thing to a client, and
46
+ // the absent one is what the specification shows, so drop rather than negate.
47
+ if (caps.tools) {
48
+ const { listChanged, ...rest } = caps.tools;
49
+ caps.tools = pushes && listChanged ? { ...rest, listChanged } : rest;
50
+ }
51
+ if (caps.prompts) {
52
+ const { listChanged, ...rest } = caps.prompts;
53
+ caps.prompts = pushes && listChanged ? { ...rest, listChanged } : rest;
54
+ }
20
55
  if (caps.resources) {
21
- const { subscribe: _subscribe, ...resources } = caps.resources;
22
- caps.resources = resources;
56
+ const { listChanged, subscribe, ...rest } = caps.resources;
57
+ caps.resources = {
58
+ ...rest,
59
+ ...(pushes && listChanged ? { listChanged } : {}),
60
+ ...(pushes && subscribe ? { subscribe } : {})
61
+ };
23
62
  }
24
63
  return caps;
25
64
  }
@@ -29,23 +68,35 @@ function advertisedCapabilities(capabilities) {
29
68
  * transport means no server-side session state at all — claude.ai reconnects
30
69
  * every few minutes without ever closing sessions, so anything stateful leaks.
31
70
  */
32
- function buildProxyServer(managed) {
33
- const server = new Server({ name: managed.serverInfo?.name ?? managed.name, version: managed.serverInfo?.version ?? '0.0.0' }, { capabilities: advertisedCapabilities(managed.capabilities) });
34
- const forwardLive = (request, resultSchema) => {
71
+ function buildProxyServer(managed, secret, era) {
72
+ const server = new Server({ name: managed.serverInfo?.name ?? managed.name, version: managed.serverInfo?.version ?? '0.0.0' }, { capabilities: advertisedCapabilities(managed.capabilities, era, subscriptionsAllowed(managed.config)) });
73
+ /**
74
+ * Forwards one request and hands back exactly what the schema describes.
75
+ *
76
+ * Generic over the schema rather than typed against a union of all of them:
77
+ * v2's request handlers are typed per method, so a `Promise<unknown>` here
78
+ * fails to assign at all eight call sites below. Inferring the result type
79
+ * from the schema is also the honest description — this returns the child's
80
+ * answer, parsed by the schema the caller chose.
81
+ */
82
+ const forwardLive = (request, resultSchema, options = {}) => {
35
83
  const client = managed.client;
36
84
  if (!client)
37
85
  throw new Error(`Server "${managed.name}" is not running`);
38
86
  return client
39
- .request(request, resultSchema, ABSOLUTE_CALL_OPTIONS)
87
+ .request(request, resultSchema, {
88
+ ...ABSOLUTE_CALL_OPTIONS,
89
+ ...options
90
+ })
40
91
  .then(assertForwardedResultSize);
41
92
  };
42
93
  // Real usage: wakes a sleeping on-demand server (blocking until it is up)
43
94
  // and resets its idle window. Everything else is answered without a child.
44
- const use = async (request, resultSchema) => {
95
+ const use = async (request, resultSchema, options = {}) => {
45
96
  if (managed.state !== 'up' || !managed.client)
46
97
  await managed.wake();
47
98
  managed.markUsed();
48
- return forwardLive(request, resultSchema);
99
+ return forwardLive(request, resultSchema, options);
49
100
  };
50
101
  const caps = managed.capabilities ?? {};
51
102
  if (caps.tools) {
@@ -53,27 +104,87 @@ function buildProxyServer(managed) {
53
104
  // all hub paths configured enumerates them on connect, so answering from
54
105
  // the cached snapshot (instead of waking) is what keeps a fleet of
55
106
  // sleeping servers asleep. Neither branch counts as usage.
56
- server.setRequestHandler(ListToolsRequestSchema, req => managed.state === 'up' && managed.client ? forwardLive(req, ListToolsResultSchema) : Promise.resolve({ tools: managed.tools }));
57
- server.setRequestHandler(CallToolRequestSchema, req => use(req, CallToolResultSchema));
107
+ server.setRequestHandler('tools/list', async (req) => {
108
+ // managed.tools is filtered on the way in, but the live branch forwards
109
+ // the upstream's own answer and never consults it — so it has to filter
110
+ // too. Missing this is the obvious bug here: the filter would appear to
111
+ // work on a sleeping server and vanish the moment it woke.
112
+ if (managed.state !== 'up' || !managed.client)
113
+ return { tools: managed.tools };
114
+ const live = (await forwardLive(req, ListToolsResultSchema));
115
+ return { ...live, tools: filterTools(managed.config, live.tools) };
116
+ });
117
+ server.setRequestHandler('tools/call', async (req, ctx) => {
118
+ // Hiding is not a boundary on this path: the hub forwards by name, so a
119
+ // client holding a stale schema would still reach it. Refused before the
120
+ // forward, which is what wakes a sleeping server — so a forbidden name
121
+ // cannot start one. The message is the neutral one a server gives for a
122
+ // tool it does not have; announcing what was hidden would be a
123
+ // disclosure in itself.
124
+ if (!toolAllowed(managed.config, req.params.name)) {
125
+ const logged = loggableToolName(req.params.name);
126
+ console.warn(`[${managed.name}] refused tools/call "${logged}": not permitted by allowTools/denyTools`);
127
+ throw new ProtocolError(ProtocolErrorCode.MethodNotFound, `Unknown tool: ${req.params.name}`);
128
+ }
129
+ // The caller's params go on unchanged: a gateway that rewrote them would
130
+ // be inventing a contract the child never agreed to.
131
+ const result = await forwardToolCall({ managed, tool: req.params.name, params: req.params, ctx, secret, via: 'server' });
132
+ // A question for the person is not a tool result and has no schema to be
133
+ // projected against.
134
+ if (isInputRequiredResult(result))
135
+ return result;
136
+ /**
137
+ * The projection `McpServer` does for its own tools, which a hand-written
138
+ * handler has to do for itself.
139
+ *
140
+ * It matters for one case, and only because this is a gateway: a child
141
+ * whose `outputSchema` describes a non-object — an array, a number — is
142
+ * advertised to a 2025-era client with that schema rewritten to
143
+ * `{result: …}`, because that revision has nowhere else to put it. The
144
+ * hub was already doing that half, for free, in `encodeResult`. Without
145
+ * this line the *value* went out unwrapped, so the client validated an
146
+ * array against a schema saying "object with a result key" and rejected
147
+ * data that was never wrong.
148
+ *
149
+ * The advertised schema is the child's own, before the rewrite: the
150
+ * codec decides from its root shape whether the wrap applies at all.
151
+ */
152
+ const advertised = managed.tools.find(t => t.name === req.params.name)?.outputSchema;
153
+ return server.projectCallToolResult(result, advertised);
154
+ });
58
155
  }
59
156
  if (caps.resources) {
60
- server.setRequestHandler(ListResourcesRequestSchema, req => use(req, ListResourcesResultSchema));
61
- server.setRequestHandler(ListResourceTemplatesRequestSchema, req => use(req, ListResourceTemplatesResultSchema));
62
- server.setRequestHandler(ReadResourceRequestSchema, req => use(req, ReadResourceResultSchema));
157
+ server.setRequestHandler('resources/list', req => use(req, ListResourcesResultSchema));
158
+ server.setRequestHandler('resources/templates/list', req => use(req, ListResourceTemplatesResultSchema));
159
+ server.setRequestHandler('resources/read', req => use(req, ReadResourceResultSchema));
63
160
  }
64
161
  if (caps.prompts) {
65
- server.setRequestHandler(ListPromptsRequestSchema, req => use(req, ListPromptsResultSchema));
66
- server.setRequestHandler(GetPromptRequestSchema, req => use(req, GetPromptResultSchema));
162
+ server.setRequestHandler('prompts/list', req => use(req, ListPromptsResultSchema));
163
+ server.setRequestHandler('prompts/get', req => use(req, GetPromptResultSchema));
67
164
  }
68
165
  if (caps.completions) {
69
- server.setRequestHandler(CompleteRequestSchema, req => use(req, CompleteResultSchema));
166
+ server.setRequestHandler('completion/complete', req => use(req, CompleteResultSchema));
70
167
  }
71
168
  return server;
72
169
  }
73
- /** Handle one Streamable-HTTP request against an MCP Server built on the fly. */
74
- export async function handleMcpRequest(buildServer, req, res) {
170
+ /**
171
+ * The 2025-era path, unchanged: one `Server` and one stateless transport per
172
+ * HTTP request, both closed when the response closes.
173
+ *
174
+ * Kept as its own function rather than folded into the modern handler's
175
+ * `legacy: 'stateless'` fallback, because the two are not the same on the wire.
176
+ * That fallback answers GET and DELETE with `405`; this transport answers a GET
177
+ * with an open `text/event-stream` and a DELETE with `200`. claude.ai opens such
178
+ * a stream on every reconnect — which is why `ClientRequestGate` counts GETs
179
+ * separately in the first place — so switching it to `405` would be a visible
180
+ * change to the one client the stateless design was built around. The stream
181
+ * carries nothing today, but "carries nothing" and "is refused" are different
182
+ * answers, and this is not the change in which to find out how clients tell them
183
+ * apart.
184
+ */
185
+ async function handleLegacyRequest(buildServer, req, res) {
75
186
  const server = buildServer();
76
- const transport = new StreamableHTTPServerTransport({
187
+ const transport = new NodeStreamableHTTPServerTransport({
77
188
  sessionIdGenerator: undefined,
78
189
  enableJsonResponse: true
79
190
  });
@@ -84,8 +195,120 @@ export async function handleMcpRequest(buildServer, req, res) {
84
195
  await server.connect(transport);
85
196
  await transport.handleRequest(req, res, req.body);
86
197
  }
198
+ export function createRoute(buildServer, options) {
199
+ const allowSubscriptions = options.allowSubscriptions ?? (() => true);
200
+ const handler = createMcpHandler(() => buildServer('modern'), {
201
+ // Strict: the legacy era is served below, by the transport that has always
202
+ // served it. A second, differently-behaving legacy path underneath this one
203
+ // would be unreachable and misleading.
204
+ legacy: 'reject',
205
+ // Set rather than inherited. These bound what one route may hold open on
206
+ // the hub's behalf, and a limit nobody wrote down is a limit nobody can
207
+ // raise when a deployment needs it.
208
+ maxSubscriptions: MAX_SUBSCRIPTIONS,
209
+ keepAliveMs: KEEPALIVE_MS,
210
+ onerror: error => console.error(`mcp-hub: modern-era request failed on ${options.label}: ${error.message}`)
211
+ });
212
+ const registry = new SubscriptionRegistry(handler.notify, { onDemandChange: options.onDemandChange });
213
+ return {
214
+ handler,
215
+ registry,
216
+ allowSubscriptions,
217
+ buildLegacyServer: () => buildServer('legacy'),
218
+ close: async () => {
219
+ registry.close();
220
+ await handler.close();
221
+ }
222
+ };
223
+ }
224
+ /**
225
+ * Take a lease for a `subscriptions/listen` stream, or answer it outright.
226
+ *
227
+ * The filter has to be read here rather than left to the SDK: the event bus is
228
+ * publish-only and never reports which URIs a stream asked for, so this is the
229
+ * hub's only chance to learn what to hold upstream. The SDK still parses the
230
+ * request properly a moment later and owns every error answer — the one refusal
231
+ * made here is the URI cap, which is the hub's limit and nobody else's.
232
+ *
233
+ * Returns false when the request has already been answered.
234
+ */
235
+ function beginListen(route, req, res) {
236
+ const filter = parseListenFilter(req.body);
237
+ if (filter.resourceSubscriptions.length > MAX_SUBSCRIPTION_URIS) {
238
+ res.status(400).json({
239
+ jsonrpc: '2.0',
240
+ error: { code: -32602, message: `A subscription may name at most ${MAX_SUBSCRIPTION_URIS} resource URIs` },
241
+ id: null
242
+ });
243
+ return false;
244
+ }
245
+ // Node's server-wide requestTimeout (310s by default) would otherwise cut
246
+ // every listen stream a few minutes in, which looks exactly like a flaky
247
+ // upstream and is not. A listening stream is idle by design; its lifetime is
248
+ // bounded by MAX_STREAM_MS below instead.
249
+ req.setTimeout(0);
250
+ const reaper = MAX_STREAM_MS > 0
251
+ ? setTimeout(() => {
252
+ // Ends the stream without the specification's graceful completion
253
+ // result — the SDK owns the stream and offers no hook for one. The
254
+ // client sees the same unexpected disconnect an HTTP timeout would
255
+ // produce, which the specification names as a way a subscription
256
+ // ends, and re-listens.
257
+ res.end();
258
+ }, MAX_STREAM_MS)
259
+ : undefined;
260
+ reaper?.unref();
261
+ // A server whose operator switched subscriptions off advertises nothing and
262
+ // is asked for nothing, so the stream stays open and silent rather than
263
+ // taking a lease that would make the hub subscribe upstream on its behalf.
264
+ const lease = route.allowSubscriptions() ? route.registry.acquire(filter) : undefined;
265
+ let done = false;
266
+ const release = () => {
267
+ if (done)
268
+ return;
269
+ done = true;
270
+ clearTimeout(reaper);
271
+ lease?.release();
272
+ };
273
+ res.once('close', release);
274
+ res.once('finish', release);
275
+ return true;
276
+ }
277
+ /**
278
+ * Handle one MCP request in whichever protocol era it arrives in.
279
+ *
280
+ * `isLegacyRequest` decides, and its contract is one-way: everything it calls
281
+ * false — including a malformed envelope or a header/body mismatch — belongs to
282
+ * the modern handler, which owns those error answers. Only what it calls true
283
+ * may reach the legacy path.
284
+ */
285
+ export async function handleMcpRequest(route, req, res) {
286
+ const probe = await toWebRequest(req, req.body);
287
+ if (await isLegacyRequest(probe)) {
288
+ await handleLegacyRequest(route.buildLegacyServer, req, res);
289
+ return;
290
+ }
291
+ if (isListenRequest(req.body) && !beginListen(route, req, res))
292
+ return;
293
+ await toNodeHandler(route.handler)(req, res, req.body);
294
+ }
295
+ /**
296
+ * The route behind each server path, created on first use and closed with the
297
+ * server. Held here rather than constructed per request because the handler
298
+ * inside owns open subscription streams.
299
+ */
300
+ function routeFor(managed, secret) {
301
+ if (!managed.channel) {
302
+ managed.channel = createRoute(era => buildProxyServer(managed, secret, era), {
303
+ label: `/${managed.name}`,
304
+ onDemandChange: () => managed.reconcileSubscriptions(),
305
+ allowSubscriptions: () => subscriptionsAllowed(managed.config)
306
+ });
307
+ }
308
+ return managed.channel;
309
+ }
87
310
  /** Express handler for /<name> and /<name>/mcp. */
88
- export function serverRequestHandler(managed) {
311
+ export function serverRequestHandler(managed, secret) {
89
312
  return async (req, res) => {
90
313
  if (managed.state !== 'up' || !managed.client) {
91
314
  if (!managed.onDemand) {
@@ -108,7 +331,12 @@ export function serverRequestHandler(managed) {
108
331
  // With a snapshot the proxy server is built from cached identity and
109
332
  // capabilities; its handlers wake the child only for real usage.
110
333
  }
111
- await handleMcpRequest(() => buildProxyServer(managed), req, res);
334
+ // Deliberately not `use()`: opening a listen stream is not usage. A client
335
+ // that subscribes to a sleeping child gets an honest acknowledgment built
336
+ // from the cached capabilities — they survive the nap — and delivery
337
+ // resumes when something actually wakes it. Waking on subscribe would undo
338
+ // on-demand for every server anyone ever watched.
339
+ await handleMcpRequest(routeFor(managed, secret), req, res);
112
340
  };
113
341
  }
114
342
  //# sourceMappingURL=proxy.js.map
package/dist/proxy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
package/dist/stdio.js CHANGED
@@ -1,12 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { randomBytes } from 'node:crypto';
5
+ import { serveStdio } from '@modelcontextprotocol/server/stdio';
5
6
  import { loadConfig, parseConfig, ConfigWatcher, warnMutableDockerImages } from './config.js';
6
- import { Supervisor } from './supervisor.js';
7
+ import { Supervisor, UpstreamAuthRegistry } from './supervisor.js';
8
+ import { AuthStore } from './auth/store.js';
7
9
  import { ToolCache } from './tool-cache.js';
8
10
  import { buildHubServer } from './hub.js';
9
11
  import { isMainModule } from './main-module.js';
12
+ import { SubscriptionRegistry } from './subscriptions.js';
13
+ import { IDLE_TIMEOUT_MS } from './timings.js';
10
14
  /**
11
15
  * Everything the hub writes with console.log/info would land in the middle of
12
16
  * the JSON-RPC stream and desynchronise the client, so both are moved to
@@ -51,6 +55,29 @@ function loadOrEmpty(configPath) {
51
55
  * Codex, …). Everything HTTP-only — OAuth, tokens, rate limiting, /health —
52
56
  * has no counterpart here; the trust boundary is the local user account.
53
57
  */
58
+ /**
59
+ * Outbound OAuth only works here when a state directory was given: there is
60
+ * nowhere else to read a token from, and no HTTP listener for a browser to
61
+ * come back to. Without one, such a server simply cannot connect, so say why
62
+ * once rather than leaving an unexplained failure in the log.
63
+ */
64
+ function buildUpstreamAuth(config, dataPath) {
65
+ const oauthServers = [...config].filter(([, server]) => server.kind === 'remote' && server.oauth !== undefined);
66
+ if (oauthServers.length === 0)
67
+ return undefined;
68
+ if (!dataPath) {
69
+ console.warn(`mcp-hub: ${oauthServers.map(([name]) => name).join(', ')} need an upstream OAuth token, but this mode has no state directory. ` +
70
+ 'Set DATA_PATH to the hub\'s /data to reuse a token authorized there.');
71
+ return undefined;
72
+ }
73
+ const store = new AuthStore(dataPath);
74
+ const externalUrl = store.getExternalUrl();
75
+ if (!externalUrl) {
76
+ console.warn(`mcp-hub: ${dataPath} holds no upstream credentials yet; authorize them against the HTTP hub first`);
77
+ return undefined;
78
+ }
79
+ return new UpstreamAuthRegistry(store, externalUrl);
80
+ }
54
81
  export function createStdioHub(options) {
55
82
  const config = loadOrEmpty(options.configPath);
56
83
  warnMutableDockerImages(config);
@@ -62,14 +89,17 @@ export function createStdioHub(options) {
62
89
  // exactly the cost this feature exists to avoid. The snapshot lives next to
63
90
  // the config rather than in a DATA_PATH — there is no state directory in
64
91
  // this mode, and no other state to put in one.
92
+ // IDLE_TIMEOUT_MS is the sub-minute sibling of the documented knob; see timings.ts.
93
+ const idleTimeoutMs = IDLE_TIMEOUT_MS || idleTimeoutMinutes * 60_000;
65
94
  const cache = new ToolCache(options.toolCachePath ?? path.join(path.dirname(options.configPath), '.mcp-hub', 'tool-cache.json'));
66
- if (idleTimeoutMinutes > 0) {
95
+ if (idleTimeoutMs > 0) {
67
96
  cache.load();
68
97
  if (!cache.probeWritable()) {
69
98
  console.warn(`mcp-hub: tool cache ${cache.filePath} is not writable — on-demand servers warm-start at every launch instead of sleeping through it`);
70
99
  }
71
100
  }
72
- const supervisor = new Supervisor(config, { idleTimeoutMinutes, cache });
101
+ const upstreamAuth = buildUpstreamAuth(config, options.dataPath);
102
+ const supervisor = new Supervisor(config, { idleTimeoutMinutes, idleTimeoutMs, cache, upstreamAuth });
73
103
  supervisor.start(); // children come up (or hydrate into `sleeping`) in the background
74
104
  void supervisor
75
105
  .reapOrphans()
@@ -89,16 +119,76 @@ export function createStdioHub(options) {
89
119
  else {
90
120
  console.warn(`mcp-hub: ${path.dirname(options.configPath)} does not exist — config hot reload is off`);
91
121
  }
92
- return { server: buildHubServer(supervisor), supervisor, watcher };
122
+ // The seal on a half-finished tool call, which in this mode only ever has to
123
+ // survive between two legs of the same connection. There is no /data here and
124
+ // nothing to persist: the process IS the session, so a key drawn once at
125
+ // start is not a shortcut but the right lifetime. When the process ends there
126
+ // is no question left to resume.
127
+ const requestStateSecret = randomBytes(32).toString('base64url');
128
+ // A factory rather than an instance: the entry point below decides the era
129
+ // from the opening exchange and pins one instance to the connection, and it
130
+ // can only do that if it owns the construction.
131
+ return { build: (era) => buildHubServer(supervisor, requestStateSecret, era), supervisor, watcher };
93
132
  }
94
133
  export async function runStdio(options) {
95
134
  redirectStdoutLogging();
96
- const { server, supervisor, watcher } = createStdioHub(options);
97
- await server.connect(new StdioServerTransport());
135
+ const { build, supervisor, watcher } = createStdioHub(options);
136
+ // serveStdio rather than server.connect(new StdioServerTransport()): the
137
+ // protocol era is decided by the opening exchange, and only this entry point
138
+ // owns that decision. With a hand-wired transport the connection is 2025 for
139
+ // its whole life, and a child's `input_required` would be answered by the
140
+ // SDK's legacy shim instead of reaching the person at the keyboard.
141
+ //
142
+ // That matters most here of all the hub's doors. Over HTTP the hub is
143
+ // stateless and shared, so a 2025 client has nowhere to receive a question;
144
+ // a workstation hub is spawned per client session and belongs to exactly one
145
+ // person, which is precisely the case where asking them is worth something.
146
+ //
147
+ // legacy: 'serve' is the default and is documented as serving a 2025 opening
148
+ // "exactly as a hand-wired stdio server serves it today" — so nothing changes
149
+ // for a client that speaks the old era. What is new is only that a modern
150
+ // opening is now accepted instead of being answered in the old one.
151
+ // The aggregate's tool list moves whenever a child's does, and over stdio the
152
+ // hub cannot see the client's listen filter: `serveStdio` owns the request and
153
+ // offers no hook for one. So it holds a standing lease instead — one client,
154
+ // one connection, one thing worth watching.
155
+ //
156
+ // That is not a way of pushing at someone who did not ask.
157
+ // `sendToolListChanged()` reaches only the subscriptions actually open, so a
158
+ // client that never sent `subscriptions/listen` receives nothing; the lease
159
+ // only decides whether the hub bothers to watch the children upstream.
160
+ let registry;
161
+ const handle = serveStdio(ctx => {
162
+ // The era the opening exchange settled on. serveStdio hands it over for
163
+ // exactly this: an instance may differ by the era it will serve.
164
+ const hub = build(ctx.era);
165
+ registry?.close();
166
+ registry = new SubscriptionRegistry({
167
+ toolsChanged: () => hub.sendToolListChanged(),
168
+ // /hub aggregates tools and nothing else, so the other three describe
169
+ // nothing a client of this endpoint could read.
170
+ promptsChanged: () => { },
171
+ resourcesChanged: () => { },
172
+ resourceUpdated: () => { }
173
+ }, { onDemandChange: () => supervisor.reconcileAll() });
174
+ registry.acquire({
175
+ toolsListChanged: true,
176
+ promptsListChanged: false,
177
+ resourcesListChanged: false,
178
+ resourceSubscriptions: []
179
+ });
180
+ supervisor.hubSubscriptions = registry;
181
+ return hub;
182
+ }, {
183
+ legacy: 'serve',
184
+ onerror: error => console.error(`mcp-hub: stdio connection error: ${error.message}`)
185
+ });
98
186
  console.error(`mcp-hub: serving the hub aggregate over stdio (config ${options.configPath})`);
99
187
  const shutdown = async (signal) => {
100
188
  console.error(`mcp-hub: received ${signal}, shutting down`);
101
189
  watcher.stop();
190
+ registry?.close();
191
+ await handle.close();
102
192
  await supervisor.stop();
103
193
  process.exit(0);
104
194
  };
package/dist/stdio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"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"}