analyze-project
Analyze a project directory to identify and recommend specialized agent templates tailored for 100+ professional roles, ensuring optimal role assignments.
Instructions
Analyze a project directory and recommend suitable sub-agents
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | Yes | Path to the project directory to analyze |
Implementation Reference
- src/index.ts:1571-1594 (handler)MCP tool handler for 'analyze-project' that invokes ProjectAnalyzer.analyzeProject(projectPath), processes the result, tracks analytics, and returns JSON response with analysis.case 'analyze-project': { const { projectPath } = args as { projectPath: string }; const analysis = await projectAnalyzer.analyzeProject(projectPath); // Track project analysis trackEvent(AnalyticsEvents.PROJECT_ANALYZED, { project_types: analysis.projectType, technologies: analysis.technologies, recommended_count: analysis.recommendedAgents.length, confidence: analysis.confidence, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, analysis, message: `Analyzed project at ${projectPath}. Found ${analysis.projectType.length} project types and recommended ${analysis.recommendedAgents.length} agents.`, }, null, 2), }, ], };
- src/index.ts:1388-1399 (schema)Input schema definition for the 'analyze-project' tool in ListToolsRequestSchema handler.name: 'analyze-project', description: 'Analyze a project directory and recommend suitable sub-agents', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to the project directory to analyze', }, }, required: ['projectPath'], },
- src/projectAnalyzer.ts:46-116 (helper)Main helper function implementing project analysis logic: scans files with glob patterns, parses package.json for dependencies, detects project types/technologies, recommends agents, and computes confidence score.async analyzeProject(projectPath: string): Promise<ProjectAnalysis> { const detectedTypes: string[] = []; const detectedTechnologies: string[] = []; const recommendedAgents = new Set<string>(); let confidence = 0; // Analyze file structure for (const [type, pattern] of Object.entries(this.patterns)) { let typeScore = 0; // Check for pattern files for (const filePattern of pattern.files) { const files = await glob(filePattern, { cwd: projectPath, ignore: ['node_modules/**', 'dist/**', 'build/**'] }); if (files.length > 0) { typeScore += files.length; } } // Check package.json for keywords const packageJsonPath = path.join(projectPath, 'package.json'); try { const packageContent = await fs.readFile(packageJsonPath, 'utf-8'); const packageJson = JSON.parse(packageContent); const deps = { ...packageJson.dependencies || {}, ...packageJson.devDependencies || {} }; for (const keyword of pattern.keywords) { if (Object.keys(deps).some(dep => dep.includes(keyword))) { typeScore += 2; detectedTechnologies.push(keyword); } } } catch (e) { // Not a Node.js project, check other files } if (typeScore > 0) { detectedTypes.push(type); pattern.agents.forEach(agent => recommendedAgents.add(agent)); confidence += typeScore * 10; } } // Add general agents based on project complexity if (detectedTypes.length > 2) { recommendedAgents.add('project-manager'); recommendedAgents.add('architect'); } // Add QA for any development project if (detectedTypes.includes('frontend') || detectedTypes.includes('backend')) { recommendedAgents.add('qa-engineer'); } // Normalize confidence to 0-100 confidence = Math.min(confidence, 100); return { projectType: detectedTypes, technologies: detectedTechnologies, recommendedAgents: Array.from(recommendedAgents), confidence }; }
- src/index.ts:1385-1558 (registration)Registration of 'analyze-project' tool in the ListToolsRequestSchema handler, making it discoverable by MCP clients.return { tools: [ { name: 'analyze-project', description: 'Analyze a project directory and recommend suitable sub-agents', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to the project directory to analyze', }, }, required: ['projectPath'], }, }, { name: 'ai-analyze-project', description: 'Perform AI-powered comprehensive project analysis and agent recommendations', inputSchema: { type: 'object', properties: { claudeMdPath: { type: 'string', description: 'Path to CLAUDE.md file or project description', }, projectPath: { type: 'string', description: 'Optional path to project root directory (defaults to CLAUDE.md directory)', }, generateRecommendations: { type: 'boolean', description: 'Whether to generate agent recommendations', default: true, }, maxRecommendations: { type: 'number', description: 'Maximum number of agent recommendations to return', default: 10, }, }, required: ['claudeMdPath'], }, }, { name: 'agent-download', description: 'AI-powered agent downloader - analyze project and download recommended agents', inputSchema: { type: 'object', properties: { targetDir: { type: 'string', description: 'Target directory for agent files', default: './.claude/agents', }, claudeMdPath: { type: 'string', description: 'Path to CLAUDE.md file', default: './CLAUDE.md', }, format: { type: 'string', enum: ['md', 'yaml', 'json'], description: 'Agent file format', default: 'md', }, language: { type: 'string', enum: ['en', 'ko', 'ja', 'zh'], description: 'Preferred language for agents', default: 'en', }, limit: { type: 'number', description: 'Maximum number of agents to download', default: 10, minimum: 1, maximum: 20, }, dryRun: { type: 'boolean', description: 'Preview recommendations without downloading', default: false, }, overwrite: { type: 'boolean', description: 'Overwrite existing agent files', default: false, }, }, }, }, { name: 'agents', description: 'Search, list, get details, recommend agents, or request new ones', inputSchema: { type: 'object', properties: { action: { type: 'string', description: 'Action to perform', enum: ['search', 'list', 'details', 'recommend', 'request'], }, query: { type: 'string', description: 'Search query (for search action) or agent name (for details action)', }, keywords: { type: 'array', items: { type: 'string' }, description: 'Keywords for recommendation (for recommend action)', }, language: { type: 'string', description: 'Language preference', enum: ['en', 'ko', 'ja', 'zh'], default: 'en', }, category: { type: 'string', description: 'Filter by category (for list action)', enum: ['development', 'data', 'design', 'management', 'marketing', 'operations', 'hr', 'finance', 'legal', 'research', 'healthcare', 'education', 'media', 'manufacturing', 'other'], }, autoCreateIssue: { type: 'boolean', description: 'Auto-create GitHub issue if no agents found (for search action)', default: false, }, issueBody: { type: 'string', description: 'Additional details for the issue (when autoCreateIssue is true)', }, }, required: ['action'], }, }, { name: 'manage-agents', description: 'Install agents, get stats, or refresh from GitHub', inputSchema: { type: 'object', properties: { action: { type: 'string', description: 'Management action to perform', enum: ['install', 'stats', 'refresh', 'version'], }, agentNames: { type: 'array', items: { type: 'string' }, description: 'Agent names to install (for install action)', }, targetPath: { type: 'string', description: 'Target directory for installation (for install action)', }, language: { type: 'string', description: 'Language preference for agents', enum: ['en', 'ko', 'ja', 'zh'], default: 'en', }, limit: { type: 'number', description: 'Number of top agents to show in stats', default: 10, }, }, required: ['action'], }, }, ], }; });
- src/index.ts:1561-2425 (registration)Registration of tool execution handler in CallToolRequestSchema, dispatching to 'analyze-project' case based on tool name.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; // Track tool usage trackEvent(AnalyticsEvents.TOOL_CALLED, { tool_name: name, args_provided: Object.keys(args || {}), }); switch (name) { case 'analyze-project': { const { projectPath } = args as { projectPath: string }; const analysis = await projectAnalyzer.analyzeProject(projectPath); // Track project analysis trackEvent(AnalyticsEvents.PROJECT_ANALYZED, { project_types: analysis.projectType, technologies: analysis.technologies, recommended_count: analysis.recommendedAgents.length, confidence: analysis.confidence, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, analysis, message: `Analyzed project at ${projectPath}. Found ${analysis.projectType.length} project types and recommended ${analysis.recommendedAgents.length} agents.`, }, null, 2), }, ], }; } case 'ai-analyze-project': { const { claudeMdPath, projectPath, generateRecommendations = true, maxRecommendations = 10 } = args as { claudeMdPath: string; projectPath?: string; generateRecommendations?: boolean; maxRecommendations?: number; }; try { // Perform AI-powered project analysis const analysis = await aiAnalysisService.analyzeProject(claudeMdPath, projectPath); let recommendations: AIAgentRecommendation[] = []; if (generateRecommendations) { const allRecommendations = await aiAnalysisService.generateRecommendations(analysis); recommendations = allRecommendations.slice(0, maxRecommendations); } // Track AI analysis event trackEvent(AnalyticsEvents.PROJECT_ANALYZED, { project_types: analysis.projectType, technologies: analysis.technologies, recommended_count: recommendations.length, confidence: analysis.complexity / 10, // Normalize complexity as confidence ai_powered: true, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, analysis: { projectType: analysis.projectType, technologies: analysis.technologies, frameworks: analysis.frameworks, complexity: analysis.complexity, phase: analysis.phase, teamSize: analysis.teamSize, description: analysis.description, goals: analysis.goals, requirements: analysis.requirements, architecturalPatterns: analysis.architecturalPatterns, developmentPractices: analysis.developmentPractices, qualityIndicators: analysis.qualityIndicators, }, recommendations: recommendations.map(rec => ({ name: rec.name, description: rec.description, relevanceScore: rec.relevanceScore, reasoning: rec.reasoning, category: rec.category, priority: rec.priority, tools: rec.tools, specificTasks: rec.specificTasks, integrationPoints: rec.integrationPoints, })), message: `AI analysis completed for ${path.basename(claudeMdPath)}. Project type: ${analysis.projectType}, Complexity: ${analysis.complexity}/10, Recommended ${recommendations.length} agents.`, aiFeatures: { intelligentAnalysis: 'Comprehensive project understanding using AI reasoning', contextAwareRecommendations: 'Agent suggestions based on project context and requirements', dynamicPrioritization: 'Smart priority assignment based on project needs', taskSpecificMatching: 'Agents matched to specific tasks and integration points' } }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `AI analysis failed: ${error instanceof Error ? error.message : String(error)}`, suggestion: 'Please check the CLAUDE.md file path and project structure', }, null, 2), }, ], }; } } case 'agent-download': { const { targetDir = './.claude/agents', claudeMdPath = './CLAUDE.md', format = 'md', language = 'en', limit = 10, dryRun = false, overwrite = false } = args as { targetDir?: string; claudeMdPath?: string; format?: 'md' | 'yaml' | 'json'; language?: 'en' | 'ko' | 'ja' | 'zh'; limit?: number; dryRun?: boolean; overwrite?: boolean; }; try { const downloader = new AgentDownloader(); const options = { targetDir, claudeMdPath, format, language, limit, dryRun, overwrite }; const result = await downloader.downloadAgents(options); // Track agent download event trackEvent(AnalyticsEvents.PROJECT_ANALYZED, { project_types: result.analysis.projectType, technologies: result.analysis.technologies, recommended_count: result.recommendations.length, confidence: result.analysis.complexity / 10, ai_powered: true, dry_run: dryRun, downloaded_count: result.downloaded?.length || 0, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, dryRun, analysis: { projectType: result.analysis.projectType, technologies: result.analysis.technologies, frameworks: result.analysis.frameworks, complexity: result.analysis.complexity, phase: result.analysis.phase, teamSize: result.analysis.teamSize, description: result.analysis.description, qualityIndicators: result.analysis.qualityIndicators, architecturalPatterns: result.analysis.architecturalPatterns, developmentPractices: result.analysis.developmentPractices, }, recommendations: result.recommendations.map(rec => ({ name: rec.name, description: rec.description, relevanceScore: rec.relevanceScore, reasoning: rec.reasoning, category: rec.category, priority: rec.priority, tools: rec.tools, specificTasks: rec.specificTasks, integrationPoints: rec.integrationPoints, })), downloaded: result.downloaded || [], message: dryRun ? `AI analysis preview completed. Found ${result.recommendations.length} recommended agents for your ${result.analysis.projectType} project.` : `Successfully downloaded ${result.downloaded?.length || 0} AI-recommended agents to ${targetDir}.`, aiFeatures: { intelligentAnalysis: 'Comprehensive project understanding using AI reasoning', contextAwareRecommendations: 'Agent suggestions based on project context and requirements', dynamicPrioritization: 'Smart priority assignment based on project needs', taskSpecificMatching: 'Agents matched to specific tasks and integration points', automaticDownload: 'Seamless agent file creation with enhanced documentation' } }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Agent download failed: ${error instanceof Error ? error.message : String(error)}`, suggestion: 'Please check the CLAUDE.md file path and ensure write permissions for the target directory', }, null, 2), }, ], }; } } case 'agents': { const { action, query, keywords, language = 'en', category, autoCreateIssue = false, issueBody } = args as { action: 'search' | 'list' | 'details' | 'recommend' | 'request'; query?: string; keywords?: string[]; language?: string; category?: string; autoCreateIssue?: boolean; issueBody?: string; }; switch (action) { case 'search': { if (!query) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Query is required for search action', }, null, 2), }, ], }; } const agents = agentManager.searchAgents(query); const filteredAgents = agents.filter( agent => !language || agent.language === language ); // Track search event trackEvent(AnalyticsEvents.AGENT_SEARCHED, { query, language, found_count: filteredAgents.length, auto_create_issue: autoCreateIssue, }); // Auto-create issue if no agents found and autoCreateIssue is true if (filteredAgents.length === 0 && autoCreateIssue) { const githubToken = process.env.GITHUB_TOKEN; if (!githubToken) { // Generate GitHub issue creation URL with pre-filled content const issueTitle = encodeURIComponent(`[Agent Request] ${query} - New agent needed`); const issueBodyContent = encodeURIComponent(`## Agent Request **Role Name**: ${query} **Language**: ${language} ## Description ${issueBody || 'A new agent is needed for this role.'} ## Use Cases - [Please describe specific use cases] ## Required Tools - [List required tools like Read, Write, Edit, etc.] ## Additional Details - No existing agents found matching: "${query}" - Please consider adding this agent to help users with this use case.`); const createIssueUrl = `https://github.com/hongsw/claude-agents-power-mcp-server/issues/new?title=${issueTitle}&body=${issueBodyContent}&labels=agent-request`; return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'No agents found. GitHub token not configured for auto-issue creation.', suggestion: 'Click the link below to create an issue manually:', createIssueUrl, message: `๐ No agents found for "${query}"\n\n๐ You can create an issue manually by clicking this link:\n${createIssueUrl}\n\n๐ก Or set GITHUB_TOKEN environment variable for automatic issue creation.`, }, null, 2), }, ], }; } try { const issueTitle = `[Agent Request] ${query} - New agent needed`; const issueBodyContent = `## Agent Request **Role Name**: ${query} **Language**: ${language} ## Description ${issueBody || 'A new agent is needed for this role.'} ## Use Cases - [Please describe specific use cases] ## Required Tools - [List required tools like Read, Write, Edit, etc.] ## Additional Details - Requested via MCP server auto-issue creation - No existing agents found matching: "${query}" --- *This issue was automatically created by claude-agents-power MCP server*`; const response = await fetch('https://api.github.com/repos/hongsw/claude-agents-power-mcp-server/issues', { method: 'POST', headers: { 'Authorization': `token ${githubToken}`, 'Accept': 'application/vnd.github+json', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: issueTitle, body: issueBodyContent, labels: ['agent-request', 'auto-created'], }), }); if (!response.ok) { throw new Error(`GitHub API error: ${response.status} ${response.statusText}`); } const issue = await response.json(); // Log to stderr for visibility console.error(`[MCP Sub-Agents] โ GitHub issue created successfully!`); console.error(`[MCP Sub-Agents] Issue #${issue.number}: ${issue.html_url}`); // Track issue creation trackEvent(AnalyticsEvents.AGENT_ISSUE_CREATED, { query, language, issue_number: issue.number, issue_url: issue.html_url, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, count: 0, message: `๐ No agents found for "${query}"\n\n๐ GitHub issue automatically created!\n\n๐ Issue #${issue.number}: ${issue.title}\n๐ ${issue.html_url}\n\n๐ก The maintainers will review and potentially add this agent.\n๐ Meanwhile, you can create your own agent following the guide.`, issueUrl: issue.html_url, issueNumber: issue.number, nextSteps: [ 'Wait for maintainers to review the issue', 'Create your own agent following the documentation', 'Check back later for the new agent' ] }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, count: 0, error: `Failed to create issue: ${error}`, suggestion: 'Visit https://github.com/hongsw/claude-agents-power-mcp-server/issues to manually create an issue', }, null, 2), }, ], }; } } // If no agents found and autoCreateIssue is false, provide manual creation link if (filteredAgents.length === 0) { const issueTitle = encodeURIComponent(`[Agent Request] ${query} - New agent needed`); const issueBodyContent = encodeURIComponent(`## Agent Request **Role Name**: ${query} **Language**: ${language} ## Description A new agent is needed for this role. ## Use Cases - [Please describe specific use cases] ## Required Tools - [List required tools like Read, Write, Edit, etc.] ## Additional Details - No existing agents found matching: "${query}" - Please consider adding this agent to help users with this use case.`); const createIssueUrl = `https://github.com/hongsw/claude-agents-power-mcp-server/issues/new?title=${issueTitle}&body=${issueBodyContent}&labels=agent-request`; return { content: [ { type: 'text', text: JSON.stringify({ success: true, count: 0, agents: [], message: `๐ No agents found for "${query}"`, suggestion: '๐ You can request this agent by creating an issue:', createIssueUrl, tip: '๐ก Set autoCreateIssue=true to automatically create issues when agents are not found.', }, null, 2), }, ], }; } return { content: [ { type: 'text', text: JSON.stringify({ success: true, count: filteredAgents.length, agents: filteredAgents.map(agent => ({ name: agent.name, description: agent.description, tools: agent.tools, language: agent.language, })), }, null, 2), }, ], }; } case 'list': { let agents = agentManager.getAllAgents(language); if (category) { agents = agents.filter(agent => { const categoryKeywords: Record<string, string[]> = { development: ['developer', 'engineer', 'architect'], data: ['data', 'analyst', 'scientist'], design: ['designer', 'ux', 'ui'], management: ['manager', 'owner', 'master'], }; const keywords = categoryKeywords[category] || []; return keywords.some(keyword => agent.name.includes(keyword) || agent.description.toLowerCase().includes(keyword) ); }); } return { content: [ { type: 'text', text: JSON.stringify({ success: true, count: agents.length, agents: agents.map(agent => ({ name: agent.name, description: agent.description, tools: agent.tools, language: agent.language, })), }, null, 2), }, ], }; } case 'details': { if (!query) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Agent name is required for details action', }, null, 2), }, ], }; } const agent = agentManager.getAgent(query, language); if (!agent) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Agent '${query}' not found in language '${language}'`, }, null, 2), }, ], }; } return { content: [ { type: 'text', text: JSON.stringify({ success: true, agent: { name: agent.name, description: agent.description, tools: agent.tools, language: agent.language, content: agent.content, }, }, null, 2), }, ], }; } case 'recommend': { if (!keywords || keywords.length === 0) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Keywords are required for recommend action', }, null, 2), }, ], }; } const recommendedAgents = await projectAnalyzer.getAgentsByKeywords(keywords); return { content: [ { type: 'text', text: JSON.stringify({ success: true, keywords, recommendedAgents, count: recommendedAgents.length, }, null, 2), }, ], }; } case 'request': { if (!query) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Agent name is required for request action', }, null, 2), }, ], }; } const githubToken = process.env.GITHUB_TOKEN; if (!githubToken) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'GitHub token not configured. Set GITHUB_TOKEN environment variable.', suggestion: 'Visit https://github.com/hongsw/claude-agents-power-mcp-server/issues to manually create an issue', }, null, 2), }, ], }; } try { const issueTitle = `[Agent Request] ${query} - New agent needed`; const issueBodyContent = `## Agent Request **Role Name**: ${query} **Language**: ${language} ## Description ${issueBody || 'A new agent is needed for this role.'} ## Use Cases - [Please describe specific use cases] ## Required Tools - [List required tools like Read, Write, Edit, etc.] ## Additional Details - Requested via MCP server manual request - Agent name: "${query}" --- *This issue was created by claude-agents-power MCP server*`; const response = await fetch('https://api.github.com/repos/hongsw/claude-agents-power-mcp-server/issues', { method: 'POST', headers: { 'Authorization': `token ${githubToken}`, 'Accept': 'application/vnd.github+json', 'Content-Type': 'application/json', }, body: JSON.stringify({ title: issueTitle, body: issueBodyContent, labels: ['agent-request'], }), }); if (!response.ok) { throw new Error(`GitHub API error: ${response.status} ${response.statusText}`); } const issue = await response.json(); return { content: [ { type: 'text', text: JSON.stringify({ success: true, message: `Created GitHub issue #${issue.number} for agent "${query}"`, issueUrl: issue.html_url, issueNumber: issue.number, }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Failed to create issue: ${error}`, suggestion: 'Visit https://github.com/hongsw/claude-agents-power-mcp-server/issues to manually create an issue', }, null, 2), }, ], }; } } default: return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Unknown action: ${action}`, }, null, 2), }, ], }; } } case 'manage-agents': { const { action, agentNames, targetPath, language = 'en', limit = 10 } = args as { action: 'install' | 'stats' | 'refresh' | 'version'; agentNames?: string[]; targetPath?: string; language?: string; limit?: number; }; switch (action) { case 'install': { if (!agentNames || !targetPath) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Agent names and target path are required for install action', }, null, 2), }, ], }; } try { const installedPaths = await agentManager.installMultipleAgents( agentNames, targetPath, language ); return { content: [ { type: 'text', text: JSON.stringify({ success: true, installedCount: installedPaths.length, installedPaths, message: `Successfully installed ${installedPaths.length} agents to ${targetPath}/claude/agents/`, }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Failed to install agents: ${error}`, }, null, 2), }, ], }; } } case 'stats': { const stats = agentManager.getMostDownloadedAgents(limit); return { content: [ { type: 'text', text: JSON.stringify({ success: true, stats, message: `Top ${limit} most downloaded agents`, }, null, 2), }, ], }; } case 'refresh': { try { await agentManager.refreshAgentsFromGitHub(); const agents = agentManager.getAllAgents(); return { content: [ { type: 'text', text: JSON.stringify({ success: true, count: agents.length, message: `Successfully refreshed agents from GitHub. Total agents: ${agents.length}`, }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Failed to refresh agents: ${error}`, }, null, 2), }, ], }; } } case 'version': { const agents = agentManager.getAllAgents(); const agentsByLanguage = { en: agentManager.getAllAgents('en').length, ko: agentManager.getAllAgents('ko').length, ja: agentManager.getAllAgents('ja').length, zh: agentManager.getAllAgents('zh').length, }; return { content: [ { type: 'text', text: JSON.stringify({ success: true, version: version, serverName: 'claude-agents-power-mcp-server', totalAgents: agents.length, agentsByLanguage, npmPackage: 'claude-agents-power', repository: 'https://github.com/hongsw/claude-agents-power-mcp-server', message: `Claude Agents Power MCP Server v${version} - ${agents.length} agents available`, }, null, 2), }, ], }; } default: return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Unknown action: ${action}`, }, null, 2), }, ], }; } } default: return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Unknown tool: ${name}`, }, null, 2), }, ], }; } });