server.ts•3.31 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
ListToolsRequestSchema,
CallToolRequestSchema,
ErrorCode,
McpError
} from '@modelcontextprotocol/sdk/types.js';
import { Config } from './config/config.js';
import { registerTools } from './tools/index.js';
interface ServerContext {
tools: ReturnType<typeof registerTools>;
}
export function createServer() {
// 创建服务器实例
const server = new Server({
name: 'project-tools',
version: '1.0.0'
}, {
capabilities: {
tools: {}
}
});
// 添加错误处理
server.onerror = (error) => {
console.error('服务器错误:', error instanceof Error ? error.message : String(error));
};
return server;
}
export function setupServer(server: Server, config: Config) {
try {
// 创建服务器上下文
const context: ServerContext = {
tools: [] // 初始化为空数组
};
// 注册工具列表处理器
server.setRequestHandler(ListToolsRequestSchema, async () => {
// 确保工具只被注册一次
if (context.tools.length === 0) {
context.tools = registerTools(server, config);
}
return {
tools: context.tools.map(tool => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema
}))
};
});
// 注册工具调用处理器
server.setRequestHandler(CallToolRequestSchema, async (request) => {
// 确保工具已注册
if (context.tools.length === 0) {
context.tools = registerTools(server, config);
}
const tool = context.tools.find(t => t.name === request.params.name);
if (!tool) {
throw new McpError(
ErrorCode.MethodNotFound,
`未知工具: ${request.params.name}`
);
}
try {
// 执行工具
const result = await tool.handler(request.params.arguments);
return result;
} catch (error) {
if (error instanceof McpError) {
throw error;
}
return {
content: [{
type: 'text',
text: `工具执行失败: ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
};
}
});
} catch (error) {
console.error('服务器设置失败:', error);
throw error;
}
}
export async function startServer(server: Server) {
try {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Project Tools MCP server running on stdio');
} catch (error) {
console.error('服务器启动失败:', error);
throw error;
}
}
// 确保在进程退出时清理资源
process.on('exit', () => {
try {
// 清理资源
console.error('正在清理资源...');
} catch (error) {
console.error('清理资源失败:', error);
}
});
// 处理未捕获的异常
process.on('uncaughtException', (error) => {
console.error('未捕获的异常:', error);
process.exit(1);
});
// 处理未处理的 Promise 拒绝
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的 Promise 拒绝:', reason);
});