feat: seed the MCP org example server as a remote first-run card (#2201)
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>
This commit is contained in:
parent
849eb08db0
commit
3e2546b040
2 changed files with 79 additions and 15 deletions
|
|
@ -3,6 +3,7 @@ import {
|
|||
cleanAuthorizationParams,
|
||||
cleanRoots,
|
||||
DEFAULT_SEED_CONFIG,
|
||||
EXAMPLE_SERVER_URL,
|
||||
envPairsToRecord,
|
||||
envRecordToPairs,
|
||||
expectedSecretFields,
|
||||
|
|
@ -865,17 +866,22 @@ describe("serializeMcpConfig", () => {
|
|||
});
|
||||
|
||||
describe("DEFAULT_SEED_CONFIG", () => {
|
||||
it("contains the two canonical seed servers", () => {
|
||||
it("contains the three canonical seed servers", () => {
|
||||
expect(Object.keys(DEFAULT_SEED_CONFIG.mcpServers)).toEqual([
|
||||
"filesystem-server-default",
|
||||
"everything-server-default",
|
||||
"example-server-default",
|
||||
]);
|
||||
});
|
||||
|
||||
it("uses stdio + npx for both seeds", () => {
|
||||
for (const cfg of Object.values(DEFAULT_SEED_CONFIG.mcpServers)) {
|
||||
expect(cfg.type).toBe("stdio");
|
||||
if (cfg.type === "stdio") {
|
||||
it("uses stdio + npx for both local seeds", () => {
|
||||
for (const key of [
|
||||
"filesystem-server-default",
|
||||
"everything-server-default",
|
||||
]) {
|
||||
const cfg = DEFAULT_SEED_CONFIG.mcpServers[key];
|
||||
expect(cfg?.type).toBe("stdio");
|
||||
if (cfg?.type === "stdio") {
|
||||
expect(cfg.command).toBe("npx");
|
||||
}
|
||||
}
|
||||
|
|
@ -887,6 +893,25 @@ describe("DEFAULT_SEED_CONFIG", () => {
|
|||
expect(fs.args).toContain("/tmp");
|
||||
}
|
||||
});
|
||||
|
||||
it("seeds the MCP org example server over streamable-http", () => {
|
||||
const example = DEFAULT_SEED_CONFIG.mcpServers["example-server-default"];
|
||||
expect(example?.type).toBe("streamable-http");
|
||||
if (example?.type === "streamable-http") {
|
||||
expect(example.url).toBe(EXAMPLE_SERVER_URL);
|
||||
expect(example.url).toBe(
|
||||
"https://example-server.modelcontextprotocol.io/mcp",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("leaves the remote seed on the default protocol era", () => {
|
||||
// Omitted rather than written as "legacy": `serverEntriesToMcpConfig`
|
||||
// strips the field when it equals DEFAULT_PROTOCOL_ERA, so a seed that
|
||||
// spelled it out would round-trip into a different file than it seeded.
|
||||
const example = DEFAULT_SEED_CONFIG.mcpServers["example-server-default"];
|
||||
expect(example).not.toHaveProperty("protocolEra");
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractSecretsFromStored", () => {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ describe("useServers", () => {
|
|||
expect(ids).toEqual([
|
||||
"filesystem-server-default",
|
||||
"everything-server-default",
|
||||
"example-server-default",
|
||||
]);
|
||||
// Map key is used as both id and name; connection initializes disconnected
|
||||
for (const s of result.current.servers) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue