Skip to content

Commit 8f4a0c7

Browse files
authored
Merge pull request #85 from modelcontextprotocol/add-stdio-transport
Add optional stdio transport to marketing example servers
2 parents ba1a27e + d6ff3d9 commit 8f4a0c7

File tree

5 files changed

+240
-183
lines changed

5 files changed

+240
-183
lines changed

examples/budget-allocator-server/server.ts

Lines changed: 48 additions & 37 deletions
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 { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
89
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
910
import type {
1011
CallToolResult,
@@ -292,50 +293,60 @@ server.registerResource(
292293
);
293294

294295
// ---------------------------------------------------------------------------
295-
// Express Server
296+
// Server Startup
296297
// ---------------------------------------------------------------------------
297298

298-
const app = express();
299-
app.use(cors());
300-
app.use(express.json());
301-
302-
app.post("/mcp", async (req: Request, res: Response) => {
303-
try {
304-
const transport = new StreamableHTTPServerTransport({
305-
sessionIdGenerator: undefined,
306-
enableJsonResponse: true,
299+
async function main() {
300+
if (process.argv.includes("--stdio")) {
301+
const transport = new StdioServerTransport();
302+
await server.connect(transport);
303+
console.error("Budget Allocator Server running in stdio mode");
304+
} else {
305+
const app = express();
306+
app.use(cors());
307+
app.use(express.json());
308+
309+
app.post("/mcp", async (req: Request, res: Response) => {
310+
try {
311+
const transport = new StreamableHTTPServerTransport({
312+
sessionIdGenerator: undefined,
313+
enableJsonResponse: true,
314+
});
315+
res.on("close", () => {
316+
transport.close();
317+
});
318+
319+
await server.connect(transport);
320+
await transport.handleRequest(req, res, req.body);
321+
} catch (error) {
322+
console.error("Error handling MCP request:", error);
323+
if (!res.headersSent) {
324+
res.status(500).json({
325+
jsonrpc: "2.0",
326+
error: { code: -32603, message: "Internal server error" },
327+
id: null,
328+
});
329+
}
330+
}
307331
});
308-
res.on("close", () => {
309-
transport.close();
332+
333+
const httpServer = app.listen(PORT, () => {
334+
console.log(
335+
`Budget Allocator Server listening on http://localhost:${PORT}/mcp`,
336+
);
310337
});
311338

312-
await server.connect(transport);
313-
await transport.handleRequest(req, res, req.body);
314-
} catch (error) {
315-
console.error("Error handling MCP request:", error);
316-
if (!res.headersSent) {
317-
res.status(500).json({
318-
jsonrpc: "2.0",
319-
error: { code: -32603, message: "Internal server error" },
320-
id: null,
339+
function shutdown() {
340+
console.log("\nShutting down...");
341+
httpServer.close(() => {
342+
console.log("Server closed");
343+
process.exit(0);
321344
});
322345
}
323-
}
324-
});
325346

326-
const httpServer = app.listen(PORT, () => {
327-
console.log(
328-
`Budget Allocator Server listening on http://localhost:${PORT}/mcp`,
329-
);
330-
});
331-
332-
function shutdown() {
333-
console.log("\nShutting down...");
334-
httpServer.close(() => {
335-
console.log("Server closed");
336-
process.exit(0);
337-
});
347+
process.on("SIGINT", shutdown);
348+
process.on("SIGTERM", shutdown);
349+
}
338350
}
339351

340-
process.on("SIGINT", shutdown);
341-
process.on("SIGTERM", shutdown);
352+
main().catch(console.error);

examples/cohort-heatmap-server/server.ts

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
34
import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
45
import cors from "cors";
@@ -204,46 +205,58 @@ const server = new McpServer({
204205
);
205206
}
206207

207-
const app = express();
208-
app.use(cors());
209-
app.use(express.json());
210-
211-
app.post("/mcp", async (req: Request, res: Response) => {
212-
try {
213-
const transport = new StreamableHTTPServerTransport({
214-
sessionIdGenerator: undefined,
215-
enableJsonResponse: true,
216-
});
217-
res.on("close", () => {
218-
transport.close();
208+
async function main() {
209+
if (process.argv.includes("--stdio")) {
210+
const transport = new StdioServerTransport();
211+
await server.connect(transport);
212+
console.error("Cohort Heatmap Server running in stdio mode");
213+
} else {
214+
const app = express();
215+
app.use(cors());
216+
app.use(express.json());
217+
218+
app.post("/mcp", async (req: Request, res: Response) => {
219+
try {
220+
const transport = new StreamableHTTPServerTransport({
221+
sessionIdGenerator: undefined,
222+
enableJsonResponse: true,
223+
});
224+
res.on("close", () => {
225+
transport.close();
226+
});
227+
228+
await server.connect(transport);
229+
230+
await transport.handleRequest(req, res, req.body);
231+
} catch (error) {
232+
console.error("Error handling MCP request:", error);
233+
if (!res.headersSent) {
234+
res.status(500).json({
235+
jsonrpc: "2.0",
236+
error: { code: -32603, message: "Internal server error" },
237+
id: null,
238+
});
239+
}
240+
}
219241
});
220242

221-
await server.connect(transport);
243+
const httpServer = app.listen(PORT, () => {
244+
console.log(
245+
`Cohort Heatmap Server listening on http://localhost:${PORT}/mcp`,
246+
);
247+
});
222248

223-
await transport.handleRequest(req, res, req.body);
224-
} catch (error) {
225-
console.error("Error handling MCP request:", error);
226-
if (!res.headersSent) {
227-
res.status(500).json({
228-
jsonrpc: "2.0",
229-
error: { code: -32603, message: "Internal server error" },
230-
id: null,
249+
function shutdown() {
250+
console.log("\nShutting down...");
251+
httpServer.close(() => {
252+
console.log("Server closed");
253+
process.exit(0);
231254
});
232255
}
233-
}
234-
});
235256

236-
const httpServer = app.listen(PORT, () => {
237-
console.log(`Server listening on http://localhost:${PORT}/mcp`);
238-
});
239-
240-
function shutdown() {
241-
console.log("\nShutting down...");
242-
httpServer.close(() => {
243-
console.log("Server closed");
244-
process.exit(0);
245-
});
257+
process.on("SIGINT", shutdown);
258+
process.on("SIGTERM", shutdown);
259+
}
246260
}
247261

248-
process.on("SIGINT", shutdown);
249-
process.on("SIGTERM", shutdown);
262+
main().catch(console.error);

examples/customer-segmentation-server/server.ts

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
34
import type {
45
CallToolResult,
@@ -103,48 +104,58 @@ const server = new McpServer({
103104
);
104105
}
105106

106-
const app = express();
107-
app.use(cors());
108-
app.use(express.json());
109-
110-
app.post("/mcp", async (req: Request, res: Response) => {
111-
try {
112-
const transport = new StreamableHTTPServerTransport({
113-
sessionIdGenerator: undefined,
114-
enableJsonResponse: true,
115-
});
116-
res.on("close", () => {
117-
transport.close();
107+
async function main() {
108+
if (process.argv.includes("--stdio")) {
109+
const transport = new StdioServerTransport();
110+
await server.connect(transport);
111+
console.error("Customer Segmentation Server running in stdio mode");
112+
} else {
113+
const app = express();
114+
app.use(cors());
115+
app.use(express.json());
116+
117+
app.post("/mcp", async (req: Request, res: Response) => {
118+
try {
119+
const transport = new StreamableHTTPServerTransport({
120+
sessionIdGenerator: undefined,
121+
enableJsonResponse: true,
122+
});
123+
res.on("close", () => {
124+
transport.close();
125+
});
126+
127+
await server.connect(transport);
128+
129+
await transport.handleRequest(req, res, req.body);
130+
} catch (error) {
131+
console.error("Error handling MCP request:", error);
132+
if (!res.headersSent) {
133+
res.status(500).json({
134+
jsonrpc: "2.0",
135+
error: { code: -32603, message: "Internal server error" },
136+
id: null,
137+
});
138+
}
139+
}
118140
});
119141

120-
await server.connect(transport);
142+
const httpServer = app.listen(PORT, () => {
143+
console.log(
144+
`Customer Segmentation Server listening on http://localhost:${PORT}/mcp`,
145+
);
146+
});
121147

122-
await transport.handleRequest(req, res, req.body);
123-
} catch (error) {
124-
console.error("Error handling MCP request:", error);
125-
if (!res.headersSent) {
126-
res.status(500).json({
127-
jsonrpc: "2.0",
128-
error: { code: -32603, message: "Internal server error" },
129-
id: null,
148+
function shutdown() {
149+
console.log("\nShutting down...");
150+
httpServer.close(() => {
151+
console.log("Server closed");
152+
process.exit(0);
130153
});
131154
}
132-
}
133-
});
134-
135-
const httpServer = app.listen(PORT, () => {
136-
console.log(
137-
`Customer Segmentation Server listening on http://localhost:${PORT}/mcp`,
138-
);
139-
});
140155

141-
function shutdown() {
142-
console.log("\nShutting down...");
143-
httpServer.close(() => {
144-
console.log("Server closed");
145-
process.exit(0);
146-
});
156+
process.on("SIGINT", shutdown);
157+
process.on("SIGTERM", shutdown);
158+
}
147159
}
148160

149-
process.on("SIGINT", shutdown);
150-
process.on("SIGTERM", shutdown);
161+
main().catch(console.error);

0 commit comments

Comments
 (0)