docs/archives/120-mcp-server-module/implementation.md
MCP Server 模块采用了分层架构设计,确保了与 Core 模块的解耦:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ MCP Client │ │ MCP Client │ │ MCP Client │
│ (Claude Desktop)│ │ (MCP Inspector) │ │ (Custom App) │
└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘
│ │ │
└──────────────────────┼──────────────────────┘
│ MCP Protocol
┌────────────────────────────────────────────────┐
│ MCP Server │
│ ┌─────────────────────────────────────────┐ │
│ │ Transport Layer │ │
│ │ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ stdio │ │ Streamable HTTP │ │ │
│ │ └─────────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────┐ │
│ │ MCP Protocol Layer │ │
│ │ ┌─────────┐ │ │
│ │ │ Tools │ │ │
│ │ └─────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────┐ │
│ │ Service Adapter Layer │ │
│ └─────────────────────────────────────────┘ │
└────────────────────┬───────────────────────────┘
│
┌────────────────────────────────────────────────┐
│ Core Module │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │PromptService│ │ LLMService │ │ Template │ │
│ └─────────────┘ └─────────────┘ │ Manager │ │
│ ┌─────────────┐ ┌─────────────┐ └──────────┘ │
│ │HistoryMgr │ │ ModelMgr │ ┌──────────┐ │
│ └─────────────┘ └─────────────┘ │ Memory │ │
│ │ Storage │ │
│ └──────────┘ │
└────────────────────────────────────────────────┘
packages/mcp-server/
├── package.json # 项目配置和依赖
├── tsconfig.json # TypeScript 配置
├── src/
│ ├── index.ts # 主入口点(仅导出)
│ ├── start.ts # 启动入口点
│ ├── config/ # 配置管理
│ │ ├── environment.ts # 环境变量管理
│ │ ├── models.ts # 默认模型配置
│ │ └── templates.ts # 默认模板配置
│ ├── tools/ # MCP Tools 实现
│ │ ├── index.ts # Tools 导出
│ │ ├── optimize-user-prompt.ts # 用户提示词优化
│ │ ├── optimize-system-prompt.ts # 系统提示词优化
│ │ └── iterate-prompt.ts # 提示词迭代优化
│ ├── adapters/ # 服务适配层
│ │ ├── core-services.ts # Core 服务初始化和管理
│ │ ├── parameter-adapter.ts # 参数格式转换
│ │ └── error-handler.ts # 错误处理适配
│ └── utils/ # 工具函数
│ └── logging.ts # 日志工具
├── examples/ # 使用示例
│ ├── stdio-client.js # stdio 客户端示例
│ └── http-client.js # HTTP 客户端示例
├── docs/ # 文档
│ └── README.md # 使用说明
└── tests/ # 测试文件
├── tools.test.ts # Tools 测试
└── integration.test.ts # 集成测试
问题描述: Core 包的 defaultModels 在模块导入时就初始化,无法读取到后来通过 dotenv 加载的环境变量。
解决方案: 创建预加载脚本 (preload-env.js),在 Node.js 启动时预加载环境变量:
// preload-env.js
import { config } from 'dotenv';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 按优先级加载环境变量
const paths = [
resolve(process.cwd(), '.env.local'),
resolve(process.cwd(), '../.env.local'),
resolve(__dirname, '../../.env.local'),
// ... 更多路径
];
paths.forEach(path => {
try {
config({ path });
} catch (error) {
// 忽略文件不存在的错误
}
});
使用 -r 参数预加载:
{
"scripts": {
"dev": "node -r ./preload-env.js dist/start.js --transport=http"
}
}
问题描述: 在 src/index.ts 文件末尾有立即执行的代码,当 tsup 构建时会意外启动服务器并占用端口。
解决方案: 文件分离策略
src/index.ts - 只导出函数,不执行:// 导出 main 函数供外部调用
export { main };
src/start.ts - 专门用于启动:#!/usr/bin/env node
import { main } from './index.js';
// 启动服务器
main().catch(console.error);
{
"scripts": {
"build": "tsup src/index.ts src/start.ts --format cjs,esm --dts --clean",
"dev": "node -r ./preload-env.js dist/start.js --transport=http"
}
}
在开发过程中,我们使用了以下调试方法: