
RUNN
from gemini2026
runn.io MCP Server
runn.io MCP Server
Standalone MCP server for the Runn API with simple reporting helpers.
Run (MCP server)
stdio (Claude Desktop)
RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport stdiostdio (Windows PowerShell)
$env:RUNN_API_KEY="LIVE_..."
py mcp_runn_server.py --transport stdiostdio (macOS / zsh)
RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport stdiostreamable-http (default)
RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport streamable-httpstreamable-http (Windows PowerShell)
$env:RUNN_API_KEY="LIVE_..."
py mcp_runn_server.py --transport streamable-httpstreamable-http (macOS / zsh)
RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport streamable-httpRun with Docker
Build the image:
docker build -t runn-mcp-server .Windows PowerShell
docker build -t runn-mcp-server .Run the container (HTTP transport):
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 runn-mcp-serverWindows PowerShell
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 runn-mcp-servermacOS (Docker Desktop)
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 runn-mcp-serverGHCR image
The GitHub Actions workflow publishes to:
ghcr.io/gemini2026/runn-mcp-serverPull and run:
docker pull ghcr.io/gemini2026/runn-mcp-server:main
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 ghcr.io/gemini2026/runn-mcp-server:mainWindows PowerShell
docker pull ghcr.io/gemini2026/runn-mcp-server:main
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 ghcr.io/gemini2026/runn-mcp-server:mainmacOS (Docker Desktop)
docker pull ghcr.io/gemini2026/runn-mcp-server:main
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 ghcr.io/gemini2026/runn-mcp-server:mainClaude Desktop config snippet
{
"mcpServers": {
"runn": {
"command": "/path/to/python3",
"args": [
"/path/to/mcp_runn_server.py",
"--transport",
"stdio"
],
"env": {
"RUNN_API_KEY": "<YOUR_API_KEY>"
}
}
}
}Windows paths example
{
"mcpServers": {
"runn": {
"command": "C:\\\\Python311\\\\python.exe",
"args": [
"C:\\\\path\\\\to\\\\mcp_runn_server.py",
"--transport",
"stdio"
],
"env": {
"RUNN_API_KEY": "<YOUR_API_KEY>"
}
}
}
}MCP tools
list_projectsβ returns{id, name}pairs.list_peopleβ returns{id, name, email}by default (setfull=truefor raw objects).billable_hoursβ aggregates billable hours grouped by project/person/month.list_clientsβ list clients (raw API objects).list_assignmentsβ list assignments (raw API objects).list_assignments_by_personβ assignments for a person, optional date range.list_assignments_by_projectβ assignments for a project, optional date range.list_assignments_by_roleβ assignments for a role, optional date range.list_assignments_by_teamβ assignments for a teamβs people, optional date range.list_actualsβ list actuals (raw API objects).list_actuals_by_date_rangeβ actuals in a date range, optional person/project filters.list_actuals_by_personβ actuals for a person, optional date range.list_actuals_by_projectβ actuals for a project, optional date range.list_actuals_by_roleβ actuals for a role, optional date range.list_actuals_by_teamβ actuals for a teamβs people, optional date range.list_rolesβ list roles (raw API objects).list_roles_by_personβ roles that include a person.list_skillsβ list skills (raw API objects).list_skills_by_personβ skills for a person with levels + names.list_teamsβ list teams (raw API objects).list_people_by_teamβ people in a team (optionally include archived).list_people_by_skillβ people who have a skill (optional min level).list_people_by_tagβ people with a tag (by id or name).list_people_by_managerβ people managed by a manager id.list_rate_cardsβ list rate cards (raw API objects).list_rate_cards_by_projectβ rate cards that include a project.runn_requestβ call any Runn API endpoint (GET/POST/PATCH/PUT/DELETE).
Pagination for list endpoints:
{
"method": "GET",
"path": "/projects",
"paginate": true
}Filter-specific tools (e.g., list_assignments_by_person) fetch list endpoints and apply filters client-side.
Reports (optional)
runn_reports.py can export billable hours grouped by project/person/month.
RUNN_API_KEY=LIVE_... python3 runn_reports.py --start 2025-01-01 --end 2025-12-31 --output billable.csvPDF output requires ReportLab:
python -m pip install reportlabCI/CD
- CI runs on every push and pull request to
main. - CD publishes a GitHub Release when you push a tag like
v0.1.0.
Example release:
git tag v0.1.0
git push origin v0.1.0python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtBefore it works, you'll need: RUNN_API_KEY
Requirements
- Python 3.10+
- Runn API key (
RUNN_API_KEY)
Install
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtWindows (PowerShell)
py -m venv .venv
.\\.venv\\Scripts\\Activate.ps1
py -m pip install --upgrade pip
pip install -r requirements.txtWindows (Command Prompt)
py -m venv .venv
.\\.venv\\Scripts\\activate.bat
py -m pip install --upgrade pip
pip install -r requirements.txtmacOS (zsh/bash: Homebrew + venv)
brew install python@3.11
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtUsage examples
HTTP transport (streamable-http)
-
Start the server:
RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport streamable-http -
Invoke a specific tool via HTTP:
curl -s http://localhost:8000/api \ -H "Content-Type: application/json" \ -d '{ "tool": "list_actuals_by_person", "args": { "person_id": 123, "start": "2025-01-01", "end": "2025-01-31" } }' | jq -
Go straight to the raw Runn API:
curl -s http://localhost:8000/api \ -H "Content-Type: application/json" \ -d '{ "tool": "runn_request", "args": { "method": "GET", "path": "/projects" } }' | jq
stdio transport (Claude/Desktop or script)
printf '{"tool":"list_projects"}' | RUNN_API_KEY=LIVE_... python3 mcp_runn_server.py --transport stdioClaude will read the JSON response from stdout, just like any MCP client.
Docker usage
docker run --rm -e RUNN_API_KEY=LIVE_... -p 8000:8000 runn-mcp-serverConnect via the HTTP examples above or switch to stdio by appending --transport stdio on the Docker command.
No common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.