feat: seed the MCP org example server as a remote first-run card - #2283
Conversation
Adds a third entry to `DEFAULT_SEED_CONFIG`, `example-server-default`, a Streamable HTTP card pointing at the MCP org's own feature-reference server (https://example-server.modelcontextprotocol.io/mcp). Until now every seeded server was a local stdio process and every remote example in the docs was a placeholder, so trying a remote connection meant finding or standing up a server first. The endpoint is protected by OAuth, but its authorization server advertises Dynamic Client Registration and fronts a *mock* upstream IdP, so the whole round trip completes with no account, no API key and no pre-registered client — which is what makes it viable as a shipped default. Verified end to end against a prod build: the card connects, negotiates MCP 2025-11-25 and lists the reference server's tools. The seed carries no `protocolEra`. That is not a default-by-omission: the server answers the plain `initialize` handshake and rejects `server/discover`, so it has no modern (SEP-2663) era to negotiate — `"auto"` would only buy a failed probe and `"modern"` would fail the connection outright. Docs updated alongside: the seeded-catalog block and per-client table in `docs/mcp-server-configuration.md`, the Streamable HTTP example there (which now leads with the live endpoint and keeps a placeholder to illustrate `headers`), and the seed description in `clients/launcher/README.md`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5 Signed-off-by: cliffhall <cliff@futurescale.com>
There was a problem hiding this comment.
🟡 Changes recommended
The server-list design specification still documents the obsolete two-server seed contract.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds the MCP organization’s remote feature-reference server to first-run web catalogs.
Changes:
- Adds the Streamable HTTP seed with legacy protocol behavior.
- Updates seed tests and documentation.
- Documents OAuth and remote connection behavior.
File summaries
| File | Description |
|---|---|
core/mcp/serverList.ts |
Adds the remote seed configuration. |
clients/web/src/test/core/mcp/serverList.test.ts |
Tests seed URL, transport, and protocol era. |
clients/web/src/test/core/react/useServers.test.tsx |
Verifies the third server appears disconnected. |
docs/mcp-server-configuration.md |
Documents the live remote example and seed catalog. |
clients/launcher/README.md |
Updates launcher seed descriptions. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Copilot review round 1. `specification/` is a maintained design record, not a historical one, so a shipped change to the seed set belongs in it. Two statements were stale and are now accurate: - **First-run behavior** said the backend writes "the two current `SEED_SERVERS`" — a reference to the `App.tsx` constant this design replaced. It now names `DEFAULT_SEED_CONFIG`, records that the set is three as of #2201, and points at `core/mcp/serverList.ts` as the source of truth for the contents rather than restating them; a second copy of a list is what goes stale. - The API sketch's `// the two existing seeds` comment is likewise corrected. Its `export function DEFAULT_SEED_CONFIG` is fixed to `export const` on the same line — it is a `const`, and leaving a known-wrong signature on a line being edited for accuracy is worse than the one-word fix. The On-disk format block is deliberately unchanged: it illustrates the file *shape*, not the seed set, and already carries a `streamable-http` entry (`acme-api`) alongside the two stdio ones. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5 Signed-off-by: cliffhall <cliff@futurescale.com>
Review round 1 — responsesOne comment, addressed in 8fd9e41. Mirrored here since inline replies go hidden once the fix is pushed.
No behavior change in this round — docs only. 🤖 Generated with Claude Code |
Copilot review round 2. The First-run behavior section said the backend writes the seed file "when the backend boots". It does not: the write lives in the `GET /api/servers` handler (`core/mcp/remote/node/server.ts`), so a backend that boots and never serves the list leaves the path untouched. Verified against a prod build with an isolated `MCP_CATALOG_PATH`: after boot + GET / : catalog ABSENT GET /api/servers : 200 after GET /api/servers : catalog EXISTS The section now says so, and picks up two adjacent facts the old wording also left out: the write happens inside the write lock (so a concurrent POST/PUT/DELETE cannot be clobbered), and a read-only `--config` source is never seeded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5 Signed-off-by: cliffhall <cliff@futurescale.com>
Review round 2 — responses🟢 Approval recommended, one comment. Addressed in d476dc5.
Correct. I checked it against a prod build with an isolated Booting the backend — even serving the SPA HTML on The inaccuracy predates this PR (it was the design's original future-tense phrasing). It is in scope because I edited that sentence in round 1, and a behavior spec whose one behavioral claim is wrong is worse than a stale count. Docs only again — no behavior change in either review round. 🤖 Generated with Claude Code |
Closes #2201
Every seeded server was a local stdio process and every remote example in the docs was a placeholder (
https://api.example.com/mcp), so trying a remote connection in the Inspector meant finding or standing up a server first. This adds a third entry toDEFAULT_SEED_CONFIG:That is the MCP org's own feature-reference server, per the direction on the issue — in-org rather than the third-party endpoint the reporter proposed.
Why this one is viable as a shipped default
It is protected by OAuth, which would normally disqualify a seed. It works anyway because its authorization server advertises Dynamic Client Registration and fronts a mock upstream IdP: no account, no API key, no pre-registered client. The user presses Connect, clicks through two consent screens, and is in. Everything it serves is synthetic reference data.
Nothing connects on its own — a seeded card is disconnected until the user toggles it, so the new entry makes no network request at first launch.
Protocol era
The seed carries no
protocolEra, and that is a deliberate match to the server rather than a default by omission. Probed directly:initialize→ negotiates2025-11-25✅server/discover→-32600 Invalid request method for existing session❌So it has no modern (SEP-2663) era to negotiate.
"auto"would only buy a failed probe on every connect and"modern"would fail the connection outright;"legacy"(theDEFAULT_PROTOCOL_ERA, omitted on disk) is correct. A test asserts the field stays absent, with that reasoning at the assertion.Docs
docs/mcp-server-configuration.md— the seeded-catalog JSON block, the per-client "Seeds a missing catalog with" row, and a paragraph on what the endpoint is and why it needs no credentials.my-http-serveralongside it to go on illustratingheaders(a made-upX-Tenanton a real URL would read as a working example that is not one).clients/launcher/README.md— the seed description and the two "two sample servers" references.Verification
Driven against a prod build (
npm run build, launcher--web, isolatedMCP_CATALOG_PATH), headless Chromium, complete OAuth round trip with no credentials of any kind:Seeded catalog — before / after
Connected — after the OAuth flow, showing
MCP 2025-11-25, with the monitor sidebar on Network: 20 real requests toexample-server.modelcontextprotocol.ioTools listed from the reference server,
echoselected, Network tab still showing the live trafficnpm run format+npm run local:gaterun. The gate went red once onSkillsScreen.stories.tsx > Long Skill Document, a collapse/reopen geometry assertion ([48, 202, 178, 262]vs[48, 202, 155, 285]) in a file this PR does not touch — the diff is seed data, two test files and docs, and no component source. Re-runningnpm run local:storybookpassed all 123 story files / 524 tests. Storybook is the last stage of the&&chain, so every prior stage was already green.🤖 Generated with Claude Code
https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5