mcp-agent-selection/test_agents.py
Ryan Malloy 997cf8dec4 Initial commit: Production-ready FastMCP agent selection server
Features:
- FastMCP-based MCP server for Claude Code agent recommendations
- Hierarchical agent architecture with 39 specialized agents
- 10 MCP tools with enhanced LLM-friendly descriptions
- Composed agent support with parent-child relationships
- Project root configuration for focused recommendations
- Smart agent recommendation engine with confidence scoring

Server includes:
- Core recommendation tools (recommend_agents, get_agent_content)
- Project management tools (set/get/clear project roots)
- Discovery tools (list_agents, server_stats)
- Hierarchy navigation (get_sub_agents, get_parent_agent, get_agent_hierarchy)

All tools properly annotated for calling LLM clarity with detailed
arguments, return values, and usage examples.
2025-09-09 09:28:23 -06:00

181 lines
6.5 KiB
Python

#!/usr/bin/env python3
"""
Test agent library functionality without external dependencies
"""
import json
import os
import yaml
from pathlib import Path
from typing import List, Dict, Optional
from dataclasses import dataclass, asdict
@dataclass
class AgentInfo:
name: str
emoji: str
description: str
tools: List[str]
content: str
file_path: str
@dataclass
class ProjectRoots:
directories: List[str]
base_path: str
description: str = ""
class SimpleAgentLibrary:
def __init__(self, templates_path: Path):
self.templates_path = templates_path
self.agents: Dict[str, AgentInfo] = {}
self.roots: Optional[ProjectRoots] = None
def load_agents(self):
"""Load all agent templates from the directory"""
if not self.templates_path.exists():
print(f"⚠️ Templates path not found: {self.templates_path}")
return
for file_path in self.templates_path.glob("*.md"):
try:
content = file_path.read_text()
# Extract YAML frontmatter
if content.startswith("---\n"):
parts = content.split("---\n", 2)
if len(parts) >= 3:
frontmatter = yaml.safe_load(parts[1])
body = parts[2]
agent = AgentInfo(
name=frontmatter.get("name", file_path.stem),
emoji=frontmatter.get("emoji", "🤖"),
description=frontmatter.get("description", ""),
tools=frontmatter.get("tools", []),
content=body.strip(),
file_path=str(file_path)
)
self.agents[agent.name] = agent
except Exception as e:
print(f"❌ Error loading {file_path}: {e}")
print(f"✅ Loaded {len(self.agents)} agents")
return self.agents
def set_roots(self, directories: List[str], base_path: str, description: str = ""):
"""Set project roots for focused analysis"""
self.roots = ProjectRoots(directories, base_path, description)
return f"✅ Set project roots: {directories} in {base_path}"
def get_roots(self) -> Optional[Dict]:
"""Get current project roots"""
if self.roots:
return asdict(self.roots)
return {"message": "No roots configured"}
def clear_roots(self):
"""Clear project roots"""
self.roots = None
return "✅ Cleared project roots"
def recommend_agents(self, task: str, project_context: str = "") -> List[Dict]:
"""Simple recommendation logic"""
recommendations = []
task_lower = task.lower()
# Keywords to agent mapping
keywords = {
"python": ["🔮-python-mcp-expert", "🧪-testing-integration-expert"],
"fastapi": ["🚄-fastapi-expert"],
"docker": ["🐳-docker-infrastructure-expert"],
"security": ["🔒-security-audit-expert"],
"documentation": ["📖-readme-expert"],
"subagent": ["🎭-subagent-expert"],
"test": ["🧪-testing-integration-expert"],
"mcp": ["🔮-python-mcp-expert"]
}
# Find matching agents
for keyword, agent_names in keywords.items():
if keyword in task_lower:
for agent_name in agent_names:
if agent_name in self.agents:
agent = self.agents[agent_name]
recommendations.append({
"name": agent.name,
"emoji": agent.emoji,
"description": agent.description,
"confidence": 0.8,
"reason": f"Matches keyword '{keyword}' in task description"
})
# If no specific matches, suggest subagent expert
if not recommendations and "🎭-subagent-expert" in self.agents:
agent = self.agents["🎭-subagent-expert"]
recommendations.append({
"name": agent.name,
"emoji": agent.emoji,
"description": agent.description,
"confidence": 0.6,
"reason": "General purpose recommendation for task planning"
})
return recommendations[:5] # Limit to top 5
def test_functionality():
"""Test the agent library functionality"""
print("🚀 Testing Claude Agent Library...")
# Initialize with local templates
templates_path = Path(__file__).parent / "agent_templates"
library = SimpleAgentLibrary(templates_path)
# Load agents
agents = library.load_agents()
print(f"\n📋 Available agents ({len(agents)}):")
for name, agent in list(agents.items())[:5]: # Show first 5
print(f" {agent.emoji} {name}")
print(f" {agent.description[:80]}...")
# Test recommendations
print("\n🔧 Testing recommendations...")
tasks = [
"I need help with Python FastAPI development",
"How do I write better documentation?",
"I need to containerize my application with Docker",
"Help me set up testing for my project"
]
for task in tasks:
print(f"\n📝 Task: \"{task}\"")
recs = library.recommend_agents(task)
for rec in recs:
print(f" {rec['emoji']} {rec['name']} (confidence: {rec['confidence']:.1f})")
print(f"{rec['reason']}")
# Test roots functionality
print("\n🗂️ Testing roots functionality...")
result = library.set_roots(['src/api', 'src/backend'], '/home/rpm/project', 'API development focus')
print(result)
roots = library.get_roots()
print(f"Current roots: {json.dumps(roots, indent=2)}")
clear_result = library.clear_roots()
print(clear_result)
# Test getting agent content
print("\n📄 Testing agent content retrieval...")
if "🎭-subagent-expert" in agents:
content = agents["🎭-subagent-expert"].content
print(f"Content preview (first 200 chars):")
print(content[:200] + "..." if len(content) > 200 else content)
print("\n✅ All tests completed!")
if __name__ == "__main__":
test_functionality()