Skip to content

Commit a2cc1a6

Browse files
committed
feat(mcp): expose public MCP endpoint at /mcp for Claude connectors
1 parent e03744a commit a2cc1a6

3 files changed

Lines changed: 56 additions & 6 deletions

File tree

‎apps/site/src/pages/.well-known/mcp/server-card.json.ts‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@ export const GET: APIRoute = async ({ locals }) => {
1616
"Search and access CodingCat.dev web development guides, coding tutorials, podcast episodes, and transcripts directly from AI models.",
1717
transport: {
1818
type: "streamable-http",
19-
endpoint: `${origin}/api/mcp`,
19+
endpoint: `${origin}/mcp`,
20+
},
21+
mcpServers: {
22+
main: {
23+
url: `${origin}/mcp`,
24+
name: "CodingCat.dev MCP Server",
25+
description:
26+
"Search and access CodingCat.dev web development guides, coding tutorials, podcast episodes, and transcripts",
27+
transport: "streamable-http",
28+
},
2029
},
2130
capabilities: {
2231
tools: { listChanged: false },
2332
resources: {},
2433
prompts: {},
2534
},
2635
auth: {
27-
type: "oauth2",
28-
authorizationServers: [origin],
36+
type: "none",
2937
},
3038
tools: [
3139
{
@@ -54,7 +62,7 @@ export const GET: APIRoute = async ({ locals }) => {
5462
"cache-control": "public, max-age=3600, s-maxage=86400",
5563
"access-control-allow-origin": "*",
5664
Vary: "Accept",
57-
Link: `<${origin}/api/mcp>; rel="mcp-endpoint", <${origin}/llms.txt>; rel="llms-txt"`,
65+
Link: `<${origin}/mcp>; rel="mcp-endpoint", <${origin}/llms.txt>; rel="llms-txt"`,
5866
},
5967
});
6068
};

‎apps/site/src/pages/api/mcp.ts‎

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,34 @@ export const OPTIONS: APIRoute = async () => {
3030
});
3131
};
3232

33-
export const GET: APIRoute = async ({ locals }) => {
33+
export const GET: APIRoute = async ({ request, locals }) => {
3434
const origin = locals.siteUrl.origin;
35+
const accept = request.headers.get("accept") || "";
36+
37+
// If client requests SSE stream (legacy MCP HTTP+SSE transport)
38+
if (accept.includes("text/event-stream")) {
39+
const encoder = new TextEncoder();
40+
const stream = new ReadableStream({
41+
start(controller) {
42+
controller.enqueue(
43+
encoder.encode(`event: endpoint\ndata: ${origin}/mcp\n\n`),
44+
);
45+
},
46+
});
47+
48+
return new Response(stream, {
49+
headers: {
50+
"content-type": "text/event-stream; charset=utf-8",
51+
"cache-control": "no-cache, no-transform",
52+
connection: "keep-alive",
53+
"access-control-allow-origin": "*",
54+
"access-control-allow-methods": "GET, POST, OPTIONS",
55+
"access-control-allow-headers":
56+
"Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version",
57+
},
58+
});
59+
}
60+
3561
return new Response(
3662
JSON.stringify(
3763
{
@@ -41,6 +67,7 @@ export const GET: APIRoute = async ({ locals }) => {
4167
protocolVersion: "2024-11-05",
4268
supportedVersions: ["2026-07-28", "2024-11-05"],
4369
transport: "streamable-http",
70+
endpoint: `${origin}/mcp`,
4471
serverCard: `${origin}/.well-known/mcp/server-card.json`,
4572
capabilities: {
4673
tools: { listChanged: false },
@@ -185,7 +212,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
185212
},
186213
type: {
187214
type: "string",
188-
enum: ["all", "post", "podcast"],
215+
enum: ["all", "post", "podcast", "author", "guest"],
189216
description:
190217
"Optional filter for content type (default: all)",
191218
},
@@ -214,6 +241,20 @@ export const POST: APIRoute = async ({ request, locals }) => {
214241
);
215242
}
216243

244+
// 6b. Resource templates list
245+
if (method === "resources/templates/list") {
246+
return new Response(
247+
JSON.stringify({
248+
jsonrpc: "2.0",
249+
id,
250+
result: {
251+
resourceTemplates: [],
252+
},
253+
}),
254+
{ headers: MCP_HEADERS },
255+
);
256+
}
257+
217258
// 7. Prompts list
218259
if (method === "prompts/list") {
219260
return new Response(

‎apps/site/src/pages/mcp.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { GET, OPTIONS, POST, prerender } from "./api/mcp";

0 commit comments

Comments
 (0)