The AI that builds its own tools.
Apollo is an agentic system with a truly dynamic toolbox. Give it any goal and it will design, generate, deploy, and orchestrate custom MCP tools on the fly. No predefined toolset, no manual wiring. Just a prompt.
"Plan a trip to Spain" โ Apollo creates a weather API tool, a destination guide tool, and a local events tool, deploys them all in seconds, then uses them to deliver a comprehensive answer.
Most AI agents are limited to a static set of tools chosen at development time. Apollo flips this model:
| Traditional Agents | Apollo |
|---|---|
| Fixed tool set at build time | Tools generated on demand from any prompt |
| Manual tool integration | Automatic deployment to serverless infra |
| Limited to pre-built capabilities | Unlimited capabilities via dynamic MCP servers |
Key capabilities:
- ๐ง Dynamic Tool Generation โ LLM-powered code generation creates custom MCP servers tailored to each task
- โ๏ธ Serverless Deployment โ Auto-deploy to Modal with zero infrastructure management
- ๐๏ธ Automatic Registry โ Modal.Dict-based tool discovery and lifecycle management
- ๐ค Smart Orchestration โ Supervisor agent with a ReAct loop for multi-step reasoning
- ๐ก Real API Integration โ Falls back to a curated knowledge base of 1,400+ public APIs to avoid hallucinated endpoints
- ๐ Live Visualization โ Real-time 3D solar system visualization of the tool-building pipeline
- Python 3.10+
- A Modal account (free tier works)
- An OpenAI and/or Anthropic API key
git clone https://github.com/your-team/apollo.git
cd apollo
pip install modal anthropic openai python-dotenv requests \
uvicorn starlette sse-starlette# Authenticate with Modal
modal setup
# Store your API keys as Modal secrets (used by cloud workers)
modal secret create openai-secret OPENAI_API_KEY=sk-proj-...
modal secret create anthropic-secret ANTHROPIC_API_KEY=sk-ant-...Create a .env file in the project root:
LLM_PROVIDER=openai # or "anthropic"
OPENAI_API_KEY=sk-proj-...
ANTHROPIC_API_KEY=sk-ant-...python backend.pyOpen http://localhost:8080 โ type a goal, hit Run, and watch Apollo build and use custom tools in real time.
python backend.py # starts on http://localhost:8080
python backend.py --port 9000 # custom portThe web UI streams the full supervisor output live โ you'll see tool planning, code generation, deployment, and the final answer rendered in markdown.
# Generate and deploy MCP tools for a goal
modal run tools_builder.py --goal "research quantum computing papers"# Run with auto-build (builds tools if registry is empty)
python supervisor.py --prompt "plan a 5-day trip to Madrid"
# Use existing tools only
python supervisor.py --prompt "what's the weather in Tokyo?" --no-auto-build
# Local test mode (no Modal required)
python supervisor.py --prompt "hello" --testmodal run registry_manager.py --action list # list registered tools
modal run registry_manager.py --action test # test all endpoints
modal run registry_manager.py --action clear # clear registry
modal run registry_manager.py --action add \
--name "my-tool" --url "https://..." # add manuallyApollo includes a 3D solar system visualization that animates the tool-building pipeline in real time:
# Launch visualization server (opens browser automatically)
python viz_server.py
# Or run tools_builder with --viz flag
modal run tools_builder.py --goal "your goal" --vizApollo/
โโโ backend.py # Web server โ serves UI + streams supervisor output
โโโ supervisor.py # Main agentic supervisor with ReAct loop
โโโ tools_builder.py # MCP generation & deployment engine (runs on Modal)
โโโ mcp_builder.py # Code generation library (used by Modal workers)
โโโ mcp_template.py # Template for all generated MCP servers
โโโ api_reference.py # Public-APIs fallback knowledge base (1,400+ APIs)
โโโ registry_manager.py # CLI for Modal.Dict registry CRUD
โโโ viz_server.py # SSE server for live pipeline visualization
โโโ ui_server.py # Alternative UI server
โโโ test_supervisor.py # Test suite (14 tests)
โโโ notes.txt # Developer notes & reference commands
โโโ .env # Local environment configuration
โโโ ui/
โ โโโ index.html # Main chat interface
โโโ demo/
โ โโโ index.html # 3D solar system visualization
โโโ api_reference_data/ # Cached public API database
โ โโโ public_apis.json
โโโ generated_mcps/ # Output directory for generated MCP servers
-
User submits a prompt โ e.g. "plan a trip to Spain"
-
Tool Builder plans MCP servers โ the LLM decomposes the goal into 2โ6 specific, single-responsibility tools (e.g.
weather-forecast,destination-guide,local-events) -
Parallel code generation โ Modal workers generate Python code from specs in parallel, using a strict MCP template and validated against real public APIs
-
Deployment & registration โ each server is deployed with
modal deploy, and its endpoint URL is registered in a sharedModal.Dictregistry -
Supervisor discovers tools โ queries the registry, fetches
tools/listfrom each MCP endpoint, and converts them to the LLM's native tool-calling format -
Agentic execution loop โ the LLM decides which tools to call, executes them via MCP JSON-RPC over HTTP, feeds results back, and repeats (up to 10 iterations)
-
Final answer โ a comprehensive, synthesized response is returned to the user
# Run all tests
python test_supervisor.py
# With pytest
pytest test_supervisor.py -v
# Local test mode (no Modal, no API keys needed)
python supervisor.py --prompt "hello" --test| Variable | Default | Description |
|---|---|---|
LLM_PROVIDER |
openai |
LLM backend (openai or anthropic) |
OPENAI_API_KEY |
โ | Your OpenAI API key |
ANTHROPIC_API_KEY |
โ | Your Anthropic API key |
REGISTRY_NAME |
mcp-tool-registry |
Name of the Modal.Dict registry |
MAX_ITERATIONS |
10 |
Max supervisor loop iterations |
REQUEST_TIMEOUT |
30 |
MCP HTTP call timeout (seconds) |
Why MCP? The Model Context Protocol gives us a standardized interface for tool discovery and execution. Every generated tool speaks the same language, making orchestration trivial.
Why Modal? Serverless deployment means we don't manage infrastructure. Generated tools go from code to live HTTPS endpoint in seconds, with automatic scaling and zero ops burden.
Why not LangGraph? A simple ReAct loop is lighter, faster to debug, and has no additional dependencies. The architecture can evolve to LangGraph later if multi-agent collaboration or complex branching is needed.
