Skip to content
Conduit

mcp server

mcp-cor

MCP server for Project COR — 61 tools across 11 modules: projects, tasks, clients, contracts, time tracking, team management, messaging, and more

fxckcode/mcp-corcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "mcp-cor": {
      "command": "uvx",
      "args": [
        "cor-mcp-server"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 27, 2026

⬡ COR MCP Server

61 MCP tools for Project COR — the project management platform for creative and professional teams.

CI Python License Ruff uv MCP Docker Tests

Exposes the complete COR REST API surface as MCP tools — usable from any MCP-compatible client: Hermes Agent, Claude Desktop, Cursor, Claude Code, Cline, Windsurf, and more.


✨ Features

  • 61 MCP tools — full CRUD for all COR entities across 11 modules
  • Dual authentication — pick what suits you:
    • User Credentials (email + password) — quick personal use
    • Client Credentials (API key + client secret) — server-to-server
  • Async everywhere — httpx + asyncio, non-blocking I/O
  • Dual transport — stdio (default for agents) and sse (HTTP for remote access)
  • OAuth token auto-refresh — never worry about expiry mid-session
  • Docker support — one-command deployment
  • Hermes Agent skill included — see skills/cor-mcp-setup/
  • 24 passing tests — fully mocked, no live credentials required

Entity Coverage

ModuleToolsCovers
Projects14CRUD, collaborators, costs, labels, ratecards, templates, profitability
Tasks10Search, CRUD, collaborators, labels
Team & Users8Profile, users, teams, working time
Clients6CRUD, fees
Contracts5CRUD, positions
Time Tracking5Log, search, status, accept suggested
Messaging4Project + task messages
Allocations3CRUD
Ratecards3CRUD
Products2CRUD
Labels1By entity type

🚀 Quick Start

Prerequisites

  • Python 3.11+
  • uv (recommended) or pip
  • COR account with credentials

Install & Run

# Clone
git clone https://github.com/fxckcode/mcp-cor.git
cd mcp-cor

# Install with uv (recommended)
uv sync

# Or with pip
pip install -e .

Configure

cp .env.example .env

Then choose one auth mode in .env:

Mode A — Email + Password (recommended for personal use)

COR_EMAIL=your.email@company.com
COR_PASSWORD=your_password
COR_API_URL=https://api.projectcor.com/v1

Mode B — API Key + Client Secret (for server-to-server)

COR_API_KEY=your_api_key
COR_CLIENT_SECRET=your_client_secret
COR_API_URL=https://api.projectcor.com/v1

The server auto-detects which mode you configured. Email/password takes priority when both are set.

Run

# stdio transport (default — for MCP agents)
uv run cor-mcp-server

# SSE/HTTP transport (for remote access)
uv run cor-mcp-server --transport sse --host 0.0.0.0 --port 8000

# Verbose logging
uv run cor-mcp-server --verbose

🔐 Authentication

Two modes supported. The server auto-detects which to use.

User Credentials (Mode A)

POST https://api.projectcor.com/v1/auth/login
Content-Type: application/x-www-form-urlencoded

email=user@corp.com&password=*****

Returns JWT access_token + refresh_token. Auto-refresh built in.

Client Credentials (Mode B)

POST https://api.projectcor.com/v1/oauth/token?grant_type=client_credentials
Authorization: Basic base64(api_key:client_secret)

Returns access_token (1-hour TTL). Cached and auto-refreshed with a 60-second safety margin.


🔌 Connecting from MCP Clients

Add to ~/.hermes/config.yaml:

mcp_servers:
  cor:
    command: "uv"
    args: ["run", "--directory", "/path/to/cor-mcp-server", "python", "-m", "cor_mcp_server"]
    env:
      COR_EMAIL: "your.email@company.com"
      COR_PASSWORD: "your_password"
      COR_API_URL: "https://api.projectcor.com/v1"
    timeout: 180
    connect_timeout: 60

Then restart or run /reload-mcp.

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "cor": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/cor-mcp-server", "python", "-m", "cor_mcp_server"],
      "env": {
        "COR_EMAIL": "your.email@company.com",
        "COR_PASSWORD": "your_password",
        "COR_API_URL": "https://api.projectcor.com/v1"
      }
    }
  }
}

