Runn MCP Server

Runn MCP Server

Connects AI assistants to the Runn.io resource planning platform to manage projects, people, assignments, and financial forecasts. It provides 37 tools for accessing real-time data and comprehensive reports with built-in caching and role-based access control.

Category
Visit Server

README

Runn MCP Server

An MCP (Model Context Protocol) server for Runn.io - a resource planning and project forecasting platform. This server allows AI assistants like Claude, ChatGPT, and Cline to interact with your Runn data.

Features

37 tools covering all Runn API endpoints, with built-in in-memory caching to reduce API calls:

People

Tool Description
get_all_people Fetches all people from Runn (with optional filters)
get_person_by_id Fetches a specific person by their ID
get_person_by_email Fetches a specific person by their email address

Projects

Tool Description
get_all_projects Fetches all projects from Runn (with optional filters)
get_project_by_id Fetches a specific project by its ID
get_project_phases Fetches all phases for a project
get_project_milestones Fetches all milestones for a project

Clients

Tool Description
get_all_clients Fetches all clients from Runn (with optional filters)
get_client_by_id Fetches a specific client by its ID
get_client_projects Fetches all projects for a specific client

Assignments

Tool Description
get_all_assignments Fetches all assignments (who is assigned to what)
get_active_assignments Fetches only currently active assignments

Actuals (Logged Time)

Tool Description
get_all_actuals Fetches all logged time with optional filters
get_person_actuals Fetches logged time for a specific person
get_project_actuals Fetches logged time for a specific project

Roles

Tool Description
get_all_roles Fetches all job roles defined in Runn
get_role_by_id Fetches a specific role by its ID

Contracts

Tool Description
get_all_contracts Fetches all employment contracts
get_person_contracts Fetches contracts for a specific person

Time Off & Holidays

Tool Description
get_all_holidays Fetches all public holidays
get_all_time_off Fetches all time off/leave entries
get_person_time_off Fetches time off for a specific person

Milestones

Tool Description
get_all_milestones Fetches all project milestones
get_project_milestones Fetches milestones for a specific project

Other Resources

Tool Description
get_all_rate_cards Fetches all billing rate cards
get_all_placeholders Fetches all placeholder resources
get_all_tags Fetches all tags/labels
get_account Fetches account information and settings

Cache Management

Tool Description
clear_cache Clears the in-memory cache to force fresh data on next request

Reports - Utilization & Revenue

Tool Description
get_all_people_metrics BETA: Utilization metrics for all people
get_person_metrics BETA: Person utilization metrics (billable %, revenue, costs, capacity)
get_all_project_metrics BETA: Financial metrics for all projects
get_project_metrics BETA: Project financial metrics (revenue, profit, margin, budget)

Reports - Hours

Tool Description
get_person_hours_report Day-by-day hours report for a person
get_project_hours_report Day-by-day hours report for a project

Reports - Totals

Tool Description
get_all_project_totals Aggregated totals for all projects
get_project_totals Aggregated totals for a specific project

Reports - Composite

Tool Description
get_weekly_schedule_vs_actuals_report Compares scheduled hours vs actual timesheet hours per project for a given week
get_weekly_person_schedule_vs_actuals_report Compares scheduled hours vs actual timesheet hours per person for a given week
get_schedule_variance_report Person × project variance showing over-scheduled assignments over multiple weeks
get_project_schedule_vs_actuals_report Project-level schedule vs actuals for any date range
get_timesheet_compliance_report Flags people who haven't logged enough hours against their schedule
get_availability_report Shows who has available capacity (bench time) for a given week
get_project_health_report Portfolio health summary with red/amber/green status for all active projects
get_revenue_forecast_report Compares forecasted revenue against actual recognized revenue
get_client_profitability_report Aggregates revenue, costs, profit, and margin by client across all projects

In-Memory Caching

All API responses (except actuals and reports) are cached in-memory with automatic TTL-based expiration. This significantly reduces redundant API calls when the same data is requested multiple times within a session.

Cache TTL Tiers

TTL Category Endpoints
10 minutes Stable reference data Roles, tags, holidays, rate cards, account, placeholders
5 minutes Semi-stable data People, clients, contracts, time off
2 minutes Dynamic data Projects, assignments, milestones, phases
No cache Time-sensitive data Actuals, all reports (metrics, hours, totals)

