server.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { createMcpApp } from "@json-render/mcp";
  2. import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
  3. import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
  4. import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
  5. import fs from "node:fs";
  6. import path from "node:path";
  7. import { fileURLToPath } from "node:url";
  8. import { catalog } from "./src/catalog.js";
  9. const __dirname = path.dirname(fileURLToPath(import.meta.url));
  10. function loadHtml(): string {
  11. const htmlPath = path.join(__dirname, "dist", "index.html");
  12. if (!fs.existsSync(htmlPath)) {
  13. throw new Error(
  14. `Built HTML not found at ${htmlPath}. Run 'pnpm build' first.`,
  15. );
  16. }
  17. return fs.readFileSync(htmlPath, "utf-8");
  18. }
  19. async function startStdio() {
  20. const html = loadHtml();
  21. const server = await createMcpApp({
  22. name: "json-render Example",
  23. version: "1.0.0",
  24. catalog,
  25. html,
  26. });
  27. await server.connect(new StdioServerTransport());
  28. }
  29. async function startHttp() {
  30. const html = loadHtml();
  31. const port = parseInt(process.env.PORT ?? "3001", 10);
  32. const expressApp = createMcpExpressApp({ host: "0.0.0.0" });
  33. expressApp.all("/mcp", async (req, res) => {
  34. const server = await createMcpApp({
  35. name: "json-render Example",
  36. version: "1.0.0",
  37. catalog,
  38. html,
  39. });
  40. const transport = new StreamableHTTPServerTransport({
  41. sessionIdGenerator: undefined,
  42. });
  43. res.on("close", () => {
  44. transport.close().catch(() => {});
  45. server.close().catch(() => {});
  46. });
  47. try {
  48. await server.connect(transport);
  49. await transport.handleRequest(req, res, req.body);
  50. } catch (error) {
  51. console.error("MCP error:", error);
  52. if (!res.headersSent) {
  53. res.status(500).json({
  54. jsonrpc: "2.0",
  55. error: { code: -32603, message: "Internal server error" },
  56. id: null,
  57. });
  58. }
  59. }
  60. });
  61. expressApp.listen(port, () => {
  62. console.log(`MCP server listening on http://localhost:${port}/mcp`);
  63. });
  64. }
  65. if (process.argv.includes("--stdio")) {
  66. startStdio().catch((e) => {
  67. console.error(e);
  68. process.exit(1);
  69. });
  70. } else {
  71. startHttp().catch((e) => {
  72. console.error(e);
  73. process.exit(1);
  74. });
  75. }