About productive-mcp
productive-mcp is an MCP server published by cameronfairbairn in the Developer Tools category: productive.io MCP server (patched fork).
Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.
Install
git clone https://github.com/cameronfairbairn/productive-mcpThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Tools (4)
productive_delete_time_entryPermanently delete a time entry
Parameters not published.
productive_list_time_entriesList time entries with date/project/owner filters
Parameters not published.
productive_log_timeCreate a time entry
Parameters not published.
productive_update_time_entryEdit hours / date / note / service on an existing entry
Parameters not published.
Ask AI
Ask AI about productive-mcp
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
productive-mcp
An MCP server for Productive.io — log time, inspect projects, manage entries, and get team reports from any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.) using plain English:
"log 2.5 hours on the Acme security review project"
"how many hours did Alice log this week?"
"give me my weekly briefing"
Built around the Productive.io JSON:API v2 with fuzzy project and person matching, a local disk cache, billing-cutoff-aware period resolution, and per-project default-service memory.
Features
- 14 tools covering projects, people, services, time entries, reports, and briefings
- Cross-platform credential storage — macOS Keychain, Windows Credential Manager (DPAPI/TPM-backed), Linux Secret Service, or environment variables
- Fuzzy matching for projects and people —
"Acme","1099 Acme","Alice", or"me"all resolve naturally - Billing-cutoff-aware period resolution —
"this_month"shifts based on your invoicing cycle - Remembers your default service per project so you don't have to specify it every time
- Local cache for projects, people, and services (1-hour TTL, manually refreshable)
- TOON output mode — optional token-optimised encoding for 30–60% fewer tokens
hoursin,hoursout — the API uses minutes internally, but you never see them- Scoped to "me" by default —
list_time_entriesonly shows your own entries unless you opt out
Requirements
- Python 3.11+
- A Productive.io account with API access enabled
- macOS, Windows, or Linux
Install
1. Clone and install
git clone https://github.com/cameronfairbairn/productive-mcp.git
cd productive-mcp
uv venv
uv pip install -e .
(or python -m venv .venv && .venv/bin/pip install -e . if you don't use uv)
2. Get your Productive credentials
You need three values:
| Value | Where to find it |
|---|---|
| API token | Productive → Settings → API integrations → Generate new token |
| Organization ID | The numeric segment in your Productive URL: app.productive.io/<ORG_ID>/… |
| Person ID | Your own user ID — open your profile in Productive; it's the numeric segment in the URL |
3. Store credentials
Option A — OS credential store (recommended)
Works on any platform via the keyring library:
python -c "import keyring; keyring.set_password('productive-mcp', 'token', '<token>')"
python -c "import keyring; keyring.set_password('productive-mcp', 'org_id', '<org_id>')"
python -c "import keyring; keyring.set_password('productive-mcp', 'person_id', '<person_id>')"
| Platform | Backend | Security |
|---|---|---|
| macOS | Keychain | Secure Enclave where available |
| Windows | Credential Manager (DPAPI) | TPM-backed on TPM 2.0 systems |
| Linux (desktop) | Secret Service (GNOME Keyring / KWallet) | Session-encrypted |
On macOS, the security CLI also works (keyring reads from the same Keychain):
security add-generic-password -s productive-mcp -a token -w "<token>" -U
security add-generic-password -s productive-mcp -a org_id -w "<org_id>" -U
security add-generic-password -s productive-mcp -a person_id -w "<person_id>" -U
Option B — environment variables (CI / headless / override)
export PRODUCTIVE_MCP_TOKEN="<token>"
export PRODUCTIVE_MCP_ORG_ID="<org_id>"
export PRODUCTIVE_MCP_PERSON_ID="<person_id>"
Environment variables take precedence over the credential store.
4. Register the server with your MCP client
Claude Code (~/.claude.json)
{
"mcpServers": {
"productive": {
"type": "stdio",
"command": "/path/to/productive-mcp/.venv/bin/productive-mcp",
"args": []
}
}
}
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"productive": {
"command": "/path/to/productive-mcp/.venv/bin/productive-mcp"
}
}
}
Restart the client after editing its config.
5. (Optional) Global install with the bundled deploy script
bash scripts/install.sh
This creates ~/.local/share/productive-mcp/ containing a fresh venv and a run.sh launcher. Point your MCP client at ~/.local/share/productive-mcp/run.sh instead. Re-running the script upgrades in place.
Tools
All tools are prefixed with productive_ so they namespace cleanly alongside other MCP servers.
Time tracking
| Tool | Purpose |
|---|---|
productive_log_time |
Create a time entry |
productive_list_time_entries |
List time entries with date/project/owner filters |
productive_update_time_entry |
Edit hours / date / note / service on an existing entry |
productive_delete_time_entry |
Permanently delete a time entry |
Reports and briefings
| Tool | Purpose |
|---|---|
productive_get_time_report |
Categorised hours summary (worked/client/internal/holidays) |
productive_get_employee_hours |
Hours summary for any team member by name |
productive_my_projects |
Projects you've logged time on recently |
productive_my_briefing |
Weekly summary with hours-by-project breakdown |
Projects, people, and services
| Tool | Purpose |
|---|---|
productive_list_projects |
List all active projects |
productive_find_project |
Fuzzy-search projects by name and/or number |
productive_find_person |
Fuzzy-search people by name or email |
productive_list_services |
List services (billable activity types) on a project |
Administration
| Tool | Purpose |
|---|---|
productive_refresh_cache |
Force an immediate cache refresh |
productive_set_default_service |
Override the remembered default service for a project |
Key tool details
productive_get_time_report
period : str? — "this_month", "last_month", "this_week", "last_week"
after : str? — ISO date; ignored if period set
before : str? — ISO date; ignored if period set
person : str? — Name, email, id, or "me" (default)
project : str? — Scope to a specific project
Returns totals_hours: {worked, client, internal, holidays}. When PRODUCTIVE_BILLING_CUTOFF_DAY is set, "this_month" shifts based on your billing cycle.
productive_my_briefing
period : str — Default "this_week"
Returns total hours, projects touched, hours-by-project breakdown, and recent entries. Designed for the Monday-morning "what am I working on?" question.
productive_get_employee_hours
person : str — Fuzzy name, email, or "me"
period : str? — Symbolic period (default: no filter)
after : str? — ISO date
before : str? — ISO date
Finds a person by fuzzy match, returns their hours for the period.
Configuration
Environment variables
| Variable | Default | Purpose |
|---|---|---|
PRODUCTIVE_MCP_TOKEN |
— | API token (overrides credential store) |
PRODUCTIVE_MCP_ORG_ID |
— | Organization ID (overrides credential store) |
PRODUCTIVE_MCP_PERSON_ID |
— | Person ID (overrides credential store) |
PRODUCTIVE_BILLING_CUTOFF_DAY |
unset | Day of month (1–31) when "this_month" flips to the current calendar month |
PRODUCTIVE_MCP_OUTPUT_FORMAT |
json |
Set to toon for Token-Optimized Object Notation (30–60% fewer tokens) |
Billing cutoff day
The PRODUCTIVE_BILLING_CUTOFF_DAY controls how symbolic periods resolve for invoicing workflows:
- Before cutoff day:
"this_month"= previous calendar month (you're still closing invoices) - From cutoff day onward:
"this_month"= current calendar month - Unset:
"this_month"always means the current calendar month
Example: with PRODUCTIVE_BILLING_CUTOFF_DAY=10, on April 5th, "this_month" resolves to March 1–31.
Security & permissions
Credential storage
API tokens are never written to disk by this project. They live in the OS credential store (Keychain / Credential Manager / Secret Service) or in environment variables.
Productive's permission model
Each team member generates their own API token via Productive → Settings → API integrations (docs). Tokens inherit the generating user's permissions:
"API tokens inherit the same access restrictions as the user they are associated with. If a user does not have permission to access certain features or data within Productive, these limitations will also apply to their API token."
Tokens also have a read-only vs read/write scope chosen at creation time.
What this means for team deployments:
- A "Member"-role user's token cannot query other members' time entries — Productive returns 403.
- The real access boundary is the Productive role (Settings → People → Role), not MCP-side configuration.
- Tools like
productive_get_employee_hourswill simply return empty/error for users whose Productive role doesn't grant team visibility.
For more on roles: User Permissions Overview | Productive API docs
How it works
Architecture
┌─────────────────────┐ stdio ┌──────────────────────┐ HTTPS ┌─────────────────┐
│ MCP client │ ─────────► │ productive-mcp │ ────────► │ Productive.io │
│ (Claude Code etc.) │ │ (FastMCP server) │ │ JSON:API v2 │
└─────────────────────┘ └──────────┬───────────┘ └─────────────────┘
│
▼
~/.config/productive-mcp/
├── cache.json (projects, people, services)
└── preferences.json (per-project default service)
Credential lookup order
- Environment variable (
PRODUCTIVE_MCP_TOKEN/_ORG_ID/_PERSON_ID) - OS credential store via
keyring(Keychain / Credential Manager / Secret Service) - Error with a helpful message pointing at both options
Local state
Two files under ~/.config/productive-mcp/, both 0600:
cache.json— projects, people (active only), per-project services. 1-hour TTL.preferences.json—{ "default_services": { "<project_id>": "<service_id>" } }.
Neither file ever contains credentials.
Development
uv pip install -e ".[dev]"
# unit tests (no network required)
pytest
# integration tests (hit the real Productive API — requires credentials)
pytest -m integration
# lint + type check
ruff check .
mypy src
Project layout
src/productive_mcp/
├── __main__.py Entrypoint (python -m productive_mcp)
├── server.py FastMCP tool definitions (14 tools)
├── client.py Async Productive.io API client + fuzzy matcher
├── auth.py Cross-platform credential loader (keyring + env)
├── storage.py Local cache + preferences persistence
├── periods.py Billing-cutoff-aware period resolution
└── reporting.py Time entry categorisation for reports
scripts/
└── install.sh One-shot deploy script for the global launcher
tests/
├── test_client.py Fuzzy matching + trim functions
├── test_periods.py Period resolution + billing cutoff
├── test_reporting.py Entry categorisation
└── test_formatter.py TOON output encoding
Troubleshooting
"Credential store lookup failed"
The keyring backend isn't configured or accessible. Check: python -c "import keyring; print(keyring.get_keyring())". On headless Linux, use environment variables instead.
"No credential found for service=productive-mcp"
Credentials haven't been stored yet. Run the keyring.set_password(...) commands from the install section.
"No project matches 'X'"
Cache may be stale. Call productive_refresh_cache and retry.
"Ambiguous project query" Two projects scored nearly identically. Be more specific — add the project number.
"Project has multiple services; pass service_hint"
Either pass service_hint="…" (it'll be remembered), or call productive_set_default_service once upfront.
Alternatives
Several other Productive.io MCP servers exist:
- berwickgeek/productive-mcp — the most feature-complete general-purpose server (projects, tasks, boards, people, workflows). Node.js. No time tracking.
- adamchrabaszcz/productive-time-mcp — companion time-tracking server for the above.
- druellan/Productive-Simple-MCP — read-only Python/FastMCP server using TOON output for low token usage.
- laurkee/productive-mcp (Codeberg) — ticketing-focused.
Why pick this one?
- Cross-platform credential store — not a
.envfile. macOS Keychain, Windows Credential Manager (TPM-backed), Linux Secret Service. - Fuzzy matching for projects and people — say
"Alice"or"1099 Acme"instead of looking up IDs. - Per-project default service memory — log time without specifying the service after the first call.
- Billing-cutoff-aware reports —
"this_month"means what your invoicing cycle says it means. - TOON output mode — 30–60% fewer tokens for long sessions.
License
MIT — see LICENSE.
Contributing
Issues and PRs welcome. Please include tests for new behaviour.
Not affiliated with Productive.io. "Productive" is a trademark of its respective owners.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.