In MCP Servers settings, add:

  • Name: COR
  • Type: command
  • Command: uv run --directory /path/to/cor-mcp-server python -m cor_mcp_server
  • Environment variables: COR_EMAIL, COR_PASSWORD, COR_API_URL
env COR_EMAIL=your@email.com COR_PASSWORD=your_pass COR_API_URL=https://api.projectcor.com/v1 \
  npx @anthropic/claude-code --mcp "uv run --directory /path/to/cor-mcp-server python -m cor_mcp_server"

Docker

docker build -t cor-mcp-server .

# stdio mode
docker run -i --rm \
  -e COR_EMAIL=your@email.com \
  -e COR_PASSWORD=your_password \
  -e COR_API_URL=https://api.projectcor.com/v1 \
  cor-mcp-server

# SSE mode
docker run -i --rm \
  -p 8000:8000 \
  -e COR_EMAIL=your@email.com \
  -e COR_PASSWORD=your_password \
  -e COR_API_URL=https://api.projectcor.com/v1 \
  cor-mcp-server --transport sse

🛠 Available Tools

All tool names are prefixed with cor_ for clean discoverability.

Projects (14 tools)

ToolDescription
cor_list_projectsList projects with filters (clientId, status, health, dates)
cor_get_projectGet project details
cor_create_projectCreate a new project
cor_update_projectUpdate a project (partial)
cor_delete_projectDelete a project
cor_get_project_collaboratorsGet project collaborators
cor_add_project_collaboratorAdd collaborator to project
cor_remove_project_collaboratorRemove collaborator from project
cor_get_project_costsGet project costs/estimates
cor_add_project_costAdd cost to project
cor_get_project_labelsGet project labels
cor_get_project_ratecardGet project ratecard
cor_get_project_templatesGet available project templates
cor_get_project_profitabilityGet project profitability

Tasks (10 tools)

ToolDescription
cor_search_tasksSearch tasks with filters (projectId, clientId, status, text, dates, labels)
cor_get_my_pending_tasksGet my pending tasks
cor_get_taskGet task details
cor_create_taskCreate a new task
cor_update_taskUpdate a task
cor_delete_taskDelete a task
cor_get_task_collaboratorsGet task collaborators
cor_sync_task_collaboratorsSync (replace) task collaborators
cor_add_task_labelAdd label to task
cor_remove_task_labelRemove label from task

Team & Users (8 tools)

ToolDescription
cor_get_my_profileGet current user profile
cor_list_usersList users with filters
cor_get_userGet user details
cor_list_teamsList teams
cor_create_teamCreate a new team
cor_add_team_usersAdd users to a team
cor_remove_team_usersRemove users from a team
cor_get_working_timeGet working time for users

Clients (6 tools)

ToolDescription
cor_list_clientsList clients
cor_get_clientGet client details
cor_create_clientCreate a new client
cor_update_clientUpdate a client
cor_delete_clientDelete a client
cor_get_client_feesGet client fees

Contracts (5 tools)

ToolDescription
cor_list_contractsList contracts
cor_get_contractGet contract details
cor_create_contractCreate a new contract
cor_get_contract_positionsGet contract positions
cor_create_contract_positionCreate position in contract

Time Tracking (5 tools)

ToolDescription
cor_log_hoursLog hours against a task
cor_search_time_entriesSearch time entries with filters
cor_get_hours_by_dateGet time entries by date
cor_change_hours_statusChange time entry status
cor_accept_suggested_hoursAccept suggested hours

Messaging (4 tools)

ToolDescription
cor_get_task_messagesGet messages on a task
cor_post_task_messagePost a message on a task
cor_get_project_messagesGet messages on a project
cor_post_project_messagePost a message on a project

Ratecards (3 tools)

ToolDescription
cor_list_ratecardsList ratecards
cor_get_ratecardGet ratecard details
cor_create_ratecardCreate a new ratecard

Allocations (3 tools)

ToolDescription
cor_get_allocations_by_projectGet allocations for a project
cor_save_allocationCreate/update a resource allocation
cor_delete_allocationDelete a resource allocation

Products (2 tools)

ToolDescription
cor_list_productsList products
cor_create_productCreate a new product

Labels (1 tool)

ToolDescription
cor_get_labelsGet labels (filter by entity type: project, task, user)

🏗 Architecture

