@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.
- package/CHANGELOG.md +388 -0
- package/README.md +77 -12
- package/dist/admin.js +1 -1
- package/dist/admin.js.map +1 -1
- package/dist/auth/api-tokens.js +27 -0
- package/dist/auth/api-tokens.js.map +1 -0
- package/dist/auth/headers.js +22 -1
- package/dist/auth/headers.js.map +1 -1
- package/dist/auth/oidc/adapter.js +135 -0
- package/dist/auth/oidc/adapter.js.map +1 -0
- package/dist/auth/oidc/interactions.js +187 -0
- package/dist/auth/oidc/interactions.js.map +1 -0
- package/dist/auth/oidc/mount.js +144 -0
- package/dist/auth/oidc/mount.js.map +1 -0
- package/dist/auth/oidc/provider.js +440 -0
- package/dist/auth/oidc/provider.js.map +1 -0
- package/dist/auth/oidc/quirks.js +234 -0
- package/dist/auth/oidc/quirks.js.map +1 -0
- package/dist/auth/oidc/verifier.js +121 -0
- package/dist/auth/oidc/verifier.js.map +1 -0
- package/dist/auth/protected-resource.js +41 -0
- package/dist/auth/protected-resource.js.map +1 -0
- package/dist/auth/rate-limit.js +115 -2
- package/dist/auth/rate-limit.js.map +1 -1
- package/dist/auth/redirect-uri.js +33 -1
- package/dist/auth/redirect-uri.js.map +1 -1
- package/dist/auth/registration.js +1 -1
- package/dist/auth/registration.js.map +1 -1
- package/dist/auth/session.js +43 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/store.js +160 -1
- package/dist/auth/store.js.map +1 -1
- package/dist/config.js +55 -2
- package/dist/config.js.map +1 -1
- package/dist/docker-proxy/policy.js +1 -0
- package/dist/docker-proxy/policy.js.map +1 -1
- package/dist/docker-proxy/server.js +1 -0
- package/dist/docker-proxy/server.js.map +1 -1
- package/dist/elicitation.js +0 -0
- package/dist/elicitation.js.map +1 -0
- package/dist/forward.js +0 -0
- package/dist/forward.js.map +1 -0
- package/dist/hub.js +309 -29
- package/dist/hub.js.map +1 -1
- package/dist/index.js +103 -21
- package/dist/index.js.map +1 -1
- package/dist/limits.js +13 -1
- package/dist/limits.js.map +1 -1
- package/dist/mcp-limits.js +14 -2
- package/dist/mcp-limits.js.map +1 -1
- package/dist/proxy.js +246 -40
- package/dist/proxy.js.map +1 -1
- package/dist/stdio.js +71 -6
- package/dist/stdio.js.map +1 -1
- package/dist/subscriptions.js +236 -0
- package/dist/subscriptions.js.map +1 -0
- package/dist/supervisor.js +322 -22
- package/dist/supervisor.js.map +1 -1
- package/dist/timings.js +61 -0
- package/dist/timings.js.map +1 -0
- package/dist/tool-filter.js +1 -0
- package/dist/tool-filter.js.map +1 -1
- package/dist/transports/docker.js.map +1 -1
- package/dist/transports/stream.js +33 -20
- package/dist/transports/stream.js.map +1 -1
- package/dist/upstream/auth.js +1 -1
- package/dist/upstream/auth.js.map +1 -1
- package/dist/upstream/provider.js.map +1 -1
- package/dist/upstream/routes.js +3 -2
- package/dist/upstream/routes.js.map +1 -1
- package/package.json +19 -6
- package/dist/auth/private-key-jwt.js +0 -213
- package/dist/auth/private-key-jwt.js.map +0 -1
- package/dist/auth/provider.js +0 -437
- package/dist/auth/provider.js.map +0 -1
- package/dist/auth/routes.js +0 -249
- 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
|
[](https://mcp-hub.ni-c.de)
|
|
10
10
|
[](https://github.com/sponsors/ni-c)
|
|
11
11
|
|
|
12
|
-
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) gateway: it
|
|
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
|
|
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
|
-
-
|
|
370
|
-
subscriptions
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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/
|
|
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"}
|