@ni-c/mcp-hub 0.10.0 → 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 (77) hide show
  1. package/CHANGELOG.md +388 -0
  2. package/README.md +77 -12
  3. package/dist/admin.js +1 -1
  4. package/dist/admin.js.map +1 -1
  5. package/dist/auth/api-tokens.js +27 -0
  6. package/dist/auth/api-tokens.js.map +1 -0
  7. package/dist/auth/headers.js +22 -1
  8. package/dist/auth/headers.js.map +1 -1
  9. package/dist/auth/oidc/adapter.js +135 -0
  10. package/dist/auth/oidc/adapter.js.map +1 -0
  11. package/dist/auth/oidc/interactions.js +187 -0
  12. package/dist/auth/oidc/interactions.js.map +1 -0
  13. package/dist/auth/oidc/mount.js +144 -0
  14. package/dist/auth/oidc/mount.js.map +1 -0
  15. package/dist/auth/oidc/provider.js +440 -0
  16. package/dist/auth/oidc/provider.js.map +1 -0
  17. package/dist/auth/oidc/quirks.js +234 -0
  18. package/dist/auth/oidc/quirks.js.map +1 -0
  19. package/dist/auth/oidc/verifier.js +121 -0
  20. package/dist/auth/oidc/verifier.js.map +1 -0
  21. package/dist/auth/protected-resource.js +41 -0
  22. package/dist/auth/protected-resource.js.map +1 -0
  23. package/dist/auth/rate-limit.js +115 -2
  24. package/dist/auth/rate-limit.js.map +1 -1
  25. package/dist/auth/redirect-uri.js +33 -1
  26. package/dist/auth/redirect-uri.js.map +1 -1
  27. package/dist/auth/registration.js +1 -1
  28. package/dist/auth/registration.js.map +1 -1
  29. package/dist/auth/session.js +43 -0
  30. package/dist/auth/session.js.map +1 -0
  31. package/dist/auth/store.js +160 -1
  32. package/dist/auth/store.js.map +1 -1
  33. package/dist/config.js +55 -2
  34. package/dist/config.js.map +1 -1
  35. package/dist/docker-proxy/policy.js +1 -0
  36. package/dist/docker-proxy/policy.js.map +1 -1
  37. package/dist/docker-proxy/server.js +1 -0
  38. package/dist/docker-proxy/server.js.map +1 -1
  39. package/dist/elicitation.js +0 -0
  40. package/dist/elicitation.js.map +1 -0
  41. package/dist/forward.js +0 -0
  42. package/dist/forward.js.map +1 -0
  43. package/dist/hub.js +309 -29
  44. package/dist/hub.js.map +1 -1
  45. package/dist/index.js +103 -21
  46. package/dist/index.js.map +1 -1
  47. package/dist/limits.js +13 -1
  48. package/dist/limits.js.map +1 -1
  49. package/dist/mcp-limits.js +14 -2
  50. package/dist/mcp-limits.js.map +1 -1
  51. package/dist/proxy.js +246 -40
  52. package/dist/proxy.js.map +1 -1
  53. package/dist/stdio.js +71 -6
  54. package/dist/stdio.js.map +1 -1
  55. package/dist/subscriptions.js +236 -0
  56. package/dist/subscriptions.js.map +1 -0
  57. package/dist/supervisor.js +322 -22
  58. package/dist/supervisor.js.map +1 -1
  59. package/dist/timings.js +61 -0
  60. package/dist/timings.js.map +1 -0
  61. package/dist/tool-filter.js +1 -0
  62. package/dist/tool-filter.js.map +1 -1
  63. package/dist/transports/docker.js.map +1 -1
  64. package/dist/transports/stream.js +33 -20
  65. package/dist/transports/stream.js.map +1 -1
  66. package/dist/upstream/auth.js +1 -1
  67. package/dist/upstream/auth.js.map +1 -1
  68. package/dist/upstream/provider.js.map +1 -1
  69. package/dist/upstream/routes.js +3 -2
  70. package/dist/upstream/routes.js.map +1 -1
  71. package/package.json +19 -6
  72. package/dist/auth/private-key-jwt.js +0 -213
  73. package/dist/auth/private-key-jwt.js.map +0 -1
  74. package/dist/auth/provider.js +0 -437
  75. package/dist/auth/provider.js.map +0 -1
  76. package/dist/auth/routes.js +0 -249
  77. package/dist/auth/routes.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,394 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  <!-- #region changelog -->
9
9
 
