MCP Demo Server with Intelligent Agent System
A production-ready demonstration of a Model Context Protocol (MCP) server implemented in Python, featuring an intelligent Agent System with subagents and orchestration capabilities. This project showcases best practices for building MCP servers and multi-agent systems with comprehensive examples.
What is MCP?
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to Large Language Models (LLMs). MCP servers expose:
- Tools: Executable functions that LLMs can call (e.g., calculator, file operations)
- Resources: Data sources that LLMs can read (e.g., configuration, documentation)
- Prompts: Reusable prompt templates for common tasks
Features
Agent System (NEW!)
Production-ready intelligent agents that work with MCP:
-
Agent - Core agent with MCP integration
- Execute tasks using MCP tools
- Delegate work to specialized subagents
- Track task execution and results
- Handle errors, retries, and timeouts
-
SubAgents - Specialized agents for specific tasks
- CalculatorSubAgent - Mathematical calculations
- FileOperationsSubAgent - File system operations
- WeatherSubAgent - Weather information
- TimestampSubAgent - Timestamp operations
- DataProcessingSubAgent - Data processing pipelines
-
AgentOrchestrator - Multi-agent coordination
- Manage pools of agents
- Auto-assign tasks to capable agents
- Execute workflows with dependencies
- Parallel and sequential execution
- Result aggregation and statistics
-
Task Management - Robust task system
- Task definitions with priorities
- State tracking (pending, in_progress, completed, failed)
- Retry logic and timeout handling
- Detailed result tracking
MCP Server Tools
-
Calculator - Basic mathematical operations
- Operations: add, subtract, multiply, divide
- Full input validation and error handling
-
File Operations - File system interactions
- Read, write, list directories, check file existence
- Safe path handling with proper error messages
-
Weather - Simulated weather information
- Get weather data for any city
- Support for Celsius and Fahrenheit
-
Timestamp - Get current time in various formats
- ISO format, Unix timestamp, human-readable format
Resources Available
-
Server Configuration (
config://server/settings)- Current server settings and metadata
- JSON formatted configuration
-
System Information (
system://info)- OS, Python version, working directory
- Server process information
-
Documentation (
docs://getting-started)- Getting started guide
- Usage instructions
Prompts Provided
-
Code Review - Generate code review checklists
- Customizable by programming language
- Adjustable complexity level
-
Documentation - Documentation templates
- API, User, and Developer documentation types
- Project-specific customization
-
Debug Assistant - Debugging guidance
- Structured debugging approach
- Common techniques and best practices
Installation
Prerequisites
- Python 3.10 or higher
- pip (Python package manager)
Install Dependencies
# Clone the repository
git clone https://github.com/yourusername/mcp-agent.git
cd mcp-agent
# Install the package
pip install -e .
# Or install dependencies directly
pip install -r requirements.txt
Development Setup
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
pytest
# Format code
black src/
# Lint code
ruff check src/
Usage
Running the Agent System Demo
Experience the full power of the agent system:
# Run comprehensive agent system demo
python examples/agent_demo.py
This demo showcases:
- Simple agent with basic tasks
- Agent with subagents (task delegation)
- Orchestrator managing multiple agents
- Multi-step workflow execution
- Data processing pipeline
Quick Agent System Example
import asyncio
from mcp_demo import Agent, AgentCapability, Task
from mcp_demo import CalculatorSubAgent, FileOperationsSubAgent
from mcp_demo import AgentOrchestrator, Workflow, WorkflowStep
async def main():
# Create main agent with subagents
main_agent = Agent(name="MainAgent")
calc_sub = CalculatorSubAgent(parent_agent=main_agent)
file_sub = FileOperationsSubAgent(parent_agent=main_agent)
# Create tasks
calc_task = Task(
name="Calculate",
task_type="calculation",
parameters={"operation": "add", "a": 10, "b": 20},
)
# Execute - automatically delegated to appropriate subagent
async with main_agent, calc_sub, file_sub:
result = await main_agent.execute_task(calc_task)
print(f"Result: {result.data}")
asyncio.run(main())
Using the Orchestrator
from mcp_demo import AgentOrchestrator, CalculatorSubAgent, Task
async def orchestrate():
# Create orchestrator
orch = AgentOrchestrator(name="MainOrch")
# Register agents
orch.register_agent(CalculatorSubAgent())
# Execute tasks in parallel
async with orch:
results = await orch.execute_tasks(
[task1, task2, task3],
parallel=True,
)
# Get statistics
stats = orch.get_statistics()
print(f"Success rate: {stats['overall_success_rate']:.1f}%")
Running the MCP Server
The server uses stdio for communication, which is the standard transport for MCP servers:
# Run directly with Python
python -m mcp_demo.server
# Or use the installed script
mcp-demo
Configuration for Claude Desktop
To use this MCP server with Claude Desktop, add it to your Claude configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"demo": {
"command": "python",
"args": [
"-m",
"mcp_demo.server"
],
"env": {}
}
}
}
Or using the installed command:
{
"mcpServers": {
"demo": {
"command": "mcp-demo",
"args": [],
"env": {}
}
}
}
Using with MCP Client
You can also use the included example client:
python examples/client.py
Project Structure
mcp-agent/
├── src/
│ └── mcp_demo/
│ ├── __init__.py # Package initialization
│ ├── server.py # MCP server implementation
│ ├── agent.py # Core agent with MCP integration
│ ├── subagent.py # Specialized subagents
│ ├── orchestrator.py # Multi-agent orchestration
│ └── task.py # Task management system
├── examples/
│ ├── client.py # Example MCP client
│ ├── agent_demo.py # Comprehensive agent system demo
│ └── claude_config.json # Example Claude Desktop config
├── tests/
│ ├── __init__.py
│ ├── test_server.py # Server tests
│ └── test_agents.py # Agent system tests
├── docs/
│ ├── ARCHITECTURE.md # MCP server architecture
│ └── AGENT_SYSTEM.md # Agent system documentation
├── pyproject.toml # Project configuration
├── requirements.txt # Production dependencies
├── requirements-dev.txt # Development dependencies
├── README.md # This file
└── LICENSE # MIT License
Code Architecture
Server Implementation
The server follows a clean, modular architecture:
class MCPDemoServer:
"""Main server class with handler methods"""
def __init__(self, name: str):
"""Initialize server and register handlers"""
async def list_tools(self) -> list[Tool]:
"""Return available tools"""
async def call_tool(self, name: str, arguments: Any) -> list[TextContent]:
"""Execute a tool"""
async def list_resources(self) -> list[Resource]:
"""Return available resources"""
async def read_resource(self, uri: AnyUrl) -> str:
"""Read a resource"""
async def list_prompts(self) -> list[Prompt]:
"""Return available prompts"""
async def get_prompt(self, name: str, arguments: dict) -> GetPromptResult:
"""Get a prompt with arguments"""
Key Design Patterns
- Type Safety: Full type hints with Pydantic models
- Error Handling: Comprehensive try-catch with logging
- Validation: Input validation using Pydantic schemas
- Logging: Structured logging to file and stderr
- Async/Await: Proper async patterns throughout
- Separation of Concerns: Each tool in its own method
Examples
Example 1: Using the Calculator Tool
# Tool call from LLM client
{
"name": "calculator",
"arguments": {
"operation": "add",
"a": 15,
"b": 27
}
}
# Response
{
"content": [
{
"type": "text",
"text": "Result: 15 add 27 = 42"
}
]
}
Example 2: Reading a Resource
# Read server configuration
{
"uri": "config://server/settings"
}
# Response (JSON)
{
"server_name": "mcp-demo-server",
"version": "1.0.0",
"max_connections": 100,
"features": ["tools", "resources", "prompts"]
}
Example 3: Getting a Prompt
# Get code review prompt
{
"name": "code-review",
"arguments": {
"language": "Python",
"complexity": "complex"
}
}
# Response: Detailed code review checklist for Python
Development
Adding a New Tool
- Define input schema with Pydantic:
class MyToolInput(BaseModel):
param1: str = Field(description="Description")
param2: int = Field(default=0, description="Description")
- Add tool to
list_tools():
Tool(
name="my_tool",
description="What this tool does",
inputSchema=MyToolInput.model_json_schema(),
)
- Implement tool logic:
async def _my_tool(self, arguments: dict) -> list[TextContent]:
tool_input = MyToolInput(**arguments)
# Your implementation here
return [TextContent(type="text", text="Result")]
- Add to
call_tool()dispatcher:
if name == "my_tool":
return await self._my_tool(arguments)
Adding a New Resource
- Add to
list_resources():
Resource(
uri=AnyUrl("my://resource"),
name="My Resource",
description="What this resource provides",
mimeType="application/json",
)
- Add handler in
read_resource():
if uri_str == "my://resource":
data = {"key": "value"}
return json.dumps(data, indent=2)
Adding a New Prompt
- Add to
list_prompts():
Prompt(
name="my-prompt",
description="What this prompt does",
arguments=[
{
"name": "arg1",
"description": "Argument description",
"required": True,
}
],
)
- Add handler in
get_prompt():
if name == "my-prompt":
arg1 = arguments.get("arg1")
message = f"Prompt template with {arg1}"
return GetPromptResult(
messages=[
PromptMessage(
role="user",
content=TextContent(type="text", text=message),
)
]
)
Testing
Run the comprehensive test suite:
# Run all tests
pytest
# Run with coverage
pytest --cov=mcp_demo --cov-report=html
# Run specific test files
pytest tests/test_server.py # MCP server tests
pytest tests/test_agents.py # Agent system tests
# Run with verbose output
pytest -v
# Run agent tests only
pytest tests/test_agents.py -v
Best Practices Demonstrated
- Input Validation: All tool inputs validated with Pydantic
- Error Handling: Comprehensive error handling with meaningful messages
- Logging: Structured logging for debugging and monitoring
- Type Safety: Full type hints throughout the codebase
- Documentation: Comprehensive docstrings and comments
- Testing: Unit tests for all major functionality
- Code Quality: Formatted with Black, linted with Ruff
- Async Patterns: Proper use of async/await
- Resource Management: Proper cleanup and resource handling
- Security: Safe file operations with path validation
Troubleshooting
Common Issues
Issue: Module not found error
# Solution: Install in development mode
pip install -e .
Issue: Server not appearing in Claude Desktop
# Solution: Check configuration file path and JSON syntax
# Restart Claude Desktop after configuration changes
Issue: Import errors for mcp package
# Solution: Install latest MCP SDK
pip install --upgrade mcp
Debug Mode
Enable debug logging:
import logging
logging.basicConfig(level=logging.DEBUG)
Check the log file:
tail -f mcp_server.log
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation
- Agent System Documentation - Complete guide to the agent system
- MCP Server Architecture - MCP server design and implementation
- Agent Demo Examples - Comprehensive usage examples
Resources
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with the MCP Python SDK
- Inspired by the MCP community examples
- Thanks to Anthropic for developing the Model Context Protocol
Support
- Create an issue: GitHub Issues
- Documentation: README
- MCP Community: MCP Discord
Happy MCP Server Building! 🚀
