import { FastMCP } from "fastmcp";
import { logger } from "./common/utils.js";
import {
GroupTextByJsonSchema,
TextToJsonSchema,
} from "./common/types.js";
import { groupTextByJsonTool, textToJsonTool } from "./common/tools.js";
import {
MCP_SERVER_NAME,
TOOL_NAMES,
VERSION,
} from "./common/constants.js";
// 创建FastMCP服务器
const mcp = new FastMCP({
name: MCP_SERVER_NAME,
version: VERSION,
// 配置健康检查
health: {
enabled: true,
path: "/health",
message: "Custom Context MCP Server is running",
status: 200,
},
// 配置ping
ping: {
enabled: true,
intervalMs: 5000,
logLevel: "debug",
},
});
// 注册工具
mcp.addTool({
name: TOOL_NAMES.groupTextByJson,
description: "Gives a prompt text for AI to group text based on JSON placeholders. This tool accepts a JSON template with placeholders.",
parameters: GroupTextByJsonSchema,
execute: async (args: { template: string }) => {
logger.info(`[FastMCP] Calling ${TOOL_NAMES.groupTextByJson} with template: ${args.template}`);
const result = await groupTextByJsonTool(args.template);
return result.content[0].text;
},
});
mcp.addTool({
name: TOOL_NAMES.textToJson,
description: `Converts groupped text from ${TOOL_NAMES.groupTextByJson} tool to JSON. This tool accepts a JSON template with placeholders and groupped text from ${TOOL_NAMES.groupTextByJson} tool.`,
parameters: TextToJsonSchema,
execute: async (args: { template: string; text: string }) => {
logger.info(`[FastMCP] Calling ${TOOL_NAMES.textToJson} with template: ${args.template}`);
const result = await textToJsonTool(args.template, args.text);
return result.content[0].text;
},
});
async function runServer() {
try {
logger.info("Initializing Custom Context MCP Server with FastMCP and SSE...");
// 启动FastMCP服务器(支持SSE和HTTP流)
await mcp.start({
transportType: "httpStream",
httpStream: {
port: 3005,
endpoint: "/sse", // 改为/sse以匹配mcp-inspector的期望
},
});
logger.info("Custom Context MCP Server running with FastMCP and SSE");
logger.info(
"Server information:",
JSON.stringify({
name: MCP_SERVER_NAME,
version: VERSION,
tools: [TOOL_NAMES.groupTextByJson, TOOL_NAMES.textToJson],
transport: "httpStream with SSE",
health: "/health",
port: 3005,
endpoint: "/sse",
})
);
logger.info("MCP Server is ready to accept requests");
process.on("SIGINT", () => {
logger.info("Received SIGINT signal, shutting down...");
process.exit(0);
});
process.on("SIGTERM", () => {
logger.info("Received SIGTERM signal, shutting down...");
process.exit(0);
});
process.on("uncaughtException", (error: Error) => {
logger.error("Uncaught exception:", error);
});
} catch (error) {
logger.error("Fatal error during server initialization:", error);
process.exit(1);
}
}
runServer().catch((error) => {
logger.error("Fatal error while running server:", error);
if (error instanceof Error) {
logger.error("Stack trace:", error.stack);
}
process.exit(1);
});