# peon-mcp

An MCP server for tracking software project tasks, features, and work logs in SQLite. Designed for AI-agent-driven development workflows. Includes a Python backend (FastMCP + Starlette) and a React/TypeScript frontend.

## What is peon-mcp?

peon-mcp is a task management system built specifically for AI-driven development. It provides:

- **MCP Server** - Tools for Claude (or other MCP clients) to create, track, and execute tasks
- **Web UI** - A React-based dashboard to visualize projects, features, tasks, and work logs
- **Agent Loop** - An autonomous loop that spawns Claude to continuously work through your task queue

The name comes from Warcraft's peons - diligent workers who respond with "Work work!" and "Zug zug!" when given tasks.

## Key Features

- **Structured Task Management** - Organize work into projects, features, and tasks with priorities
- **Autonomous Execution** - The `peon-loop` command runs Claude continuously to work through tasks
- **Git Integration** - Tracks commit SHAs for audit trails (base and head commits per task)
- **Work Logging** - Records what was done, files changed, and test results for each task
- **Web Dashboard** - Monitor progress, create tasks, and view work logs in real-time
- **SQLite Backend** - Lightweight, file-based storage with no external database required

## Installation

### From PyPI

```bash
pip install peon-mcp
```

### From source

```bash
git clone https://github.com/pyrabbit/peon-mcp.git
cd peon-mcp
uv sync
```

## Quick Start

### 1. Run the MCP Server

For use with Claude Desktop or Claude Code:

```bash
peon-mcp
# or
uv run python -m peon_mcp.server
```

### 2. Run the Web UI

Launch the web interface and REST API:

```bash
peon-ui
# or
uv run python -m peon_mcp.web
```

Then open http://127.0.0.1:8420 in your browser.

### 3. Run the Agent Loop

Start an autonomous loop that continuously works through tasks:

```bash
peon-loop peon-mcp /path/to/your/repo --once
# or for continuous operation:
peon-loop peon-mcp /path/to/your/repo
```

Options:
- `--once` - Run a single iteration then exit
- `--model sonnet` - Choose Claude model (sonnet, opus, haiku)
- `--timeout 1800` - Max seconds per agent run (default: 1800)
- `--sleep 30` - Seconds between iterations (default: 30)
- `--max-budget 5.0` - Max USD budget per agent invocation
- `--permission-mode bypassPermissions` - Claude permission mode

## Configuration

### Claude Desktop / Claude Code

Add to your MCP config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "peon-mcp": {
      "command": "peon-mcp"
    }
  }
}
```

Or if running from source:

```json
{
  "mcpServers": {
    "peon-mcp": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/peon-mcp", "python", "-m", "peon_mcp.server"]
    }
  }
}
```

### Environment Variables

| Variable | Default | Description |
|---|---|---|
| `PEON_DB_PATH` | `~/.peon/peon_tasks.db` | SQLite database path |
| `PEON_UI_HOST` | `127.0.0.1` | Web UI bind address |
| `PEON_UI_PORT` | `8420` | Web UI port (auto-fallback if taken) |

## Architecture

### Three Entry Points

peon-mcp provides three command-line tools:

1. **peon-mcp** - MCP server exposing 24 tools + 2 prompts via stdio for Claude integration
2. **peon-ui** - Starlette REST API + SPA serving on port 8420
3. **peon-loop** - CLI that repeatedly spawns Claude to work through the task queue

### Backend (`peon_mcp/`)

- **server.py** - FastMCP server with `@mcp.tool()` decorated functions for CRUD operations on projects, features, tasks, and work logs
- **db.py** - SQLite schema initialization via aiosqlite. Uses WAL mode and foreign keys
- **web.py** - Starlette REST API mirroring MCP tools as HTTP endpoints under `/api/`
- **loop.py** - Agent loop that checks for todo tasks, spawns `claude` CLI, writes heartbeat to DB, and repeats

### Frontend (`ui/`)

- React 19 + React Router v7 + Tailwind CSS v4 + Vite 6 + TypeScript 5.7
- Routes: `/` (project list), `/projects/:id` (dashboard), `/projects/:id/features`, `/projects/:id/tasks`, `/projects/:id/logs`
- Built assets output to `peon_mcp/static/` and are included in the Python wheel
- Warcraft-inspired dark theme with green accent colors

## Data Model

```
projects
 +-- features    (high-level planned work areas)
 +-- tasks       (actionable units of work)
 +-- work_logs   (audit trail of completed work)
