| import express, { Request, Response } from "express"; |
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; |
| import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; |
| import { z } from "zod"; |
|
|
| const server = new McpServer({ |
| name: "mcp-streamable-http", |
| version: "1.0.0", |
| }); |
|
|
| |
| const getChuckJoke = server.tool( |
| "get-chuck-joke", |
| "Get a random Chuck Norris joke", |
| async () => { |
| const response = await fetch("https://api.chucknorris.io/jokes/random"); |
| const data = await response.json(); |
| return { |
| content: [ |
| { |
| type: "text", |
| text: data.value, |
| }, |
| ], |
| }; |
| } |
| ); |
|
|
| |
| const getChuckJokeByCategory = server.tool( |
| "get-chuck-joke-by-category", |
| "Get a random Chuck Norris joke by category", |
| { |
| category: z.string().describe("Category of the Chuck Norris joke"), |
| }, |
| async (params: { category: string }) => { |
| const response = await fetch( |
| `https://api.chucknorris.io/jokes/random?category=${params.category}` |
| ); |
| const data = await response.json(); |
| return { |
| content: [ |
| { |
| type: "text", |
| text: data.value, |
| }, |
| ], |
| }; |
| } |
| ); |
|
|
| |
| const getChuckCategories = server.tool( |
| "get-chuck-categories", |
| "Get all available categories for Chuck Norris jokes", |
| async () => { |
| const response = await fetch("https://api.chucknorris.io/jokes/categories"); |
| const data = await response.json(); |
| return { |
| content: [ |
| { |
| type: "text", |
| text: data.join(", "), |
| }, |
| ], |
| }; |
| } |
| ); |
|
|
| |
| const getDadJoke = server.tool( |
| "get-dad-joke", |
| "Get a random dad joke", |
| async () => { |
| const response = await fetch("https://icanhazdadjoke.com/", { |
| headers: { |
| Accept: "application/json", |
| }, |
| }); |
| const data = await response.json(); |
| return { |
| content: [ |
| { |
| type: "text", |
| text: data.joke, |
| }, |
| ], |
| }; |
| } |
| ); |
|
|
| const app = express(); |
| app.use(express.json()); |
|
|
| const transport: StreamableHTTPServerTransport = |
| new StreamableHTTPServerTransport({ |
| sessionIdGenerator: undefined, |
| }); |
|
|
| |
| const setupServer = async () => { |
| await server.connect(transport); |
| }; |
|
|
| app.post("/mcp", async (req: Request, res: Response) => { |
| console.log("Received MCP request:", req.body); |
| try { |
| await transport.handleRequest(req, res, req.body); |
| } catch (error) { |
| console.error("Error handling MCP request:", error); |
| if (!res.headersSent) { |
| res.status(500).json({ |
| jsonrpc: "2.0", |
| error: { |
| code: -32603, |
| message: "Internal server error", |
| }, |
| id: null, |
| }); |
| } |
| } |
| }); |
|
|
| app.get("/mcp", async (req: Request, res: Response) => { |
| console.log("Received GET MCP request"); |
| res.writeHead(405).end( |
| JSON.stringify({ |
| jsonrpc: "2.0", |
| error: { |
| code: -32000, |
| message: "Method not allowed.", |
| }, |
| id: null, |
| }) |
| ); |
| }); |
|
|
| app.delete("/mcp", async (req: Request, res: Response) => { |
| console.log("Received DELETE MCP request"); |
| res.writeHead(405).end( |
| JSON.stringify({ |
| jsonrpc: "2.0", |
| error: { |
| code: -32000, |
| message: "Method not allowed.", |
| }, |
| id: null, |
| }) |
| ); |
| }); |
|
|
| |
| const PORT = process.env.PORT || 3000; |
| setupServer() |
| .then(() => { |
| app.listen(PORT, () => { |
| console.log(`MCP Streamable HTTP Server listening on port ${PORT}`); |
| }); |
| }) |
| .catch((error) => { |
| console.error("Failed to set up the server:", error); |
| process.exit(1); |
| }); |
|
|