@iflow-mcp/chess-mcp
Version:
A Model Context Protocol (MCP) server that provides an interactive chess game experience using MCP-UI. This server exposes chess game functionality through MCP tools and provides a web-based chessboard interface for playing games.
94 lines (93 loc) • 3.2 kB
JavaScript
import express, {} from "express";
import { randomUUID } from "node:crypto";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
import header from "./header";
import { validUUID } from "./uuid";
export function Middleware(newServer) {
const middleware = new McpServerMiddleware(newServer);
return middleware.middleware;
}
class McpServerMiddleware {
transports = {};
app = express();
newServer;
get middleware() {
return this.app;
}
constructor(newServer) {
this.newServer = newServer;
this.setup();
}
setup = () => {
this.app.use(express.json());
this.app.post("/", this.post);
this.app.get("/", this.post);
this.app.delete("/", this.getDelete);
};
newTransport = async (sessionId, req, res) => {
let transport;
if (sessionId) {
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
transport.sessionId = sessionId;
this.transports[sessionId] = transport;
transport.onclose = () => {
if (transport.sessionId) {
delete this.transports[transport.sessionId];
}
};
}
else {
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
onsessioninitialized: (sessionId) => {
this.transports[sessionId] = transport;
},
});
}
transport.onclose = () => {
if (transport.sessionId) {
delete this.transports[transport.sessionId];
}
};
const server = await this.newServer(req, res, transport);
await server.connect(transport);
return transport;
};
post = async (req, res) => {
const sessionId = header(req.headers, "mcp-session-id");
let transport;
if (sessionId && this.transports[sessionId]) {
transport = this.transports[sessionId];
}
else if ((!sessionId && isInitializeRequest(req.body)) ||
validUUID(sessionId)) {
transport = await this.newTransport(sessionId, req, res);
}
else {
res.status(404).json({
jsonrpc: "2.0",
error: {
code: -32000,
message: "Bad Request: No valid session ID provided",
},
id: null,
});
return;
}
await transport.handleRequest(req, res, req.body);
};
getDelete = async (req, res) => {
const sessionId = header(req.headers, "mcp-session-id");
const transport = sessionId && this.transports[sessionId];
if (!transport) {
res
.status(400)
.send(`Invalid or missing session ID: ${sessionId ? sessionId.slice(0, 8) : "none"}`);
return;
}
await transport.handleRequest(req, res);
};
}