Skip to content

feat: seed the MCP org example server as a remote first-run card - #2283

Merged
cliffhall merged 3 commits into
v2/mainfrom
v2/feat/2201-seed-example-server
Sep 7, 2026
Merged

feat: seed the MCP org example server as a remote first-run card#2283
cliffhall merged 3 commits into
v2/mainfrom
v2/feat/2201-seed-example-server

Conversation

@cliffhall

@cliffhall cliffhall commented Sep 7, 2026

Copy link
Copy Markdown
Member

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 to DEFAULT_SEED_CONFIG:

"example-server-default": {
  "type": "streamable-http",
  "url": "https://example-server.modelcontextprotocol.io/mcp"
}

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:

  • plain initialize → negotiates 2025-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" (the DEFAULT_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.
  • The Streamable HTTP / SSE example in the same file now leads with the live endpoint so it can be pasted as-is, and keeps a clearly-fictional my-http-server alongside it to go on illustrating headers (a made-up X-Tenant on 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, isolated MCP_CATALOG_PATH), headless Chromium, complete OAuth round trip with no credentials of any kind:

Seeded catalog — before / after

before after

Connected — after the OAuth flow, showing MCP 2025-11-25, with the monitor sidebar on Network: 20 real requests to example-server.modelcontextprotocol.io

Tools listed from the reference server, echo selected, Network tab still showing the live traffic

npm run format + npm run local:gate run. The gate went red once on SkillsScreen.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-running npm run local:storybook passed 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

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>
@cliffhall cliffhall added the v2 Issues and PRs for v2 label Sep 7, 2026
@cliffhall
cliffhall requested a balanced review from Copilot September 7, 2026 03:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Comment thread core/mcp/serverList.ts
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>
@cliffhall

Copy link
Copy Markdown
Member Author

Review round 1 — responses

One comment, addressed in 8fd9e41. Mirrored here since inline replies go hidden once the fix is pushed.

# File Finding Response
1 core/mcp/serverList.ts specification/v2_servers_file.md still documents a two-seed contract at :36-49, :79, :116 Fixed at :79 and :116; declined at :36-49 — see below

:79 and :116 — fixed. specification/ is a maintained design record in this repo, not a historical one, so the finding is right that a shipped change to the seed set belongs in it. :79 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 the set as 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 the list is exactly what went stale here. :116's // the two existing seeds comment is corrected, and its export function DEFAULT_SEED_CONFIG fixed to export const on the same line.

:36-49 — declined. That block is headed ## On-disk format and illustrates the file shape, not the seed set. The comment describes it as showing "only the local entries", which is not the case: it already carries a streamable-http entry (acme-api) alongside the two stdio ones, specifically to show the remote transport. A third real seed there would duplicate the seed list without teaching anything new about the format.

No behavior change in this round — docs only.

🤖 Generated with Claude Code

https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation and tests are consistent, with only a minor non-blocking timing inaccuracy in the specification wording.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread specification/v2_servers_file.md Outdated
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>
@cliffhall

Copy link
Copy Markdown
Member Author

Review round 2 — responses

🟢 Approval recommended, one comment. Addressed in d476dc5.

# File Finding Response
1 specification/v2_servers_file.md First-run behavior says the backend writes the catalog at boot; the write is actually in the GET /api/servers handler Fixed — and verified empirically

Correct. I checked it against a prod build with an isolated MCP_CATALOG_PATH rather than reading the handler and assuming:

after boot + GET /       : catalog ABSENT
GET /api/servers         : 200
after GET /api/servers   : catalog EXISTS

Booting the backend — even serving the SPA HTML on / — leaves the path untouched. The section now says "when the backend first serves the catalog — the GET /api/servers handler, not boot", and picks up two adjacent facts the boot-time phrasing also obscured: the write happens inside the write lock, so a concurrent POST/PUT/DELETE cannot be clobbered by it, and a read-only --config source is never seeded.

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

https://claude.ai/code/session_012x3rC3JXU17aW3uSwjPoi5

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The seed is correctly disconnected by default, consistently documented, and covered by appropriate unit and integration contracts.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The runtime change, tests, user documentation, launcher guidance, and maintained specification are consistent and complete.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@cliffhall cliffhall linked an issue Sep 7, 2026 that may be closed by this pull request
2 tasks
@cliffhall
cliffhall merged commit aab6475 into v2/main Sep 7, 2026
6 checks passed
@cliffhall
cliffhall deleted the v2/feat/2201-seed-example-server branch September 7, 2026 03:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a remote HTTP walkthrough for a first tool call

2 participants