Skip to main content
Glama
http.ts3.42 kB
#!/usr/bin/env node import express from "express"; import cors from "cors"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import createServer from "./index.js"; const app = express(); app.use(express.json()); // CORS for local development app.use( cors({ origin: "*", methods: ["GET", "POST", "DELETE", "OPTIONS"], allowedHeaders: ["Content-Type", "Mcp-Session-Id"], exposedHeaders: ["Mcp-Session-Id"], }) ); // MCP server instance (initialized on startup) let mcpServer: Awaited<ReturnType<typeof createServer>>; // Health check endpoint app.get("/health", (req, res) => { res.json({ status: "ok", transport: "streamable-http", server: "thoughtbox", version: "1.1.0", persistence: "enabled", }); }); // Server info on GET /mcp app.get("/mcp", (req, res) => { res.json({ status: "ok", server: { name: "thoughtbox-server", version: "1.1.0", transport: "streamable-http", mode: "stateless", persistence: "enabled", }, }); }); // Streamable HTTP endpoint - stateless mode app.post("/mcp", async (req, res) => { try { // In stateless mode, create a new transport for each request // This prevents request ID collisions between different clients const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, // Stateless mode enableJsonResponse: true, }); res.on("close", () => { transport.close(); }); await mcpServer.connect(transport); 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, }); } } }); // DELETE for session termination (not supported in stateless mode) app.delete("/mcp", (req, res) => { res.status(405).json({ jsonrpc: "2.0", error: { code: -32601, message: "Session termination not supported in stateless mode", }, id: null, }); }); // Startup function async function start() { // Create the MCP server with default config (synchronous factory) mcpServer = createServer({ config: { disableThoughtLogging: (process.env.DISABLE_THOUGHT_LOGGING || "").toLowerCase() === "true", }, }); const port = parseInt(process.env.PORT || "1729"); const server = app.listen(port, () => { console.log( `Thoughtbox MCP Server running on http://localhost:${port}/mcp` ); console.log(`Health check: http://localhost:${port}/health`); console.log(`Data directory: ${process.env.THOUGHTBOX_DATA_DIR || "~/.thoughtbox"}`); }); // Setup graceful shutdown after server is created setupGracefulShutdown(server); } // Graceful shutdown handlers function setupGracefulShutdown(server: ReturnType<typeof app.listen>) { const shutdown = (signal: string) => { console.log(`Received ${signal}, shutting down gracefully...`); server.close(() => { process.exit(0); }); }; process.on("SIGTERM", () => shutdown("SIGTERM")); process.on("SIGINT", () => shutdown("SIGINT")); } // Start the server start().catch((error) => { console.error("Fatal error starting server:", error); process.exit(1); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/glassBead-tc/Thoughtbox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server