Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/http.config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,47 @@ describe("HTTP transport configuration", () => {
expect(status).toBe(200);
});
});

describe("stateless request handling", () => {
it("serves multiple sequential requests on one app instance", async () => {
await start();

const listTools = () =>
fetch(`${baseUrl}/mcp`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json, text/event-stream",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/list",
params: {},
}),
});

// A single server instance can only bind one transport, so the app must
// build a fresh pair per request; before that fix the second request
// failed with a 500 "Already connected to a transport".
const first = await listTools();
expect(first.status).toBe(200);

const second = await listTools();
expect(second.status).toBe(200);
const data = await second.json();
expect(data.result.tools).toHaveLength(4);
});

it("serves the health endpoint", async () => {
await start();

const response = await fetch(`${baseUrl}/health`);
expect(response.ok).toBe(true);
expect(await response.json()).toEqual({
status: "ok",
service: "perplexity-mcp-server",
});
});
});
});
6 changes: 4 additions & 2 deletions src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,19 @@ export function createHttpApp(options: HttpAppOptions): Express {

app.use(express.json());

const mcpServer = createPerplexityServer();

app.all("/mcp", async (req, res) => {
try {
// Stateless mode: a Protocol instance supports one transport, so build
// a fresh server + transport pair per request.
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true,
});
const mcpServer = createPerplexityServer();

res.on("close", () => {
transport.close();
mcpServer.close();
});

await mcpServer.connect(transport);
Expand Down