Skip to main content
Glama

productive-mcp

Ein MCP-Server für Productive.io — erfasse Zeit, prüfe Projekte und verwalte Zeiteinträge von jedem MCP-kompatiblen Client (Claude Code, Claude Desktop, Cursor, etc.) in einfachem Englisch:

"log 2.5 hours on the Acme security review project"

"show me my time entries for last week"

"delete time entry 123456"

Aufgebaut auf der Productive.io JSON:API v2 mit Fuzzy-Projekt-Matching, einem lokalen Festplatten-Cache und einem Speicher für Standardservices pro Projekt, sodass der Standardfall — das Erfassen von Zeit für ein Projekt, das Sie regelmäßig nutzen — nur einen einzigen Satz erfordert.


Funktionen

  • 9 Tools für Projekte, Services und Zeiteinträge (auflisten / erstellen / aktualisieren / löschen)

  • Fuzzy-Projekt-Matching"Acme", "1099 Acme" oder "1099" führen alle zum selben Projekt

  • Speichert Ihren Standardservice pro Projekt, sodass Sie ihn nicht jedes Mal angeben müssen

  • Lokaler Cache für Projekte und Services (1 Stunde TTL, manuell aktualisierbar)

  • Sicherheit der Anmeldedaten: API-Token wird standardmäßig aus dem macOS-Schlüsselbund gelesen (Umgebungsvariablen werden als Fallback für Linux/WSL oder Headless-Nutzung unterstützt)

  • hours rein, hours raus — die API verwendet intern Minuten, aber Sie sehen diese nie

  • Standardmäßig auf "mich" beschränktlist_time_entries zeigt nur Ihre eigenen Einträge an, sofern Sie dies nicht ändern

Anforderungen

  • Python 3.11+

  • Ein Productive.io-Konto mit aktiviertem API-Zugriff

  • macOS (empfohlen, für Schlüsselbund-Integration) — Linux / WSL funktionieren über Umgebungsvariablen

Installation

1. Klonen und installieren

git clone https://github.com/<you>/productive-mcp.git
cd productive-mcp
uv venv
uv pip install -e .

(oder python -m venv .venv && .venv/bin/pip install -e ., falls Sie uv nicht verwenden)

2. Productive-Anmeldedaten abrufen

Sie benötigen drei Werte:

Wert

Wo zu finden

API-Token

Productive → Einstellungen → API-Integrationen → Neuen Token generieren

Organisations-ID

Der numerische Teil in Ihrer Productive-URL: app.productive.io/<ORG_ID>/…

Personen-ID

Ihre eigene Benutzer-ID — öffnen Sie Ihr Profil in Productive; es ist der numerische Teil in der URL

3. Anmeldedaten speichern

Option A — macOS-Schlüsselbund (empfohlen auf macOS)

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

Der Server sucht diese beim Start über die security CLI. Sie werden von diesem Projekt niemals auf die Festplatte geschrieben.

Option B — Umgebungsvariablen (Linux / WSL / CI / Überschreiben)

export PRODUCTIVE_MCP_TOKEN="<token>"
export PRODUCTIVE_MCP_ORG_ID="<org_id>"
export PRODUCTIVE_MCP_PERSON_ID="<person_id>"

Umgebungsvariablen haben Vorrang vor Schlüsselbund-Abfragen und sind daher auch der einfachste Weg, um alternative Konten vorübergehend zu testen.

4. Server bei Ihrem MCP-Client registrieren

Claude Code (~/.claude.json)

Unter mcpServers hinzufügen:

{
  "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"
    }
  }
}

Starten Sie den Client nach dem Bearbeiten der Konfiguration neu.

5. (Optional) Globale Installation mit dem mitgelieferten Deploy-Skript

Wenn Sie eine gemeinsame Installation wünschen, die nicht an ein Klon-Verzeichnis gebunden ist:

bash scripts/install.sh

Dies erstellt ~/.local/share/productive-mcp/ mit einem frischen venv und einem run.sh-Launcher. Verweisen Sie Ihren MCP-Client auf ~/.local/share/productive-mcp/run.sh anstelle der venv-Binärdatei. Ein erneutes Ausführen des Skripts aktualisiert das venv an Ort und Stelle.


Tools

Alle Tools haben das Präfix productive_, damit sie sauber neben anderen MCP-Servern in ihren eigenen Namespace passen.

Tool

Zweck

productive_list_projects

Alle aktiven Projekte auflisten (ID, Name, Nummer, Firma)

productive_find_project

Projekte per Fuzzy-Suche nach Name und/oder Nummer finden

productive_list_services

