A multi-agent simulation platform where AI agents self-organize to process work across different domains. Create boards for Publishing, Software Development, Talent Acquisition, Sales, or Security Operations - each with its own domain-specific agents that collaborate in real-time on a Kanban board.
Try the live demo · Read the deep-dive · Watch the explainer
"Beyond the single agent: building a Jira + Slack for AI swarms with LangGraph, Google A2A, and MCP." — blog post
make install && make devAgent Scrum is built on three core ideas: a LangGraph swarm that continuously scans for work, an A2A protocol that lets agents talk to each other, and an MCP server that exposes the board to external tools. Here's how they fit together.
When you click "Start Swarm", a background loop begins:
every 3-6 seconds:
for each board where agent_automation is enabled:
look up TEMPLATE_WORKFLOWS[board.template_id]
for each (status -> agent_role, action) mapping:
find items stuck in that status
dispatch the right agent to handle them
This is implemented as a LangGraph StateGraph with two nodes:
- Router node - scans all boards, finds stuck items, picks the next agent
- Agent node - invokes the selected agent, which does its work and moves the item forward
The graph loops: router -> agent -> router -> agent -> ... -> end (when no more work is found or max iterations hit). Then the monitor sleeps 3-6 seconds and runs again.
┌──────────┐ has work? ┌───────────────────┐
│ Router │ ───── yes ──────→ │ dynamic_agent_node │
│ (scan) │ │ (invoke agent) │
└──────────┘ └────────┬───────────┘
↑ │
└────────── more work? ────────────┘
no → END
Each board template defines which agent handles which column transition. For example, the Publisher template (default):
| When item reaches status | Agent dispatched | Action |
|---|---|---|
writing |
Journalist | Write article |
editing |
Editor | Review article |
creatives |
Creative Director | Create visuals |
ready_to_publish |
Publisher | Publish content |
Or the Software Development template:
| When item reaches status | Agent dispatched | Action |
|---|---|---|
ready_for_breakdown |
Developer | Break story into tasks |
tasks_in_review |
Tech Lead | Review task breakdown |
ready_for_development |
Developer | Write implementation notes |
code_review |
Code Reviewer | Review implementation |
ready_for_qa |
QA | Create test scenarios |
Agents are board-scoped: developer_1 is the Developer on board 1, recruiter_3 is the Recruiter on board 3. The swarm resolves agent_id -> role + board_id to dispatch the right agent.
Agents communicate through the A2A protocol, Google's open standard for agent interoperability. The implementation follows the JSON-RPC 2.0 spec:
How agents talk to each other:
When the swarm dispatches an agent, it doesn't call the agent directly. Instead, it sends an A2A message through the router:
Swarm ──→ a2a_router.send_to_agent(
from_agent="scrum_master",
to_agent="developer_1",
message="Process story #5: User Authentication",
context={story_id: 5, board_id: 1}
)
The A2A router then:
- Records the outgoing message in
AgentMessagetable (visible in chat) - Broadcasts it via WebSocket (appears in the UI chat panel in real-time)
- Calls
executor.execute_agent()which invokes the LangGraph agent - Records the agent's response as a reply message
- Returns an
A2ATaskobject with state (submitted/working/completed/failed)
JSON-RPC methods implemented:
| Method | Description |
|---|---|
tasks/send |
Send a message to create or continue an A2A task |
tasks/get |
Retrieve a task's current state and message history |
tasks/cancel |
Cancel a running task |
Agent discovery:
Each agent has an A2A Agent Card accessible at /api/agents/{id} containing:
- Name, description, capabilities
- Skills list (what the agent can do)
- Status (idle/working)
The Agent Registry (a2a/registry.py) tracks all agents and their current state, enabling agents to discover each other's capabilities at runtime.
Chat visibility:
Every A2A message is persisted to the database and broadcast via WebSocket, so the UI chat panel shows the full conversation between agents as they work. You can see agents handing off work, reporting results, and coordinating in real-time.
The board is exposed as an MCP server so external AI tools (Claude Desktop, Cursor, etc.) can read and manipulate the board programmatically.
┌──────────────────┐ stdio ┌───────────────────┐
│ Claude Desktop │ ◄────────────────────► │ MCP Task Server │
│ or any MCP │ JSON-RPC over │ (14 tools) │
│ client │ stdin/stdout │ │
└──────────────────┘ └─────────┬─────────┘
│
▼
┌───────────────┐
│ SQLite Database│
└───────────────┘
Start the MCP server:
make mcpAdd to your MCP client config (e.g., Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"agent-scrum-tasks": {
"command": "python",
"args": ["-m", "app.mcp.task_server"],
"cwd": "/path/to/agent-scrum/backend"
}
}
}14 MCP tools available:
| Tool | Description |
|---|---|
get_story |
Fetch a story by ID |
create_story |
Create a new story on a board |
update_story_status |
Move a story to a new column |
list_stories_by_status |
List all stories in a given status |
get_task |
Fetch a task by ID |
create_task |
Create a task under a story |
update_task_status |
Move a task to a new status |
get_tasks_for_story |
Get all tasks for a story |
update_task_implementation |
Write implementation notes on a task |
update_task_test_scenarios |
Write test scenarios on a task |
list_tasks_by_status |
List tasks by status |
add_comment |
Add a comment to a story or task |
get_task_comments |
Get all comments on a task |
get_board_summary |
Get a summary of all boards and their items |
This means you can ask Claude: "Look at the scrum board, find any stories stuck in code review, and summarize what's blocking them" - and it will use the MCP tools to query your board directly.
By default, agents run in simulation mode - no API key needed. Simulated agents:
- Sleep 2-4 seconds (simulated work time)
- Use domain-specific response templates (e.g., a Recruiter says "Reviewed candidate resume. 5 years experience. Recommending for phone screen.")
- Actually create/modify records in the database (stories, tasks, status transitions)
- Post chat messages through A2A so you can watch the conversation
With a Gemini API key, agents use real LLM calls via LangChain + LangGraph ReAct agents with database tools.
Each board is created from a template that defines its columns, agents, and workflow rules:
| Template | Items | Agents |
|---|---|---|
| Publisher (default) | Articles + Sections | News Curator, Journalist, Editor, Creative Director, Publisher, Editor-in-Chief |
| Software Development | Stories + Tasks | Product Owner, Developer, Tech Lead, Code Reviewer, QA, Scrum Master |
| Talent Acquisition | Candidates | Sourcing Specialist, Recruiter, Hiring Manager, Interview Coordinator, HR Coordinator |
| Sales | Deals | Lead Generator, Account Executive, Sales Manager, Solutions Engineer, Contract Specialist |
| CISO | Risks | Threat Analyst, Security Engineer, Compliance Officer, Incident Responder, Risk Manager |
Click "Generate Articles" to auto-generate news briefs, then start the swarm:
- News Curator scans news sources, selects newsworthy items, and creates articles
- Journalist writes articles from curated news items
- Editor reviews articles for quality, accuracy, and tone
- Creative Director selects or generates visuals and thumbnails
- Publisher formats content, optimizes SEO, and publishes
- Editor-in-Chief oversees the pipeline and assigns stories
Pipeline: Inbox → Writing → Editing → Creatives → Ready to Publish → Published
Submit a PRD and watch agents build it:
- Product Owner parses the PRD and creates user stories
- Developer breaks each story into tasks
- Tech Lead reviews and approves task breakdowns
- Developer writes implementation notes
- Code Reviewer reviews the implementation
- QA creates test scenarios and runs tests
Submit a job requisition and watch the hiring pipeline:
- Sourcing Specialist finds candidates
- Recruiter screens resumes and conducts phone screens
- Interview Coordinator schedules interviews
- Hiring Manager evaluates candidates
- HR Coordinator prepares offers
Submit a lead and watch the deal flow:
- Lead Generator qualifies leads
- Account Executive runs demos and creates proposals
- Solutions Engineer builds POCs
- Sales Manager reviews and approves deals
- Contract Specialist handles negotiations
Submit a risk and watch the response:
- Threat Analyst assesses and classifies risks
- Security Engineer implements mitigations
- Compliance Officer audits regulatory alignment
- Incident Responder verifies mitigations
- Risk Manager assesses residual risk
┌─────────────────────────────────────────────────────────────┐
│ Frontend (React) │
│ http://localhost:5173 │
│ │
│ Board Selector ──→ Kanban Board ──→ Agent Chat Panel │
└────────────────────────┬────────────────────────────────────┘
│ REST + WebSocket
┌────────────────────────▼────────────────────────────────────┐
│ Backend (FastAPI) │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ LangGraph Swarm (StateGraph) │ │
│ │ │ │
│ │ Router ──→ scan_board() ──→ TEMPLATE_WORKFLOWS │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ dynamic_agent_node ──→ A2A Router ──→ Executor │ │
│ │ │ │ │ │
│ │ │ record message │ │
│ │ │ broadcast WS │ │
│ │ │ │ │ │
│ │ └───────────────────────┘ │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────┐ ┌────┴─────┐ ┌─────────────────────┐ │
│ │ REST API │ │ WebSocket │ │ MCP Server (14) │ │
│ │ /api/* │ │ /ws │ │ stdio transport │ │
│ └──────────────┘ └──────────┘ └─────────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ SQLite Database │
│ PipelineConfig │ Stories │ Tasks │ Comments │ DynamicAgents │
│ AgentMessages │ │ │ │ (per-board) │
└─────────────────────────────────────────────────────────────┘
| Component | Technology |
|---|---|
| Agent orchestration | LangGraph StateGraph + LangChain |
| Agent communication | A2A protocol (JSON-RPC 2.0) |
| External tool access | MCP (Model Context Protocol) |
| Backend | FastAPI, SQLAlchemy (async), SQLite |
| Frontend | React 18, TypeScript, Tailwind CSS, Vite |
| Real-time | WebSocket |
| AI | Google Gemini API (or simulation mode) |
# First time setup
make install # Install Python + Node dependencies
# Start the app
make dev # Start backend (port 8000) + frontend (port 5173)
# Open http://localhost:5173
# Other commands
make test # Run backend tests
make docker-up # Start with Docker
make mcp # Start MCP server for external tools
make reset # Delete database and re-seed fresh
make backend # Start backend only
make frontend # Start frontend onlyTo switch the default board template, delete the database and restart:
make reset && make devCreate backend/.env:
GEMINI_API_KEY=your-key # Optional - for real LLM responses
SIMULATE_MODE=true # Default - uses mock agent responsesGet a Gemini API key at https://aistudio.google.com/apikey
Click the gear icon to access settings:
- Start/Stop/Pause Swarm - Control agent automation
- API Key - Add or clear your Gemini API key
- Simulation Mode - Toggle mock responses
- Reset Data - Clear all stories and tasks
agent-scrum/
├── backend/
│ ├── app/
│ │ ├── agents/
│ │ │ ├── langgraph_agents.py # Agent definitions + domain simulations
│ │ │ ├── swarm/graph.py # LangGraph StateGraph (router + agent nodes)
│ │ │ ├── swarm/state.py # Swarm state schema
│ │ │ ├── tools/db_tools.py # LangChain tools for DB operations
│ │ │ ├── tools/registry.py # Tool basket (Publishing, HR, Sales, InfoSec, Dev)
│ │ │ └── executor.py # Agent execution with capacity limits
│ │ ├── a2a/
│ │ │ ├── protocol.py # JSON-RPC 2.0 handler (tasks/send, get, cancel)
│ │ │ ├── router.py # A2A message routing + chat recording
│ │ │ └── registry.py # Agent discovery (cards, skills, status)
│ │ ├── mcp/
│ │ │ ├── task_server.py # MCP server (14 tools, stdio transport)
│ │ │ └── client.py # MCP client for connecting to the server
│ │ ├── api/ # REST + WebSocket routes
│ │ ├── pipeline/
│ │ │ └── templates.py # Board templates + TEMPLATE_WORKFLOWS
│ │ ├── workflow/
│ │ │ ├── orchestrator.py # Status transition handlers
│ │ │ └── triggers.py # Event-based triggers (PRD submit, etc.)
│ │ ├── db/
│ │ │ ├── models.py # SQLAlchemy models
│ │ │ ├── seed.py # Per-board agent seeding
│ │ │ └── database.py # Async engine + session
│ │ └── main.py
│ ├── tests/ # 80 pytest tests
│ ├── Dockerfile
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── components/ # React components (Kanban, modals, chat)
│ │ ├── api/client.ts # API client
│ │ ├── store/ # Zustand stores (story + pipeline)
│ │ └── hooks/useWebSocket.ts # WebSocket hook
│ ├── Dockerfile
│ └── package.json
├── docker-compose.yml
├── Makefile
└── README.md
- REST API: http://localhost:8000/docs (Swagger UI)
- WebSocket:
ws://localhost:8000/ws - Health: http://localhost:8000/health
| Endpoint | Description |
|---|---|
GET/POST /api/boards |
List or create boards |
GET/DELETE /api/boards/{id} |
Get or delete a board |
GET /api/pipeline/templates |
List available board templates |
POST /api/prd |
Submit a PRD / work item |
GET/POST /api/stories |
List or create stories |
GET/POST /api/tasks |
List or create tasks |
GET /api/agents |
List all active agents |
GET /api/agents/{id} |
Get agent card (A2A discovery) |
GET /api/chat |
Get A2A chat messages |
POST /api/chat/send |
Send message to agent via A2A |
| Event | Description |
|---|---|
story:created |
New story added |
story:updated |
Story status/content changed |
task:created |
New task added |
task:updated |
Task status/content changed |
agent:status_changed |
Agent started/stopped work |
agent:chat |
A2A message between agents |
swarm:status |
Swarm started/stopped/paused |
board:created |
New board created |
board:deleted |
Board deleted |
# Production
docker-compose up -d
# Development (hot reload)
docker-compose --profile dev upmake test # Run all tests
cd backend && pytest -v # Verbose output80 tests covering API endpoints, A2A protocol, agent workflows, multi-board operations, and database models.
MIT
