UNPKG

@aipmanager/project-manager-mcp

Version:

MCP for the Project Manager Agent, providing full control over projects, phases, and tasks.

451 lines (450 loc) 22.5 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const zod_1 = require("zod"); const axios_1 = __importDefault(require("axios")); const API_BASE_URL = process.env.API_BASE_URL || "http://localhost:3001/api"; const apiClient = axios_1.default.create({ baseURL: API_BASE_URL, headers: { "Content-Type": "application/json" }, }); // Helper to create a standardized error response const createErrorResponse = (error, toolName) => { let errorMessage = `An unexpected error occurred in ${toolName}.`; let statusCode; let details; if (axios_1.default.isAxiosError(error)) { const axiosError = error; statusCode = axiosError.response?.status; const apiError = axiosError.response?.data?.error || axiosError.message; details = axiosError.response?.data; errorMessage = `API Error in ${toolName} (Status ${statusCode}): ${apiError}`; } else if (error instanceof Error) { errorMessage = `Error in ${toolName}: ${error.message}`; } return { isError: true, content: [{ type: "text", text: JSON.stringify({ error: errorMessage, statusCode, details, }, null, 2) }] }; }; const server = new mcp_js_1.McpServer({ name: "aipm-project-manager-agent", version: "1.0.0", description: "项目管理智能体,负责项目的全生命周期管理,包括项目、阶段、任务和智能体的协调。", }); // --- Project Management Tools --- server.registerTool("createProject", { title: "创建新项目", description: "创建一个新的项目,包含目标、约束等信息。", inputSchema: { name: zod_1.z.string().describe("项目名称,例如:'AI电商平台重构'"), description: zod_1.z.string().describe("项目的详细描述,例如:'使用最新的微服务架构和AI推荐算法重构现有电商平台,提高性能和用户体验'"), goals: zod_1.z.string().describe("项目的主要目标,例如:'提升用户转化率20%,优化推荐精准度,减少系统响应时间50%'"), timeline: zod_1.z.string().optional().describe("项目的时间线或截止日期,例如:'2025-12-31'(可选)"), budget: zod_1.z.number().optional().describe("项目的预算金额,例如:500000(可选)"), }, }, async (input) => { try { const response = await apiClient.post("/projects", input); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "createProject"); } }); server.registerTool("getAllProjects", { title: "获取所有项目", description: "列出系统中的所有项目。", inputSchema: {}, }, async () => { try { const response = await apiClient.get("/projects"); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAllProjects"); } }); server.registerTool("getProjectDetails", { title: "获取项目详情", description: "通过ID获取单个项目的详细信息,包括其所有阶段和任务。", inputSchema: { projectId: zod_1.z.string().describe("项目ID,例如:'clxyztqf000008jsb4fsc6f8e'"), }, }, async ({ projectId }) => { try { const response = await apiClient.get(`/projects/${projectId}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getProjectDetails"); } }); server.registerTool("updateProject", { title: "更新项目", description: "更新现有项目的信息。", inputSchema: { id: zod_1.z.string().describe("要更新的项目ID,例如:'clxyztqf000008jsb4fsc6f8e'"), name: zod_1.z.string().optional().describe("新的项目名称,例如:'AI电商平台重构2.0'(可选)"), description: zod_1.z.string().optional().describe("新的项目描述,例如:'增加区块链支付功能和多语言支持'(可选)"), goals: zod_1.z.string().optional().describe("新的项目目标,例如:'拓展国际市场,提升安全性'(可选)"), }, }, async ({ id, ...data }) => { try { const response = await apiClient.put(`/projects/${id}`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "updateProject"); } }); server.registerTool("getProjectStats", { title: "获取项目统计信息", description: "获取特定项目的统计信息,如任务完成率、进度等。", inputSchema: { id: zod_1.z.string().describe("要获取统计信息的项目ID,例如:'clxyztqf000008jsb4fsc6f8e'"), }, }, async ({ id }) => { try { const response = await apiClient.get(`/projects/${id}/stats`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getProjectStats"); } }); // --- Phase Management Tools --- server.registerTool("createPhase", { title: "创建阶段", description: "在指定项目中创建一个新的阶段。", inputSchema: { projectId: zod_1.z.string().describe("阶段所属的项目ID,例如:'clxyztqf000008jsb4fsc6f8e'"), name: zod_1.z.string().describe("阶段名称,例如:'第一阶段:需求分析与设计'"), description: zod_1.z.string().describe("阶段的详细描述,例如:'收集和分析用户需求,设计系统架构和数据模型,创建原型'"), startDate: zod_1.z.string().datetime().describe("阶段开始日期,ISO 8601格式,例如:'2025-08-01T00:00:00.000Z'"), endDate: zod_1.z.string().datetime().describe("阶段结束日期,ISO 8601格式,例如:'2025-09-01T00:00:00.000Z'"), }, }, async ({ projectId, ...data }) => { try { const response = await apiClient.post(`/phases/project/${projectId}`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "createPhase"); } }); server.registerTool("getPhasesByProject", { title: "获取项目阶段", description: "获取指定项目的所有阶段列表。", inputSchema: { projectId: zod_1.z.string().describe("项目ID,例如:'clxyztqf000008jsb4fsc6f8e'"), }, }, async ({ projectId }) => { try { const response = await apiClient.get(`/phases/project/${projectId}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getPhasesByProject"); } }); server.registerTool("getPhaseDetails", { title: "获取阶段详情", description: "获取单个阶段的信息。", inputSchema: { id: zod_1.z.string().describe("阶段ID,例如:'clxyztqf000018jsb4fsc6f8e'"), }, }, async ({ id }) => { try { const response = await apiClient.get(`/phases/${id}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getPhaseDetails"); } }); server.registerTool("updatePhase", { title: "更新阶段", description: "更新一个阶段。", inputSchema: { id: zod_1.z.string().describe("要更新的阶段ID,例如:'clxyztqf000018jsb4fsc6f8e'"), name: zod_1.z.string().optional().describe("新的阶段名称,例如:'第一阶段:需求分析与原型设计'(可选)"), description: zod_1.z.string().optional().describe("新的阶段描述,例如:'增加用户访谈和竞品分析环节'(可选)"), startDate: zod_1.z.string().datetime().optional().describe("新的开始日期,ISO 8601格式,例如:'2025-07-25T00:00:00.000Z'(可选)"), endDate: zod_1.z.string().datetime().optional().describe("新的结束日期,ISO 8601格式,例如:'2025-09-10T00:00:00.000Z'(可选)"), status: zod_1.z.enum(['PLANNED', 'IN_PROGRESS', 'COMPLETED', 'DELAYED']).optional().describe("阶段状态,例如:'IN_PROGRESS'(可选)"), }, }, async ({ id, ...data }) => { try { const response = await apiClient.put(`/phases/${id}`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "updatePhase"); } }); // --- Task Management Tools --- server.registerTool("createTask", { title: "创建任务", description: "在指定阶段中创建一个新任务。", inputSchema: { name: zod_1.z.string().min(1).max(255).describe("任务名称,例如:'实现用户登录功能'"), description: zod_1.z.string().min(1).describe("任务详细描述,例如:'设计并实现基于JWT的用户登录和注册API接口,包括密码加密、token生成和验证'"), type: zod_1.z.enum(['CODING', 'TESTING', 'DATA_ANALYSIS', 'RESEARCH', 'DOCUMENTATION', 'REVIEW', 'DEPLOYMENT']).describe("任务类型,例如:'CODING'"), priority: zod_1.z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).default('MEDIUM').describe("优先级,例如:'HIGH'"), estimatedHours: zod_1.z.number().min(1).max(1000).describe("预计工时,例如:8"), phaseId: zod_1.z.string().cuid().describe("阶段ID,例如:'clxyztqf000018jsb4fsc6f8e'"), assignedAgentId: zod_1.z.string().cuid().optional().describe("分配的智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'(可选)"), dependencies: zod_1.z.array(zod_1.z.string().cuid()).default([]).describe("依赖的任务ID列表,例如:['clxyztqf000038jsb4fsc6f8e', 'clxyztqf000048jsb4fsc6f8e'](可选)"), }, }, async (data) => { try { const response = await apiClient.post(`/tasks`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "createTask"); } }); server.registerTool("getAllTasks", { title: "获取所有任务", description: "获取系统中的所有任务。", inputSchema: { projectId: zod_1.z.string().cuid().optional().describe("项目ID,例如:'clxyztqf000008jsb4fsc6f8e'(可选)"), status: zod_1.z.enum(['PENDING', 'IN_PROGRESS', 'COMPLETED', 'BLOCKED', 'FAILED']).optional().describe("任务状态,例如:'IN_PROGRESS'(可选)"), type: zod_1.z.enum(['CODING', 'TESTING', 'DATA_ANALYSIS', 'RESEARCH', 'DOCUMENTATION', 'REVIEW', 'DEPLOYMENT']).optional().describe("任务类型,例如:'CODING'(可选)"), priority: zod_1.z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).optional().describe("优先级,例如:'HIGH'(可选)"), assignedAgentId: zod_1.z.string().cuid().optional().describe("分配的智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'(可选)"), available: zod_1.z.string().optional().describe("是否只显示可领取的任务,例如:'true'(可选)"), page: zod_1.z.number().default(1).describe("页码,例如:1"), limit: zod_1.z.number().default(50).describe("每页数量,例如:20"), }, }, async (query) => { try { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== undefined) { params.append(key, String(value)); } } const response = await apiClient.get(`/tasks?${params.toString()}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAllTasks"); } }); server.registerTool("getTaskDetails", { title: "获取任务详情", description: "通过ID获取特定任务的完整详情。", inputSchema: { id: zod_1.z.string().describe("任务ID,例如:'clxyztqf000038jsb4fsc6f8e'"), }, }, async ({ id }) => { try { const response = await apiClient.get(`/tasks/${id}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getTaskDetails"); } }); server.registerTool("updateTask", { title: "更新任务", description: "更新一个现有任务的信息。", inputSchema: { id: zod_1.z.string().describe("要更新的任务ID,例如:'clxyztqf000038jsb4fsc6f8e'"), name: zod_1.z.string().min(1).max(255).optional().describe("任务名称,例如:'优化用户登录功能'(可选)"), description: zod_1.z.string().min(1).optional().describe("任务描述,例如:'添加双因素认证和登录限制功能'(可选)"), type: zod_1.z.enum(['CODING', 'TESTING', 'DATA_ANALYSIS', 'RESEARCH', 'DOCUMENTATION', 'REVIEW', 'DEPLOYMENT']).optional().describe("任务类型,例如:'CODING'(可选)"), status: zod_1.z.enum(['PENDING', 'IN_PROGRESS', 'COMPLETED', 'BLOCKED', 'FAILED']).optional().describe("任务状态,例如:'IN_PROGRESS'(可选)"), priority: zod_1.z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).optional().describe("优先级,例如:'HIGH'(可选)"), estimatedHours: zod_1.z.number().min(1).max(1000).optional().describe("预计工时,例如:12(可选)"), actualHours: zod_1.z.number().min(0).max(1000).optional().describe("实际工时,例如:10(可选)"), assignedAgentId: zod_1.z.string().cuid().optional().describe("分配的智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'(可选)"), startDate: zod_1.z.string().datetime().optional().describe("开始日期,ISO 8601格式,例如:'2025-08-15T09:00:00.000Z'(可选)"), endDate: zod_1.z.string().datetime().optional().describe("结束日期,ISO 8601格式,例如:'2025-08-20T18:00:00.000Z'(可选)"), completedAt: zod_1.z.string().datetime().optional().describe("完成日期,ISO 8601格式,例如:'2025-08-20T18:00:00.000Z'(可选)"), }, }, async ({ id, ...data }) => { try { const response = await apiClient.put(`/tasks/${id}`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "updateTask"); } }); server.registerTool("completeTask", { title: "完成任务", description: "将任务标记为已完成。", inputSchema: { id: zod_1.z.string().describe("要标记为完成的任务ID,例如:'clxyztqf000038jsb4fsc6f8e'"), result: zod_1.z.any().optional().describe("任务结果,例如:{ 'success': true, 'features': ['登录', '注册', '密码重置'] }(可选)"), actualHours: zod_1.z.number().optional().describe("实际工时,例如:8.5(可选)"), notes: zod_1.z.string().optional().describe("备注,例如:'完成了所有功能,并进行了单元测试'(可选)"), }, }, async ({ id, ...data }) => { try { const response = await apiClient.post(`/tasks/${id}/complete`, data); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "completeTask"); } }); server.registerTool("getAvailableTasks", { title: "获取可用任务", description: "获取状态为'PENDING',且未分配给任何智能体的任务列表。", inputSchema: { type: zod_1.z.enum(['CODING', 'TESTING', 'DATA_ANALYSIS', 'RESEARCH', 'DOCUMENTATION', 'REVIEW', 'DEPLOYMENT']).optional().describe("任务类型,例如:'CODING'(可选)"), priority: zod_1.z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).optional().describe("优先级,例如:'HIGH'(可选)"), projectId: zod_1.z.string().cuid().optional().describe("项目ID,例如:'clxyztqf000008jsb4fsc6f8e'(可选)"), }, }, async (query) => { try { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== undefined) { params.append(key, String(value)); } } const response = await apiClient.get(`/tasks/available?${params.toString()}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAvailableTasks"); } }); server.registerTool("claimTask", { title: "领取任务", description: "为智能体领取任务,并将其状态设置为进行中。", inputSchema: { id: zod_1.z.string().describe("要领取的任务ID,例如:'clxyztqf000038jsb4fsc6f8e'"), agentId: zod_1.z.string().cuid().describe("领取任务的智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'"), }, }, async ({ id, agentId }) => { try { const response = await apiClient.post(`/tasks/${id}/claim`, { agentId }); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "claimTask"); } }); // --- Agent and Monitoring Tools --- server.registerTool("getAllAgents", { title: "获取所有已注册的智能体", description: "列出系统中所有已注册的智能体及其状态。", inputSchema: {}, }, async () => { try { const response = await apiClient.get("/agents"); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAllAgents"); } }); server.registerTool("getAgentsByType", { title: "按类型获取智能体", description: "根据指定的类型筛选智能体。", inputSchema: { type: zod_1.z.string().describe("智能体类型,例如:'CODING'、'TESTING'、'DATA_ANALYSIS'等"), }, }, async ({ type }) => { try { const response = await apiClient.get(`/agents/type/${type}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAgentsByType"); } }); server.registerTool("assignTaskToAgent", { title: "分配任务给智能体", description: "将一个指定的任务分配给一个指定的智能体。", inputSchema: { id: zod_1.z.string().describe("智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'"), taskId: zod_1.z.string().describe("任务ID,例如:'clxyztqf000038jsb4fsc6f8e'"), }, }, async ({ id, taskId }) => { try { const response = await apiClient.post(`/agents/${id}/assign`, { taskId }); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "assignTaskToAgent"); } }); server.registerTool("getAgentMetrics", { title: "获取Agent性能指标", description: "获取所有Agent的性能指标,如任务完成数、平均耗时等。", inputSchema: { timeRange: zod_1.z.enum(['DAY', 'WEEK', 'MONTH', 'ALL']).optional().describe("时间范围,例如:'WEEK'(可选,默认为'ALL')"), agentId: zod_1.z.string().optional().describe("特定智能体ID,例如:'clxyztqf000028jsb4fsc6f8e'(可选,默认返回所有智能体)"), }, }, async (query) => { try { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== undefined) { params.append(key, String(value)); } } const response = await apiClient.get(`/monitoring/agents/metrics?${params.toString()}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getAgentMetrics"); } }); server.registerTool("getProjectMetrics", { title: "获取项目进度指标", description: "获取所有项目的整体进度和性能指标。", inputSchema: { projectId: zod_1.z.string().optional().describe("特定项目ID,例如:'clxyztqf000008jsb4fsc6f8e'(可选,默认返回所有项目)"), includePhases: zod_1.z.boolean().optional().describe("是否包含阶段级别的指标,例如:true(可选,默认为false)"), includeTasks: zod_1.z.boolean().optional().describe("是否包含任务级别的指标,例如:false(可选,默认为false)"), }, }, async (query) => { try { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== undefined) { params.append(key, String(value)); } } const response = await apiClient.get(`/monitoring/projects/metrics?${params.toString()}`); return { content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }] }; } catch (error) { return createErrorResponse(error, "getProjectMetrics"); } }); async function main() { try { console.log("[ProjectManagerAgent] Starting MCP server..."); const transport = new stdio_js_1.StdioServerTransport(); await server.connect(transport); console.log("[ProjectManagerAgent] MCP server connected and listening on stdio."); } catch (error) { console.error("[ProjectManagerAgent] Failed to start MCP server:", error); process.exit(1); } } main();