claude-agents-power
Version:
Unleash the power of 100+ specialized Claude agents for your development team via MCP
1,215 lines (1,155 loc) β’ 78.8 kB
JavaScript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
import { Command } from 'commander';
import { ProjectAnalyzer } from './projectAnalyzer.js';
import { AgentManager } from './agentManager.js';
import { initializeAnalytics, trackEvent, AnalyticsEvents, shutdown as shutdownAnalytics } from './analytics.js';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import fs from 'fs';
import os from 'os';
import dotenv from 'dotenv';
import { AgentDownloader } from './agentDownloader.js';
import { AIAnalysisService } from './aiAnalysisService.js';
// ES module compatibility
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load environment variables from .env file
dotenv.config();
// Get version from package.json
const packageJsonPath = path.join(__dirname, '../package.json');
let version = '1.6.0'; // fallback version
try {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
version = packageJson.version;
}
catch (error) {
console.error('[MCP Sub-Agents] Could not read package.json version:', error);
}
// Check for slash commands flags first (manual parsing to avoid commander issues)
const hasInstallSlashCommands = process.argv.includes('--install-slash-commands');
const hasUninstallSlashCommands = process.argv.includes('--uninstall-slash-commands');
const hasAgentDownload = process.argv.includes('--agent-download');
// Parse CLI arguments using commander
const program = new Command()
.name('claude-agents-power')
.option('--transport <stdio>', 'transport type', 'stdio')
.option('--debug', 'enable debug logging')
.option('--install', 'install MCP configuration to Claude Desktop')
.option('--install-slash-commands', 'install slash commands to Claude Code')
.option('--uninstall-slash-commands', 'uninstall slash commands from Claude Code')
.option('--agent-download', 'download recommended agents for current project')
.option('--target-dir <dir>', 'target directory for agent files (default: "./agents")')
.option('--claude-md <path>', 'path to CLAUDE.md file (default: "./CLAUDE.md")')
.option('--format <format>', 'agent file format: md, yaml, json (default: "md")')
.option('--language <lang>', 'preferred language: en, ko, ja, zh (default: "en")')
.option('--limit <n>', 'maximum number of agents to download (default: 10)')
.option('--dry-run', 'preview recommendations without downloading')
.option('--overwrite', 'overwrite existing agent files')
.allowUnknownOption() // let MCP Inspector / other wrappers pass through extra flags
.parse(process.argv);
const cliOptions = program.opts();
// Override with manual parsing results
if (hasInstallSlashCommands) {
cliOptions.installSlashCommands = true;
}
if (hasUninstallSlashCommands) {
cliOptions.uninstallSlashCommands = true;
}
if (hasAgentDownload) {
cliOptions.agentDownload = true;
}
// Handle --install flag
if (cliOptions.install) {
console.log('π Claude Agents Power MCP Installer\n');
// Get Claude Desktop config path
const configPaths = [
path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
path.join(os.homedir(), '.config', 'claude', 'claude_desktop_config.json'),
path.join(os.homedir(), 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json')
];
let configPath = null;
for (const p of configPaths) {
if (fs.existsSync(p)) {
configPath = p;
break;
}
}
if (!configPath) {
// Try to find Claude config directory
const configDirs = [
path.join(os.homedir(), 'Library', 'Application Support', 'Claude'),
path.join(os.homedir(), '.config', 'claude'),
path.join(os.homedir(), 'AppData', 'Roaming', 'Claude')
];
for (const dir of configDirs) {
if (fs.existsSync(dir)) {
configPath = path.join(dir, 'claude_desktop_config.json');
break;
}
}
}
if (!configPath) {
console.error('β Could not find Claude Desktop configuration directory');
console.log('\nPlease create the config file manually at one of these locations:');
configPaths.forEach(p => console.log(` - ${p}`));
process.exit(1);
}
console.log(`π Found Claude config at: ${configPath}`);
// Read existing config or create new one
let config = { mcpServers: {} };
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, 'utf8');
config = JSON.parse(content);
if (!config.mcpServers) {
config.mcpServers = {};
}
}
catch (error) {
console.error('β οΈ Error reading existing config, will create new one');
}
}
// Check if already installed
if (config.mcpServers['claude-agents-power']) {
console.log('β
claude-agents-power is already configured in Claude Desktop');
console.log('\nTo update, remove the existing entry and run this installer again.');
process.exit(0);
}
// Add claude-agents-power to config
config.mcpServers['claude-agents-power'] = {
command: 'npx',
args: ['claude-agents-power']
};
// Write config
try {
// Create directory if it doesn't exist
const dir = path.dirname(configPath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log('β
Successfully added claude-agents-power to Claude Desktop configuration');
console.log('\nπ Next steps:');
console.log('1. Restart Claude Desktop');
console.log('2. Look for MCP tools starting with "mcp__claude-agents-power__"');
console.log('\nπ― Example usage in Claude:');
console.log(' "claude-agents-powerλ₯Ό μ΄μ©ν΄μ μ΄ νλ‘μ νΈλ₯Ό μν μΆμ² λ° agents/*.md νμΌμ λ€μ΄λ‘λ ν΄μ€"');
}
catch (error) {
console.error('β Error writing configuration:', error.message);
console.log('\nPlease add this to your claude_desktop_config.json manually:');
console.log(JSON.stringify({
mcpServers: {
'claude-agents-power': {
command: 'npx',
args: ['claude-agents-power']
}
}
}, null, 2));
process.exit(1);
}
process.exit(0);
}
// Handle --install-slash-commands flag
if (cliOptions.installSlashCommands) {
console.log('π Claude Agents Power - Slash Commands Installer\n');
try {
const claudeDir = path.join(os.homedir(), '.claude');
const commandsDir = path.join(claudeDir, 'commands');
const sourceDir = path.join(__dirname, '../claude-slash-commands');
// Create directories if they don't exist
if (!fs.existsSync(claudeDir)) {
fs.mkdirSync(claudeDir, { recursive: true });
console.log(`π Created: ${claudeDir}`);
}
if (!fs.existsSync(commandsDir)) {
fs.mkdirSync(commandsDir, { recursive: true });
console.log(`π Created: ${commandsDir}`);
}
// Copy command files
console.log('π Installing slash commands...');
const commandFiles = fs.readdirSync(sourceDir);
for (const file of commandFiles) {
if (file.endsWith('.md')) {
const sourcePath = path.join(sourceDir, file);
const targetPath = path.join(commandsDir, file);
fs.copyFileSync(sourcePath, targetPath);
console.log(` β
Installed: ${file}`);
}
}
// Create README
const readmeContent = `# Claude Agents Power - Slash Commands
Available commands:
- /agents:load - Load and display available agents
- /agents:search - Search agents by skills or keywords
- /agents:suggest - Get intelligent agent recommendations
- /agents:version - Check system version and status
Generated by claude-agents-power v${version}
`;
fs.writeFileSync(path.join(commandsDir, 'README.md'), readmeContent);
console.log('\nβ
Slash commands installed successfully!');
console.log('\nAvailable commands in Claude Code:');
console.log(' /agents:load - Load and display available agents');
console.log(' /agents:search - Search agents by skills or keywords');
console.log(' /agents:suggest - Get intelligent agent recommendations');
console.log(' /agents:version - Check system version and status');
console.log('\nπ‘ Try "/agents:load" in Claude Code to get started!');
}
catch (error) {
console.error('β Installation failed:', error);
process.exit(1);
}
process.exit(0);
}
// Handle --uninstall-slash-commands flag
if (cliOptions.uninstallSlashCommands) {
console.log('ποΈ Uninstalling claude-agents-power slash commands...\n');
try {
const commandsDir = path.join(os.homedir(), '.claude', 'commands');
if (fs.existsSync(commandsDir)) {
const files = fs.readdirSync(commandsDir);
const agentCommandFiles = files.filter(file => file.startsWith('agents-') && file.endsWith('.md'));
for (const file of agentCommandFiles) {
const filePath = path.join(commandsDir, file);
fs.unlinkSync(filePath);
console.log(` ποΈ Removed: ${file}`);
}
// Remove README if it exists
const readmePath = path.join(commandsDir, 'README.md');
if (fs.existsSync(readmePath)) {
fs.unlinkSync(readmePath);
console.log(' ποΈ Removed: README.md');
}
console.log('\nβ
Slash commands uninstalled successfully!');
}
else {
console.log('No slash commands found to uninstall.');
}
}
catch (error) {
console.error('β Uninstallation failed:', error);
process.exit(1);
}
process.exit(0);
}
// Handle --agent-download flag
if (cliOptions.agentDownload) {
console.log('π€ Claude Agents Power - Agent Downloader\n');
try {
const downloader = new AgentDownloader();
const options = {
targetDir: cliOptions.targetDir || './agents',
claudeMdPath: cliOptions.claudeMd || './CLAUDE.md',
format: cliOptions.format || 'md',
language: cliOptions.language || 'en',
limit: cliOptions.limit ? parseInt(cliOptions.limit) : 10,
dryRun: cliOptions.dryRun || false,
overwrite: cliOptions.overwrite || false
};
console.log('π Analyzing project...');
const result = await downloader.downloadAgents(options);
// Display enhanced AI analysis results
console.log('\nπ§ AI-Powered Project Analysis Results:');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββ');
console.log(`π Project Type: ${result.analysis.projectType}`);
console.log(`π οΈ Technologies: ${result.analysis.technologies.join(', ') || 'None detected'}`);
console.log(`π Frameworks: ${result.analysis.frameworks.join(', ') || 'None detected'}`);
console.log(`π Complexity: ${result.analysis.complexity}/10`);
console.log(`π Development Phase: ${result.analysis.phase}`);
console.log(`π₯ Recommended Team Size: ${result.analysis.teamSize} agents`);
if (result.analysis.description) {
console.log(`π Description: ${result.analysis.description}`);
}
// Display quality indicators
if (result.analysis.qualityIndicators) {
console.log('\nπ Quality Assessment:');
const qi = result.analysis.qualityIndicators;
console.log(` ${qi.hasTests ? 'β
' : 'β'} Automated Testing`);
console.log(` ${qi.hasDocumentation ? 'β
' : 'β'} Documentation`);
console.log(` ${qi.hasCI ? 'β
' : 'β
'} CI/CD Pipeline`);
console.log(` ${qi.hasLinting ? 'β
' : 'β'} Code Quality Tools`);
console.log(` π Code Complexity: ${qi.codeComplexity}`);
}
// Display architectural patterns if available
if (result.analysis.architecturalPatterns && result.analysis.architecturalPatterns.length > 0) {
console.log(`\nποΈ Architectural Patterns: ${result.analysis.architecturalPatterns.join(', ')}`);
}
// Display development practices if available
if (result.analysis.developmentPractices && result.analysis.developmentPractices.length > 0) {
console.log(`\nβοΈ Development Practices: ${result.analysis.developmentPractices.join(', ')}`);
}
console.log('\nπ AI-Generated Recommendations:');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββ');
result.recommendations.forEach((rec, index) => {
const icon = rec.priority === 'essential' ? 'β' :
rec.priority === 'recommended' ? 'π§' : 'π‘';
console.log(`${index + 1}. ${icon} ${rec.name} (${rec.relevanceScore}% match)`);
console.log(` ββ ${rec.reasoning}`);
// Display specific tasks if available
if (rec.specificTasks && rec.specificTasks.length > 0) {
console.log(` π― Key Tasks: ${rec.specificTasks.slice(0, 2).join(', ')}${rec.specificTasks.length > 2 ? '...' : ''}`);
}
// Display integration points if available
if (rec.integrationPoints && rec.integrationPoints.length > 0) {
console.log(` π Integrations: ${rec.integrationPoints.slice(0, 2).join(', ')}${rec.integrationPoints.length > 2 ? '...' : ''}`);
}
});
if (options.dryRun) {
console.log('\nπ‘ This was an AI-powered dry run analysis. Use without --dry-run to download agents.');
console.log('\nπ§ AI Analysis Features Used:');
console.log(' β’ Intelligent project structure analysis');
console.log(' β’ Context-aware agent recommendations');
console.log(' β’ Dynamic priority assignment');
console.log(' β’ Task-specific role matching');
}
else if (result.downloaded && result.downloaded.length > 0) {
console.log('\nπ₯ Downloaded AI-Recommended Agents:');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββ');
result.downloaded.forEach(filePath => {
const fileName = path.basename(filePath);
const fileSize = fs.statSync(filePath).size;
const fileSizeKB = (fileSize / 1024).toFixed(1);
console.log(`β
${fileName.padEnd(25)} (${fileSizeKB}KB)`);
});
console.log('\nπ AI-Powered Summary:');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββ');
console.log(`β
${result.downloaded.length} agents intelligently selected and downloaded`);
console.log(`π Files saved to: ${options.targetDir}`);
console.log(`π Enhanced README.md created with AI analysis insights`);
console.log(`π§ AI Features: Dynamic analysis, context-aware recommendations, smart prioritization`);
console.log(`π‘ Next: Try using your AI-recommended agents in your development workflow`);
}
}
catch (error) {
console.error('β Agent download failed:', error);
process.exit(1);
}
process.exit(0);
}
// Debug logging function
const debug = (...args) => {
if (cliOptions.debug) {
console.error('[MCP Sub-Agents DEBUG]', ...args);
}
};
// Validate transport option
const allowedTransports = ['stdio'];
if (!allowedTransports.includes(cliOptions.transport)) {
console.error(`Invalid --transport value: '${cliOptions.transport}'. Must be: stdio.`);
process.exit(1);
}
// Transport configuration
const TRANSPORT_TYPE = 'stdio';
// Function to create a new server instance with all tools registered
function createServerInstance() {
const server = new Server({
name: 'claude-agents-power-mcp-server',
version: version,
}, {
capabilities: {
tools: {},
resources: {},
},
});
return server;
}
// Initialize analytics
initializeAnalytics();
trackEvent(AnalyticsEvents.SERVER_STARTED, {
debug_mode: cliOptions.debug,
transport: cliOptions.transport,
});
// Initialize managers
// Support both development and production paths
const isDevelopment = process.env.NODE_ENV === 'development';
// Try multiple possible agent paths
let agentsPath;
const possiblePaths = [
// Development path
path.join(__dirname, '../../claude/agents'),
// Production NPM global install
path.join(__dirname, '../claude/agents'),
// Alternative production path
path.resolve(process.cwd(), 'claude/agents'),
// NPM package structure
path.join(__dirname, '..', '..', 'claude', 'agents'),
];
// Find the first existing path
agentsPath = possiblePaths.find(p => {
const exists = existsSync(p);
if (cliOptions.debug) {
console.error(`[MCP Sub-Agents DEBUG] Checking path: ${p} - ${exists ? 'EXISTS' : 'NOT FOUND'}`);
}
return exists;
}) || possiblePaths[0];
debug(`Current working directory: ${process.cwd()}`);
debug(`__dirname: ${__dirname}`);
debug(`Loading agents from: ${agentsPath}`);
// Check if agents directory exists
import { existsSync } from 'fs';
if (cliOptions.debug && existsSync(agentsPath)) {
debug(`Agents directory exists: ${agentsPath}`);
const { readdirSync } = await import('fs');
const files = readdirSync(agentsPath);
debug(`Found ${files.length} files in agents directory`);
}
else if (cliOptions.debug) {
debug(`ERROR: Agents directory not found: ${agentsPath}`);
}
const projectAnalyzer = new ProjectAnalyzer();
const agentManager = new AgentManager(agentsPath, {
owner: 'baryonlabs',
repo: 'claude-sub-agent-contents',
branch: 'main',
path: 'claude/agents'
}, cliOptions.debug || false);
const aiAnalysisService = new AIAnalysisService();
// Function to setup tools for a server instance
function setupTools(server, projectAnalyzer, agentManager, aiAnalysisService) {
// Define resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: 'mcp://claude-agents-power/how-it-works',
name: 'MCP λμ μ리',
description: 'Claude Agents Power MCP μλ²μ λμ μ리μ ꡬ쑰 μ€λͺ
',
mimeType: 'text/markdown',
},
{
uri: 'mcp://claude-agents-power/tool-guide',
name: 'λꡬ μ¬μ© κ°μ΄λ',
description: 'ν΅ν©λ 3κ° λꡬμ μ¬μ© λ°©λ²κ³Ό μμ ',
mimeType: 'text/markdown',
},
{
uri: 'mcp://claude-agents-power/agent-structure',
name: 'μμ΄μ νΈ κ΅¬μ‘°',
description: 'μμ΄μ νΈ νμΌ κ΅¬μ‘°μ λ€κ΅μ΄ μ§μ μ€λͺ
',
mimeType: 'text/markdown',
},
],
};
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const { uri } = request.params;
switch (uri) {
case 'mcp://claude-agents-power/how-it-works':
return {
contents: [
{
uri,
mimeType: 'text/markdown',
text: `# Claude Agents Power MCP μλ² λμ μ리
## κ°μ
Claude Agents Powerλ Model Context Protocol(MCP)μ μ¬μ©νμ¬ 100κ° μ΄μμ μ λ¬Έ μμ΄μ νΈλ₯Ό Claudeμμ μ¬μ©ν μ μκ² ν΄μ£Όλ μλ²μ
λλ€.
## MCP (Model Context Protocol) λ?
MCPλ Claudeμ κ°μ LLMμ΄ μΈλΆ λꡬμ 리μμ€μ μ κ·Όν μ μκ² ν΄μ£Όλ νμ€ νλ‘ν μ½μ
λλ€.
### μ£Όμ κ΅¬μ± μμ:
1. **Tools (λꡬ)**: Claudeκ° μ€νν μ μλ ν¨μλ€
2. **Resources (리μμ€)**: Claudeκ° μ½μ μ μλ λ¬Έμλ λ°μ΄ν°
3. **Prompts (ν둬ννΈ)**: 미리 μ μλ ν둬ννΈ ν
νλ¦Ώ
## μλ² μν€ν
μ²
### 1. μμ΄μ νΈ λ§€λμ (AgentManager)
- μμ΄μ νΈ νμΌ λ‘λ© λ° μΊμ±
- λ€κ΅μ΄ μ§μ (en, ko, ja, zh)
- GitHubμμ μμ΄μ νΈ λμ λ‘λ©
### 2. νλ‘μ νΈ λΆμκΈ° (ProjectAnalyzer)
- νλ‘μ νΈ κ΅¬μ‘° λΆμ
- μ ν©ν μμ΄μ νΈ μΆμ²
- ν€μλ κΈ°λ° λ§€μΉ
### 3. ν΅ν© λꡬ μμ€ν
κΈ°μ‘΄ 8κ° λꡬλ₯Ό 3κ°λ‘ ν΅ν©:
- \`analyze-project\`: νλ‘μ νΈ λΆμ
- \`agents\`: μμ΄μ νΈ κ²μ/λͺ©λ‘/μμΈ/μΆμ²
- \`manage-agents\`: μ€μΉ/ν΅κ³/μλ‘κ³ μΉ¨
## λ°μ΄ν° νλ¦
\`\`\`
Claude Desktop β MCP Protocol β Agent Manager β Local Files
β
GitHub Repository (fallback)
\`\`\`
## μμ΄μ νΈ λ‘λ© κ³Όμ
1. **μμμ**: \`claude/agents/{μΈμ΄}/\` λλ ν 리μμ μμ΄μ νΈ λ‘λ
2. **μμ²μ**: μΊμμμ λΉ λ₯Έ κ²μ
3. **λ―Έλ°κ²¬μ**: GitHubμμ λμ λ€μ΄λ‘λ
4. **μ€μΉ**: νλ‘μ νΈ λλ ν 리μ μμ΄μ νΈ νμΌ λ³΅μ¬
## μ±λ₯ μ΅μ ν
- λ©λͺ¨λ¦¬ μΊμ±μΌλ‘ λΉ λ₯Έ μλ΅
- YAML frontmatter νμ±μΌλ‘ λ©νλ°μ΄ν° μΆμΆ
- μΈμ΄λ³ ν€ λ§€νμΌλ‘ ν¨μ¨μ μΈ κ²μ
`,
},
],
};
case 'mcp://claude-agents-power/tool-guide':
return {
contents: [
{
uri,
mimeType: 'text/markdown',
text: `# λꡬ μ¬μ© κ°μ΄λ
## ν΅ν©λ 3κ° λꡬ μ¬μ©λ²
### 1. analyze-project
νλ‘μ νΈ λλ ν 리λ₯Ό λΆμνμ¬ μ ν©ν μμ΄μ νΈλ₯Ό μΆμ²ν©λλ€.
**μ¬μ©λ²:**
\`\`\`json
{
"tool": "analyze-project",
"arguments": {
"projectPath": "/path/to/project"
}
}
\`\`\`
### 2. agents
μμ΄μ νΈ κ΄λ ¨ λͺ¨λ μμ
μ μ²λ¦¬νλ ν΅ν© λꡬμ
λλ€.
#### 2.1 κ²μ (search)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "search",
"query": "frontend",
"language": "en"
}
}
\`\`\`
#### 2.2 λͺ©λ‘ μ‘°ν (list)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "list",
"language": "ko",
"category": "development"
}
}
\`\`\`
#### 2.3 μμΈ μ 보 (details)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "details",
"query": "frontend-developer",
"language": "en"
}
}
\`\`\`
#### 2.4 μΆμ² (recommend)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "recommend",
"keywords": ["react", "typescript", "ui"]
}
}
\`\`\`
#### 2.5 κ²μ (μλ Issue μμ±)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "search",
"query": "blockchain-architect",
"language": "en",
"autoCreateIssue": true,
"issueBody": "We need a blockchain architect for smart contract development"
}
}
\`\`\`
#### 2.6 μμ² (request)
\`\`\`json
{
"tool": "agents",
"arguments": {
"action": "request",
"query": "ai-ethics-officer",
"language": "en",
"issueBody": "Need an AI ethics specialist for responsible AI development"
}
}
\`\`\`
### 3. manage-agents
μμ΄μ νΈ κ΄λ¦¬ μμ
μ μ²λ¦¬ν©λλ€.
#### 3.1 μ€μΉ (install)
\`\`\`json
{
"tool": "manage-agents",
"arguments": {
"action": "install",
"agentNames": ["frontend-developer", "backend-engineer"],
"targetPath": "/path/to/project",
"language": "en"
}
}
\`\`\`
#### 3.2 ν΅κ³ (stats)
\`\`\`json
{
"tool": "manage-agents",
"arguments": {
"action": "stats",
"limit": 10
}
}
\`\`\`
#### 3.3 μλ‘κ³ μΉ¨ (refresh)
\`\`\`json
{
"tool": "manage-agents",
"arguments": {
"action": "refresh"
}
}
\`\`\`
## μΈμ΄ μ§μ
- \`en\`: English
- \`ko\`: νκ΅μ΄
- \`ja\`: ζ₯ζ¬θͺ
- \`zh\`: δΈζ
## μΉ΄ν
κ³ λ¦¬
- development, data, design, management
- marketing, operations, hr, finance
- legal, research, healthcare, education
- media, manufacturing, other
`,
},
],
};
case 'mcp://claude-agents-power/agent-structure':
return {
contents: [
{
uri,
mimeType: 'text/markdown',
text: `# μμ΄μ νΈ κ΅¬μ‘°
## νμΌ κ΅¬μ‘°
\`\`\`
claude/agents/
βββ en/ # μμ΄ μμ΄μ νΈ
β βββ frontend-developer.md
β βββ backend-engineer.md
β βββ ...
βββ ko/ # νκ΅μ΄ μμ΄μ νΈ
β βββ frontend-developer.md
β βββ backend-engineer.md
β βββ ...
βββ ja/ # μΌλ³Έμ΄ μμ΄μ νΈ
βββ zh/ # μ€κ΅μ΄ μμ΄μ νΈ
\`\`\`
## μμ΄μ νΈ νμΌ νμ
κ° μμ΄μ νΈ νμΌμ YAML frontmatterμ Markdown μ½ν
μΈ λ‘ κ΅¬μ±λ©λλ€:
\`\`\`markdown
---
name: frontend-developer
description: UI/UX implementation specialist with React, Vue, and modern web technologies expertise.
tools: Read, Write, Edit, MultiEdit, Bash, WebSearch
---
You are a frontend engineer specializing in modern web applications.
Focus areas:
- Build responsive and accessible interfaces
- Implement state management solutions
- Optimize performance and bundle sizes
- Ensure cross-browser compatibility
- Write maintainable component architectures
Key practices:
- Follow semantic HTML standards
- Implement WCAG accessibility guidelines
- Use modern CSS features (Grid, Flexbox)
- Optimize for Core Web Vitals
- Write comprehensive tests
\`\`\`
## λ©νλ°μ΄ν° νλ
### name (νμ)
μμ΄μ νΈμ κ³ μ μλ³μμ
λλ€. νμΌλͺ
κ³Ό μΌμΉν΄μΌ ν©λλ€.
### description (νμ)
μμ΄μ νΈμ μν κ³Ό μ λ¬Έμ±μ μ€λͺ
ν©λλ€. κ²μμ μ¬μ©λ©λλ€.
### tools (νμ)
μμ΄μ νΈκ° μ¬μ©ν μ μλ λꡬ λͺ©λ‘μ
λλ€.
**μ¬μ© κ°λ₯ν λꡬ:**
- Read, Write, Edit, MultiEdit
- Bash, Grep, Glob
- WebSearch, WebFetch
- TodoWrite, Task
- NotebookRead, NotebookEdit
## λ€κ΅μ΄ μ§μ
### μΈμ΄λ³ ν€ λ§€ν
- μμ΄: \`agent-name\`
- κΈ°ν μΈμ΄: \`agent-name-{μΈμ΄μ½λ}\`
μ:
- \`frontend-developer\` (μμ΄)
- \`frontend-developer-ko\` (νκ΅μ΄)
- \`frontend-developer-ja\` (μΌλ³Έμ΄)
### μΈμ΄ κ°μ§
1. μμ²λ μΈμ΄μ λ°λ₯Έ μμ΄μ νΈ κ²μ
2. ν΄λΉ μΈμ΄κ° μμΌλ©΄ μμ΄ λ²μ μ¬μ©
3. λͺ¨λ μμΌλ©΄ GitHubμμ λ€μ΄λ‘λ μλ
## μμ΄μ νΈ νμ§ κΈ°μ€
### νμ μμ
1. λͺ
νν μν μ μ
2. ꡬ체μ μΈ μ±
μ λ²μ
3. μ€μ©μ μΈ κ°μ΄λλΌμΈ
4. λꡬ μ μ ν μ ν
### κΆμ₯ ꡬ쑰
1. μν μκ°
2. ν΅μ¬ νλ/μ±
μ
3. μ£Όμ κ΄ν
4. νμ§ κΈ°μ€
5. νμ
λ°©μ
## μμ΄μ νΈ μμ± κ°μ΄λ
μ μμ΄μ νΈλ₯Ό λ§λ€ λ:
1. κΈ°μ‘΄ μμ΄μ νΈ μ°Έκ³
2. μΌκ΄λ νμ μ μ§
3. μΈμ΄λ³ λ²μ μ 곡
4. μ μ ν λꡬ μ ν
5. ꡬ체μ μ΄κ³ μ€μ©μ μΈ λ΄μ© μμ±
`,
},
],
};
default:
throw new Error(`Unknown resource: ${uri}`);
}
});
// Define tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
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'],
},
},
],
};
});
// Handle tool calls
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;
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;
try {
// Perform AI-powered project analysis
const analysis = await aiAnalysisService.analyzeProject(claudeMdPath, projectPath);
let recommendations = [];
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;
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;
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 age