This project is a hands-on educational resource for building modular, containerized, agentic systems using the Google Agent Development Kit (ADK), the Model Context Protocol (MCP), and the Agent-to-Agent (A2A) Protocol.
The lab is structured as a distributed microservices architecture, orchestrated via Docker Compose.
graph TD
UI[Frontend UI<br>React/Vite] -->|SSE Stream| ORCH[Root Orchestrator<br>Google ADK / FastAPI]
ORCH -->|Local Tools| TOOLS[System / Sensor / API Agents]
ORCH -->|Model Context Protocol| MCP[MCP Server<br>FastMCP / SQLite]
ORCH -->|A2A Protocol| A2A[Weather Sub-Agent<br>A2A SDK]
nexus-orchestrator: The central intelligence. Runs a FastAPI web server usingAdkWebServer. It routes incoming user requests to the appropriate sub-agent based on context and history.nexus-mcp: A standalone tool server. Demonstrates how to expose a local, private SQLite database (HR Directory) to the LLM without giving the LLM direct code execution or network access.nexus-a2a: A standalone sub-agent. Demonstrates how to build an independent agent service (Weather Forecaster) that the orchestrator can "hire" over an HTTP network using a standardized JSON-RPC protocol.nexus-ui: A modern, real-time React UI that connects to the orchestrator via Server-Sent Events (SSE), parsing streaming deltas to build the chat interface.
- Docker & Docker Compose
- Node.js + npm (the UI is built on the host before its image is assembled)
- A Gemini API Key (get one at aistudio.google.com)
Copy the documented template and add your API key:
cp .env.example .env
# then edit .env and set GEMINI_API_KEY=<your real key>.env.example documents every variable the stack consumes; only GEMINI_API_KEY is required.
make doctorVerifies Docker (CLI + daemon), your .env / API key, the shared nexus-net network, Node/npm, and uv (the Python test/lint targets run through the workspace-root uv environment) — with a fix suggestion for anything missing.
# Build and start all services in the background
make upmake demoSends a short scripted conversation through the orchestrator — one prompt each for MCP delegation (HR directory), A2A delegation (weather agent), and a local tool (sensor reading) — printing each response plus its trace ID with a Grafana Tempo link.
- Web UI: Open http://localhost:5173 in your browser.
- CLI Chat: If you prefer the terminal:
make chat
Session history is persisted to Redis by default (PERSISTENCE_BACKEND=redis), so conversations survive orchestrator restarts. Set PERSISTENCE_BACKEND=in_memory in .env to opt out.
make downThis repository is heavily commented with # EDUCATIONAL NOTE: tags across its configuration files. Start exploring here:
- Orchestrator Setup: Read
nexus-orchestrator/server.pyto learn how to wrap an ADK agent in a FastAPI web server with InMemory state management. - Routing Logic: Read
nexus-orchestrator/main.pyto see how theroot_agentis instructed to delegate tasks. - MCP Integration: Read
nexus-mcp/server.pyto see how@mcp.tool()automatically generates JSON schemas from Python functions. - A2A Protocol: Read
nexus-a2a/server.pyto understand how theAgentCardfacilitates dynamic capability discovery. - Streaming UIs: Read
nexus-ui/src/App.tsx(specifically thefetchloop) to learn how to parse LLM SSE streams and handle progressive text updates without duplication. - Foundation Model Abstraction: Check out
nexus-orchestrator/adapters/bedrock_adapter.pyandollama_adapter.pyto learn how the ADK allows you to swap out Gemini for other models (like Claude on Bedrock or local OSS models via Ollama) without changing your orchestration logic.
This project adheres to strict production-ready engineering standards:
- Educational Integrity: All "Why" and "How" documentation is standardized using the
# EDUCATIONAL NOTE:prefix. - Testing Isolation: All tests are guaranteed to be isolated. We use robust mocking to ensure that tests never hit external APIs or production resources.
- Containerization: Docker configurations utilize multi-stage builds, non-root users, and native healthchecks.
- Code Quality: Strict linting and type safety are enforced across all Python (Ruff/Mypy) and TypeScript (ESLint/TSC) services.
You can run this lab entirely locally using Ollama.
- Install Ollama and pull a model:
ollama pull llama3
- Start the services (the orchestrator will detect the adapter):
make up
- Switch the model in the frontend or by setting the
AGENT_MODELenvironment variable toollama/llama3.
Want to add a new specialized sub-agent to the system? Scaffold one:
make new-agent NAME=stock-ticker # PORT is optional (defaults to the next free 800x)This copies templates/a2a-service/ — a complete A2A sub-agent modeled on nexus-a2a (agent card, two-phase streaming, /health + telemetry, passing tests, Dockerfile, docs) — to ../nexus-stock-ticker and prints a numbered checklist of the remaining wiring: the ready-to-paste docker-compose.yml snippet, the orchestrator's A2A_AGENT_URLS entry (the orchestrator discovers A2A agents dynamically from that list — each agent card it can fetch becomes a registered sub-agent, named from the card), the Prometheus scrape target, and the uv workspace member. Then implement your capability at the TODO in the new server.py.
The orchestrator includes a suite of integration tests, including an "LLM-as-a-judge" pattern.
# Run backend tests
make test