```

### Projects

Represent a repository or codebase.

| Column | Type | Description |
|---|---|---|
| `id` | TEXT PK | Repo name (e.g. `peon-mcp`) |
| `path` | TEXT | Absolute path on disk |
| `created_at` | TIMESTAMP | Auto-set on insert |

### Features

High-level groupings of related work (optional).

| Column | Type | Description |
|---|---|---|
| `id` | INTEGER PK | Auto-increment |
| `project_id` | TEXT FK | References `projects.id` |
| `name` | TEXT | Short feature name |
| `description` | TEXT | Scope and goals |
| `status` | TEXT | `planned`, `in_progress`, `done`, `cancelled` |
| `created_at` | TIMESTAMP | Auto-set on insert |
| `updated_at` | TIMESTAMP | Updated on modification |

### Tasks

Actionable units of work with priority and status tracking.

| Column | Type | Description |
|---|---|---|
| `id` | INTEGER PK | Auto-increment |
| `project_id` | TEXT FK | References `projects.id` |
| `title` | TEXT | Short summary |
| `description` | TEXT | Detailed description |
| `priority` | TEXT | `low`, `medium`, `high`, `critical` |
| `status` | TEXT | `todo`, `in_progress`, `done`, `cancelled` |
| `commit_base` | TEXT | Git commit SHA when work began |
| `commit_head` | TEXT | Git commit SHA after work completed |
| `created_at` | TIMESTAMP | Auto-set on insert |
| `updated_at` | TIMESTAMP | Updated on modification |

### Work Logs

Audit trail of work done on tasks.

| Column | Type | Description |
|---|---|---|
| `id` | INTEGER PK | Auto-increment |
| `task_id` | INTEGER FK | References `tasks.id` |
| `project_id` | TEXT FK | References `projects.id` |
| `summary` | TEXT | What was done and the outcome |
| `files_changed` | TEXT | Comma-separated list of files touched |
| `test_result` | TEXT | `pass`, `fail`, `skip`, or empty |
| `created_at` | TIMESTAMP | Auto-set on insert |

## MCP Tools

peon-mcp exposes 24 tools via the MCP protocol:

### Projects

| Tool | Description |
|---|---|
| `create_project` | Register a project (repo name + path) |
| `list_projects` | List all registered projects |
| `get_project` | Get a project by ID |

### Features

| Tool | Description |
|---|---|
| `create_feature` | Create a high-level feature for a project |
| `list_features` | List features, optionally filtered by status |
| `get_feature` | Get a feature by ID |
| `update_feature` | Update feature name, description, or status |
| `delete_feature` | Delete a feature |

### Tasks

| Tool | Description |
|---|---|
| `create_task` | Create a task scoped to a project |
| `list_tasks` | List tasks, filterable by priority and/or status |
| `get_task` | Get a task by ID |
| `next_task` | Pick up the highest-priority `todo` task and mark it `in_progress` |
| `update_task` | Update task title, description, priority, status, or git commits |
| `delete_task` | Delete a task |

### Work Logs

| Tool | Description |
|---|---|
| `log_work` | Log the results of work done on a task |
| `list_work_logs` | List work logs, filterable by task or project |

**Key behaviors:**
- `create_task` and `create_feature` check that the project exists first
- `next_task` returns tasks in priority order (critical > high > medium > low), oldest first within the same priority

## MCP Prompts

peon-mcp provides two prompts for agent orchestration:

### `start_work`

Bootstrap prompt for an agent beginning work on a project. Guides the agent to:

1. Register the project if needed
2. Ensure a clean git working tree (stash any uncommitted changes and log it)
3. Call `next_task` to pick up work
4. Use the `execute_task` prompt for full instructions

**Parameters:** `project_id`, `repo_path`

### `execute_task`

Instructions for executing a single task. Covers:

- Scoping changes to the task
- Reading code before modifying it
- Running tests and keeping the suite green
- Reverting if things break
- Capturing follow-up work as new tasks
- Committing and pushing on success
- Logging all work via `log_work` (including failures)

**Parameters:** `project_id`, `task_title`, `task_description`

## Usage Workflow

### Manual Workflow (with Claude Desktop/Code)

1. Register your project:
   ```
   Call create_project with your repo name and path
   ```

2. Create tasks:
   ```
   Call create_task to add work items
   ```

3. Pick up tasks:
   ```
   Call next_task to claim the highest-priority task
   ```

4. Work on the task following the execute_task prompt guidance

5. Log your work:
   ```
   Call log_work to record what was done
   ```

### Autonomous Workflow (with peon-loop)

1. Create tasks via the web UI or MCP tools

2. Start the loop:
   ```bash
   peon-loop my-project /path/to/repo
   ```

3. The loop will:
   - Check for todo tasks
   - Spawn Claude with the start_work prompt
   - Let Claude work through the task
   - Sleep and repeat

4. Monitor progress in the web UI at http://127.0.0.1:8420

## Development

### Run UI in Development Mode

```bash
# Terminal 1: Start the backend API
uv run python -m peon_mcp.web

