productive-mcp
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 ProjektSpeichert 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)
hoursrein,hoursraus — die API verwendet intern Minuten, aber Sie sehen diese nieStandardmäßig auf "mich" beschränkt —
list_time_entrieszeigt 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: |
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>" -UDer 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.shDies 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 |
| Alle aktiven Projekte auflisten (ID, Name, Nummer, Firma) |
| Projekte per Fuzzy-Suche nach Name und/oder Nummer finden |
| Services (abrechenbare Aktivitätstypen) eines Projekts auflisten |
| Einen Zeiteintrag erstellen |
| Zeiteinträge mit optionalen Datums-/Projekt-/Besitzer-Filtern auflisten |
| Stunden / Datum / Notiz / Service eines bestehenden Eintrags bearbeiten |
| Einen Zeiteintrag dauerhaft löschen |
| Sofortige Cache-Aktualisierung erzwingen (nach Erstellung neuer Projekte/Services) |
| 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 entriesEinträ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_hintweglassen — der Standard wird pro Projekt inpreferences.jsongespeichert.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 überproductive_refresh_cache.preferences.json—{ "default_services": { "<project_id>": "<service_id>" } }.
Keine der Dateien enthält jemals Anmeldedaten.
Reihenfolge der Anmeldedaten-Suche
Umgebungsvariable (
PRODUCTIVE_MCP_TOKEN/_ORG_ID/_PERSON_ID)macOS-Schlüsselbund (
security find-generic-password -s productive-mcp -a <account>)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 srcStarten Sie den Server direkt zum Debuggen:
.venv/bin/productive-mcp
# or
python -m productive_mcpEr 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 matchingFehlerbehebung
"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:
berwickgeek/productive-mcp — der funktionsreichste Allzweck-Server (Projekte, Aufgaben, Boards, Personen, Workflows). Node.js. Keine Zeiterfassung.
adamchrabaszcz/productive-time-mcp — begleitender Zeiterfassungs-Server für den obigen.
druellan/Productive-Simple-MCP — schreibgeschützter Python/FastMCP-Server, der TOON-Ausgabe für geringen Token-Verbrauch verwendet.
laurkee/productive-mcp (Codeberg) — fokussiert auf Ticketing.
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:
Anmeldedaten standardmäßig im macOS-Schlüsselbund, nicht in einer
.env— kein Risiko, dass ein Token ingit statuslandet.Fuzzy-Projekt-Matching mit Projektnummer-Boost — sagen Sie
"1099 Acme"oder einfach"Acme"; beides funktioniert.Speicher für Standardservices pro Projekt — nach dem ersten
productive_log_timefü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.
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