10
+ ## [0.11.0] - 2026-09-03
11
+
12
+ ### Added
13
+
14
+ - **The meta-tools answer in both channels.** Five of the six now declare an
15
+ `outputSchema` and return the same object as `structuredContent` as well as
16
+ the JSON text block they always returned. A client that wants to *use* the
17
+ answer no longer has to parse a string and hope; one that wants to read it
18
+ still gets the text, because the SDK does not synthesize a text block for an
19
+ object-shaped value and dropping it would have left older clients with
20
+ nothing.
21
+
22
+ `list_servers` and `list_tools` therefore answer with `{"servers": […]}` and
23
+ `{"tools": […]}` rather than a bare array. That is the breaking part of this
24
+ change, and it is not cosmetic: the 2025 wire cannot carry a non-object
25
+ `structuredContent`, so the SDK wraps one in `{"result": …}` — and an
26
+ array-rooted answer would let a client tell from the payload which protocol
27
+ revision it had been given. The hub's promise is that it cannot. There is a
28
+ test comparing both eras field for field.
29
+
30
+ `call_tool` is the one without a schema. It returns the child's own result,
31
+ and a schema of the hub's would only be honest if the hub wrapped somebody
32
+ else's payload — which would break the passthrough the era matrix pins across
33
+ all four client/child combinations.
34
+
35
+ - **`get_tool_schema` hands on the child's `outputSchema`.** This is the gap the
36
+ rest of the work uncovered. `call_tool` has always returned a child's
37
+ `structuredContent` verbatim, but the schema to validate it against was
38
+ dropped on the way out of `/hub`, so an aggregate client received structured
39
+ data it had no way to check — while `hub-tools.md` claimed structured content
40
+ "passes through". Half of it did.
41
+
42
+ `list_tools` marks such a tool with `hasOutputSchema: true` rather than
43
+ inlining the schema, so a large server's list stays a list. Both follow the
44
+ rule `annotations` already followed: the child's own document, verbatim, and
45
+ the key absent when it declared none.
46
+
47
+ - **`list_tools` and `get_tool_schema` carry a child's tool annotations
48
+ through.** Over `/hub` a client never sees the child's own `tools/list`, so
49
+ those two answers are the only place it can learn that one of two similarly
50
+ named tools deletes and the other does not. They came back as name plus
51
+ description, which left every tool looking identical at exactly the moment a
52
+ model decides which to call. The proxy endpoint `/<name>/mcp` was already
53
+ correct; there is a test for it now too, because "already correct" is a
54
+ property that stops being true silently.
55
+
56
+ Verbatim, not summarised into a marker of the hub's own. The specification
57
+ says a client "MUST consider tool annotations to be untrusted unless they come
58
+ from trusted servers", and the hub is in no position to vouch for a child it
59
+ merely forwards to — a derived `kind` would have been the hub's claim about
60
+ somebody else's server. A child that declared nothing arrives with no
61
+ `annotations` key at all; an empty object would read as all four defaults,
62
+ which is a claim it did not make.
63
+
64
+ - **The six meta-tools annotate themselves**, which they never did. The
65
+ specification gives `destructiveHint` and `openWorldHint` a default of `true`,
66
+ so silence declared `list_servers` a destructive tool in an open world.
67
+ `call_tool` is the one where that really is the answer: whatever the named
68
+ tool does, `call_tool` does.
69
+
70
+ - **The hub speaks both MCP revisions on every endpoint.** `2026-07-28` and
71
+ `2025-11-25`, on `/hub`, on `/<name>/mcp` and over `--stdio`; the client
72
+ picks during its opening exchange and cannot tell from the answers which one
73
+ it got. Which traffic is carried on which revision is a
74
+ [matrix](https://mcp-hub.ni-c.de/reference/standards#what-is-carried-per-revision)
75
+ now, with a test behind every row, because this project has twice announced
76
+ something it did not deliver.
77
+
78
+ The 2025 path is untouched: it is served by the same transport that always
79
+ served it, so a `GET` still opens a stream and a `DELETE` still answers 200
80
+ rather than the 405 the modern handler's own fallback would give. claude.ai
81
+ opens that stream on every reconnect.
82
+
83
+ - **Change notifications travel, on both sides.** A `2026-07-28` client opens a
84
+ `subscriptions/listen` stream and names what it wants — tool, prompt and
85
+ resource list changes, or specific resource URIs — and the hub delivers.
86
+ Upstream it subscribes to each child the way that child understands:
87
+ `subscriptions/listen` to a 2026 server, `resources/subscribe` to a 2025 one.
88
+ So a server that has never heard of the newer mechanism still reaches a client
89
+ that speaks nothing else, which is the common case in practice.
90
+ [Details](https://mcp-hub.ni-c.de/guide/subscriptions).
91
+
92
+ This is the second thing the 2026 revision made possible for a stateless
93
+ gateway, and for the same reason as the first: the state is the open HTTP
94
+ response rather than a session table, so a client reconnecting without closing
95
+ anything leaves nothing behind. One handler per route now outlives the
96
+ request, because it owns those streams — it holds the sockets currently open
97
+ and no record of who opened them.
98
+
99
+ The bookkeeping is a lease per stream rather than a reference count per URI.
100
+ A count cannot tell "nobody wants this any more" from "the one leaving wanted
101
+ it too", and gets it wrong in the direction that silently stops delivering to
102
+ the client that stayed.
103
+
104
+ A sleeping [on-demand](https://mcp-hub.ni-c.de/guide/on-demand) server watches
105
+ nothing: subscribing does not wake it — the acknowledgment comes from the
106
+ cached capabilities — and the subscription is re-established when something
107
+ else does, followed by a re-read signal for everything that client was
108
+ watching. What changed during the nap is not reported, only that there is
109
+ reason to look. `subscriptions: "off"` withdraws one server's right to push.
110
+
111
+ - **An end-to-end suite that runs the hub the way it ships.** Three tiers: in
112
+ this process, as `node dist/index.js`, and as the published image through
113
+ `demo/compose.yml`. It is not part of `npm test`, which stays fast and stays
114
+ the pull-request gate; this one runs nightly, on any pull request that touches
115
+ it, and as a gate on release tags. [What it is
116
+ for](https://github.com/ni-c/mcp-hub/blob/main/e2e/README.md).
117
+
118
+ The tiers exist because a class of question cannot be asked from inside the
119
+ process being tested. `src/index.ts`'s startup block — environment parsing,
120
+ the listener, signal handlers — is entered only when the file is the program.
121
+ `mcp-hub-admin` is a *separate program* sharing `/data` with a running hub,
122
+ and a test that called the same `AuthStore` instance proves the hub can read
123
+ its own memory; that mistake shipped once, as a revocation that reported
124
+ success and did nothing. An `uncaughtException` in-process takes the test
125
+ runner down rather than the hub. And uid 1000, a read-only root filesystem,
126
+ the healthcheck and tini cannot be wrong in a bare process at all.
127
+
128
+ The consumer is a scripted agent rather than a model. It discovers through the
129
+ six meta-tools and then builds its arguments *from the schema the hub
130
+ published*, which is the whole point: a schema damaged in transit — truncated,
131
+ budget-clipped, missing a property it declares required — stops working there
132
+ and nowhere else. A model handed a broken schema improvises around it, and
133
+ improvisation is not an assertion.
134
+
135
+ Alongside it: thirteen fixture servers that each misbehave in one specific way
136
+ no off-the-shelf server does, a four-cell client-era × child-era matrix built
137
+ on one catalogue registered twice so a difference can only be the hub's, raw
138
+ `fetch` conformance checks that assert an HTTP status and a JSON-RPC code
139
+ together, and a recorder for what real clients put on the wire.
140
+
141
+ - **`src/timings.ts`.** The supervisor's ping interval, wake timeout, idle
142
+ sweep and backoff curve read the environment, the same way `mcp-limits.ts`
143
+ already did for the call deadline. `IDLE_TIMEOUT_MS` is the sub-minute sibling
144
+ of `IDLE_TIMEOUT_MINUTES`.
145
+
146
+ Defaults are unchanged, so no deployment behaves differently. What changes is
147
+ that the behaviour becomes observable: at the shipped numbers, watching a
148
+ server fall asleep costs a minute and the five-minute backoff ceiling cannot
149
+ be reached at all. Four minutes of a test suite spent asleep is four minutes
150
+ somebody eventually deletes.
151
+
152
+ - **`describe_connection`, behind `MCP_DIAGNOSTICS`.** A seventh meta-tool that
153
+ answers the one question a client cannot answer for itself: which protocol
154
+ era this connection is on, whether this request carried an elicitation
155
+ capability, and — for a named server — whether a question from it would
156
+ actually reach the person at the far end.
157
+
158
+ It exists because a server falling back to its two-call token looks identical
159
+ to a server that simply did not ask. From inside the client both are silence,
160
+ and only the hub knows which one it was. The first thing it reported in
161
+ anger: a connector on the `2026-07-28` era that declares no `elicitation`
162
+ capability at all — which the era, unlike the older one, would let it do.
163
+
164
+ Off by default. Not for safety — it reports only what the caller's own request
165
+ already carried, and nothing about any other client — but because every tool a
166
+ client can see costs context in every conversation it has, and "six meta-tools
167
+ instead of N×tools" is the argument for the aggregate. With the switch on,
168
+ `/hub` and `--stdio` serve seven.
169
+
170
+ - **One log line when a question is dropped.** When the hub declines to carry a
171
+ child's elicitation it now says so once per client, server and reason, instead
172
+ of leaving the only trace inside a tool result that one caller sees. The
173
+ decision itself moved into a single function that both the forwarding path and
174
+ the new tool call, so the explanation cannot drift from the behaviour.
175
+
176
+ ### Fixed
177
+
178
+ - **The meta-tools no longer advertise an empty schema where they mean
179
+ "anything".** Five fields carry a document the hub does not own — a child's
180
+ `annotations` on `list_tools` and `get_tool_schema`, the two schemas on
181
+ `get_tool_schema`, and the `arguments` of `call_tool` — and zod writes that
182
+ as `"additionalProperties": {}`. An empty schema is legal and means exactly
183
+ what `true` means, but it is the spelling some MCP clients refuse or
184
+ mishandle, which is the worst kind of bug to own: the tool works against the
185
+ client you tested with and fails against the one you did not.
186
+
187
+ Only the emitted JSON Schema changes. The runtime is still as permissive as
188
+ it has to be, and deliberately so: those fields are validated against the zod
189
+ schema, a child is free to put anything in them, and the SDK turns a refused
190
+ answer into an error result. A test walks every schema the hub advertises and
191
+ fails on any node that constrains nothing, so a future zod release cannot put
192
+ the spelling back without saying so.
193
+
194
+ - **A non-object output schema now reaches a 2025 client with its value wrapped
195
+ to match.** The per-server endpoint writes its own `tools/call` handler, and
196
+ such a handler has to run the result through the wire codec itself. It did
197
+ not. The schema half was already being rewritten to `{"result": …}` on the
198
+ way out, so a child whose `outputSchema` describes an array handed a 2025
199
+ client a bare array to validate against a schema saying "object" — correct
200
+ data that looks broken. Both halves are projected now, and a fixture with an
201
+ array-rooted schema pins it on every era pair.
202
+
203
+ The e2e agent, which checks that a result carries everything its schema
204
+ requires, was silently doing nothing on the `/hub` door for the same reason:
205
+ the schema it read from `get_tool_schema` was always `undefined`. It bites
206
+ there now, and it also asserts that the text block and `structuredContent`
207
+ agree.
208
+
209
+ - **Three capabilities the hub announced but did not serve.** `listChanged` for
210
+ tools, prompts and resources is now advertised only on the revision that
211
+ carries it, and is true there; `resources.subscribe` likewise, having been
212
+ stripped outright since 0.6.3. `logging` is no longer advertised at all —
213
+ `logging/setLevel` never had a handler, so a client that believed it got a
214
+ `-32601` at call time, and on `2026-07-28` the level is per-request `_meta`
215
+ with no RPC left to implement.
216
+
217
+ A 2025 client is now told none of the three. That is a visible change, and the
218
+ honest one: it was never going to receive any of them.
219
+
220
+ - **A `subscriptions/listen` POST no longer occupies an in-flight slot.** It is
221
+ a POST whose response stays open for the life of the subscription, so counted
222
+ as work in progress it held one of `MCP_MAX_CONCURRENT_REQUESTS` (default
223
+ four) the entire time — a handful of subscribed clients would have locked
224
+ every tool call on the hub out with a 429 while nothing was running. It is the
225
+ standing channel by another name and is charged to
226
+ `MCP_MAX_CONCURRENT_STREAMS`, where the 2025 era's `GET` already went.
227
+
228
+ - **Elicitation travels end to end.** A child server that needs to ask the
229
+ person at the far end something — `smtp-mcp` before it sends, `imap-mcp`
230
+ before it expunges a mailbox — now reaches them through the hub instead of
231
+ silently falling back to a weaker check. On `2026-07-28` a question is a
232
+ *result*, not a push: the call ends, the person decides, the client retries
233
+ with the answer. Nothing is held open, so the stateless transport is what
234
+ makes this work rather than what prevented it.
235
+
236
+ The hub adds what follows from the question crossing a trust boundary. It is
237
+ attributed to the server that asked, after the text has been stripped of the
238
+ bidirectional and zero-width characters that could visually undo that line.
239
+ Embedded `sampling/createMessage` and `roots/list` requests are dropped and
240
+ named in the log — relaying them would spend the caller's model budget and
241
+ hand out its workspace layout on a child's say-so. The child's `_meta` is
242
+ removed. The resumption state is signed and bound to the server, the tool,
243
+ the OAuth client and the endpoint, so it cannot be pasted onto another call.
244
+
245
+ The capability is mirrored per request from what the client itself declared,
246
+ and never widened — so it is announced only for a call whose answer has
247
+ somewhere to go. A `2025-11-25` client over HTTP is therefore not offered it
248
+ at all, and the child takes its own fallback, which is the same rule this
249
+ project already applies to `listChanged`.
250
+
251
+ `"passthrough": "off"` on a server withdraws its right to put words in front
252
+ of the user without switching it off; `MCP_ELICITATION=false` is the global
253
+ brake. Four further `MCP_ELICITATION_*` variables bound rounds, lifetime,
254
+ message size and payload size. See
255
+ [Elicitation](https://mcp-hub.ni-c.de/guide/elicitation).
256
+
257
+ - **A question from a server that had gone to sleep was lost.** The hub decided
258
+ whether a child could be asked by reading the protocol era off its client,
259
+ and an on-demand child that is asleep has none — so the first tool call after
260
+ an idle nap silently took the weaker path and the second one worked. The wake
261
+ now happens before the decision.
262
+
263
+ ### Changed
264
+
265
+ - **On MCP SDK 2.0.** The single `@modelcontextprotocol/sdk` package has been
266
+ replaced by the split `@modelcontextprotocol/{core,client,server,node,express}`.
267
+ Behaviour is unchanged by the migration itself: no wire format, endpoint or
268
+ response differs, and deployments need do nothing. Speaking `2026-07-28` as
269
+ well is a separate change, listed under Added above — it is what the
270
+ migration was for.
271
+
272
+ Notably **not** installed is `@modelcontextprotocol/server-legacy`, the frozen
273
+ copy of v1's authorization-server helpers that npm marks deprecated on
274
+ install. Replacing the hand-written OAuth server with `oidc-provider` first is
275
+ what made that possible — this migration only had to touch the MCP wire layer.
276
+
277
+ Two things the mechanical migration would have changed quietly, and did not:
278
+ `tools/list` is still walked one page at a time, because v2's `listTools()`
279
+ aggregates the whole pagination internally and would have bypassed the tool
280
+ count and metadata budgets that bound what a hostile child can make the hub
281
+ hold in memory; and a malformed line on a child's stdio is still reported,
282
+ because v2's read buffer skips unparseable lines in silence.
283
+
284
+ - **The authorization server is now `oidc-provider` instead of ~900 lines of
285
+ hand-written OAuth.** Every endpoint keeps its path, the login and consent
286
+ pages are the same pages, and the discovery document advertises everything it
287
+ advertised before — there is a test that compares it field by field against
288
+ the old one and fails on anything that is not a written-down decision.
289
+
290
+ **This is a clean cut, not a migration: every client re-registers and
291
+ authorizes once more.** Tokens issued by the previous server are refused
292
+ rather than honoured, because a credential nothing can revoke is worse than a
293
+ reconnect. Registrations, approvals and API tokens in `state.json` are
294
+ untouched; only the OAuth artifacts are new.
295
+
296
+ Access tokens are **opaque** rather than JWTs. That is what makes
297
+ `mcp-hub-admin clients revoke` take effect on the next call instead of when
298
+ the token expires: oidc-provider never persists a JWT, so a JWT could not be
299
+ withdrawn at all. Nothing that presents a token has to change.
300
+
301
+ Several things got stricter on the way. Replaying a rotated refresh token now
302
+ revokes the grant's access tokens as well. Client assertions may not be valid
303
+ for longer than five minutes. Nothing an authorization server holds is written
304
+ to `state.json` in a form anyone could present — the file used to keep hashes
305
+ of refresh tokens, and now keeps hashes of everything. A `Host` header can no
306
+ longer influence the URLs in the discovery document.
307
+
308
+ Visible differences, none of which change what is allowed: redirects use
309
+ `303` where they used `302`, `invalid_client` may be answered `401` rather
310
+ than `400` (RFC 6749 §5.2 allows either), a rejected redirect URI is reported
311
+ as `invalid_redirect_uri`, and the login page lives at `/interaction/<id>/`
312
+ instead of being rendered by `/authorize` directly. The discovery document
313
+ gained the OpenID fields oidc-provider always publishes; no ID token is ever
314
+ issued.
315
+
316
+ - **Four more reserved server names: `jwks`, `interaction`, `session` and
317
+ `userinfo`.** They are paths the authorization server answers on, and a server
318
+ configured under one of them would shadow the login flow rather than merely be
319
+ unreachable. A configuration using one of these names is now refused at
320
+ startup with the same message as for `token` or `authorize`.
321
+
322
+ - **Both images now run on Node 24 ("Krypton"), the active LTS line, instead of
323
+ Node 26.** Node 26 is Current until October, and a non-LTS build leaves
324
+ `process.release.lts` unset — which is not cosmetic, because libraries branch
325
+ on it. It is also what the CI matrix already tests against, so the container
326
+ and the test runs no longer sat on different majors.
327
+
328
+ Nothing else changes: npm is still replaced wholesale and its three vulnerable
329
+ vendored packages still overwritten in place, verified against the built
330
+ image.
331
+
332
+ ### Security
333
+
334
+ Five findings from an internal review of the authorization surface, which is the
335
+ half that was rewritten onto oidc-provider in this cycle and had not been looked
336
+ at adversarially since.
337
+
338
+ - **`/token` bounds the body it reads.** It is the one provider path whose
339
+ request stream the hub takes away from the library — `stripPhantomSecret` has
340
+ to read it to strip a presented secret — and it read it without a ceiling.
341
+ `/token` cannot ask who is calling before it reads, because the credentials
342
+ are in the body, so an anonymous 300 MB request took the process from 157 MB
343
+ resident to 1.4 GB, and the per-path budget still allows fifty of them per
344
+ caller per window. The ceiling is oidc-provider's own 56 KiB, so nothing a
345
+ legitimate client sends changes, and an oversized body now gets the same
346
+ answer the library would have given it.
347
+
348
+ - **A public client's record no longer carries a secret.** RFC 7591 makes
349
+ `client_secret_basic` the default when `token_endpoint_auth_method` is
350
+ omitted — which is what Claude and ChatGPT both do — so the authorization
351
+ server minted and persisted a real secret before `clientDefaults` rewrote the
352
+ method to `none`. Two consequences, neither visible from outside:
353
+ `state.json` gained a value someone could present, which is the one thing it
354
+ is careful never to hold; and `stripPhantomSecret` gates on the stored client
355
+ having no secret, so it stopped firing for exactly the clients it exists for.
356
+ A connector that echoed the secret from its registration response got
357
+ `401 invalid_client` — the failure quirk 2 was written to prevent. The
358
+ response still carries a secret, because ChatGPT insists on one; only the
359
+ record is cleaned.
360
+
361
+ - **A hundred wrong passwords no longer lock the operator out.** The global
362
+ failure ceiling refused every address once it was reached, so an attacker
363
+ could close the only administrative way in — from one host, in under a second,
364
+ renewable every fifteen minutes — and the operator holding the correct
365
+ password got `429` from an address that had never touched the form. The
366
+ ceiling now refuses the callers that are guessing, and refuses them on their
367
+ first failure rather than their tenth once the hub is under a distributed
368
+ attempt, so the total number of guesses still collapses. What it no longer
369
+ does is let them spend somebody else's budget.
370
+
371
+ - **Every per-caller budget counts an IPv6 /64, not an address.** A /64 is the
372
+ smallest block one subscriber is handed, and a /56 or /48 is what a
373
+ residential line usually gets, so a limiter keyed on the full address counted
374
+ one host as billions of callers: twenty-five registrations from twenty-five
375
+ addresses in one network spent twenty-five budgets of twenty. IPv4 keeps its
376
+ own address, and an IPv4-mapped form is folded back onto it so the same caller
377
+ is not counted twice for arriving over a dual-stack listener. Log lines are
378
+ unchanged — fail2ban still gets the host that actually connected.
379
+
380
+ - **A `TRUSTED_PROXIES` list that never matches is now said out loud.** It is
381
+ compared against the address the connection came from, and the easiest way to
382
+ get it wrong is the least visible: a proxy configured as
383
+ `proxy_pass http://localhost:…` on a dual-stack host arrives over `::1`,
384
+ which `127.0.0.1` does not cover. Every forwarded header is then ignored and
385
+ per-caller limiting collapses into one global counter — the exact failure the
386
+ startup warning covers for an *unset* list, with nothing said when the list is
387
+ merely wrong. The hub now says so once, when a forwarded header arrives from
388
+ an address it does not trust.
389
+
390
+ Unchanged, and confirmed by the same review: the docker policy proxy refused
391
+ every one of thirty-three attempts to reach the daemon past it — privileged
392
+ containers, host mounts, `Mounts` instead of `Binds`, foreign images, prototype
393
+ pollution in the create body, duplicate query parameters, encoded traversal in a
394
+ container name, `exec`, `build`, `networks/create`; and the metadata-document
395
+ fetcher refused literal private addresses, IPv4-mapped ones and public names
396
+ that resolve inward.
397
+
10
398
  ## [0.10.0] - 2026-08-27
11
399
 
12
400
  ### Added
package/README.md CHANGED
@@ -9,8 +9,17 @@
9
9
  [![docs](https://img.shields.io/badge/docs-mcp--hub.ni--c.de-informational)](https://mcp-hub.ni-c.de)
10
10
  [![sponsor](https://img.shields.io/badge/sponsor-ni--c-ea4aaa?logo=githubsponsors&logoColor=white)](https://github.com/sponsors/ni-c)
11
11
 
12
- A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) gateway: it serves
13
- many stdio MCP servers from **one container**, published over HTTPS.
12
+ A dual-era [Model Context Protocol](https://modelcontextprotocol.io) (MCP) gateway: it
13
+ serves many stdio MCP servers from **one container**, published over HTTPS, and speaks
14
+ **both MCP revisions on every endpoint** — `2026-07-28` and `2025-11-25`. The client
15
+ picks, and cannot tell which one it is on from the answers. On the 2026 revision that
16
+ includes **elicitation** — a child server's question reaches the person at the far end
17
+ instead of dying at the gateway
18
+ ([how](https://mcp-hub.ni-c.de/guide/elicitation)) — and **subscriptions**: the hub
19
+ serves `subscriptions/listen` to its clients and subscribes to its children on
20
+ whichever revision _they_ speak, so a server that has never heard of it still reaches
21
+ a client that speaks nothing else
22
+ ([how](https://mcp-hub.ni-c.de/guide/subscriptions)).
14
23
 
15
24
  Lets MCP clients that cannot spawn a local process — ChatGPT connectors, Claude on
16
25
  the Web and in Code, Mistral Le Chat, Cursor, LibreChat and any other
@@ -83,11 +92,62 @@ replaces N containers with one process:
83
92
  servers.
84
93
  - **Stateless Streamable HTTP**: no session state, so claude.ai's
85
94
  reconnect-without-DELETE behaviour cannot leak processes or memory.
95
+ - **Dual-era**: every endpoint — `/hub`, `/<name>/mcp` and `--stdio` — answers
96
+ MCP `2026-07-28` and `2025-11-25` alike; the client picks and cannot tell
97
+ from the answers which it got. On the 2026 revision that includes
98
+ **elicitation**: a server asking the user something returns the question
99
+ rather than pushing it, so it reaches the person at the far end instead of
100
+ dying at the gateway. The hub attributes it to the server that asked, strips
101
+ what could lie about that, drops embedded sampling and roots requests, and
102
+ seals the resumption state against the call it belongs to. `passthrough:
103
+ "off"` withdraws one server's right to ask;
104
+ [details](https://mcp-hub.ni-c.de/guide/elicitation).
105
+ - **Change notifications, in both eras**: a client opens a
106
+ `subscriptions/listen` stream and hears when a child's tools, prompts or
107
+ resources change. The hub subscribes to each child the way that child
108
+ understands — `subscriptions/listen` to a 2026 server, `resources/subscribe`
109
+ to a 2025 one — so the era gap is the gateway's problem rather than either
110
+ end's. The state is the open response, not a session table, so this costs the
111
+ stateless design nothing. A sleeping server watches nothing and is told to
112
+ re-read on waking; `subscriptions: "off"` withdraws one server's right to
113
+ push; [details](https://mcp-hub.ni-c.de/guide/subscriptions).
86
114
  - **Lightweight by design**: one Node process, no database (state is one JSON
87
- file plus a JWT key under `/data`), a handful of runtime dependencies, and
115
+ file plus a signing key under `/data`), six runtime dependencies, and
88
116
  multi-arch images — a stated project goal is to run comfortably on a
89
117
  single-board computer like a Raspberry Pi.
90
118
 
119
+ ## Servers to run behind it
120
+
121
+ The hub is server-agnostic — it serves any stdio MCP server whose entry fits
122
+ Claude Code's `mcpServers` format, which is most of them. These seventeen are
123
+ built and maintained alongside it, so their documentation carries the hub entry
124
+ you need and their tool filters line up with the hub's own `allowTools` /
125
+ `denyTools`:
126
+
127
+ | Server | npm | What it reaches |
128
+ | ---------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------ |
129
+ | [audiobookshelf-mcp](https://audiobookshelf-mcp.ni-c.de) | `audiobookshelf-mcp` | Audiobookshelf — libraries, listening progress, collections and playlists |
130
+ | [calibreweb-mcp](https://calibreweb-mcp.ni-c.de) | `calibreweb-mcp` | Calibre-Web — read-only library access through the OPDS feed |
131
+ | [freshrss-mcp](https://freshrss-mcp.ni-c.de) | `@ni-c/freshrss-mcp` | FreshRSS — feeds, categories and articles as plain text, not stream ids |
132
+ | [google-search-console-mcp](https://google-search-console-mcp.ni-c.de) | `@ni-c/google-search-console-mcp` | Google Search Console — properties, sitemaps, search analytics, URL inspection |
133
+ | [healthchecks-mcp](https://healthchecks-mcp.ni-c.de) | `healthchecks-mcp` | Healthchecks — cron and uptime checks, and why one failed |
134
+ | [hetzner-dns-mcp](https://hetzner-dns-mcp.ni-c.de) | `hetzner-dns-mcp` | Hetzner Cloud DNS — zones, record sets and BIND import/export |
135
+ | [imap-mcp](https://imap-mcp.ni-c.de) | `@ni-c/imap-mcp` | IMAP mailboxes — read, search, organise and draft mail; it cannot send |
136
+ | [linkwarden-mcp](https://linkwarden-mcp.ni-c.de) | `linkwarden-mcp` | Linkwarden — bookmarks, collections and the article text it preserved |
137
+ | [mealie-mcp](https://mealie-mcp.ni-c.de) | `@ni-c/mealie-mcp` | Mealie — recipes, meal plans, shopping lists and cookbooks |
138
+ | [ntfy-mcp](https://ntfy-mcp.ni-c.de) | `@ni-c/ntfy-mcp` | ntfy — publish and update notifications, manage users and topic access |
139
+ | [opengist-mcp](https://opengist-mcp.ni-c.de) | `opengist-mcp` | Opengist — gists, revisions, commit history and raw files |
140
+ | [osm-mcp](https://osm-mcp.ni-c.de) | `osm-mcp` | OpenStreetMap — geocoding, routing, isochrones and POI search |
141
+ | [rustpad-mcp](https://rustpad-mcp.ni-c.de) | `rustpad-mcp` | Rustpad — collaborative pads edited through real OT, not overwrites |
142
+ | [smtp-mcp](https://smtp-mcp.ni-c.de) | `@ni-c/smtp-mcp` | SMTP — sends mail, behind a recipient allowlist and a human confirmation |
143
+ | [wg-easy-mcp](https://wg-easy-mcp.ni-c.de) | `wg-easy-mcp` | wg-easy v15+ — the full WireGuard client lifecycle |
144
+ | [wikijs-mcp](https://wikijs-mcp.ni-c.de) | `@ni-c/wikijs-mcp` | Wiki.js — search, read and edit pages, plus assets, users and groups |
145
+ | [woodpecker-ci-mcp](https://woodpecker-ci-mcp.ni-c.de) | `@ni-c/woodpecker-ci-mcp` | Woodpecker CI — repositories, pipelines, logs, secrets and crons |
146
+
147
+ Each one runs perfectly well on its own over stdio. Put them behind the hub when
148
+ you want them reachable from a client that cannot spawn a local process, or when
149
+ you would rather register one connector than seventeen.
150
+
91
151
  ## Configuration
92
152
 
93
153
  `/config/mcp.json` — identical to Claude Code (`${VAR}` expands from the
@@ -366,15 +426,20 @@ immediately. Per-client recipes:
366
426
 
367
427
  ## Notes & limitations
368
428
 
369
- - Stateless transport: server-initiated notifications (`listChanged`,
370
- subscriptions, sampling) are not delivered to clients. Tool/resource/prompt
371
- request-response works fully; the hub's tool cache does follow
372
- `tools/list_changed` internally.
373
- - Access tokens are self-contained 15-minute JWTs. Revoking a client rejects
374
- its existing JWTs and removes all of its refresh tokens. Refresh tokens
375
- rotate; replaying a token
376
- that was already rotated away revokes its whole chain, and a refresh cannot
377
- ask for more scope than the original grant.
429
+ - Change notifications (`listChanged`, resource updates) are carried on
430
+ `2026-07-28` via `subscriptions/listen`, whose state is the open response
431
+ rather than a session table. A `2025-11-25` client is offered neither, because
432
+ that revision needs a channel the stateless transport does not keep — so the
433
+ capability is withheld instead of announced and dropped. An on-demand server
434
+ watches nothing while it sleeps; the subscription is re-established on the
435
+ next wake and the client is told to re-read.
436
+ - Elicitation travels end to end on `2026-07-28`: it is a result rather than a
437
+ push. Sampling and log messages are not forwarded.
438
+ - Access tokens are opaque and last 15 minutes. Revoking a client takes effect
439
+ on its next request rather than when the token expires — the token is a
440
+ reference to a stored record, so withdrawing it is a deletion. Refresh tokens
441
+ rotate; replaying one that was already rotated away is treated as a leak and
442
+ revokes the whole grant, access tokens included.
378
443
  - Upstream auth is fully decoupled from the hub's own OAuth: an expired
379
444
  upstream token just marks that one server `down` (503 on its path, visible
380
445
  in `/health`) — clients never see the upstream's 401.
package/dist/admin.js CHANGED
@@ -4,7 +4,7 @@ import { AuthStore, clientLimitsFromEnv } from './auth/store.js';
4
4
  import { isSafeRedirectUri } from './auth/redirect-uri.js';
5
5
  import { clampDisplayName } from './auth/text.js';
6
6
  import { isClientIdMetadataUrl } from './auth/cimd.js';
7
- import { mintApiToken } from './auth/provider.js';
7
+ import { mintApiToken } from './auth/api-tokens.js';
8
8
  import { loadConfig } from './config.js';
9
9
  import { authFor, requireOAuthServer, startUpstreamLogin, upstreamStatus } from './upstream/login.js';
10
10
  function usage() {
package/dist/admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import crypto from 'node:crypto';
2
+ import { SignJWT } from 'jose';
3
+ /** Distinguishes admin-minted API tokens from interactive OAuth tokens. */
4
+ export const API_TOKEN_SUBJECT = 'mcp-hub-token';
5
+ /**
6
+ * Mint a long-lived, resource-bound API token for clients that cannot do
7
+ * OAuth (OpenAI Responses API, xAI API, Gemini API, plain-header clients).
8
+ * The JWT is returned exactly once; only its record (jti) is persisted, which
9
+ * is what `tokens list` shows and `tokens revoke` deletes.
10
+ */
11
+ export async function mintApiToken(store, externalUrl, resource, days, label) {
12
+ const id = crypto.randomBytes(8).toString('base64url');
13
+ const now = Math.floor(Date.now() / 1000);
14
+ const expiresAt = now + days * 86_400;
15
+ const token = await new SignJWT({})
16
+ .setProtectedHeader({ alg: 'EdDSA' })
17
+ .setIssuer(new URL(externalUrl).href)
18
+ .setAudience(resource.href)
19
+ .setSubject(API_TOKEN_SUBJECT)
20
+ .setIssuedAt(now)
21
+ .setExpirationTime(expiresAt)
22
+ .setJti(id)
23
+ .sign(store.privateKey);
24
+ store.saveApiToken(id, { label, resource: resource.href, createdAt: now, expiresAt });
25
+ return { id, token, expiresAt };
26
+ }
27
+ //# sourceMappingURL=api-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-tokens.js","sourceRoot":"","sources":["../../src/auth/api-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAI/B,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAgB,EAChB,WAAmB,EACnB,QAAa,EACb,IAAY,EACZ,KAAa;IAEb,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;SAChC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,SAAS,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC;SACpC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC1B,UAAU,CAAC,iBAAiB,CAAC;SAC7B,WAAW,CAAC,GAAG,CAAC;SAChB,iBAAiB,CAAC,SAAS,CAAC;SAC5B,MAAM,CAAC,EAAE,CAAC;SACV,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IACtF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAClC,CAAC"}