Manual Cache Invalidation

Use the clear_cache tool to immediately invalidate all cached entries when you need guaranteed fresh data. The cache is also automatically cleared when the MCP server process restarts.

Prerequisites

Installation

1. Clone and Build

# Navigate to the project directory
cd runn-mcp

# Install dependencies
npm install

# Build the project
npm run build

2. Get Your Runn API Key

  1. Log in to Runn
  2. Go to SettingsAPI
  3. Generate a new API key
  4. Copy the key for use in configuration

Configuration

The server supports two transport modes:

  • stdio — for local development (runs as a child process)
  • HTTP — for production deployment (runs as a web server)

Local Mode (stdio) — For Development

Claude Desktop

Add the following to your Claude Desktop configuration file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "runn": {
      "command": "node",
      "args": ["/absolute/path/to/runn-mcp/build/index.js"],
      "env": {
        "RUNN_API_KEY": "your-runn-api-key-here"
      }
    }
  }
}

ChatGPT Desktop

{
  "mcpServers": {
    "runn": {
      "command": "node",
      "args": ["/absolute/path/to/runn-mcp/build/index.js"],
      "env": {
        "RUNN_API_KEY": "your-runn-api-key-here"
      }
    }
  }
}

Cline (VS Code Extension)

{
  "mcpServers": {
    "runn": {
      "command": "node",
      "args": ["/absolute/path/to/runn-mcp/build/index.js"],
      "env": {
        "RUNN_API_KEY": "your-runn-api-key-here"
      }
    }
  }
}

Important: Replace /absolute/path/to/runn-mcp with the actual absolute path to your runn-mcp directory.


Remote Mode (HTTP) — For Production / Team Access

When deployed as an HTTP server, coworkers connect via URL instead of running the server locally.

Claude Team (Custom Connector with OAuth)

The server supports OAuth 2.0 Client Credentials flow, which integrates with Claude's custom connector feature for team-wide access.

Setup in Claude Admin Console:

  1. Go to your Claude team's Admin SettingsConnectorsAdd Custom Connector
  2. Fill in:
Field Value
Name Runn
Remote MCP server URL https://mcp-runn.gigaplayops.com/mcp
OAuth Client ID Your client ID (from OAUTH_CLIENTS env var)
OAuth Client Secret Your client secret (from OAUTH_CLIENTS env var)
  1. Click Add

Claude will automatically discover the OAuth metadata endpoints, exchange credentials for a Bearer token, and authenticate all MCP requests.

How it works under the hood:

  1. Claude connects to /mcp → receives 401 with WWW-Authenticate header
  2. Claude fetches /.well-known/oauth-protected-resource → learns the auth server
  3. Claude fetches /.well-known/oauth-authorization-server → learns the token endpoint
  4. Claude POSTs client_credentials to /oauth/token → receives a Bearer token (1-hour TTL)
  5. Claude uses the Bearer token for all subsequent /mcp requests
  6. When the token expires or the container restarts, Claude re-authenticates automatically

Claude Desktop (Remote with Static Token)

{
  "mcpServers": {
    "runn": {
      "url": "https://mcp-runn.gigaplayops.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN_HERE"
      }
    }
  }
}

Cline (Remote)

Same format — point to the URL with the auth header in your MCP server settings.


Authentication

The HTTP server supports two authentication methods that can be used simultaneously:

Method 1: OAuth 2.0 Client Credentials (for Claude Team)

Configure OAuth clients via the OAUTH_CLIENTS environment variable:

OAUTH_CLIENTS={"claude-team":{"secret":"long-random-secret","role":"god"}}

Each entry maps a client_id{ secret, role }:

  • client_id: Any string identifier (e.g., claude-team, claude-executive)
  • secret: A long, random string (generate with openssl rand -hex 32)
  • role: One of god, executive, or project-manager

Multiple OAuth clients can be configured:

OAUTH_CLIENTS={"claude-god":{"secret":"aaa...","role":"god"},"claude-pm":{"secret":"bbb...","role":"project-manager"}}

OAuth Endpoints:

Endpoint Purpose
GET /.well-known/oauth-protected-resource Protected Resource Metadata (RFC 9728)
GET /.well-known/oauth-authorization-server Authorization Server Metadata (RFC 8414)
POST /oauth/token Token endpoint — client_credentials grant
POST /oauth/register Dynamic Client Registration (RFC 7591)

