A distributed Proof of Concept (PoC) agent platform built with Python and gRPC, featuring service discovery, dynamic routing, horizontal scaling with HAProxy load balancing, and extensible agent/tool architecture. This PoC demonstrates a more efficient model to deploy agents in a standardized way.
β οΈ Not Production Ready: This is a PoC based on Docker Compose for development and testing. For production deployment, the next moves should be in the direction of deploying to a Kubernetes cluster using Terraform, Helm charts, and proper CI/CD pipelines.
π€ Name Origins: Inspired by "The Hitchhiker's Guide to the Galaxy" - where the Deep Thought computer calculated that the answer to the ultimate question of life, the universe, and everything is 42. This platform represents our attempt to build the "agent infrastructure" that can help answer complex questions through distributed AI agents.
The platform consists of the following components:
-
MCP Router - Central routing service with service discovery
- Routes requests to agents and tools
- Manages service registry via Consul
- Handles load balancing and failover
- Horizontally scalable with HAProxy load balancer
- Port:
50051(public endpoint through HAProxy)
-
HAProxy - Load balancer for all HTTP/gRPC services
- Round-robin load distribution
- Health checks every 2 seconds
- Real-time statistics dashboard
- Routes: gRPC Router (50051), MCP Server (3000), Catalog API (8000), Catalog UI (8080)
- Stats UI available at
http://localhost:8404
-
Consul - Service discovery and health checking
- Centralized service registry
- Health monitoring with automatic failover
- UI available at
http://localhost:8500
-
Catalog Services - Web-based service catalog and documentation
- Catalog API (Port:
8000via HAProxy) - FastAPI backend- Lists all agents, tools, and workers
- Shows parameters, schemas, and examples
- Queries Consul and gRPC for live data
- Scalable (1-3 instances)
- Catalog UI (Port:
8080via HAProxy) - React frontend- Modern web interface for browsing services
- Real-time service status
- Request/response examples
- Scalable (1-3 instances)
- Catalog API (Port:
Agents are autonomous services that can execute tasks with specific capabilities.
- Echo Agent (Port:
50052)- Simple demonstration agent
- Echoes back input with processing
- Shows streaming capabilities
Tools provide specific functionality that agents can use.
- Weather Tool (Port:
50053)- Provides weather information
- Supports current weather and forecasts
- Mock data for demonstration
Specialized workers for complex, long-running tasks.
- Itinerary Task Worker (Port:
50054)- Plans travel itineraries
- AI-powered route optimization
- Integrates with weather tool
- Python 3.11 or higher
- Docker and Docker Compose
- Git
- Clone the repository
cd agent-platform-server- One-command setup (recommended)
make quick-startThis will automatically:
- Create a virtual environment
- Install dependencies
- Compile Protocol Buffer definitions
- Build Docker images
- Start all services
OR manual setup:
# Run setup
make setup
# Build images
make build
# Start services
make up- Verify services are running
make statusAll services should show as "healthy" or "running".
- Test the platform
make testTests will connect through the MCP Router and verify all services.
- Browse the service catalog
make ui-catalog
# Or visit: http://localhost:8080The Catalog UI provides a web interface to:
- Browse all available agents, tools, and workers
- View parameters and schemas
- See example requests and responses
- Check real-time service status
- Monitor instance counts
The platform includes a web-based service catalog that dynamically discovers and documents all available services:
- Live Service Discovery: Automatically finds all agents, tools, and workers via Consul
- Health-Aware Consolidation β¨: Shows service health (healthy/degraded/unhealthy/down) with instance breakdown
- Automatic Deduplication β¨: Multiple instances display as single entry with instance count
- Interactive Documentation: Browse parameters, types, and descriptions
- Example Requests: See how to call each service
- Example Responses: View expected output format with session_id support
- Real-time Status: Check service health and instance counts
- Scalable Architecture: Both API and UI scale independently
- Web UI: http://localhost:8080 (or
make ui-catalog) - REST API: http://localhost:8000
/api/catalog- Complete catalog (agents, tools, workers)/api/agents- List all agents/api/tools- List all tools/api/workers- List all workers/health- Health check
Browser β HAProxy:8080 β catalog-ui (1-3 instances) β Consul
β
HAProxy:8000 β catalog-api (1-3 instances) β Consul + gRPC
Both services:
- Register with Consul for service discovery
- Route through HAProxy for load balancing
- Scale independently (1-3 instances each)
- Provide health checks
- Deduplicate services automatically (no duplicate entries)
- Track health status (healthy/unhealthy instance counts)
The platform supports horizontal scaling of all services with HAProxy load balancing for the MCP Router and Consul-based service discovery!
# Scale to 3 instances (recommended for production)
docker-compose up -d --scale mcp-router=3
# Scale to 5 instances (high availability)
docker-compose up -d --scale mcp-router=5
# Use the convenient management script
./scripts/manage_routers.sh scale 3
# Or use Makefile
make scale-router N=3# Scale agents, tools, and workers
make scale-echo N=3
make scale-weather N=2
make scale-itinerary N=3
# Scale catalog services
make scale-catalog N=3 # Both API and UI
make scale-catalog-api N=3 # API only
make scale-catalog-ui N=3 # UI only
# Or scale all services at once
make scale-all N=3- Catalog UI: http://localhost:8080 (or
make ui-catalog) - Browse all services with examples - HAProxy Stats: http://localhost:8404 (or
make ui-haproxy) - Load balancer dashboard - Consul Service Registry: http://localhost:8500 (or
make ui-consul) - Service discovery - Service Health:
make consul-check - Service Status:
make status
# Show status of all router instances
./scripts/manage_routers.sh status
# Check health of all services
./scripts/manage_routers.sh health
# View logs from all routers
./scripts/manage_routers.sh logs
# Open HAProxy dashboard
./scripts/manage_routers.sh haproxy
# Open Consul UI
./scripts/manage_routers.sh consulFor detailed information, see:
- LOAD_BALANCING.md - Complete load balancing guide
- SCALING_GUIDE.md - Comprehensive scaling documentation
- QUICK_REFERENCE_LOAD_BALANCING.md - Quick command reference
Note: All clients connect through the MCP Router (port 50051), which handles service discovery and routing to backend services.
All services now support session IDs for context recovery and maintaining conversational state across multiple requests:
import uuid
# Generate a session ID (use same ID for related requests)
session_id = str(uuid.uuid4())
# Include session_id in your requests
request = agent_platform_pb2.TaskRequest(
task_id=str(uuid.uuid4()),
agent_id='echo-agent',
input='Remember this context',
parameters={'key': 'value'},
session_id=session_id # NEW: Session ID for context recovery
)
# Response includes the session_id for correlation
response = stub.ExecuteTask(request)
print(f"Session ID: {response.session_id}")
# Use same session_id in follow-up requests to maintain context
request2 = agent_platform_pb2.TaskRequest(
task_id=str(uuid.uuid4()),
agent_id='echo-agent',
input='Do you remember?',
session_id=session_id # Same session ID
)Session IDs enable:
- π§ Context Memory - Agents remember previous interactions
- π Multi-Turn Conversations - Build complex workflows
- π Session Tracking - Monitor user sessions
- πΎ State Recovery - Resume from interruptions
π Complete guide: SESSION_ID_GUIDE.md
import grpc
import agent_platform_pb2
import agent_platform_pb2_grpc
import uuid
# Connect through MCP Router (NOT directly to agent!)
channel = grpc.insecure_channel('localhost:50051')
stub = agent_platform_pb2_grpc.AgentServiceStub(channel)
# Execute a task
task_id = str(uuid.uuid4())
request = agent_platform_pb2.TaskRequest(
task_id=task_id,
agent_id='echo-agent',
input='Hello, World!',
parameters={'key': 'value'}
)
response = stub.ExecuteTask(request)
print(f"Success: {response.success}")
print(f"Output: {response.output}")
# Get agent status
status_request = agent_platform_pb2.StatusRequest(agent_id='echo-agent')
status = stub.GetStatus(status_request)
print(f"Status: {status.status}")
print(f"Active tasks: {status.active_tasks}")import grpc
import agent_platform_pb2
import agent_platform_pb2_grpc
# Connect through MCP Router
channel = grpc.insecure_channel('localhost:50051')
stub = agent_platform_pb2_grpc.ToolServiceStub(channel)
# Get weather
request = agent_platform_pb2.ToolRequest(
tool_id='weather-tool',
operation='get_weather',
parameters={'location': 'Paris'}
)
response = stub.ExecuteTool(request)
print(response.result)
# Get forecast
forecast_request = agent_platform_pb2.ToolRequest(
tool_id='weather-tool',
operation='get_forecast',
parameters={'location': 'Tokyo', 'days': '5'}
)
forecast_response = stub.ExecuteTool(forecast_request)
print(forecast_response.result)import grpc
import agent_platform_pb2
import agent_platform_pb2_grpc
import uuid
# Connect through MCP Router
channel = grpc.insecure_channel('localhost:50051')
stub = agent_platform_pb2_grpc.TaskWorkerStub(channel)
# Plan an itinerary
task_id = str(uuid.uuid4())
request = agent_platform_pb2.TaskRequest(
task_id=task_id,
agent_id='itinerary-worker',
input='Plan a vacation',
parameters={
'destination': 'Paris',
'days': '3',
'interests': 'culture,food,history'
}
)
response = stub.ProcessTask(request)
print(f"Success: {response.success}")
print(f"Itinerary:\n{response.output}")agent-platform-server/
βββ proto/ # Protocol Buffer definitions
β βββ agent_platform.proto
βββ mcp-router/ # MCP Router service
β βββ app.py
β βββ Dockerfile
β βββ requirements.txt
βββ mcp-server/ # MCP Server (Cursor integration)
β βββ server.py
β βββ Dockerfile
β βββ requirements.txt
βββ catalog-api/ # Catalog API backend
β βββ app.py
β βββ Dockerfile
β βββ requirements.txt
β βββ README.md
β βββ SCALING.md
βββ catalog-ui/ # Catalog UI frontend
β βββ src/
β β βββ App.jsx
β β βββ App.css
β βββ Dockerfile
β βββ nginx.conf
β βββ docker-entrypoint.sh
β βββ register_consul.py
βββ agents/
β βββ echo/ # Echo Agent
β βββ server.py
β βββ Dockerfile
β βββ requirements.txt
βββ tools/
β βββ weather-tool/ # Weather Tool
β βββ server.py
β βββ Dockerfile
β βββ requirements.txt
βββ tasks/
β βββ itinerary-task/ # Itinerary Worker
β βββ worker.py
β βββ Dockerfile
β βββ requirements.txt
βββ haproxy/ # Load balancer
β βββ haproxy.cfg
β βββ Dockerfile
βββ scripts/ # Utility scripts
β βββ setup.sh
β βββ compile_proto.sh
β βββ test_client.py
βββ docs/ # Documentation
βββ docker-compose.yml
βββ requirements.txt
βββ Makefile
βββ README.md
- Create agent directory
mkdir -p agents/my-agent- Create server.py
# Implement AgentService interface from proto
class MyAgentService:
def ExecuteTask(self, request, context):
# Your agent logic here
pass- Create Dockerfile
FROM python:3.11-slim
# ... (follow pattern from echo agent)- Add to docker-compose.yml
my-agent:
build:
context: .
dockerfile: agents/my-agent/Dockerfile
# ... (follow pattern from other services)Follow the same pattern as agents, but implement the ToolService interface.
After modifying agent_platform.proto:
bash scripts/compile_proto.shThis generates:
agent_platform_pb2.py- Message definitionsagent_platform_pb2_grpc.py- Service stubs
python scripts/test_client.py# Test Echo Agent
python scripts/test_client.py --service echo
# View logs
docker-compose logs echo-agent
# Check service health in Consul
open http://localhost:8500Access the Consul UI to monitor service health and registry:
http://localhost:8500
Monitor load balancer performance and backend health:
http://localhost:8404
# All services
docker-compose logs -f
# Specific services
docker-compose logs -f mcp-router
docker-compose logs -f echo-agent
docker-compose logs -f weather-tool
docker-compose logs -f itinerary-worker
docker-compose logs -f haproxy
# Using Makefile
make logs # All services
make router-logs # MCP Router only
make haproxy-logs # HAProxy only
make consul-logs # Consul only# List running services
docker-compose ps
# Check health via Consul
docker-compose exec consul consul members
# Check all services in Consul
make check-consul
# Check router instances
./scripts/manage_routers.sh statusThe Agent Platform supports horizontal scaling of all services with automatic service discovery and load balancing. Scale up to handle increased load, improve availability, or distribute workload.
# Scale MCP Router (with HAProxy load balancing)
make scale-router N=3
./scripts/manage_routers.sh scale 3
# Scale individual services
make scale-echo N=3 # Echo Agent
make scale-weather N=5 # Weather Tool
make scale-itinerary N=2 # Itinerary Worker
# Scale all services to 3 instances
make scale-all N=3
# Scale down to 1 instance each
make scale-down
# Check all services registered in Consul
make check-consul- Automatic Service Discovery: Each instance registers with Consul using a unique ID
- Load Balancing:
- MCP Router: HAProxy distributes requests across router instances
- Other Services: Consul-based service discovery for load distribution
- Health Monitoring: Unhealthy instances are automatically removed from rotation
- Dynamic Ports: Docker assigns unique host ports to avoid conflicts
- Zero-Downtime: Add or remove instances without service interruption
# Start services
docker-compose up -d
# Scale MCP Router for high availability
make scale-router N=3
# Scale agents and workers based on load
make scale-echo N=3
make scale-weather N=2
make scale-itinerary N=3
# Verify all instances are registered
make check-consul
# Monitor status
docker-compose ps
./scripts/manage_routers.sh statusβ
High Availability - Service continues if instances fail
β
Load Distribution - Requests spread across multiple instances
β
Easy Scaling - One command to scale up or down
β
Auto-Discovery - New instances join automatically
β
Health Checks - Failed instances removed automatically
π For detailed scaling information, see:
- SCALING_GUIDE.md - Comprehensive scaling guide
- LOAD_BALANCING.md - MCP Router load balancing details
- SCALING_DEMO.md - Live demo of scaling capabilities
NEW! Use your platform's agents and tools directly in Cursor IDE via the Model Context Protocol (MCP):
# MCP Server runs automatically with the platform
make up
# Configure Cursor (Settings β MCP Servers)
{
"mcpServers": {
"agent-platform": {
"url": "http://localhost:3000/sse",
"transport": "sse"
}
}
}
# Then ask in Cursor: "What's the weather in Tokyo?"Cursor can now:
- β Call tools (weather-tool) directly from chat
- β Execute agents and workers as callable tools
- β Access agents and workers as resources
- β Auto-discover all platform capabilities
- β See comprehensive metadata (detailed descriptions, use cases, return formats)
- β Use SSE transport (HTTP-based, easy to debug)
- β
Load balanced via HAProxy (scalable with
make scale-mcp N=3) - β Monitored via Consul (visible at http://localhost:8500)
Complete setup guide: CURSOR_INTEGRATION.md
Discover what agents, tools, and workers are available in your platform:
# Query all services
make mcp-query
# Query specific service types
make mcp-query-agents # List all agents
make mcp-query-tools # List all tools
make mcp-query-workers # List all workers
# Get JSON output (useful for scripting)
make mcp-query-json
# Or use the script directly
python scripts/query_mcp.py all
python scripts/query_mcp.py agents --jsonExample output:
======================================================================
AGENTS
======================================================================
π¦ Echo Agent
ID: echo-agent
Description: Echo agent service
Endpoint: container:50052
Capabilities: agent, echo, text-processing
======================================================================
TOOLS
======================================================================
π οΈ Weather Tool
ID: weather-tool
Description: Provides weather information and forecasts
Endpoint: container:50053
Parameters:
- location (string, required): City or location name
- days (integer, optional): Number of days for forecast
For a complete list of all available commands, see MAKEFILE_REFERENCE.md.
# Service Management
make up # Start all services
make down # Stop all services
make restart # Restart all services
make status # Show service status
# Service Discovery
make mcp-query # Query all available services
make mcp-query-agents # List agents
make mcp-query-tools # List tools
make mcp-query-workers # List workers
# Web Interfaces
make ui-catalog # Open Catalog UI (service browser)
make ui-consul # Open Consul UI
make ui-haproxy # Open HAProxy stats
# Monitoring
make logs # Stream all logs
make logs-router # View MCP Router logs
make logs-echo # View Echo Agent logs
make logs-catalog-api # View Catalog API logs
make logs-catalog-ui # View Catalog UI logs
# Testing
make test # Run test suite
# Consul Operations
make consul-check # Check registered services
make consul-cleanup # Clean up stale registrations
make consul-purge # Nuclear: delete all Consul data
# Scaling
make scale-router N=3 # Scale router to 3 instances
make scale-catalog N=3 # Scale catalog services to 3
make scale-catalog-api N=3 # Scale catalog API to 3
make scale-catalog-ui N=3 # Scale catalog UI to 3
make scale-all N=3 # Scale all services to 3
make scale-down # Scale back to 1 instance
# Catalog Services
make catalog-build # Build catalog services
make catalog-up # Start catalog services
make catalog-restart # Restart catalog services
# Development
make proto-compile # Compile protocol buffers
make rebuild # Full rebuild
make clean # Clean up everythingOver time, Consul may accumulate stale service registrations (e.g., from container restarts during development).
# View all registered services and their health
make consul-check# Remove only unhealthy/stale registrations (safe)
make consul-cleanup
# Or use the cleanup script directly
./scripts/cleanup_consul.sh stale# WARNING: This removes ALL Consul data!
make consul-purge
# Services will automatically re-register when restarted
make restartFor more details, see the cleanup script: scripts/cleanup_consul.sh
make proto-compile
# Or manually:
pip install grpcio-tools==1.60.0
bash scripts/compile_proto.sh# Check logs
make logs-router # or logs-echo, logs-weather, etc.
# Check status
make status
# Restart specific service
docker-compose restart mcp-router
# Rebuild and restart
docker-compose up -d --build [service-name]# Restart Consul
docker-compose restart consul
# Wait for Consul to be healthy
docker-compose ps consulEdit .env file to change ports:
# Change ports if needed
MCP_ROUTER_PORT=50051
AGENT_PORT=50052
TOOL_PORT=50053
WORKER_PORT=50054ExecuteTask(TaskRequest) -> TaskResponse- Execute a taskStreamTask(TaskRequest) -> stream TaskChunk- Stream task executionGetStatus(StatusRequest) -> StatusResponse- Get agent statusRegisterAgent(AgentInfo) -> RegistrationResponse- Register agent
ExecuteTool(ToolRequest) -> ToolResponse- Execute tool operationListTools(ListToolsRequest) -> ListToolsResponse- List available toolsRegisterTool(ToolInfo) -> RegistrationResponse- Register tool
ProcessTask(TaskRequest) -> TaskResponse- Process a taskGetTaskStatus(TaskStatusRequest) -> TaskStatusResponse- Get task status
# Start all services
docker-compose up -d
# Scale MCP Router for high availability (recommended: 3-5 instances)
docker-compose up -d --scale mcp-router=3
# Scale agents and workers based on load
docker-compose up -d --scale echo-agent=3 --scale weather-tool=2 --scale itinerary-worker=3
# Or use convenient Makefile commands
make scale-all N=3Minimum High Availability Setup:
make scale-router N=3 # 3 router instances
make scale-echo N=2 # 2 agent instances
make scale-weather N=2 # 2 tool instances
make scale-itinerary N=2 # 2 worker instancesHigh-Load Setup:
make scale-router N=5 # 5 router instances
make scale-echo N=5 # 5 agent instances
make scale-weather N=3 # 3 tool instances
make scale-itinerary N=5 # 5 worker instancesCreate a .env file based on .env.example for configuration:
# Copy example
cp .env.example .env
# Edit as needed
vim .env- Set up alerts on HAProxy metrics: http://localhost:8404
- Monitor Consul health checks: http://localhost:8500
- Aggregate logs with ELK stack or similar
- Use Prometheus + Grafana for metrics (see Future Enhancements)
- Create a new branch for your feature
- Implement your changes
- Add tests for new functionality
- Update documentation
- Submit a pull request
This project is provided as-is for educational and development purposes.
π Complete Documentation Index - All documentation organized in the docs/ folder
Getting Started:
- START_HERE.md - New user welcome guide
- QUICKSTART.md - 5-minute quick start
Architecture:
- ARCHITECTURE.md - Overall system architecture
- ARCHITECTURE_GRPC.md - gRPC subsystem details
- ARCHITECTURE_MCP.md - MCP subsystem details
- ARCHITECTURE_OVERVIEW.md - Documentation navigation guide
Integration:
- CURSOR_INTEGRATION.md - Complete Cursor IDE setup guide
- MCP_CURSOR_SETUP.md - Quick MCP reference
Scaling & Operations:
- SCALING_GUIDE.md - Comprehensive scaling guide
- LOAD_BALANCING.md - Load balancing configuration
- SCALING_DEMO.md - Live demo of scaling
Features & Guides:
- CATALOG.md - Web-based service catalog and documentation
- HEALTH_RESILIENCE.md - NEW: Health-aware service consolidation
- DEDUPLICATION_GUIDE.md - NEW: Automatic service deduplication
- SESSION_ID_GUIDE.md - Session ID for context recovery
- ECHO_AGENT_USAGE.md - How to use the Echo Agent
- MCP_SERVICE_DISCOVERY.md - Service discovery guide
- MAKEFILE_REFERENCE.md - All make commands
- AGENTS_AS_TOOLS.md - Using agents as MCP tools in Cursor
Examples:
- examples/README.md - Code examples
- Add Authentication - Implement token-based auth for services
- Add Persistence - Store task results in a database
- Add Monitoring - Integrate Prometheus/Grafana
- Add Message Queue - Use RabbitMQ or Kafka for async tasks
- Add API Gateway - REST API wrapper for gRPC services
- Add Real AI - Integrate OpenAI, Anthropic, or local LLMs
- Add More Tools - Database tools, API clients, etc.
- Add Agent Orchestration - Multi-agent collaboration
- Add TLS/SSL for secure communication
- Implement proper authentication and authorization
- Add rate limiting and request throttling
- Set up centralized logging (ELK, Loki)
- Implement distributed tracing (Jaeger, Zipkin)
- Add backup and disaster recovery
- Configure horizontal pod autoscaling
- Set up CI/CD pipelines
Built with β€οΈ using Python, gRPC, and Consul

