Skip to content

Commit 3b87ef6

Browse files
committed
fix: cors headers
1 parent 2abafd2 commit 3b87ef6

1 file changed

Lines changed: 78 additions & 22 deletions

File tree

apps/mcp-server/src/index.ts

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,55 +26,111 @@ const PART_DESCRIPTIONS: Record<number, string> = {
2626
4: "Transitional Migration Features",
2727
};
2828

29+
// CORS allowed origins
30+
const ALLOWED_ORIGINS = ["https://ooxml.dev", "https://www.ooxml.dev"];
31+
const DEV_ORIGINS = ["http://localhost:5173", "http://127.0.0.1:5173"];
32+
33+
function getCorsHeaders(request: Request, env: Env): Record<string, string> {
34+
const origin = request.headers.get("Origin");
35+
if (!origin) return {};
36+
37+
// Check if origin is allowed
38+
const isProduction = !env.DATABASE_URL.includes("localhost");
39+
const allowedOrigins = isProduction ? ALLOWED_ORIGINS : [...ALLOWED_ORIGINS, ...DEV_ORIGINS];
40+
41+
if (allowedOrigins.includes(origin)) {
42+
return {
43+
"Access-Control-Allow-Origin": origin,
44+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
45+
"Access-Control-Allow-Headers": "Content-Type",
46+
};
47+
}
48+
49+
return {};
50+
}
51+
52+
function addCorsHeaders(response: Response, corsHeaders: Record<string, string>): Response {
53+
if (Object.keys(corsHeaders).length === 0) return response;
54+
55+
const newHeaders = new Headers(response.headers);
56+
for (const [key, value] of Object.entries(corsHeaders)) {
57+
newHeaders.set(key, value);
58+
}
59+
return new Response(response.body, {
60+
status: response.status,
61+
statusText: response.statusText,
62+
headers: newHeaders,
63+
});
64+
}
65+
2966
export default {
3067
async fetch(request: Request, env: Env, _ctx: ExecutionContext): Promise<Response> {
3168
const url = new URL(request.url);
69+
const corsHeaders = getCorsHeaders(request, env);
70+
71+
// Handle CORS preflight
72+
if (request.method === "OPTIONS") {
73+
return new Response(null, {
74+
status: 204,
75+
headers: corsHeaders,
76+
});
77+
}
3278

3379
// Health check
3480
if (url.pathname === "/health") {
35-
return new Response(JSON.stringify({ status: "ok" }), {
36-
headers: { "Content-Type": "application/json" },
37-
});
81+
return addCorsHeaders(
82+
new Response(JSON.stringify({ status: "ok" }), {
83+
headers: { "Content-Type": "application/json" },
84+
}),
85+
corsHeaders,
86+
);
3887
}
3988

4089
// MCP endpoint
4190
if (url.pathname === "/mcp" || url.pathname === "/sse") {
4291
if (request.method === "POST") {
4392
// MCP protocol (JSON-RPC)
44-
return handleMcpRequest(request, env);
93+
const response = await handleMcpRequest(request, env);
94+
return addCorsHeaders(response, corsHeaders);
4595
}
4696
// GET returns server info for debugging
47-
return handleMcpInfo();
97+
return addCorsHeaders(handleMcpInfo(), corsHeaders);
4898
}
4999

50100
// REST API endpoints
51101
if (url.pathname === "/search" && request.method === "POST") {
52-
return handleSearch(request, env);
102+
const response = await handleSearch(request, env);
103+
return addCorsHeaders(response, corsHeaders);
53104
}
54105

55106
if (url.pathname === "/section" && request.method === "GET") {
56-
return handleGetSection(request, env);
107+
const response = await handleGetSection(request, env);
108+
return addCorsHeaders(response, corsHeaders);
57109
}
58110

59111
if (url.pathname === "/stats") {
60-
return handleStats(env);
112+
const response = await handleStats(env);
113+
return addCorsHeaders(response, corsHeaders);
61114
}
62115

63-
return new Response(
64-
JSON.stringify({
65-
name: "ECMA-376 Spec MCP Server",
66-
version: "0.1.0",
67-
endpoints: {
68-
mcp: "/mcp",
69-
health: "/health",
70-
search: "POST /search",
71-
section: "GET /section?id=17.3.2&part=1",
72-
stats: "/stats",
116+
return addCorsHeaders(
117+
new Response(
118+
JSON.stringify({
119+
name: "ECMA-376 Spec MCP Server",
120+
version: "0.1.0",
121+
endpoints: {
122+
mcp: "/mcp",
123+
health: "/health",
124+
search: "POST /search",
125+
section: "GET /section?id=17.3.2&part=1",
126+
stats: "/stats",
127+
},
128+
}),
129+
{
130+
headers: { "Content-Type": "application/json" },
73131
},
74-
}),
75-
{
76-
headers: { "Content-Type": "application/json" },
77-
},
132+
),
133+
corsHeaders,
78134
);
79135
},
80136
};

0 commit comments

Comments
 (0)