┌──────────────────────┐     ┌───────────────────────────┐     ┌──────────────────────┐
│  MCP Client          │     │  COR MCP Server           │     │  COR REST API        │
│  (Hermes / Claude /  │◄───►│  (FastMCP + httpx)        │────►│  api.projectcor.com  │
│   Cursor / etc.)     │     │                            │     │  /v1                 │
└──────────────────────┘     ├───────────────────────────┤     └──────────────────────┘
                             │  Auth auto-detection       │
                             │  • Email/Password (prio)   │
                             │  • API Key + Secret        │
                             └───────────────────────────┘

🧑‍💻 Development

# Install dev deps
uv sync --dev

# Run tests (24 passing tests — no live API needed, uses mocking)
uv run pytest tests/ -v

# Test server startup
uv run cor-mcp-server --help

# Lint
uv run ruff check .

Adding New Tools

To add a new tool to the COR MCP Server:

  1. Create or edit a tool module in cor_mcp_server/tools/ (e.g., reports.py).

  2. Write an async function with the cor_ prefix pattern:

    from ..context import get_client
    
    async def cor_list_reports(page: int = 1, per_page: int = 20) -> str:
        """List reports.
    
        Args:
            page: Page number (default: 1)
            per_page: Results per page (default: 20)
        """
        client = get_client()
        data = await client.get("/reports", page=page, per_page=per_page)
        import json
        return json.dumps(data, indent=2, ensure_ascii=False, default=str)
    
  3. Register the tool in cor_mcp_server/server.py:

    from .tools import reports as _reports
    
    mcp.tool(
        name="cor_list_reports",
        description=_reports.cor_list_reports.__doc__,
    )(_reports.cor_list_reports)
    
  4. Add tests in tests/test_tools.py following the existing patterns (import assertion + tool count update).

  5. Update the tool count in tests/test_tools.py if needed.

The get_client() function provides a fully-authenticated CORClient instance with automatic Bearer token handling. All tools return JSON strings for consistent serialization.

Test Structure

Tests are in tests/test_tools.py and cover:

  • TestTokenStore — Thread-safe token caching, expiry, and refresh logic
  • TestCORClient — HTTP methods (GET, POST, PUT, DELETE), pagination, auth headers
  • TestToolFunctions — Import verification for all 61 tool functions across 11 modules
  • TestServerCreation — Server factory creates a valid FastMCP instance

All tests use mocking — no live COR credentials required to run them.


📁 Project Structure

cor-mcp-server/
├── pyproject.toml              # Dependencies and metadata
├── README.md                   # This file
├── LICENSE                     # MIT license
├── .env.example                # Env var template (both auth modes)
├── Dockerfile                  # Container deployment
├── skills/                     # Hermes Agent skills
│   └── cor-mcp-setup/
│       └── SKILL.md            # Skill: setup + usage guide
├── handoff-personal-hermes.md  # Self-contained instructions for personal Hermes
├── cor_mcp_server/
│   ├── __init__.py             # Package init
│   ├── __main__.py             # CLI entry point
│   ├── server.py               # FastMCP server + tool registration (all 61 tools)
│   ├── auth.py                 # OAuth 2.0 dual-mode (user creds + client creds)
│   ├── client.py               # COR API HTTP client (httpx, async)
│   ├── context.py              # Shared client context / dependency injection
│   ├── models.py               # Pydantic models (14 entity types)
│   └── tools/
│       ├── __init__.py
│       ├── projects.py         # 14 tools
│       ├── tasks.py            # 10 tools
│       ├── time_tracking.py    # 5 tools
│       ├── clients.py          # 6 tools
│       ├── contracts.py        # 5 tools
│       ├── messaging.py        # 4 tools
│       ├── team.py             # 8 tools
│       ├── labels.py           # 1 tool
│       ├── ratecards.py        # 3 tools
│       ├── allocations.py      # 3 tools
│       └── products.py         # 2 tools
├── tests/
│   ├── __init__.py
│   └── test_tools.py           # 24 tests for auth, client, and tools
├── .github/                    # GitHub community files
│   ├── dependabot.yml          # Dependency auto-updates
│   ├── ISSUE_TEMPLATE/         # Bug report + feature request templates
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/              # CI + Release pipelines
├── .gitignore
├── .gitattributes
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
└── SECURITY.md

📄 License

MIT

👤 Author

Alejandro Duran — Omnicom Media Group

↑↓ navigate openesc close