使用说明
mcp-task-server
A generic, client-agnostic MCP server for managing tasks, checkpoints, and agent handoffs. Communicates via STDIO (JSON-RPC 2.0) or HTTP/SSE and works with any MCP-capable client.
Use case: Agent A hits its context limit or needs to hand off work. It saves a checkpoint with all relevant state. Agent B (same or different AI system) picks up the task and continues exactly where A left off — with full context, completed steps, remaining steps, and a resume prompt.
Agent A → save_checkpoint() → handoff_task() → [task-server]
↓
Agent B ← get_task() ←────────────────────────────────────
Features
- Task management — create, read, update tasks with full lifecycle tracking
- Checkpoint system — agents save progress (completed steps, remaining steps, test results)
- Handoff — transfer tasks between any agents with ownership tracking
- Artifacts — attach files, diffs, and logs to tasks
- Resources — read tasks via
task://<id>as MCP resources - Dual transport — STDIO for direct subprocess use, HTTP/SSE for persistent service
- SQLite — persistent storage, no external database required
- Zero dependencies beyond
pydantic
Requirements
- Python 3.11+
pydantic >= 2.0
Installation
git clone https://github.com/Mr-Websaint/mcp-task-server.git
cd mcp-task-server
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Usage
STDIO mode (recommended for MCP clients)
python3 server.py
The server reads JSON-RPC messages from stdin and writes responses to stdout. Debug logging goes to stderr:
MCP_DEBUG=1 python3 server.py
HTTP/SSE mode (persistent service)
python3 server.py --http --port 8766
Endpoints:
| Endpoint | Description |
|---|---|
GET /health |
Health check → {"status": "ok"} |
GET /sse |
SSE stream (MCP SSE transport) |
POST /message?clientId=<id> |
Send JSON-RPC message |
Admin CLI (interactive task management)
A bundled admin script lets you inspect and manage the MCP task server directly from the terminal.
python3 /home/websaint/mcp-task-server/admin.py
If you want a shorter command, add this Bash alias for the websaint user:
alias mcptask='python3 /home/websaint/mcp-task-server/admin.py'
After adding the alias, reload your shell configuration:
source ~/.bashrc
The admin CLI provides:
- browse tasks in read-only menus
- search and filter tasks
- open a task detail menu for one task
- update status, owners, checkpoints, and handoffs
- read task data as JSON or as an MCP resource
Status values can be entered by name or by number (1 to 5) in the menus and direct CLI commands.
MCP Client Configuration
Any client supporting STDIO transport
{
"mcpServers": {
"task-handoff": {
"command": "python3",
"args": ["/path/to/mcp-task-server/server.py"],
"env": {
"MCP_TASK_DB_PATH": "/path/to/tasks.db",
"MCP_TASK_ARTIFACTS_DIR": "/path/to/artifacts"
}
}
}
}
Claude Code (~/.claude/settings.json)
{
"mcpServers": {
"task-handoff": {
"command": "/path/to/mcp-task-server/.venv/bin/python3",
"args": ["/path/to/mcp-task-server/server.py"]
}
}
}
Hermes Agent (~/.hermes/config.yaml)
mcp_servers:
task_handoff:
command: "/path/to/mcp-task-server/.venv/bin/python3"
args: ["/path/to/mcp-task-server/server.py"]
env:
MCP_TASK_DB_PATH: "/path/to/mcp-task-server/tasks.db"
MCP_TASK_ARTIFACTS_DIR: "/path/to/mcp-task-server/artifacts"
timeout: 60
connect_timeout: 30
HTTP client (SSE transport)
mcp_servers:
task_handoff:
url: "http://127.0.0.1:8766/sse"
Environment Variables
| Variable | Default | Description |
|---|---|---|
MCP_TASK_DB_PATH |
./tasks.db |
Path to the SQLite database |
MCP_TASK_ARTIFACTS_DIR |
./artifacts/ |
Directory for artifacts |
MCP_TASK_BASE_DIR |
Directory of server.py |
Base path |
MCP_TASK_PORT |
8766 |
HTTP port (overridden by --port) |
MCP_DEBUG |
(unset) | Enable debug logging when set |
Available Tools
| Tool | Description |
|---|---|
create_task |
Create a new task |
get_task |
Read a task by ID |
save_checkpoint |
Save agent progress (steps, tests, resume prompt) |
handoff_task |
Transfer task from one agent to another |
mark_exhausted |
Mark task as "agent cannot proceed" |
attach_artifact |
Attach a file, diff, or log to a task |
list_tasks |
List tasks with optional filters |
update_task |
Update a task with partial field updates |
search_tasks |
Search tasks by text in the goal and title fields |
MCP Resource
- URI:
task://<task_id> - Type:
application/json - Returns the full task as JSON (read-only)
Task Lifecycle
open → in_progress → handoff_ready → in_progress → done
↘ agent_exhausted
Example Workflow (JSON-RPC)
1. Initialize
→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}
← {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false}},"serverInfo":{"name":"mcp-task-server","version":"1.0.0"}}}
→ {"jsonrpc":"2.0","method":"notifications/initialized"}
2. Create task
→ {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"create_task","arguments":{"task_id":"task-001","title":"Fix login bug","goal":"Resolve auth error on /login","repo_path":"/home/dev/myapp"}}}
3. Save checkpoint (Agent A)
→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"save_checkpoint","arguments":{"task_id":"task-001","agent":"claude-code","completed_steps":["Reproduced bug","Found root cause in auth/login.py:42"],"remaining_steps":["Implement fix","Write tests"],"resume_prompt":"Fix null check in auth/login.py line 42"}}}
4. Hand off to Agent B
→ {"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"handoff_task","arguments":{"task_id":"task-001","from_agent":"claude-code","to_agent":"hermes","reason":"Context limit reached, fix not yet implemented"}}}
5. Agent B reads task
→ {"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"get_task","arguments":{"task_id":"task-001"}}}
Or via resource:
→ {"jsonrpc":"2.0","id":6,"method":"resources/read","params":{"uri":"task://task-001"}}
6. Update task (Agent B makes progress)
→ {"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"update_task","arguments":{"task_id":"task-001","title":"Fix login bug","goal":"Implementing solution for auth error","status":"in_progress","current_owner":"hermes","completed_steps":["Reproduced bug","Found root cause","Implemented fix"],"remaining_steps":["Write tests","Deploy to staging"]}}}
Running as a systemd Service
A service template is provided in systemd/mcp-task-server.service.template.
# 1. Copy and adapt the template
cp systemd/mcp-task-server.service.template /etc/systemd/system/mcp-task-server.service
# Edit User=, WorkingDirectory=, ExecStart= and Environment= paths
# 2. Enable and start
systemctl daemon-reload
systemctl enable --now mcp-task-server
# 3. Check status
systemctl status mcp-task-server
journalctl -u mcp-task-server -f
Health Check
# Run the bundled health check script
./healthcheck.sh
# Or hit the HTTP endpoint directly (HTTP mode only)
curl http://127.0.0.1:8766/health
The health check verifies: venv, pydantic import, DB write access, artifacts directory, STDIO response, and HTTP service status.
Project Structure
mcp-task-server/
├── admin.py # Interactive admin CLI for browsing and managing tasks
├── server.py # Main server (STDIO + HTTP/SSE transport, MCP protocol)
├── config.py # Configuration via environment variables
├── models.py # Pydantic data models (Task, Artifact, TestRun, ...)
├── store.py # SQLite persistence layer
├── healthcheck.sh # Health check script
├── requirements.txt # Python dependencies
├── systemd/
│ └── mcp-task-server.service.template # systemd unit file template
└── artifacts/ # Runtime artifact storage (gitignored)
License
MIT — do whatever you want with it.