Services (abrechenbare Aktivitätstypen) eines Projekts auflisten

productive_log_time

Einen Zeiteintrag erstellen

productive_list_time_entries

Zeiteinträge mit optionalen Datums-/Projekt-/Besitzer-Filtern auflisten

productive_update_time_entry

Stunden / Datum / Notiz / Service eines bestehenden Eintrags bearbeiten

productive_delete_time_entry

Einen Zeiteintrag dauerhaft löschen

productive_refresh_cache

Sofortige Cache-Aktualisierung erzwingen (nach Erstellung neuer Projekte/Services)

productive_set_default_service

Den gespeicherten Standardservice für ein Projekt überschreiben

Tool-Referenz

productive_log_time

project       : str   — Project name (fuzzy) or numeric id. e.g. "1099 Acme", "42"
hours         : float — Hours worked (e.g. 2.5). Converted to minutes internally.
note          : str?  — Description of the work
date          : str?  — ISO date (YYYY-MM-DD). Defaults to today.
service_hint  : str?  — Service name or id (only needed when the project has
                        multiple services and no remembered default)

Bei Erfolg wird der erstellte Eintrag sowie eine service_resolution-Notiz zurückgegeben, die erklärt, wie der Service ausgewählt wurde ("auto-selected only service" / "used remembered default" / "matched by name" etc.).

Wenn das Projekt nur einen Service hat, wird dieser automatisch ausgewählt und für das nächste Mal als Standard gespeichert. Wenn es mehrere gibt, gibt der Server einen umsetzbaren Fehler mit einer Liste der Optionen zurück.

productive_find_project

query : str — Partial name or number (e.g. "Acme", "1099 acme", "1099")
limit : int — Max matches (default 5)

Gibt bewertete Treffer zurück, sortiert nach bester Übereinstimmung. Der Fuzzy-Scorer kombiniert Teilstring-Matching, einen Sequence-Matcher als Fallback für Tippfehler und einen Boost, wenn die Abfrage eine exakte Projektnummer enthält.

productive_list_time_entries

after     : str?  — Include entries on/after this ISO date
before    : str?  — Include entries on/before this ISO date
project   : str?  — Filter by project name or id
mine_only : bool  — Default True; set False to see the whole team's entries

Einträge werden von neu nach alt zurückgegeben, wobei die Summen in total_hours zusammengefasst sind.


Funktionsweise

Architektur

┌─────────────────────┐   stdio    ┌──────────────────────┐   HTTPS   ┌─────────────────┐
│  MCP client         │ ─────────► │  productive-mcp      │ ────────► │  Productive.io  │
│  (Claude Code etc.) │            │  (FastMCP server)    │           │  JSON:API v2    │
└─────────────────────┘            └──────────┬───────────┘           └─────────────────┘
                                              │
                                              ▼
                                    ~/.config/productive-mcp/
                                    ├── cache.json        (projects, services; 1h TTL)
                                    └── preferences.json  (per-project default service)

Wichtige Designentscheidungen

  • Services sind Deals zugeordnet, die zu Projekten gehören. Das Datenmodell von Productive macht dies sichtbar; das MCP durchläuft die Hierarchie transparent, sodass "services on project X" einfach funktioniert.

  • Stunden sind die einzige benutzerseitige Einheit. Die API speichert Zeit in Minuten; diese Ebene konvertiert an der Schnittstelle.

  • Gespeicherte Standards reduzieren Rückfragen. Nachdem Sie einmal Zeit für ein Projekt erfasst haben, können nachfolgende Aufrufe service_hint weglassen — der Standard wird pro Projekt in preferences.json gespeichert.

  • Fuzzy-Matching statt exaktem Matching. Die meisten Zeiterfassungsanfragen lauten etwa "diese Sicherheitsüberprüfung für Acme", nicht "Projekt #1099". Der Resolver bevorzugt natürliche Sprache.

  • Standardmäßig nur "meine". Sie erfassen fast immer Zeit für sich selbst; die eine Person, die teamweite Sichtbarkeit benötigt, kann mine_only=False übergeben.

Lokaler Status

Zwei Dateien befinden sich unter ~/.config/productive-mcp/, beide mit 0600-Berechtigungen erstellt:

  • cache.json — gekürzte Projektliste und Service-Lookup pro Projekt. Aktualisiert sich automatisch bei Ablauf der TTL oder über productive_refresh_cache.

  • preferences.json{ "default_services": { "<project_id>": "<service_id>" } }.

Keine der Dateien enthält jemals Anmeldedaten.

