Skip to content

Commit 7b090ca

Browse files
ochafikclaude
andcommitted
feat(examples): add SSE transport support to all example servers
Add backwards-compatible SSE transport support alongside the current Streamable HTTP transport. Each server now exposes: - /mcp (GET, POST, DELETE) - Streamable HTTP transport (current spec) - /sse (GET) - Legacy SSE transport stream endpoint - /messages (POST) - Legacy SSE transport message endpoint This enables older clients using the deprecated HTTP+SSE protocol (version 2024-11-05) to connect to the example servers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8075bff commit 7b090ca

9 files changed

Lines changed: 207 additions & 9 deletions

File tree

examples/basic-server-react/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
34
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
45
import cors from "cors";
@@ -62,7 +63,8 @@ const app = express();
6263
app.use(cors());
6364
app.use(express.json());
6465

65-
app.post("/mcp", async (req: Request, res: Response) => {
66+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
67+
app.all("/mcp", async (req: Request, res: Response) => {
6668
try {
6769
const transport = new StreamableHTTPServerTransport({
6870
sessionIdGenerator: undefined,
@@ -85,6 +87,26 @@ app.post("/mcp", async (req: Request, res: Response) => {
8587
}
8688
});
8789

90+
// Legacy SSE transport (deprecated) - for backwards compatibility
91+
const sseTransports = new Map<string, SSEServerTransport>();
92+
93+
app.get("/sse", async (_req: Request, res: Response) => {
94+
const transport = new SSEServerTransport("/messages", res);
95+
sseTransports.set(transport.sessionId, transport);
96+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
97+
await server.connect(transport);
98+
});
99+
100+
app.post("/messages", async (req: Request, res: Response) => {
101+
const sessionId = req.query.sessionId as string;
102+
const transport = sseTransports.get(sessionId);
103+
if (!transport) {
104+
res.status(404).json({ error: "Session not found" });
105+
return;
106+
}
107+
await transport.handlePostMessage(req, res, req.body);
108+
});
109+
88110
const httpServer = app.listen(PORT, (err) => {
89111
if (err) {
90112
console.error("Error starting server:", err);

examples/basic-server-vanillajs/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
34
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
45
import cors from "cors";
@@ -62,7 +63,8 @@ const app = express();
6263
app.use(cors());
6364
app.use(express.json());
6465

65-
app.post("/mcp", async (req: Request, res: Response) => {
66+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
67+
app.all("/mcp", async (req: Request, res: Response) => {
6668
try {
6769
const transport = new StreamableHTTPServerTransport({
6870
sessionIdGenerator: undefined,
@@ -85,6 +87,26 @@ app.post("/mcp", async (req: Request, res: Response) => {
8587
}
8688
});
8789

90+
// Legacy SSE transport (deprecated) - for backwards compatibility
91+
const sseTransports = new Map<string, SSEServerTransport>();
92+
93+
app.get("/sse", async (_req: Request, res: Response) => {
94+
const transport = new SSEServerTransport("/messages", res);
95+
sseTransports.set(transport.sessionId, transport);
96+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
97+
await server.connect(transport);
98+
});
99+
100+
app.post("/messages", async (req: Request, res: Response) => {
101+
const sessionId = req.query.sessionId as string;
102+
const transport = sseTransports.get(sessionId);
103+
if (!transport) {
104+
res.status(404).json({ error: "Session not found" });
105+
return;
106+
}
107+
await transport.handlePostMessage(req, res, req.body);
108+
});
109+
88110
const httpServer = app.listen(PORT, (err) => {
89111
if (err) {
90112
console.error("Error starting server:", err);

examples/budget-allocator-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* and industry benchmarks by company stage.
66
*/
77
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
89
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
910
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1011
import type {
@@ -306,7 +307,8 @@ async function main() {
306307
app.use(cors());
307308
app.use(express.json());
308309

309-
app.post("/mcp", async (req: Request, res: Response) => {
310+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
311+
app.all("/mcp", async (req: Request, res: Response) => {
310312
try {
311313
const transport = new StreamableHTTPServerTransport({
312314
sessionIdGenerator: undefined,
@@ -330,6 +332,26 @@ async function main() {
330332
}
331333
});
332334

335+
// Legacy SSE transport (deprecated) - for backwards compatibility
336+
const sseTransports = new Map<string, SSEServerTransport>();
337+
338+
app.get("/sse", async (_req: Request, res: Response) => {
339+
const transport = new SSEServerTransport("/messages", res);
340+
sseTransports.set(transport.sessionId, transport);
341+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
342+
await server.connect(transport);
343+
});
344+
345+
app.post("/messages", async (req: Request, res: Response) => {
346+
const sessionId = req.query.sessionId as string;
347+
const transport = sseTransports.get(sessionId);
348+
if (!transport) {
349+
res.status(404).json({ error: "Session not found" });
350+
return;
351+
}
352+
await transport.handlePostMessage(req, res, req.body);
353+
});
354+
333355
const httpServer = app.listen(PORT, (err) => {
334356
if (err) {
335357
console.error("Error starting server:", err);

examples/cohort-heatmap-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
45
import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
@@ -215,7 +216,8 @@ async function main() {
215216
app.use(cors());
216217
app.use(express.json());
217218

218-
app.post("/mcp", async (req: Request, res: Response) => {
219+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
220+
app.all("/mcp", async (req: Request, res: Response) => {
219221
try {
220222
const transport = new StreamableHTTPServerTransport({
221223
sessionIdGenerator: undefined,
@@ -240,6 +242,26 @@ async function main() {
240242
}
241243
});
242244

245+
// Legacy SSE transport (deprecated) - for backwards compatibility
246+
const sseTransports = new Map<string, SSEServerTransport>();
247+
248+
app.get("/sse", async (_req: Request, res: Response) => {
249+
const transport = new SSEServerTransport("/messages", res);
250+
sseTransports.set(transport.sessionId, transport);
251+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
252+
await server.connect(transport);
253+
});
254+
255+
app.post("/messages", async (req: Request, res: Response) => {
256+
const sessionId = req.query.sessionId as string;
257+
const transport = sseTransports.get(sessionId);
258+
if (!transport) {
259+
res.status(404).json({ error: "Session not found" });
260+
return;
261+
}
262+
await transport.handlePostMessage(req, res, req.body);
263+
});
264+
243265
const httpServer = app.listen(PORT, (err) => {
244266
if (err) {
245267
console.error("Error starting server:", err);

examples/customer-segmentation-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
45
import type {
@@ -114,7 +115,8 @@ async function main() {
114115
app.use(cors());
115116
app.use(express.json());
116117

117-
app.post("/mcp", async (req: Request, res: Response) => {
118+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
119+
app.all("/mcp", async (req: Request, res: Response) => {
118120
try {
119121
const transport = new StreamableHTTPServerTransport({
120122
sessionIdGenerator: undefined,
@@ -139,6 +141,26 @@ async function main() {
139141
}
140142
});
141143

144+
// Legacy SSE transport (deprecated) - for backwards compatibility
145+
const sseTransports = new Map<string, SSEServerTransport>();
146+
147+
app.get("/sse", async (_req: Request, res: Response) => {
148+
const transport = new SSEServerTransport("/messages", res);
149+
sseTransports.set(transport.sessionId, transport);
150+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
151+
await server.connect(transport);
152+
});
153+
154+
app.post("/messages", async (req: Request, res: Response) => {
155+
const sessionId = req.query.sessionId as string;
156+
const transport = sseTransports.get(sessionId);
157+
if (!transport) {
158+
res.status(404).json({ error: "Session not found" });
159+
return;
160+
}
161+
await transport.handlePostMessage(req, res, req.body);
162+
});
163+
142164
const httpServer = app.listen(PORT, (err) => {
143165
if (err) {
144166
console.error("Error starting server:", err);

examples/scenario-modeler-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
45
import type {
@@ -322,7 +323,8 @@ async function main() {
322323
app.use(cors());
323324
app.use(express.json());
324325

325-
app.post("/mcp", async (req: Request, res: Response) => {
326+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
327+
app.all("/mcp", async (req: Request, res: Response) => {
326328
try {
327329
const transport = new StreamableHTTPServerTransport({
328330
sessionIdGenerator: undefined,
@@ -346,6 +348,26 @@ async function main() {
346348
}
347349
});
348350

351+
// Legacy SSE transport (deprecated) - for backwards compatibility
352+
const sseTransports = new Map<string, SSEServerTransport>();
353+
354+
app.get("/sse", async (_req: Request, res: Response) => {
355+
const transport = new SSEServerTransport("/messages", res);
356+
sseTransports.set(transport.sessionId, transport);
357+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
358+
await server.connect(transport);
359+
});
360+
361+
app.post("/messages", async (req: Request, res: Response) => {
362+
const sessionId = req.query.sessionId as string;
363+
const transport = sseTransports.get(sessionId);
364+
if (!transport) {
365+
res.status(404).json({ error: "Session not found" });
366+
return;
367+
}
368+
await transport.handlePostMessage(req, res, req.body);
369+
});
370+
349371
const httpServer = app.listen(PORT, (err) => {
350372
if (err) {
351373
console.error("Error starting server:", err);

examples/system-monitor-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
45
import type {
@@ -186,7 +187,8 @@ async function main() {
186187
app.use(cors());
187188
app.use(express.json());
188189

189-
app.post("/mcp", async (req: Request, res: Response) => {
190+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
191+
app.all("/mcp", async (req: Request, res: Response) => {
190192
try {
191193
const transport = new StreamableHTTPServerTransport({
192194
sessionIdGenerator: undefined,
@@ -211,6 +213,26 @@ async function main() {
211213
}
212214
});
213215

216+
// Legacy SSE transport (deprecated) - for backwards compatibility
217+
const sseTransports = new Map<string, SSEServerTransport>();
218+
219+
app.get("/sse", async (_req: Request, res: Response) => {
220+
const transport = new SSEServerTransport("/messages", res);
221+
sseTransports.set(transport.sessionId, transport);
222+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
223+
await server.connect(transport);
224+
});
225+
226+
app.post("/messages", async (req: Request, res: Response) => {
227+
const sessionId = req.query.sessionId as string;
228+
const transport = sseTransports.get(sessionId);
229+
if (!transport) {
230+
res.status(404).json({ error: "Session not found" });
231+
return;
232+
}
233+
await transport.handlePostMessage(req, res, req.body);
234+
});
235+
214236
const httpServer = app.listen(PORT, (err) => {
215237
if (err) {
216238
console.error("Error starting server:", err);

examples/threejs-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Provides tools for rendering interactive 3D scenes using Three.js.
55
*/
66
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
78
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
89
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
910
import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
@@ -195,7 +196,8 @@ async function main() {
195196
app.use(cors());
196197
app.use(express.json());
197198

198-
app.post("/mcp", async (req: Request, res: Response) => {
199+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
200+
app.all("/mcp", async (req: Request, res: Response) => {
199201
try {
200202
const transport = new StreamableHTTPServerTransport({
201203
sessionIdGenerator: undefined,
@@ -220,6 +222,26 @@ async function main() {
220222
}
221223
});
222224

225+
// Legacy SSE transport (deprecated) - for backwards compatibility
226+
const sseTransports = new Map<string, SSEServerTransport>();
227+
228+
app.get("/sse", async (_req: Request, res: Response) => {
229+
const transport = new SSEServerTransport("/messages", res);
230+
sseTransports.set(transport.sessionId, transport);
231+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
232+
await server.connect(transport);
233+
});
234+
235+
app.post("/messages", async (req: Request, res: Response) => {
236+
const sessionId = req.query.sessionId as string;
237+
const transport = sseTransports.get(sessionId);
238+
if (!transport) {
239+
res.status(404).json({ error: "Session not found" });
240+
return;
241+
}
242+
await transport.handlePostMessage(req, res, req.body);
243+
});
244+
223245
const httpServer = app.listen(PORT, () => {
224246
console.log(`Three.js Server listening on http://localhost:${PORT}/mcp`);
225247
});

examples/wiki-explorer-server/server.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
23
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
45
import type {
@@ -152,7 +153,8 @@ async function main() {
152153
app.use(cors());
153154
app.use(express.json());
154155

155-
app.post("/mcp", async (req: Request, res: Response) => {
156+
// Streamable HTTP transport (current spec) - handles GET, POST, DELETE
157+
app.all("/mcp", async (req: Request, res: Response) => {
156158
try {
157159
const transport = new StreamableHTTPServerTransport({
158160
sessionIdGenerator: undefined,
@@ -177,6 +179,26 @@ async function main() {
177179
}
178180
});
179181

182+
// Legacy SSE transport (deprecated) - for backwards compatibility
183+
const sseTransports = new Map<string, SSEServerTransport>();
184+
185+
app.get("/sse", async (_req: Request, res: Response) => {
186+
const transport = new SSEServerTransport("/messages", res);
187+
sseTransports.set(transport.sessionId, transport);
188+
res.on("close", () => { sseTransports.delete(transport.sessionId); });
189+
await server.connect(transport);
190+
});
191+
192+
app.post("/messages", async (req: Request, res: Response) => {
193+
const sessionId = req.query.sessionId as string;
194+
const transport = sseTransports.get(sessionId);
195+
if (!transport) {
196+
res.status(404).json({ error: "Session not found" });
197+
return;
198+
}
199+
await transport.handlePostMessage(req, res, req.body);
200+
});
201+
180202
const httpServer = app.listen(PORT, () => {
181203
console.log(
182204
`Wiki Explorer server listening on http://localhost:${PORT}/mcp`,

0 commit comments

Comments
 (0)