Tokens are issued with a 1-hour TTL and stored in-memory. Container restarts clear all issued tokens — clients simply re-authenticate.

Method 2: Static Bearer Tokens (for Cline / Claude Desktop)

Configure static tokens via the MCP_AUTH_TOKENS environment variable:

MCP_AUTH_TOKENS={"god":"token-aaa","executive":"token-bbb,token-ccc","project-manager":"token-ddd,token-eee"}
  • Each role maps to one or more bearer tokens (comma-separated)
  • Tokens must be unique across all roles
  • Use long, random strings for production tokens (e.g., openssl rand -hex 32)

Both methods are optional

  • Set only OAUTH_CLIENTS → only OAuth authentication works
  • Set only MCP_AUTH_TOKENS → only static Bearer token authentication works
  • Set both → both methods work simultaneously

Role-Based Access Control

The HTTP server supports three access tiers. Each bearer token is mapped to a role, and the role determines which tools are available.

Role Description
god Full access to all tools
executive All tools (customizable — can restrict to financial/portfolio views)
project-manager All tools (customizable — can restrict to operational tools only)

Currently all roles have access to all tools. To restrict tools per role, edit src/tool-permissions.ts and change the minimum role for each tool.

Token Configuration

Set the MCP_AUTH_TOKENS environment variable as JSON:

MCP_AUTH_TOKENS={"god":"token-aaa","executive":"token-bbb,token-ccc","project-manager":"token-ddd,token-eee"}
  • Each role maps to one or more bearer tokens (comma-separated)
  • Tokens must be unique across all roles
  • Use long, random strings for production tokens (e.g., openssl rand -hex 32)

Production Deployment

Environment Variables