Reihenfolge der Anmeldedaten-Suche

  1. Umgebungsvariable (PRODUCTIVE_MCP_TOKEN / _ORG_ID / _PERSON_ID)

  2. macOS-Schlüsselbund (security find-generic-password -s productive-mcp -a <account>)

  3. Fehler — der Server verweigert den Start mit einer hilfreichen Meldung, die auf beide Optionen hinweist.


Entwicklung

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

Starten Sie den Server direkt zum Debuggen:

.venv/bin/productive-mcp
# or
python -m productive_mcp

Er kommuniziert über stdio JSON-RPC. Um ihn manuell zu testen, benötigen Sie einen MCP-Client oder mcp-inspector.

Projektstruktur

src/productive_mcp/
├── __main__.py      Entrypoint (`python -m productive_mcp`)
├── server.py        FastMCP tool definitions
├── client.py        Async Productive.io API client + fuzzy matcher
├── auth.py          Keychain / env-var credential loader
└── storage.py       Local cache + preferences persistence
scripts/
└── install.sh       One-shot deploy script for the global launcher
tests/
└── test_client.py   Unit tests for trimming + fuzzy matching

Fehlerbehebung

"Keychain lookup failed" Entweder existiert das Element noch nicht (führen Sie die security add-generic-password-Befehle in Schritt 3 erneut aus) oder Sie verwenden kein macOS. Verwenden Sie stattdessen Umgebungsvariablen.

"No project matches 'X'" Ihr Cache ist möglicherweise veraltet, wenn das Projekt kürzlich erstellt wurde. Rufen Sie productive_refresh_cache auf und versuchen Sie es erneut.

"Ambiguous project query" Zwei Projekte wurden fast identisch bewertet. Seien Sie spezifischer — fügen Sie die Projektnummer oder den Firmennamen hinzu.

"Project has multiple services; pass service_hint" Für das Projekt wurde noch kein Standard festgelegt. Übergeben Sie entweder service_hint="…" bei diesem Aufruf (es wird gespeichert) oder rufen Sie einmalig productive_set_default_service auf.

Der Server startet, aber der Client meldet "no tools" Stellen Sie sicher, dass Ihr MCP-Client auf die productive-mcp-Binärdatei des venv (oder den run.sh-Launcher) verweist und nicht auf eine Quelldatei. FastMCP kündigt Tools beim Handshake an — wenn der Prozess mcp nicht importieren kann, erscheinen keine Tools.


Sicherheitshinweise

  • API-Token werden von diesem Projekt niemals auf die Festplatte geschrieben. Sie befinden sich nur im Schlüsselbund oder in Umgebungsvariablen.

  • Die Cache- und Einstellungsdateien werden mit 0600-Berechtigungen erstellt und enthalten keine Anmeldedaten.

  • Das Productive-API-Token gewährt denselben Zugriff, den Ihr Benutzer hat. Behandeln Sie es entsprechend. Rotieren Sie es über Productive → Einstellungen → API-Integrationen, falls Sie eine Offenlegung vermuten.

Alternativen

Es existieren mehrere andere Productive.io-MCP-Server — es lohnt sich, diese vor der Entscheidung zu prüfen:

Warum diesen wählen? Dieser Server ist eng auf den Workflow "Zeit erfassen und Einträge verwalten" fokussiert, und die UX basiert auf drei bewussten Entscheidungen:

  1. Anmeldedaten standardmäßig im macOS-Schlüsselbund, nicht in einer .env — kein Risiko, dass ein Token in git status landet.

  2. Fuzzy-Projekt-Matching mit Projektnummer-Boost — sagen Sie "1099 Acme" oder einfach "Acme"; beides funktioniert.

  3. Speicher für Standardservices pro Projekt — nach dem ersten productive_log_time für ein Projekt müssen nachfolgende Aufrufe keinen Service mehr angeben.

Wenn Sie primär Aufgaben/Boards/Workflows statt Zeiterfassung benötigen, verwenden Sie stattdessen berwickgeek/productive-mcp — oder führen Sie beide nebeneinander aus (sie verwenden unterschiedliche Tool-Präfixe).

Lizenz

MIT — siehe LICENSE.

Mitwirken

Issues und PRs sind willkommen. Dies ist ein kleines Projekt; bitte halten Sie Änderungen fokussiert und fügen Sie Tests für jedes neue Verhalten in client.py hinzu.


Nicht mit Productive.io verbunden. "Productive" ist eine Marke der jeweiligen Eigentümer.

Install Server
A
security – no known vulnerabilities
A
license - permissive license
A
quality - A tier

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cameronfairbairn/productive-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server