Files
wehub-resource-sync c56bef871b
Sync docs with Docusaurus / sync (push) Waiting to run
Tests / Check if changed (push) Waiting to run
Tests / format (push) Blocked by required conditions
Tests / check-imports (push) Blocked by required conditions
Tests / Unit / macos-latest (push) Blocked by required conditions
Tests / Unit / ubuntu-latest (push) Blocked by required conditions
Tests / Unit / windows-latest (push) Blocked by required conditions
Tests / mypy (push) Blocked by required conditions
Tests / Integration / ubuntu-latest (push) Blocked by required conditions
Tests / Integration / macos-latest (push) Blocked by required conditions
Tests / Integration / windows-latest (push) Blocked by required conditions
Tests / notify-slack-on-failure (push) Blocked by required conditions
Tests / Mark tests as completed (push) Blocked by required conditions
Docker image release / Build base image (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:28 +08:00

73 lines
2.7 KiB
TypeScript

// Files under `api/` become HTTP endpoints automatically — this is `/api/mcp`.
import { VercelRequest, VercelResponse } from "@vercel/node";
export default async function handler(req: VercelRequest, res: VercelResponse) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
res.setHeader(
"Access-Control-Allow-Headers",
"Content-Type, Accept, Mcp-Session-Id, Mcp-Protocol-Version"
);
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
if (req.method === "OPTIONS") {
return res.status(204).end();
}
if (req.method !== "POST") {
res.setHeader("Allow", "POST, OPTIONS");
return res.status(405).end("Method Not Allowed");
}
// Get environment variables
const { MCP_WORKSPACE_ID, SEARCH_API_TOKEN } = process.env;
if (!MCP_WORKSPACE_ID || !SEARCH_API_TOKEN) {
return res.status(500).json({ error: "MCP service is not configured." });
}
try {
// Forward the JSON-RPC body unchanged with the API key injected, so we
// don't need to know any MCP methods — new upstream tools just work.
const apiResponse = await fetch(
`https://api.cloud.deepset.ai/api/v2/workspaces/${MCP_WORKSPACE_ID}/mcp`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept:
(req.headers.accept as string) ||
"application/json, text/event-stream",
"X-Client-Source": "haystack-docs",
Authorization: `Bearer ${SEARCH_API_TOKEN}`,
// Forward MCP session id so upstream can correlate requests.
...(req.headers["mcp-session-id"] && {
"Mcp-Session-Id": req.headers["mcp-session-id"] as string,
}),
// Forward the protocol version the client negotiated.
...(req.headers["mcp-protocol-version"] && {
"Mcp-Protocol-Version": req.headers[
"mcp-protocol-version"
] as string,
}),
},
body: JSON.stringify(req.body),
}
);
// Pass the response through as-is (status, content-type, raw body).
const text = await apiResponse.text();
res.status(apiResponse.status);
const contentType = apiResponse.headers.get("content-type");
if (contentType) res.setHeader("Content-Type", contentType);
// Surface the session id back to the client (browsers can read it because
// it's in Access-Control-Expose-Headers above).
const sessionId = apiResponse.headers.get("mcp-session-id");
if (sessionId) res.setHeader("Mcp-Session-Id", sessionId);
return res.send(text);
} catch (error) {
console.error("MCP proxy error:", error);
return res.status(502).json({ error: "Failed to reach MCP upstream." });
}
}