Variable Required Description
RUNN_API_KEY Yes Your Runn API key
OAUTH_CLIENTS No* JSON mapping client_id → { secret, role } for OAuth 2.0
MCP_AUTH_TOKENS No* JSON mapping roles to static bearer tokens
MCP_BASE_URL No Public base URL for OAuth metadata (e.g., https://mcp-runn.gigaplayops.com)
PORT No HTTP port (default: 3000)

* At least one of OAUTH_CLIENTS or MCP_AUTH_TOKENS should be set, otherwise all requests will be rejected.

Running Locally (HTTP mode)

npm run build

# With OAuth (for Claude Team connector testing):
RUNN_API_KEY=your-key \
  OAUTH_CLIENTS='{"claude-team":{"secret":"test-secret","role":"god"}}' \
  MCP_BASE_URL=http://localhost:3000 \
  npm run start:http

# With static tokens (for Cline/Claude Desktop):
RUNN_API_KEY=your-key \
  MCP_AUTH_TOKENS='{"god":"test-token"}' \
  npm run start:http

# With both:
RUNN_API_KEY=your-key \
  OAUTH_CLIENTS='{"claude-team":{"secret":"test-secret","role":"god"}}' \
  MCP_AUTH_TOKENS='{"god":"test-token"}' \
  MCP_BASE_URL=http://localhost:3000 \
  npm run start:http

Docker

# Build
docker build -t runn-mcp .

# Run
docker run -p 3000:3000 \
  -e RUNN_API_KEY=your-key \
  -e OAUTH_CLIENTS='{"claude-team":{"secret":"long-random-secret","role":"god"}}' \
  -e MCP_AUTH_TOKENS='{"god":"token-aaa","executive":"token-bbb"}' \
  -e MCP_BASE_URL=https://mcp-runn.gigaplayops.com \
  runn-mcp

Health check: GET /health

AWS App Runner

The server is designed for AWS App Runner with Docker image source from ECR.

One-time setup:

  1. Create an ECR repository named runn-mcp
  2. Create an App Runner service with:
    • Source: ECR image (<account>.dkr.ecr.<region>.amazonaws.com/runn-mcp:latest)
    • Port: 3000
    • Health check: HTTP /health
    • Environment variables: RUNN_API_KEY, OAUTH_CLIENTS, MCP_AUTH_TOKENS, MCP_BASE_URL, PORT=3000
  3. Add custom domain mcp-runn.gigaplayops.com in App Runner console
  4. Create CNAME in Route53 pointing to the App Runner domain

GitHub Actions CI/CD

The repo includes .github/workflows/deploy.yml that automatically builds and deploys on push to main.

Required GitHub Secrets:

Secret Description
AWS_ACCESS_KEY_ID IAM credentials with ECR + App Runner permissions
AWS_SECRET_ACCESS_KEY Corresponding secret key
AWS_REGION e.g. us-east-1
ECR_REPOSITORY ECR repository name (e.g. runn-mcp)
APPRUNNER_SERVICE_ARN ARN of the App Runner service

The workflow:

  1. Checks out code and builds TypeScript
  2. Builds Docker image and pushes to ECR (tagged with commit SHA + latest)
  3. Triggers App Runner deployment via aws apprunner start-deployment

Usage Examples

Once configured, you can ask your AI assistant questions like:

People:

  • "Show me all active people in Runn"
  • "Find the person with email john@example.com in Runn"

Projects:

  • "What projects are currently active?"
  • "Show me details for project ID 12345"

Clients:

  • "List all our clients"
  • "What projects does client X have?"

Assignments:

  • "Who is assigned to which projects?"
  • "Show me all active assignments"

Available Tools

People Tools

get_all_people

Fetches all people from Runn with optional filtering.

  • onlyActive (optional, boolean): If true, only returns active people
  • modifiedAfter (optional, string): ISO 8601 date string to filter by modification date

get_person_by_id

Fetches a specific person by their unique ID.

  • personId (required, string): The unique identifier of the person

get_person_by_email

Fetches a specific person by their email address.

  • email (required, string): The email address of the person

Project Tools

get_all_projects

Fetches all projects from Runn with optional filtering.

  • onlyActive (optional, boolean): If true, only returns active projects
  • modifiedAfter (optional, string): ISO 8601 date string to filter by modification date

get_project_by_id

Fetches a specific project by its unique ID.

  • projectId (required, string): The unique identifier of the project

Client Tools

get_all_clients

Fetches all clients from Runn with optional filtering.

  • onlyActive (optional, boolean): If true, only returns active clients
  • modifiedAfter (optional, string): ISO 8601 date string to filter by modification date

get_client_by_id

Fetches a specific client by its unique ID.

  • clientId (required, string): The unique identifier of the client

get_client_projects

Fetches all projects assigned to a specific client.

  • clientId (required, string): The unique identifier of the client

Assignment Tools

get_all_assignments

Fetches all assignments from Runn with optional filtering.

  • onlyActive (optional, boolean): If true, only returns active assignments
  • modifiedAfter (optional, string): ISO 8601 date string to filter by modification date

get_active_assignments

Fetches only currently active assignments from Runn.

  • No parameters required

Actuals Tools

get_all_actuals

Fetches all logged time (actuals) from Runn with optional filtering.

  • minDate (optional, string): Minimum date filter (YYYY-MM-DD format)
  • maxDate (optional, string): Maximum date filter (YYYY-MM-DD format)
  • projectId (optional, string): Filter by project ID
  • personId (optional, string): Filter by person ID
  • roleId (optional, string): Filter by role ID

get_person_actuals

Fetches logged time for a specific person.

  • personId (required, string): The unique identifier of the person
  • minDate (optional, string): Minimum date filter (YYYY-MM-DD format)
  • maxDate (optional, string): Maximum date filter (YYYY-MM-DD format)

get_project_actuals

Fetches logged time for a specific project.

  • projectId (required, string): The unique identifier of the project
  • minDate (optional, string): Minimum date filter (YYYY-MM-DD format)
  • maxDate (optional, string): Maximum date filter (YYYY-MM-DD format)

Reports Tools

get_person_metrics

BETA: Fetches utilization metrics for a person (billable utilization, revenue, costs, capacity).

  • personId (required, string): The unique identifier of the person
  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

get_project_metrics

BETA: Fetches financial metrics for a project (revenue, profit, costs, margin, budget).

  • projectId (required, string): The unique identifier of the project
  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

get_person_hours_report

Fetches day-by-day hours report for a person (scheduled vs actual).

  • personId (required, string): The unique identifier of the person
  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)

get_project_hours_report

Fetches day-by-day hours report for a project (scheduled vs actual).

  • projectId (required, string): The unique identifier of the project
  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)

