diff --git a/examples/basic-server-preact/main.ts b/examples/basic-server-preact/main.ts new file mode 100644 index 00000000..d9a51a2e --- /dev/null +++ b/examples/basic-server-preact/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-server-basic-preact + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Preact)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-preact/package.json b/examples/basic-server-preact/package.json index 84cba1e2..2ec4738f 100644 --- a/examples/basic-server-preact/package.json +++ b/examples/basic-server-preact/package.json @@ -9,16 +9,14 @@ "directory": "examples/basic-server-preact" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -27,7 +25,9 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "preact": "^10.0.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@preact/preset-vite": "^2.0.0", @@ -35,11 +35,19 @@ "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-server-basic-preact": "dist/index.js" } } diff --git a/examples/basic-server-preact/server.ts b/examples/basic-server-preact/server.ts index 2f4af3dc..91711590 100644 --- a/examples/basic-server-preact/server.ts +++ b/examples/basic-server-preact/server.ts @@ -1,17 +1,14 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (Preact)", version: "1.0.0", @@ -55,17 +52,3 @@ function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (Preact)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-preact/tsconfig.server.json b/examples/basic-server-preact/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-preact/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-react/main.ts b/examples/basic-server-react/main.ts new file mode 100644 index 00000000..39840a13 --- /dev/null +++ b/examples/basic-server-react/main.ts @@ -0,0 +1,90 @@ +/** + * Entry point for running the MCP server. + * Run with: npx @modelcontextprotocol/server-basic-react + * Or: node dist/index.js [--stdio] + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (React)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-react/package.json b/examples/basic-server-react/package.json index 8cdcf617..62312332 100644 --- a/examples/basic-server-react/package.json +++ b/examples/basic-server-react/package.json @@ -9,16 +9,24 @@ "directory": "examples/basic-server-react" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", + "types": "dist/server.d.ts", + "bin": { + "mcp-server-basic-react": "dist/index.js" + }, "files": [ - "server.ts", - "server-utils.ts", "dist" ], + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -26,6 +34,8 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^4.1.13" @@ -38,9 +48,7 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" diff --git a/examples/basic-server-react/server.ts b/examples/basic-server-react/server.ts index 76d332a6..45b1dc99 100644 --- a/examples/basic-server-react/server.ts +++ b/examples/basic-server-react/server.ts @@ -1,10 +1,8 @@ import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -52,17 +50,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (React)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-react/tsconfig.server.json b/examples/basic-server-react/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-react/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-solid/main.ts b/examples/basic-server-solid/main.ts new file mode 100644 index 00000000..23353486 --- /dev/null +++ b/examples/basic-server-solid/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-server-basic-solid + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Solid)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-solid/package.json b/examples/basic-server-solid/package.json index 536c3171..3ee1c6f3 100644 --- a/examples/basic-server-solid/package.json +++ b/examples/basic-server-solid/package.json @@ -9,16 +9,14 @@ "directory": "examples/basic-server-solid" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -27,19 +25,29 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "solid-js": "^1.9.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0", "vite-plugin-solid": "^2.0.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-server-basic-solid": "dist/index.js" } } diff --git a/examples/basic-server-solid/server.ts b/examples/basic-server-solid/server.ts index 902649cf..6659ab70 100644 --- a/examples/basic-server-solid/server.ts +++ b/examples/basic-server-solid/server.ts @@ -1,17 +1,14 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (Solid)", version: "1.0.0", @@ -55,17 +52,3 @@ function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (Solid)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-solid/tsconfig.server.json b/examples/basic-server-solid/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-solid/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-svelte/main.ts b/examples/basic-server-svelte/main.ts new file mode 100644 index 00000000..762a40eb --- /dev/null +++ b/examples/basic-server-svelte/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-server-basic-svelte + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Svelte)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-svelte/package.json b/examples/basic-server-svelte/package.json index a5445bfd..33bf3b4b 100644 --- a/examples/basic-server-svelte/package.json +++ b/examples/basic-server-svelte/package.json @@ -9,16 +9,14 @@ "directory": "examples/basic-server-svelte" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -27,7 +25,9 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "svelte": "^5.0.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", @@ -35,11 +35,19 @@ "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-server-basic-svelte": "dist/index.js" } } diff --git a/examples/basic-server-svelte/server.ts b/examples/basic-server-svelte/server.ts index a9c2f4ab..b90e70b0 100644 --- a/examples/basic-server-svelte/server.ts +++ b/examples/basic-server-svelte/server.ts @@ -1,17 +1,14 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (Svelte)", version: "1.0.0", @@ -55,17 +52,3 @@ function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (Svelte)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-svelte/tsconfig.server.json b/examples/basic-server-svelte/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-svelte/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-vanillajs/main.ts b/examples/basic-server-vanillajs/main.ts new file mode 100644 index 00000000..d53d53b5 --- /dev/null +++ b/examples/basic-server-vanillajs/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-server-basic-vanillajs + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3102", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Vanilla JS)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-vanillajs/package.json b/examples/basic-server-vanillajs/package.json index 0643c732..f71899f0 100644 --- a/examples/basic-server-vanillajs/package.json +++ b/examples/basic-server-vanillajs/package.json @@ -9,16 +9,14 @@ "directory": "examples/basic-server-vanillajs" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -26,18 +24,28 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-server-basic-vanillajs": "dist/index.js" } } diff --git a/examples/basic-server-vanillajs/server-utils.ts b/examples/basic-server-vanillajs/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/basic-server-vanillajs/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/basic-server-vanillajs/server.ts b/examples/basic-server-vanillajs/server.ts index c95b3ca6..167b056f 100644 --- a/examples/basic-server-vanillajs/server.ts +++ b/examples/basic-server-vanillajs/server.ts @@ -1,12 +1,9 @@ import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); /** @@ -62,17 +59,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3102", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (Vanilla JS)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-vanillajs/tsconfig.server.json b/examples/basic-server-vanillajs/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-vanillajs/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-vue/main.ts b/examples/basic-server-vue/main.ts new file mode 100644 index 00000000..0304600e --- /dev/null +++ b/examples/basic-server-vue/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-server-basic-vue + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Vue)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-vue/package.json b/examples/basic-server-vue/package.json index 27af1337..386c7c63 100644 --- a/examples/basic-server-vue/package.json +++ b/examples/basic-server-vue/package.json @@ -9,16 +9,14 @@ "directory": "examples/basic-server-vue" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -27,7 +25,9 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "vue": "^3.5.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -35,11 +35,19 @@ "@types/node": "^22.0.0", "@vitejs/plugin-vue": "^5.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-server-basic-vue": "dist/index.js" } } diff --git a/examples/basic-server-vue/server-utils.ts b/examples/basic-server-vue/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/basic-server-vue/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/basic-server-vue/server.ts b/examples/basic-server-vue/server.ts index dcb08314..45762636 100644 --- a/examples/basic-server-vue/server.ts +++ b/examples/basic-server-vue/server.ts @@ -1,17 +1,14 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (Vue)", version: "1.0.0", @@ -55,17 +52,3 @@ function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Basic MCP App Server (Vue)" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/basic-server-vue/tsconfig.server.json b/examples/basic-server-vue/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/basic-server-vue/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-react/server-utils.ts b/examples/budget-allocator-server/main.ts similarity index 77% rename from examples/basic-server-react/server-utils.ts rename to examples/budget-allocator-server/main.ts index 9fe9745a..534e876d 100644 --- a/examples/basic-server-react/server-utils.ts +++ b/examples/budget-allocator-server/main.ts @@ -1,12 +1,20 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-budget-allocator-server + * Or: node dist/index.js [--stdio] + */ + /** * Shared utilities for running MCP servers with Streamable HTTP transport. */ +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; +import { createServer } from "./server.js"; export interface ServerOptions { port: number; @@ -70,3 +78,17 @@ export async function startServer( process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3103", 10); + await startServer(createServer, { port, name: "Marketing" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/budget-allocator-server/package.json b/examples/budget-allocator-server/package.json index 65de035b..843701ab 100644 --- a/examples/budget-allocator-server/package.json +++ b/examples/budget-allocator-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/budget-allocator-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,24 +22,35 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-budget-allocator-server": "dist/index.js" } } diff --git a/examples/budget-allocator-server/server-utils.ts b/examples/budget-allocator-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/budget-allocator-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/budget-allocator-server/server.ts b/examples/budget-allocator-server/server.ts index abc4a9b6..90fcef94 100755 --- a/examples/budget-allocator-server/server.ts +++ b/examples/budget-allocator-server/server.ts @@ -5,7 +5,6 @@ * and industry benchmarks by company stage. */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -18,8 +17,6 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); // --------------------------------------------------------------------------- @@ -335,17 +332,3 @@ export function createServer(): McpServer { // --------------------------------------------------------------------------- // Server Startup // --------------------------------------------------------------------------- - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3103", 10); - await startServer(createServer, { port, name: "Budget Allocator Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/budget-allocator-server/tsconfig.server.json b/examples/budget-allocator-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/budget-allocator-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/cohort-heatmap-server/main.ts b/examples/cohort-heatmap-server/main.ts new file mode 100644 index 00000000..0b716d1d --- /dev/null +++ b/examples/cohort-heatmap-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-cohort-heatmap-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3104", 10); + await startServer(createServer, { port, name: "Cohort Heatmap Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/cohort-heatmap-server/package.json b/examples/cohort-heatmap-server/package.json index 4798b999..833afb9c 100644 --- a/examples/cohort-heatmap-server/package.json +++ b/examples/cohort-heatmap-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/cohort-heatmap-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,14 +22,17 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -41,11 +42,19 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-cohort-heatmap-server": "dist/index.js" } } diff --git a/examples/cohort-heatmap-server/server-utils.ts b/examples/cohort-heatmap-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/cohort-heatmap-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/cohort-heatmap-server/server.ts b/examples/cohort-heatmap-server/server.ts index 7c79f91e..6f0c975f 100644 --- a/examples/cohort-heatmap-server/server.ts +++ b/examples/cohort-heatmap-server/server.ts @@ -1,5 +1,4 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; @@ -9,8 +8,6 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); // Schemas - types are derived from these using z.infer @@ -222,17 +219,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3104", 10); - await startServer(createServer, { port, name: "Cohort Heatmap Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/cohort-heatmap-server/tsconfig.server.json b/examples/cohort-heatmap-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/cohort-heatmap-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/customer-segmentation-server/main.ts b/examples/customer-segmentation-server/main.ts new file mode 100644 index 00000000..7be715a4 --- /dev/null +++ b/examples/customer-segmentation-server/main.ts @@ -0,0 +1,97 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-customer-segmentation-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3105", 10); + await startServer(createServer, { + port, + name: "Customer Segmentation Server", + }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/customer-segmentation-server/package.json b/examples/customer-segmentation-server/package.json index ee4ba8f7..50afe8df 100644 --- a/examples/customer-segmentation-server/package.json +++ b/examples/customer-segmentation-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/customer-segmentation-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,24 +22,35 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-customer-segmentation-server": "dist/index.js" } } diff --git a/examples/customer-segmentation-server/server-utils.ts b/examples/customer-segmentation-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/customer-segmentation-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/customer-segmentation-server/server.ts b/examples/customer-segmentation-server/server.ts index 28e43e78..8bfa65cc 100644 --- a/examples/customer-segmentation-server/server.ts +++ b/examples/customer-segmentation-server/server.ts @@ -1,5 +1,4 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,12 +11,11 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; import { generateCustomers, generateSegmentSummaries, -} from "./src/data-generator.ts"; -import { SEGMENTS, type Customer, type SegmentSummary } from "./src/types.ts"; +} from "./src/data-generator.js"; +import { SEGMENTS, type Customer, type SegmentSummary } from "./src/types.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -142,20 +140,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3105", 10); - await startServer(createServer, { - port, - name: "Customer Segmentation Server", - }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/customer-segmentation-server/src/data-generator.ts b/examples/customer-segmentation-server/src/data-generator.ts index 10cfd062..35e01a7a 100644 --- a/examples/customer-segmentation-server/src/data-generator.ts +++ b/examples/customer-segmentation-server/src/data-generator.ts @@ -1,5 +1,5 @@ -import type { Customer, SegmentSummary, SegmentName } from "./types.ts"; -import { SEGMENT_COLORS, SEGMENTS } from "./types.ts"; +import type { Customer, SegmentSummary, SegmentName } from "./types.js"; +import { SEGMENT_COLORS, SEGMENTS } from "./types.js"; // Company name generation const PREFIXES = [ diff --git a/examples/customer-segmentation-server/src/mcp-app.ts b/examples/customer-segmentation-server/src/mcp-app.ts index f02bc6bb..bc7c7e07 100644 --- a/examples/customer-segmentation-server/src/mcp-app.ts +++ b/examples/customer-segmentation-server/src/mcp-app.ts @@ -11,8 +11,8 @@ import { import { Chart, registerables } from "chart.js"; import "./global.css"; import "./mcp-app.css"; -import type { Customer, SegmentSummary, MetricName } from "./types.ts"; -import { SEGMENT_COLORS, METRIC_LABELS } from "./types.ts"; +import type { Customer, SegmentSummary, MetricName } from "./types.js"; +import { SEGMENT_COLORS, METRIC_LABELS } from "./types.js"; // Register Chart.js components Chart.register(...registerables); diff --git a/examples/customer-segmentation-server/tsconfig.server.json b/examples/customer-segmentation-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/customer-segmentation-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/integration-server/main.ts b/examples/integration-server/main.ts new file mode 100644 index 00000000..5340e8a8 --- /dev/null +++ b/examples/integration-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-integration-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Integration Test Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/integration-server/package.json b/examples/integration-server/package.json index ea17e4f3..b1c12688 100644 --- a/examples/integration-server/package.json +++ b/examples/integration-server/package.json @@ -4,21 +4,24 @@ "private": true, "type": "module", "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "../..", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -28,10 +31,22 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "main": "dist/server.js", + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "files": [ + "dist" + ], + "bin": { + "mcp-integration-server": "dist/index.js" } } diff --git a/examples/integration-server/server-utils.ts b/examples/integration-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/integration-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/integration-server/server.ts b/examples/integration-server/server.ts index f017e4d1..d86a9fd1 100644 --- a/examples/integration-server/server.ts +++ b/examples/integration-server/server.ts @@ -4,7 +4,6 @@ import { RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,8 +11,6 @@ import type { import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://get-time/mcp-app.html"; @@ -72,17 +69,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Integration Test Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/integration-server/tsconfig.server.json b/examples/integration-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/integration-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/map-server/server-utils.ts b/examples/map-server/main.ts similarity index 76% rename from examples/map-server/server-utils.ts rename to examples/map-server/main.ts index c700c818..44956598 100644 --- a/examples/map-server/server-utils.ts +++ b/examples/map-server/main.ts @@ -1,12 +1,20 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-map-server + * Or: node dist/index.js [--stdio] + */ + /** * Shared utilities for running MCP servers with Streamable HTTP transport. */ +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; +import { createServer } from "./server.js"; export interface ServerOptions { port: number; @@ -66,3 +74,17 @@ export async function startServer( process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "CesiumJS Map Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/map-server/package.json b/examples/map-server/package.json index f1c9db84..e2f372c0 100644 --- a/examples/map-server/package.json +++ b/examples/map-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/map-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,23 +22,34 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-map-server": "dist/index.js" } } diff --git a/examples/map-server/server.ts b/examples/map-server/server.ts index 26e64148..f860649f 100644 --- a/examples/map-server/server.ts +++ b/examples/map-server/server.ts @@ -6,7 +6,6 @@ * - show-map: Display an interactive 3D globe at a given location */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -20,7 +19,6 @@ import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; import { randomUUID } from "crypto"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -81,7 +79,7 @@ async function geocodeWithNominatim(query: string): Promise { ); } - return response.json(); + return response.json() as Promise; } /** @@ -256,17 +254,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "CesiumJS Map Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/map-server/tsconfig.server.json b/examples/map-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/map-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/pdf-server/.gitignore b/examples/pdf-server/.gitignore new file mode 100644 index 00000000..849ddff3 --- /dev/null +++ b/examples/pdf-server/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/examples/pdf-server/main.ts b/examples/pdf-server/main.ts new file mode 100644 index 00000000..ac0b8ccb --- /dev/null +++ b/examples/pdf-server/main.ts @@ -0,0 +1,130 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-pdf-server + * Or: node dist/index.js [--stdio] [pdf-urls...] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer, initializePdfIndex } from "./server.js"; +import { isArxivUrl, toFileUrl, normalizeArxivUrl } from "./src/pdf-indexer.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +const DEFAULT_PDF = "https://arxiv.org/pdf/1706.03762"; // Attention Is All You Need + +function parseArgs(): { urls: string[]; stdio: boolean } { + const args = process.argv.slice(2); + const urls: string[] = []; + let stdio = false; + + for (const arg of args) { + if (arg === "--stdio") { + stdio = true; + } else if (!arg.startsWith("-")) { + // Convert local paths to file:// URLs, normalize arxiv URLs + let url = arg; + if ( + !arg.startsWith("http://") && + !arg.startsWith("https://") && + !arg.startsWith("file://") + ) { + url = toFileUrl(arg); + } else if (isArxivUrl(arg)) { + url = normalizeArxivUrl(arg); + } + urls.push(url); + } + } + + return { urls: urls.length > 0 ? urls : [DEFAULT_PDF], stdio }; +} + +async function main() { + const { urls, stdio } = parseArgs(); + + console.error(`[pdf-server] Initializing with ${urls.length} PDF(s)...`); + await initializePdfIndex(urls); + console.error(`[pdf-server] Ready`); + + if (stdio) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3120", 10); + await startServer(createServer, { port, name: "PDF Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/pdf-server/package.json b/examples/pdf-server/package.json index 40a3d7cc..bead4234 100644 --- a/examples/pdf-server/package.json +++ b/examples/pdf-server/package.json @@ -9,37 +9,44 @@ "directory": "examples/pdf-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", - "src", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", - "watch": "cross-env NODE_ENV=development INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", - "serve:http": "bun --watch server.ts", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "start": "npm run serve" + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", + "watch": "cross-env INPUT=mcp-app.html vite build --watch", + "serve": "bun --watch main.ts", + "start": "cross-env NODE_ENV=development npm run build && npm run serve", + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "pdfjs-dist": "^5.0.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-pdf-server": "dist/index.js" } } diff --git a/examples/pdf-server/server-utils.ts b/examples/pdf-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/pdf-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/pdf-server/server.ts b/examples/pdf-server/server.ts index 883ed357..f07921fd 100644 --- a/examples/pdf-server/server.ts +++ b/examples/pdf-server/server.ts @@ -13,7 +13,6 @@ import { RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -29,7 +28,6 @@ import { createEntry, isArxivUrl, isFileUrl, - toFileUrl, normalizeArxivUrl, } from "./src/pdf-indexer.js"; import { loadPdfBytesChunk, populatePdfMetadata } from "./src/pdf-loader.js"; @@ -38,7 +36,6 @@ import { PdfBytesChunkSchema, type PdfIndex, } from "./src/types.js"; -import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://pdf-viewer/mcp-app.html"; @@ -46,6 +43,18 @@ const DEFAULT_PDF = "https://arxiv.org/pdf/1706.03762"; // Attention Is All You let pdfIndex: PdfIndex | null = null; +/** + * Initialize the PDF index with the given URLs. + * Must be called before createServer(). + */ +export async function initializePdfIndex(urls: string[]): Promise { + pdfIndex = await buildPdfIndex(urls); +} + +/** + * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. + */ export function createServer(): McpServer { const server = new McpServer({ name: "PDF Server", version: "1.0.0" }); @@ -204,51 +213,3 @@ The viewer supports zoom, navigation, text selection, and fullscreen mode.`, return server; } - -// CLI -function parseArgs(): { urls: string[]; stdio: boolean } { - const args = process.argv.slice(2); - const urls: string[] = []; - let stdio = false; - - for (const arg of args) { - if (arg === "--stdio") { - stdio = true; - } else if (!arg.startsWith("-")) { - // Convert local paths to file:// URLs, normalize arxiv URLs - let url = arg; - if ( - !arg.startsWith("http://") && - !arg.startsWith("https://") && - !arg.startsWith("file://") - ) { - url = toFileUrl(arg); - } else if (isArxivUrl(arg)) { - url = normalizeArxivUrl(arg); - } - urls.push(url); - } - } - - return { urls: urls.length > 0 ? urls : [DEFAULT_PDF], stdio }; -} - -async function main() { - const { urls, stdio } = parseArgs(); - - console.error(`[pdf-server] Initializing with ${urls.length} PDF(s)...`); - pdfIndex = await buildPdfIndex(urls); - console.error(`[pdf-server] Ready`); - - if (stdio) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "PDF Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/pdf-server/tsconfig.server.json b/examples/pdf-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/pdf-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/scenario-modeler-server/main.ts b/examples/scenario-modeler-server/main.ts new file mode 100644 index 00000000..b7cc7d00 --- /dev/null +++ b/examples/scenario-modeler-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-scenario-modeler-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3106", 10); + await startServer(createServer, { port, name: "SaaS Scenario Modeler" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/scenario-modeler-server/package.json b/examples/scenario-modeler-server/package.json index 4a32db76..44b00b53 100644 --- a/examples/scenario-modeler-server/package.json +++ b/examples/scenario-modeler-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/scenario-modeler-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,7 +22,8 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", @@ -32,7 +31,9 @@ "chart.js": "^4.4.0", "react": "^19.2.0", "react-dom": "^19.2.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -42,11 +43,19 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-scenario-modeler-server": "dist/index.js" } } diff --git a/examples/scenario-modeler-server/server-utils.ts b/examples/scenario-modeler-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/scenario-modeler-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/scenario-modeler-server/server.ts b/examples/scenario-modeler-server/server.ts index 86657f42..d3cbf0d1 100644 --- a/examples/scenario-modeler-server/server.ts +++ b/examples/scenario-modeler-server/server.ts @@ -4,7 +4,6 @@ import { registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,8 +11,6 @@ import type { import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); // ============================================================================ @@ -371,20 +368,3 @@ export function createServer(): McpServer { // ============================================================================ // Server Startup // ============================================================================ - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3106", 10); - await startServer(createServer, { - port, - name: "SaaS Scenario Modeler Server", - }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/scenario-modeler-server/tsconfig.server.json b/examples/scenario-modeler-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/scenario-modeler-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-solid/server-utils.ts b/examples/shadertoy-server/main.ts similarity index 77% rename from examples/basic-server-solid/server-utils.ts rename to examples/shadertoy-server/main.ts index 9fe9745a..717f5e64 100644 --- a/examples/basic-server-solid/server-utils.ts +++ b/examples/shadertoy-server/main.ts @@ -1,12 +1,20 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-shadertoy-server + * Or: node dist/index.js [--stdio] + */ + /** * Shared utilities for running MCP servers with Streamable HTTP transport. */ +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; +import { createServer } from "./server.js"; export interface ServerOptions { port: number; @@ -70,3 +78,17 @@ export async function startServer( process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "ShaderToy Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/shadertoy-server/package.json b/examples/shadertoy-server/package.json index 7164bcd1..c3f18666 100644 --- a/examples/shadertoy-server/package.json +++ b/examples/shadertoy-server/package.json @@ -9,16 +9,14 @@ "directory": "examples/shadertoy-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -26,18 +24,28 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-shadertoy-server": "dist/index.js" } } diff --git a/examples/shadertoy-server/server-utils.ts b/examples/shadertoy-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/shadertoy-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/shadertoy-server/server.ts b/examples/shadertoy-server/server.ts index ff4d336d..0d9ec8b6 100644 --- a/examples/shadertoy-server/server.ts +++ b/examples/shadertoy-server/server.ts @@ -4,7 +4,6 @@ import { RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,8 +11,6 @@ import type { import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); const TOOL_DESCRIPTION = `Renders a ShaderToy-compatible GLSL fragment shader in real-time using WebGL 2.0. @@ -140,17 +137,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "ShaderToy Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/shadertoy-server/tsconfig.server.json b/examples/shadertoy-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/shadertoy-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/sheet-music-server/main.ts b/examples/sheet-music-server/main.ts new file mode 100644 index 00000000..4b206e72 --- /dev/null +++ b/examples/sheet-music-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-sheet-music-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Sheet Music Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/sheet-music-server/package.json b/examples/sheet-music-server/package.json index 51aa9a20..ba0d57b1 100644 --- a/examples/sheet-music-server/package.json +++ b/examples/sheet-music-server/package.json @@ -9,16 +9,14 @@ "directory": "examples/sheet-music-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -27,18 +25,28 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "abcjs": "^6.4.4", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-sheet-music-server": "dist/index.js" } } diff --git a/examples/sheet-music-server/server-utils.ts b/examples/sheet-music-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/sheet-music-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/sheet-music-server/server.ts b/examples/sheet-music-server/server.ts index cec1c3d1..4a1cb8c8 100644 --- a/examples/sheet-music-server/server.ts +++ b/examples/sheet-music-server/server.ts @@ -12,9 +12,6 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); const DEFAULT_ABC_NOTATION_INPUT = `X:1 @@ -29,7 +26,7 @@ C C G G | A A G2 | F F E E | D D C2 |`; /** * Creates a new MCP server instance with the sheet music tool and resource. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Sheet Music Server", version: "1.0.0", @@ -115,17 +112,3 @@ function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Sheet Music Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/sheet-music-server/tsconfig.server.json b/examples/sheet-music-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/sheet-music-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/system-monitor-server/main.ts b/examples/system-monitor-server/main.ts new file mode 100644 index 00000000..19624809 --- /dev/null +++ b/examples/system-monitor-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-system-monitor-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3107", 10); + await startServer(createServer, { port, name: "System Monitor Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/system-monitor-server/package.json b/examples/system-monitor-server/package.json index 1df4c2bd..a42ecbc7 100644 --- a/examples/system-monitor-server/package.json +++ b/examples/system-monitor-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/system-monitor-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,25 +22,36 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "systeminformation": "^5.27.11", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-system-monitor-server": "dist/index.js" } } diff --git a/examples/system-monitor-server/server-utils.ts b/examples/system-monitor-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/system-monitor-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/system-monitor-server/server.ts b/examples/system-monitor-server/server.ts index 9283e211..1a1b56f9 100644 --- a/examples/system-monitor-server/server.ts +++ b/examples/system-monitor-server/server.ts @@ -4,7 +4,6 @@ import { registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -14,8 +13,6 @@ import os from "node:os"; import path from "node:path"; import si from "systeminformation"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - // Schemas - types are derived from these using z.infer const CpuCoreSchema = z.object({ idle: z.number(), @@ -204,17 +201,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3107", 10); - await startServer(createServer, { port, name: "System Monitor Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/system-monitor-server/tsconfig.server.json b/examples/system-monitor-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/system-monitor-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-preact/server-utils.ts b/examples/threejs-server/main.ts similarity index 77% rename from examples/basic-server-preact/server-utils.ts rename to examples/threejs-server/main.ts index 9fe9745a..1f779a97 100644 --- a/examples/basic-server-preact/server-utils.ts +++ b/examples/threejs-server/main.ts @@ -1,12 +1,20 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-threejs-server + * Or: node dist/index.js [--stdio] + */ + /** * Shared utilities for running MCP servers with Streamable HTTP transport. */ +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; +import { createServer } from "./server.js"; export interface ServerOptions { port: number; @@ -70,3 +78,17 @@ export async function startServer( process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3108", 10); + await startServer(createServer, { port, name: "Three.js Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/threejs-server/package.json b/examples/threejs-server/package.json index 0adc7049..25a3b8ee 100644 --- a/examples/threejs-server/package.json +++ b/examples/threejs-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/threejs-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,7 +22,8 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", @@ -32,7 +31,9 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "three": "^0.181.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -43,11 +44,19 @@ "@types/three": "^0.181.0", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-threejs-server": "dist/index.js" } } diff --git a/examples/threejs-server/server-utils.ts b/examples/threejs-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/threejs-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/threejs-server/server.ts b/examples/threejs-server/server.ts index 75ef7871..eef79976 100644 --- a/examples/threejs-server/server.ts +++ b/examples/threejs-server/server.ts @@ -9,16 +9,10 @@ import { registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - -// ============================================================================= -// Constants -// ============================================================================= const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -230,17 +224,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3108", 10); - await startServer(createServer, { port, name: "Three.js Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/threejs-server/tsconfig.server.json b/examples/threejs-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/threejs-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/transcript-server/main.ts b/examples/transcript-server/main.ts new file mode 100644 index 00000000..2a927041 --- /dev/null +++ b/examples/transcript-server/main.ts @@ -0,0 +1,91 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-transcript-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3109", 10); + await startServer(createServer, { port, name: "Transcript Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/transcript-server/package.json b/examples/transcript-server/package.json index 63bbd29d..43e17fe8 100644 --- a/examples/transcript-server/package.json +++ b/examples/transcript-server/package.json @@ -9,16 +9,14 @@ "directory": "examples/transcript-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -26,7 +24,9 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", - "zod": "^3.23.0" + "zod": "^3.23.0", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", @@ -34,11 +34,19 @@ "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-transcript-server": "dist/index.js" } } diff --git a/examples/transcript-server/server-utils.ts b/examples/transcript-server/server-utils.ts deleted file mode 100644 index 752edfaf..00000000 --- a/examples/transcript-server/server-utils.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/transcript-server/server.ts b/examples/transcript-server/server.ts index b4cdd09d..96afe09d 100644 --- a/examples/transcript-server/server.ts +++ b/examples/transcript-server/server.ts @@ -1,5 +1,4 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,8 +11,6 @@ import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://transcript/mcp-app.html"; @@ -84,17 +81,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3109", 10); - await startServer(createServer, { port, name: "Transcript Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/transcript-server/tsconfig.server.json b/examples/transcript-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/transcript-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/video-resource-server/main.ts b/examples/video-resource-server/main.ts new file mode 100644 index 00000000..ff304639 --- /dev/null +++ b/examples/video-resource-server/main.ts @@ -0,0 +1,94 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-video-resource-server + * Or: node dist/index.js [--stdio] + */ + +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; +import { createServer } from "./server.js"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, (err) => { + if (err) { + console.error("Failed to start server:", err); + process.exit(1); + } + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Video Resource Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/video-resource-server/package.json b/examples/video-resource-server/package.json index b35862fd..27ab7703 100644 --- a/examples/video-resource-server/package.json +++ b/examples/video-resource-server/package.json @@ -9,16 +9,14 @@ "directory": "examples/video-resource-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve": "bun --watch server.ts", + "serve": "bun --watch main.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" @@ -26,18 +24,28 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-video-resource-server": "dist/index.js" } } diff --git a/examples/video-resource-server/server-utils.ts b/examples/video-resource-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/video-resource-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/video-resource-server/server.ts b/examples/video-resource-server/server.ts index 7a793f2a..71be1a0c 100644 --- a/examples/video-resource-server/server.ts +++ b/examples/video-resource-server/server.ts @@ -13,7 +13,6 @@ import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -21,8 +20,6 @@ import type { import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://video-player/mcp-app.html"; @@ -56,7 +53,7 @@ const VIDEO_LIBRARY: Record = { }, }; -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Video Resource Server", version: "1.0.0", @@ -177,17 +174,3 @@ ${Object.entries(VIDEO_LIBRARY) return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3001", 10); - await startServer(createServer, { port, name: "Video Resource Server" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/video-resource-server/tsconfig.server.json b/examples/video-resource-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/video-resource-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/examples/basic-server-svelte/server-utils.ts b/examples/wiki-explorer-server/main.ts similarity index 77% rename from examples/basic-server-svelte/server-utils.ts rename to examples/wiki-explorer-server/main.ts index 9fe9745a..d83ac427 100644 --- a/examples/basic-server-svelte/server-utils.ts +++ b/examples/wiki-explorer-server/main.ts @@ -1,12 +1,20 @@ +/** + * Entry point for running the MCP server. + * Run with: npx mcp-wiki-explorer-server + * Or: node dist/index.js [--stdio] + */ + /** * Shared utilities for running MCP servers with Streamable HTTP transport. */ +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import cors from "cors"; import type { Request, Response } from "express"; +import { createServer } from "./server.js"; export interface ServerOptions { port: number; @@ -70,3 +78,17 @@ export async function startServer( process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3109", 10); + await startServer(createServer, { port, name: "Wiki Explorer" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/wiki-explorer-server/package.json b/examples/wiki-explorer-server/package.json index ce00dc71..d5666ba8 100644 --- a/examples/wiki-explorer-server/package.json +++ b/examples/wiki-explorer-server/package.json @@ -9,14 +9,12 @@ "directory": "examples/wiki-explorer-server" }, "license": "MIT", - "main": "server.ts", + "main": "dist/server.js", "files": [ - "server.ts", - "server-utils.ts", "dist" ], "scripts": { - "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", + "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve:http": "bun --watch server.ts", "serve:stdio": "bun server.ts --stdio", @@ -24,25 +22,36 @@ "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "serve": "bun --watch main.ts" }, "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "cheerio": "^1.0.0", - "zod": "^4.1.13" + "zod": "^4.1.13", + "cors": "^2.8.5", + "express": "^5.1.0" }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "force-graph": "^1.49.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" + }, + "types": "dist/server.d.ts", + "exports": { + ".": { + "types": "./dist/server.d.ts", + "default": "./dist/server.js" + } + }, + "bin": { + "mcp-wiki-explorer-server": "dist/index.js" } } diff --git a/examples/wiki-explorer-server/server-utils.ts b/examples/wiki-explorer-server/server-utils.ts deleted file mode 100644 index 9fe9745a..00000000 --- a/examples/wiki-explorer-server/server-utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Shared utilities for running MCP servers with Streamable HTTP transport. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -export interface ServerOptions { - port: number; - name?: string; -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - * @param options - Server configuration options. - */ -export async function startServer( - createServer: () => McpServer, - options: ServerOptions, -): Promise { - const { port, name = "MCP Server" } = options; - - const app = createMcpExpressApp({ host: "0.0.0.0" }); - app.use(cors()); - - app.all("/mcp", async (req: Request, res: Response) => { - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const httpServer = app.listen(port, (err) => { - if (err) { - console.error("Failed to start server:", err); - process.exit(1); - } - console.log(`${name} listening on http://localhost:${port}/mcp`); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); -} diff --git a/examples/wiki-explorer-server/server.ts b/examples/wiki-explorer-server/server.ts index 8c331509..faf1d661 100644 --- a/examples/wiki-explorer-server/server.ts +++ b/examples/wiki-explorer-server/server.ts @@ -4,7 +4,6 @@ import { registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -13,8 +12,6 @@ import * as cheerio from "cheerio"; import fs from "node:fs/promises"; import path from "node:path"; import { z } from "zod"; -import { startServer } from "./server-utils.js"; - const DIST_DIR = path.join(import.meta.dirname, "dist"); type PageInfo = { url: string; title: string }; @@ -169,17 +166,3 @@ export function createServer(): McpServer { return server; } - -async function main() { - if (process.argv.includes("--stdio")) { - await createServer().connect(new StdioServerTransport()); - } else { - const port = parseInt(process.env.PORT ?? "3109", 10); - await startServer(createServer, { port, name: "Wiki Explorer" }); - } -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/wiki-explorer-server/tsconfig.server.json b/examples/wiki-explorer-server/tsconfig.server.json new file mode 100644 index 00000000..05ddd8ec --- /dev/null +++ b/examples/wiki-explorer-server/tsconfig.server.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": ".", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["server.ts"] +} diff --git a/package-lock.json b/package-lock.json index 9f548c65..4930413f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -105,8 +105,6 @@ }, "examples/basic-host/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -117,18 +115,21 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "preact": "^10.0.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-preact": "dist/index.js" + }, "devDependencies": { "@preact/preset-vite": "^2.0.0", "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -144,8 +145,6 @@ }, "examples/basic-server-preact/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -156,10 +155,15 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-react": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", @@ -168,9 +172,7 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -186,8 +188,6 @@ }, "examples/basic-server-react/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -198,17 +198,20 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "solid-js": "^1.9.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-solid": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0", @@ -225,8 +228,6 @@ }, "examples/basic-server-solid/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -237,18 +238,21 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "svelte": "^5.0.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-svelte": "dist/index.js" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -264,8 +268,6 @@ }, "examples/basic-server-svelte/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -276,16 +278,19 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-vanillajs": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -301,8 +306,6 @@ }, "examples/basic-server-vanillajs/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -313,18 +316,21 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "vue": "^3.5.0", "zod": "^4.1.13" }, + "bin": { + "mcp-server-basic-vue": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "@vitejs/plugin-vue": "^5.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -340,8 +346,6 @@ }, "examples/basic-server-vue/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -353,16 +357,19 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-budget-allocator-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -378,8 +385,6 @@ }, "examples/budget-allocator-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -390,10 +395,15 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^4.1.13" }, + "bin": { + "mcp-cohort-heatmap-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", @@ -402,9 +412,7 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -420,8 +428,6 @@ }, "examples/cohort-heatmap-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -433,16 +439,19 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-customer-segmentation-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -458,8 +467,6 @@ }, "examples/customer-segmentation-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -468,10 +475,15 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "../..", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^4.1.13" }, + "bin": { + "mcp-integration-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", @@ -480,8 +492,6 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -497,8 +507,6 @@ }, "examples/integration-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -509,16 +517,19 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-map-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -534,8 +545,6 @@ }, "examples/map-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -546,17 +555,20 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "pdfjs-dist": "^5.0.0", "zod": "^4.1.13" }, + "bin": { + "mcp-pdf-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -572,8 +584,6 @@ }, "examples/pdf-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -585,10 +595,15 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^4.1.13" }, + "bin": { + "mcp-scenario-modeler-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", @@ -597,9 +612,7 @@ "@types/react-dom": "^19.2.2", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -615,8 +628,6 @@ }, "examples/scenario-modeler-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -627,16 +638,19 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-shadertoy-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -652,8 +666,6 @@ }, "examples/shadertoy-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -665,16 +677,19 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "abcjs": "^6.4.4", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-sheet-music-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -690,8 +705,6 @@ }, "examples/sheet-music-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -703,17 +716,20 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", + "cors": "^2.8.5", + "express": "^5.1.0", "systeminformation": "^5.27.11", "zod": "^4.1.13" }, + "bin": { + "mcp-system-monitor-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -729,8 +745,6 @@ }, "examples/system-monitor-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -741,11 +755,16 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "react": "^19.2.0", "react-dom": "^19.2.0", "three": "^0.181.0", "zod": "^4.1.13" }, + "bin": { + "mcp-threejs-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", @@ -755,9 +774,7 @@ "@types/three": "^0.181.0", "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -773,8 +790,6 @@ }, "examples/threejs-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -785,17 +800,20 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^3.23.0" }, + "bin": { + "mcp-transcript-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/dom-speech-recognition": "^0.0.7", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -811,15 +829,11 @@ }, "examples/transcript-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/transcript-server/node_modules/zod": { "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -832,16 +846,19 @@ "dependencies": { "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-video-resource-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" @@ -857,8 +874,6 @@ }, "examples/video-resource-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -870,16 +885,19 @@ "@modelcontextprotocol/ext-apps": "^0.4.0", "@modelcontextprotocol/sdk": "^1.24.0", "cheerio": "^1.0.0", + "cors": "^2.8.5", + "express": "^5.1.0", "zod": "^4.1.13" }, + "bin": { + "mcp-wiki-explorer-server": "dist/index.js" + }, "devDependencies": { "@types/cors": "^2.8.19", "@types/express": "^5.0.0", "@types/node": "^22.0.0", "concurrently": "^9.2.1", - "cors": "^2.8.5", "cross-env": "^10.1.0", - "express": "^5.1.0", "force-graph": "^1.49.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -896,8 +914,6 @@ }, "examples/wiki-explorer-server/node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -1769,9 +1785,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.8", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.8.tgz", - "integrity": "sha512-0/g2lIOPzX8f3vzW1ggQgvG5mjtFBDBHFAzI5SFAi2DzSqS9luJwqg9T6O/gKYLi+inS7eNxBeIFkkghIPvrMA==", + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -2790,9 +2806,9 @@ ] }, "node_modules/@oven/bun-linux-aarch64": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.3.5.tgz", - "integrity": "sha512-zkcHPI23QxJ1TdqafhgkXt1NOEN8o5C460sVeNnrhfJ43LwZgtfcvcQE39x/pBedu67fatY8CU0iY00nOh46ZQ==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.3.6.tgz", + "integrity": "sha512-YaQEAYjBanoOOtpqk/c5GGcfZIyxIIkQ2m1TbHjedRmJNwxzWBhGinSARFkrRIc3F8pRIGAopXKvJ/2rjN1LzQ==", "cpu": [ "arm64" ], @@ -2803,9 +2819,9 @@ ] }, "node_modules/@oven/bun-linux-aarch64-musl": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.3.5.tgz", - "integrity": "sha512-HKBeUlJdNduRkzJKZ5DXM+pPqntfC50/Hu2X65jVX0Y7hu/6IC8RaUTqpr8FtCZqqmc9wDK0OTL+Mbi9UQIKYQ==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.3.6.tgz", + "integrity": "sha512-FR+iJt17rfFgYgpxL3M67AUwujOgjw52ZJzB9vElI5jQXNjTyOKf8eH4meSk4vjlYF3h/AjKYd6pmN0OIUlVKQ==", "cpu": [ "arm64" ], @@ -3499,13 +3515,13 @@ } }, "node_modules/@types/bun": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.3.5.tgz", - "integrity": "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.3.6.tgz", + "integrity": "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==", "dev": true, "license": "MIT", "dependencies": { - "bun-types": "1.3.5" + "bun-types": "1.3.6" } }, "node_modules/@types/chai": { @@ -3602,9 +3618,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.6.tgz", - "integrity": "sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q==", + "version": "25.0.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.8.tgz", + "integrity": "sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg==", "dev": true, "license": "MIT", "dependencies": { @@ -3989,9 +4005,9 @@ "license": "MIT" }, "node_modules/@webgpu/types": { - "version": "0.1.68", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.68.tgz", - "integrity": "sha512-3ab1B59Ojb6RwjOspYLsTpCzbNB3ZaamIAxBMmvnNkiDoLTZUOBXZ9p5nAYVEkQlDdf6qAZWi1pqj9+ypiqznA==", + "version": "0.1.69", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz", + "integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==", "dev": true, "license": "BSD-3-Clause" }, @@ -4373,9 +4389,9 @@ } }, "node_modules/bun-types": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.5.tgz", - "integrity": "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.6.tgz", + "integrity": "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4993,9 +5009,9 @@ } }, "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.1.tgz", + "integrity": "sha512-ryitBnaRbXQtgZ/gU50GSn6jQRwinSCQclpakXymvLd8ytTgE5bmSfgYcUxD7XYL34qHhFDyVk71qqKsfSyvmA==", "dev": true, "license": "ISC", "engines": {