// ABOUTME: MCP SDK server wiring for Minesweeper tool requests.
// ABOUTME: Registers tool list/call handlers and formats tool responses.
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { Config, ConfigError } from "./config.js";
import { RailsClient, RailsHttpError } from "./rails/client.js";
import { createTools, ToolHandler } from "./tools/handlers.js";
import { ValidationError } from "./tools/validation.js";
type ToolResponse = {
content: { type: "text"; text: string }[];
isError?: boolean;
};
function toolText(text: string): { type: "text"; text: string }[] {
return [{ type: "text", text }];
}
export async function handleToolCall(
handlers: Map<string, ToolHandler>,
toolName: string,
args: unknown
): Promise<ToolResponse> {
const handler = handlers.get(toolName);
if (!handler) {
return { content: toolText(`Unknown tool: ${toolName}`), isError: true };
}
try {
const result = await handler(args);
return { content: toolText(JSON.stringify(result)) };
} catch (error) {
const messageText = formatToolError(error);
logError(error);
return { content: toolText(messageText), isError: true };
}
}
export function createServer(config: Config): Server {
const rails = new RailsClient(config);
const { definitions, handlers } = createTools(rails);
const server = new Server(
{ name: "minesweeper-mcp", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: definitions,
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (!name) {
return { content: toolText("Missing tool name"), isError: true };
}
return handleToolCall(handlers, name, args);
});
return server;
}
function formatToolError(error: unknown): string {
if (error instanceof ValidationError) {
return error.message;
}
if (error instanceof ConfigError) {
return error.message;
}
if (error instanceof RailsHttpError) {
return error.message;
}
if (error instanceof Error) {
return error.message || "Unexpected error";
}
return "Unexpected error";
}
function logError(error: unknown): void {
if (error instanceof RailsHttpError) {
console.error(JSON.stringify({ level: "error", status: error.status, message: error.message }));
return;
}
if (error instanceof Error) {
console.error(JSON.stringify({ level: "error", message: error.message }));
return;
}
console.error(JSON.stringify({ level: "error", message: "Unknown error" }));
}