get_all_project_totals

Fetches aggregated totals for all projects (hours, revenue, costs).

  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

get_project_totals

Fetches aggregated totals for a specific project.

  • projectId (required, string): The unique identifier of the project
  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

get_all_people_metrics

BETA: Fetches utilization metrics for all people.

  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

get_all_project_metrics

BETA: Fetches financial metrics for all projects.

  • startDate (required, string): Start date for the report period (YYYY-MM-DD)
  • endDate (required, string): End date for the report period (YYYY-MM-DD)
  • todayDate (optional, string): Reference date for calculations (YYYY-MM-DD)

Roles Tools

get_all_roles

Fetches all job roles defined in Runn.

  • No parameters required

get_role_by_id

Fetches a specific role by its unique ID.

  • roleId (required, string): The unique identifier of the role

Contracts Tools

get_all_contracts

Fetches all employment contracts from Runn.

  • No parameters required

get_person_contracts

Fetches all employment contracts for a specific person.

  • personId (required, string): The unique identifier of the person

Holidays Tools

get_all_holidays

Fetches all public holidays configured in Runn.

  • No parameters required

Time Off Tools

get_all_time_off

Fetches all time off (leave/vacation) entries.

  • personId (optional, string): Filter by person ID
  • minDate (optional, string): Minimum date filter (YYYY-MM-DD)
  • maxDate (optional, string): Maximum date filter (YYYY-MM-DD)

get_person_time_off

Fetches time off for a specific person.

  • personId (required, string): The unique identifier of the person
  • minDate (optional, string): Minimum date filter (YYYY-MM-DD)
  • maxDate (optional, string): Maximum date filter (YYYY-MM-DD)

Milestones Tools

get_all_milestones

Fetches all project milestones from Runn.

  • projectId (optional, string): Filter by project ID

get_project_milestones

Fetches all milestones for a specific project.

  • projectId (required, string): The unique identifier of the project

Phases Tools

get_project_phases

Fetches all phases for a specific project.

  • projectId (required, string): The unique identifier of the project

Rate Cards Tools

get_all_rate_cards

Fetches all billing rate cards from Runn.

  • No parameters required

Placeholders Tools

get_all_placeholders

Fetches all placeholder resources from Runn.

  • No parameters required

Tags Tools

get_all_tags

Fetches all tags/labels from Runn.

  • No parameters required

Account Tools

get_account

Fetches your Runn account information and settings.

  • No parameters required

Cache Management Tools

clear_cache

Clears the in-memory cache for all Runn API responses. Use this if you need fresh data immediately without waiting for cached entries to expire.

  • No parameters required

Composite Report Tools

get_weekly_schedule_vs_actuals_report

Generates a composite report comparing scheduled assignment hours vs actual timesheet hours per project for a given week (Monday–Sunday). Fetches assignments, actuals, and projects in parallel, calculates overlap days, and returns structured JSON with per-project and total rows including a delta (scheduled − actual).

  • weekOf (optional, string): Any date (YYYY-MM-DD) within the desired week. The tool automatically resolves to the Monday–Sunday window containing that date. Defaults to last week if omitted.

get_client_profitability_report

Aggregates financial metrics (revenue, costs, profit, margin) by client across all their projects. Ranks clients from most to least profitable, with per-project breakdowns nested within each client. Also shows projects with no client assignment. Useful for executives to understand which clients are most/least profitable and where to focus account management.

  • startDate (optional, string): Start date for the report period (YYYY-MM-DD). Defaults to first day of current month.
  • endDate (optional, string): End date for the report period (YYYY-MM-DD). Defaults to last day of current month.

Development

# Install dependencies
npm install

# Build the project
npm run build

# Watch mode (auto-rebuild on changes)
npm run dev

# Run the server (for testing)
npm start

Troubleshooting

"RUNN_API_KEY environment variable is required"

Make sure you've added the RUNN_API_KEY to your MCP server configuration's env section.

Server not connecting

  1. Verify the path to build/index.js is correct and absolute
  2. Ensure you've run npm run build after any changes
  3. Check that Node.js 20+ is installed: node --version

API errors

  1. Verify your Runn API key is valid
  2. Check that your Runn account has API access enabled
  3. Ensure you have permissions to access the requested data

License

MIT

Credits

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured