Skip to content

Commit 6ab6e6b

Browse files
committed
feat(mcp): add MCP Server Card at /.well-known/mcp/server-card.json
Implements SEP-1649 server card so MCP clients can discover the server's transport and capabilities without prior configuration. Version is read dynamically from package.json. The endpoint advertises the streamable-http transport mounted at /api/mcp. Spec: modelcontextprotocol/modelcontextprotocol#2127
1 parent 0d13f30 commit 6ab6e6b

2 files changed

Lines changed: 83 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { describe, it, expect } from "vitest";
2+
3+
import pkg from "../../../../../package.json";
4+
5+
import { GET } from "./route";
6+
7+
describe("GET /.well-known/mcp/server-card.json", () => {
8+
it("returns 200 with JSON content type", async () => {
9+
const response = GET();
10+
expect(response.status).toBe(200);
11+
expect(response.headers.get("Content-Type")).toBe("application/json");
12+
});
13+
14+
it("sets Cache-Control header for 1 hour", () => {
15+
const response = GET();
16+
expect(response.headers.get("Cache-Control")).toBe(
17+
"public, max-age=3600",
18+
);
19+
});
20+
21+
it("advertises serverInfo with name and dynamic package version", async () => {
22+
const response = GET();
23+
const body = await response.json();
24+
expect(body.serverInfo).toEqual({
25+
name: "firefly",
26+
version: pkg.version,
27+
});
28+
});
29+
30+
it("advertises streamable-http transport pointing at /api/mcp", async () => {
31+
const response = GET();
32+
const body = await response.json();
33+
expect(body.transport).toEqual({
34+
type: "streamable-http",
35+
endpoint: "/api/mcp",
36+
});
37+
});
38+
39+
it("advertises capabilities (tools + resources, no prompts)", async () => {
40+
const response = GET();
41+
const body = await response.json();
42+
expect(body.capabilities).toEqual({
43+
tools: true,
44+
resources: true,
45+
prompts: false,
46+
});
47+
});
48+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import pkg from "../../../../../package.json";
2+
3+
/**
4+
* MCP Server Card endpoint (SEP-1649).
5+
*
6+
* Advertises this server's MCP capabilities and transport so that clients
7+
* can discover the MCP endpoint without prior configuration.
8+
*
9+
* Spec: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127
10+
*/
11+
export function GET() {
12+
const body = {
13+
serverInfo: {
14+
name: "firefly",
15+
version: pkg.version,
16+
},
17+
transport: {
18+
type: "streamable-http",
19+
endpoint: "/api/mcp",
20+
},
21+
capabilities: {
22+
tools: true,
23+
resources: true,
24+
prompts: false,
25+
},
26+
};
27+
28+
return new Response(JSON.stringify(body), {
29+
status: 200,
30+
headers: {
31+
"Content-Type": "application/json",
32+
"Cache-Control": "public, max-age=3600",
33+
},
34+
});
35+
}

0 commit comments

Comments
 (0)