Install registry servers by name through the MCP API - #7
Merged
Conversation
czpython
force-pushed
the
mcp-registry-2-headers
branch
3 times, most recently
from
July 13, 2026 20:14
477a963 to
f4cfca4
Compare
czpython
force-pushed
the
mcp-registry-3-install-api
branch
from
July 13, 2026 20:26
7c3c64f to
5f4d4cf
Compare
czpython
force-pushed
the
mcp-registry-2-headers
branch
2 times, most recently
from
July 14, 2026 06:20
d6980a2 to
b10836d
Compare
czpython
force-pushed
the
mcp-registry-3-install-api
branch
5 times, most recently
from
July 14, 2026 20:31
1d436d0 to
01adf65
Compare
GET /api/mcp-servers/registry?q= surfaces the resolved candidates — the route fetches (registry + pins) and the response models are pure projections: druks name, registry name, description, url, the official badge, the bearer classification, and each declared header input the form renders. Registry failures surface as a 502, an unreadable pins file as a named 500 — never an empty list that reads as "no such server". POST /api/mcp-servers grows the registry path beside the custom one: a body naming a registry entry is re-resolved server-side, so the url, the auth shape and each header's secrecy come from the registry — the client supplies only the druks name and the filled values. Required headers are enforced, unknown ones rejected, and the values split into the row's plain/secret columns by the spec's isSecret flags. A remote that authenticates through a secret header installs ready and enabled; anything else is assumed OAuth and ships dark until its Connect lands, exactly like the catalog's oauth default. Connect now looks the server up in the resolved view, so an installed registry row reuses the existing consent flow against its registry-supplied url; deleting a row drops its grant with it — an orphan grant would revive as the name's credential on re-add. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
czpython
force-pushed
the
mcp-registry-3-install-api
branch
from
July 14, 2026 20:41
01adf65 to
579bf0c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack 3/4 of the registry install feature (resolver → headers → install API → UI). Base:
mcp-registry-2-headers.What
GET /api/mcp-servers/registry?q=— resolved candidates for the picker. The route does all the fetching (registry search + trust pins);McpRegistryCandidateResponse/RegistryHeaderResponseare pure projections of the resolver's dicts, no I/O in schemas. Each candidate carries: druksname,registryName,description,url, theofficialbadge,tokenSource, and the declared header inputs (name/description/placeholder/isRequired/isSecret/format) the form renders. An unreachable registry maps to 502, an unreadable pins file to a named 500 — never an empty list.POST /api/mcp-serversgrows the registry path beside the unchanged custom one:{name, registry, headers}is re-resolved server-side — url, auth shape, and per-header secrecy come from the registry, never the client. Required headers enforced (named 422), unknown headers rejected, values split into the row's plain/secret columns by the spec'sisSecret.none-source, ready and enabled. Anything else is assumed OAuth (the streamable-http default) → ships dark until Connect lands, exactly like the catalog's linear default. Known ceiling, commented in place: the registry schema declares no auth mode, so a no-auth public server reads as oauth and its Connect fails at discovery.mcp/oauth.pydiscovery + consent flow against its registry-supplied url. The linear builtin path is untouched (its tests pass unmodified).McpOauthGrantand evicts the cached access token — an orphan grant would revive as the name's credential on re-add.Verify
HTTP tests on canned registry wire bytes (MockTransport under the real client + the packaged
trusted.json): search route projects candidates (badge,tokenSource, header specs, pinned sentry url) · 502 mapping · add-from-registry writes the row with the secret stored encrypted and redacted in every response · oauth candidate ships dark and Connect uses the row's url · missing-required/unknown-header 422s · uninstallable entry 404 · delete drops the grant.🤖 Generated with Claude Code