Skip to main content
Glama
PLAN-001-project-initialization.md15.9 kB
# PLAN-001: 聚义厅MCP项目初始化 ## 📋 任务概述 完成聚义厅MCP客户端项目的基础架构搭建,包括项目结构创建、依赖配置、基础类型定义和开发环境设置。 ## 🎯 目标成果 - [ ] 项目目录结构完整 - [ ] package.json和tsconfig.json配置完成 - [ ] 核心依赖安装成功 - [ ] 基础类型定义完成 - [ ] 开发环境可正常运行 ## 📅 时间规划 **预计耗时**: 2-3天 **优先级**: 高 **依赖**: 无 ## 🔧 具体实施步骤 ### 步骤1: 创建项目基础结构 ```bash # 进入juyitingmcp目录 cd juyitingmcp # 创建src目录结构 mkdir -p src/utils mkdir -p tests/{unit,integration,fixtures} mkdir -p examples mkdir -p scripts mkdir -p dist ``` ### 步骤2: 初始化package.json ```json { "name": "@juyiting/mcp-client", "version": "1.0.0", "description": "聚义厅MCP客户端 - AI人格协作工具", "main": "dist/server.js", "type": "module", "bin": { "juyiting-mcp": "./dist/server.js" }, "files": [ "dist", "README.md", "LICENSE" ], "scripts": { "dev": "tsx src/server.ts", "build": "tsc", "start": "node dist/server.js", "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", "lint": "eslint src/**/*.ts", "lint:fix": "eslint src/**/*.ts --fix", "type-check": "tsc --noEmit", "clean": "rm -rf dist", "package": "npm run build && pkg dist/server.js --targets node18-macos-x64,node18-win-x64,node18-linux-x64 --out-path ./releases" }, "keywords": [ "mcp", "model-context-protocol", "ai", "persona", "collaboration", "juyiting" ], "author": "聚义厅技术团队", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.12.3", "commander": "^12.1.0", "zod": "^3.25.67", "posthog-node": "^5.1.1" }, "devDependencies": { "@types/node": "^24.0.3", "typescript": "^5.8.3", "tsx": "^4.20.3", "jest": "^29.0.0", "ts-jest": "^29.0.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "eslint": "^8.0.0", "prettier": "^3.0.0", "pkg": "^5.8.1" } } ``` ### 步骤3: 配置TypeScript (tsconfig.json) ```json { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "rootDir": "./src", "declaration": true, "declarationMap": true, "sourceMap": true, "resolveJsonModule": true, "allowSyntheticDefaultImports": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "tests"] } ``` ### 步骤4: 配置ESLint (.eslintrc.json) ```json { "extends": [ "@typescript-eslint/recommended", "prettier" ], "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "parserOptions": { "ecmaVersion": 2022, "sourceType": "module" }, "rules": { "@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/explicit-function-return-type": "warn", "@typescript-eslint/no-explicit-any": "warn", "prefer-const": "error", "no-var": "error" } } ``` ### 步骤5: 配置Prettier (.prettierrc) ```json { "semi": true, "trailingComma": "es5", "singleQuote": true, "printWidth": 100, "tabWidth": 2, "useTabs": false } ``` ### 步骤6: 配置Jest (jest.config.js) ```javascript export default { preset: 'ts-jest/presets/default-esm', extensionsToTreatAsEsm: ['.ts'], testEnvironment: 'node', roots: ['<rootDir>/src', '<rootDir>/tests'], testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], transform: { '^.+\\.ts$': ['ts-jest', { useESM: true }] }, collectCoverageFrom: [ 'src/**/*.ts', '!src/**/*.d.ts', '!src/index.ts' ], coverageDirectory: 'coverage', coverageReporters: ['text', 'lcov', 'html'] }; ``` ### 步骤7: 创建核心类型定义 (src/types.ts) ```typescript // 核心人格接口 export interface Persona { id: string; name: string; rule: string; goal: string; version: string; description?: string; category?: string; tags?: string[]; source?: 'local' | 'remote' | 'default'; capabilities?: string[]; limitations?: string[]; examples?: string[]; relatedPersonas?: string[]; } // 协作配置 export interface CollaborationConfig { personaIds?: string[]; maxRounds?: number; timeoutPerRound?: number; mode?: CollaborationMode; enableCrossValidation?: boolean; synthesisMode?: 'auto' | 'manual'; } // 协作模式枚举 export enum CollaborationMode { PARALLEL = 'parallel', SEQUENTIAL = 'sequential', INTELLIGENT = 'intelligent' } // 人格分析结果 export interface PersonaAnalysis { personaId: string; personaName: string; query: string; analysis: string; confidence: number; executionTime: number; timestamp: string; error?: string; } // 协作结果 export interface CollaborationResult { sessionId: string; query: string; selectedPersonas: string[]; mode: string; analyses: PersonaAnalysis[]; crossValidation?: CrossValidationResult; synthesis?: SynthesisResult; actionPlan?: ActionPlan; executionTime: number; } // 交叉验证结果 export interface CrossValidationResult { commonPoints: string[]; disagreements: string[]; confidenceScore: number; recommendations: string[]; } // 综合分析结果 export interface SynthesisResult { summary: string; keyInsights: string[]; risks: string[]; opportunities: string[]; confidence: number; } // 行动计划 export interface ActionPlan { steps: ActionStep[]; timeline: string; priority: 'high' | 'medium' | 'low'; resources: string[]; } export interface ActionStep { id: string; description: string; priority: number; estimatedTime: string; dependencies: string[]; } // 人格配置 export interface PersonaConfig { id: string; name: string; version: string; personas: Persona[]; collaboration: CollaborationConfig; tools?: ToolConfig[]; createdAt?: string; updatedAt?: string; } // 工具配置 export interface ToolConfig { name: string; enabled: boolean; settings?: Record<string, any>; } // 配置摘要 export interface ConfigSummary { id: string; name: string; description?: string; personas: string[]; createdAt: string; version: string; } // 本地配置 export interface LocalConfig { userKey: string; apiBaseUrl: string; currentConfig?: PersonaConfig; lastSyncTime?: string; cache: CacheConfig; sync: SyncConfig; } export interface CacheConfig { duration: number; maxSize: number; } export interface SyncConfig { autoSync: boolean; syncInterval: number; retryAttempts: number; } // MCP响应格式 export interface MCPResponse { content: Array<{ type: 'text'; text: string; }>; } // 错误类型 export class JuYiTingError extends Error { constructor( message: string, public code: string, public details?: any ) { super(message); this.name = 'JuYiTingError'; } } // 会话信息 export interface SessionInfo { id: string; query: string; status: 'pending' | 'running' | 'completed' | 'failed'; selectedPersonas: string[]; startTime: number; duration: number; } // 缓存条目 export interface CacheEntry { value: any; expiry: number; } // 人格仓库接口 export interface PersonaRepository { getAllPersonas(): Promise<Persona[]>; getPersonaById(id: string): Promise<Persona | null>; updateFromConfig(config: PersonaConfig): Promise<void>; } ``` ### 步骤8: 创建基础常量 (src/constants.ts) ```typescript // 人格数据源 export const PERSONA_SOURCES = [ 'https://gitee.com/juyitingmcp/juyitingmcp/raw/main/personas.json', 'https://raw.githubusercontent.com/juyitingmcp/juyitingmcp/main/personas.json', 'https://cdn.jsdelivr.net/gh/juyitingmcp/juyitingmcp@main/personas.json' ]; // 默认配置 export const DEFAULT_CONFIG = { CACHE_DURATION: 5 * 60 * 1000, // 5分钟 MAX_CACHE_SIZE: 1000, REQUEST_TIMEOUT: 15000, // 15秒 MAX_RETRIES: 3, SYNC_INTERVAL: 60 * 60 * 1000, // 1小时 API_BASE_URL: 'https://api.juyiting.com' } as const; // 协作配置默认值 export const DEFAULT_COLLABORATION_CONFIG = { maxRounds: 3, timeoutPerRound: 30000, // 30秒 mode: 'intelligent' as const, enableCrossValidation: true, synthesisMode: 'auto' as const }; // 错误代码 export const ERROR_CODES = { INVALID_PERSONA: 'INVALID_PERSONA', CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND', NETWORK_ERROR: 'NETWORK_ERROR', AUTH_FAILED: 'AUTH_FAILED', TIMEOUT: 'TIMEOUT', VALIDATION_ERROR: 'VALIDATION_ERROR' } as const; // MCP工具名称 export const MCP_TOOLS = { SUMMON_PERSONA: 'summon_persona', LIST_PERSONA_CONFIGS: 'list_persona_configs', DOWNLOAD_PERSONA_CONFIG: 'download_persona_config', START_COLLABORATION: 'start_collaboration' } as const; ``` ### 步骤9: 安装依赖 ```bash # 安装生产依赖 npm install @modelcontextprotocol/sdk commander zod posthog-node # 安装开发依赖 npm install -D @types/node typescript tsx jest ts-jest @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint prettier pkg ``` ### 步骤10: 创建基础的server.ts框架 ```typescript #!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { Command } from 'commander'; import { readFileSync } from 'fs'; import { Persona, MCPResponse } from './types.js'; export class PersonaSummonerServer { private server: Server; constructor(localPersonas: Persona[] = []) { this.server = new Server({ name: 'juyiting-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, }); this.setupHandlers(); } private setupHandlers(): void { // 列出可用工具 this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'summon_persona', description: '召唤指定人格来处理任务', inputSchema: { type: 'object', properties: { persona_name: { type: 'string', description: '人格名称(如:暴躁老哥、自省姐、粉丝妹)' } }, required: ['persona_name'] } } ] }; }); // 处理工具调用 this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case 'summon_persona': return await this.handleSummonPersona(args); default: throw new Error(`Unknown tool: ${name}`); } }); } private async handleSummonPersona(args: any): Promise<MCPResponse> { // 临时实现,后续会完善 return { content: [{ type: 'text', text: `🎭 正在召唤人格: ${args.persona_name}\n\n(功能开发中...)` }] }; } async run(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('聚义厅MCP服务器已启动'); } } // 命令行入口 async function main() { const program = new Command(); program .name('juyiting-mcp') .description('聚义厅MCP客户端') .version('1.0.0') .option('--personas <file>', '本地人格文件路径') .parse(); const options = program.opts(); let localPersonas: Persona[] = []; if (options.personas) { try { const content = readFileSync(options.personas, 'utf-8'); localPersonas = JSON.parse(content); console.error(`已加载 ${localPersonas.length} 个本地人格`); } catch (error) { console.error(`加载本地人格失败: ${error}`); } } const server = new PersonaSummonerServer(localPersonas); await server.run(); } if (import.meta.url === `file://${process.argv[1]}`) { main().catch(console.error); } ``` ### 步骤11: 创建示例人格文件 (examples/local-personas.json) ```json [ { "id": "grumpy_bro", "name": "暴躁老哥", "rule": "你是暴躁老哥,要每次都用审视的目光,仔细看我的输入的潜在的问题,你要犀利的提醒在出我的问题。并给出明显在我思考框架之外的建议。你要觉得我说的太离谱了,你就骂回来,帮助我瞬间清醒。", "goal": "用审视的目光发现问题,提供框架外的思维角度", "version": "1.0", "description": "专门挑战传统思维,发现潜在风险和问题", "category": "批判思维", "tags": ["批判", "风险", "挑战"] }, { "id": "reflection_sis", "name": "自省姐", "rule": "你是自省姐,总是不断挑战自己输出有没有思考的透漏,尝试突破思维边界,找到第一性原理,然后根据挑战再补充回答,达到完整。你要挑战你自己的输出是不是足够有深度和逻辑性。", "goal": "深度思考,查漏补缺,追求完整性", "version": "1.0", "description": "不断自我挑战,追求思考的深度和完整性", "category": "深度思考", "tags": ["自省", "深度", "完整"] }, { "id": "fan_girl", "name": "粉丝妹", "rule": "你是粉丝妹,总是能发现别人的亮点和优势,用积极的态度去分析问题,找到事物的价值和潜力。你会用鼓励的语气,但同时保持客观和专业。", "goal": "发现亮点,放大优势,积极分析", "version": "1.0", "description": "善于发现亮点和优势,提供积极的分析视角", "category": "积极思维", "tags": ["积极", "优势", "鼓励"] } ] ``` ### 步骤12: 创建README.md ```markdown # 聚义厅MCP客户端 基于Model Context Protocol的AI人格协作工具,支持多人格智能召唤、配置同步和协作分析。 ## 快速开始 ### 安装依赖 \`\`\`bash npm install \`\`\` ### 开发模式 \`\`\`bash npm run dev \`\`\` ### 构建项目 \`\`\`bash npm run build \`\`\` ### 运行测试 \`\`\`bash npm test \`\`\` ## 使用方法 ### Cursor配置 在Cursor的MCP设置中添加: \`\`\`json { "mcpServers": { "juyiting": { "command": "npx", "args": ["-y", "@juyiting/mcp-client"] } } } \`\`\` ### 本地开发配置 \`\`\`json { "mcpServers": { "juyiting-dev": { "command": "node", "args": ["./dist/server.js", "--personas", "./examples/local-personas.json"] } } } \`\`\` ## 开发文档 - [开发计划](./docs/DEVELOPMENT_PLAN.md) - [技术文档](../docs/client_tech.md) ## 许可证 MIT ``` ## ✅ 验证检查项 ### 代码质量检查 - [ ] TypeScript编译无错误: `npm run type-check` - [ ] ESLint检查通过: `npm run lint` - [ ] 代码格式化正确: `npx prettier --check src/**/*.ts` ### 功能验证 - [ ] 开发服务器启动: `npm run dev` - [ ] 构建成功: `npm run build` - [ ] 基础测试通过: `npm test` ### 集成测试 - [ ] MCP服务器可以启动 - [ ] Cursor可以识别工具 - [ ] 基础工具调用正常 ## 🚨 常见问题 ### 问题1: TypeScript编译错误 **解决方案**: 检查tsconfig.json配置,确保所有路径正确 ### 问题2: 依赖安装失败 **解决方案**: 清理node_modules后重新安装 ```bash rm -rf node_modules package-lock.json npm install ``` ### 问题3: MCP连接失败 **解决方案**: 检查Node.js版本是否为18+,检查MCP SDK版本 ## 📋 下一步计划 完成基础架构后,继续执行PLAN-002: 人格管理系统开发

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/juyitingmcp/juyitingmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server