# Terminal 2: Start Vite dev server with hot reload
cd ui && npm run dev
```

The dev server runs on http://localhost:5173 and proxies `/api` to the backend.

### Build UI for Production

```bash
cd ui
npm run build
```

This outputs assets to `peon_mcp/static/` which are served by the backend.

### Build Python Wheel

```bash
uv build
```

### Deploy to PyPI

```bash
./deploy.sh              # PyPI
./deploy.sh testpypi     # TestPyPI
```

## Testing the MCP Server

Use the MCP inspector for interactive testing:

```bash
uv run mcp dev peon_mcp/server.py
```

## Common Commands Reference

```bash
# Python dependencies
uv sync

# UI dependencies
cd ui && npm install

# Run MCP server (stdio transport)
uv run python -m peon_mcp.server

# Run web UI + REST API
uv run python -m peon_mcp.web

# Run UI dev server with hot reload
cd ui && npm run dev

# Build UI
cd ui && npm run build

# Run agent loop (single iteration)
peon-loop PROJECT_ID /path/to/repo --once

# Run agent loop (continuous)
peon-loop PROJECT_ID /path/to/repo --model sonnet --timeout 1800
```

## Project Structure

```
peon-mcp/
├── peon_mcp/
│   ├── __init__.py
│   ├── server.py        # MCP server (24 tools + 2 prompts)
│   ├── db.py            # SQLite schema and utilities
│   ├── web.py           # Starlette REST API + static serving
│   ├── loop.py          # Agent loop CLI
│   └── static/          # Built React app
├── ui/
│   ├── src/
│   │   ├── components/  # React components
│   │   ├── api.ts       # REST client
│   │   ├── types.ts     # TypeScript types
│   │   └── main.tsx     # App entry point
│   ├── package.json
│   └── vite.config.ts
├── pyproject.toml       # Python project config
├── deploy.sh            # PyPI deployment script
└── README.md
```

## License

MIT

## Contributing

Contributions welcome! Please open an issue or PR on GitHub.

## Support

- GitHub Issues: https://github.com/pyrabbit/peon-mcp/issues
- MCP Documentation: https://modelcontextprotocol.io

---

**Work work!** Ready to serve, master.
