Ein MCP-Server, der auf Customer-Success-Teams ausgerichtet ist, die HubSpot verwenden. Gibt Kontakte, Unternehmen, Tickets und Deals als Claude-Tools frei, mit CS-spezifischen Helfern für Renewal-Datum-Abfragen, Ticket-Alterung und Health-Score-Reads. Der CSM fragt „Was ist diesen Monat gefährdet” — Claude ruft die tatsächlichen Daten ab.
Was Sie benötigen
HubSpot Sales Hub Pro oder höher mit Service Hub für Tickets
Ein HubSpot-Private-App-Token mit Read-Scopes für Kontakte, Unternehmen, Deals und Tickets
Claude Desktop oder Claude Code als MCP-Client
Eine Health-Score-Feld-Konvention, die mit Ihrer CS-Leitung abgestimmt ist
Setup
Server ausführen. Die Referenzimplementierung ist Python im FastAPI-Stil. Klonen, installieren, HUBSPOT_TOKEN und HUBSPOT_PORTAL_ID setzen. Der Server startet auf stdio für lokales Claude Desktop oder HTTP für gehostete Clients.
Helfer-Tools konfigurieren. Drei CS-spezifische Helfer werden standardmäßig mitgeliefert: at_risk_renewals, aging_tickets, accounts_needing_qbr. Jeder mappt auf eine parametrisierte HubSpot-Abfrage. Bearbeiten Sie die Abfragevorlagen entsprechend Ihren Feldern.
Zum MCP-Client-Config hinzufügen. Claude Desktop auf den Server verweisen. Beim Start sollten Sie rund zwölf registrierte Tools sehen.
Das Health-Score-Feld setzen. Die meisten Teams verwenden eine benutzerdefinierte Zahleneigenschaft. Übergeben Sie deren internen Namen an den Server, damit die Helfer darauf filtern können.
„Zeige mir gefährdete Renewals in den nächsten neunzig Tagen” ausführen. Die Ausgabe gegen dieselbe Abfrage in HubSpots UI auf Plausibilität prüfen.
Wie es funktioniert
Der Server ist bewusst read-mostly. CS-Workflows gehen darum zu wissen, was passiert, nicht darum, Datensätze in großem Umfang zu mutieren. Die Standard-Tool-Oberfläche umfasst Objekt-Reads, Assoziations-Traversals (Kontakt zu Unternehmen zu Deals zu Tickets) und die drei CS-spezifischen Helfer.
Writes sind auf Ticket-Erstellung und Notizen beschränkt. Keine Deal-Stadiumwechsel, keine Kontakt-Merges, keine Property-Updates für Unternehmen. Das Prinzip: Claude kann fragen, zusammenfassen und dokumentieren, aber der CSM treibt weiterhin die tatsächlichen kundenseitigen Änderungen an.
Fallstricke
Health-Score-Feld-Drift. Teams ändern die Formel jedes Quartal. Der Server cached nichts; Abfragen treffen die Live-Property. Aktualisieren Sie die Helfer-Dokumentation, wenn sich die Formel ändert, damit Prompts korrekt bleiben.
Ticket-Volumen. Aging-Tickets-Abfragen können auf stark genutzten Portalen Tausende von Zeilen zurückgeben. Der Helfer paginiert und deckt standardmäßig bei fünfhundert ab. Für Ihr Volumen anpassen.
Cross-Object-Joins. HubSpots Assoziations-API ist langsamer als direkte Abfragen. Der Server bündelt Assoziationen, aber ein Deal-zu-Tickets-Traversal über tausend Deals dauert Minuten, nicht Sekunden.
Berechtigungen. Private-App-Tokens umgehen Benutzerebenen-Berechtigungen. Jeder mit Zugriff auf den MCP-Client sieht alle Daten. Dokumentieren Sie dies klar mit Ihrem Sicherheitsteam.
# mcp-server-hubspot-cs
An MCP server tuned for customer success teams using HubSpot. Exposes contacts, companies, tickets, and deals as Claude tools, plus three CS-specific helpers: `at_risk_renewals`, `aging_tickets`, `accounts_needing_qbr`.
> **STATUS: scaffold — not runtime-tested.** The code below is structurally
> complete and follows the official `mcp` Python SDK conventions, but it
> has not been executed against a live HubSpot portal. Treat it as a
> starting point you adapt to your portal's field conventions, not as a
> deployable binary. Health-score field names, custom property paths, and
> association labels vary by portal.
## What it exposes
### Object-read tools (read-only)
- `get_contact(contact_id)` — full contact properties
- `get_company(company_id)` — full company properties + associated contacts
- `get_deal(deal_id)` — full deal properties + associated contacts/company
- `get_ticket(ticket_id)` — full ticket properties + associated company
### Search tools (read-only)
- `search_contacts(query, limit?)`
- `search_companies(query, limit?)`
- `search_deals(filters, limit?)`
- `search_tickets(filters, limit?)`
### CS-specific helpers (read-only)
- `at_risk_renewals(window_days=90)` — deals in renewal stages closing in the window, filtered by configured health-score threshold
- `aging_tickets(min_age_hours=48, limit=500)` — open tickets older than the threshold, grouped by company
- `accounts_needing_qbr(months_since_last=3)` — companies with no recorded QBR activity in the window
### Light-write tools (CSM-driven)
- `create_ticket(subject, body, company_id?)` — open a new ticket
- `add_note(object_type, object_id, body)` — append a note to a record
The server **does not** expose deal-stage changes, contact merges, or company property updates. The principle: Claude can ask, summarize, and document; the CSM drives every customer-facing change.
## Setup
### 1. Install
```bash
git clone <wherever you put this>
cd mcp-server-hubspot-cs
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -e .
```
### 2. Create a HubSpot Private App token
In HubSpot: Settings → Integrations → Private Apps → Create. Grant these scopes:
- `crm.objects.contacts.read`
- `crm.objects.companies.read`
- `crm.objects.deals.read`
- `tickets` (read)
- `crm.objects.contacts.write` (only for `add_note`)
- `tickets` (write — only for `create_ticket`)
Copy the access token.
### 3. Configure environment
```bash
export HUBSPOT_TOKEN="pat-na1-..."
export HUBSPOT_PORTAL_ID="12345678"
export HUBSPOT_HEALTH_SCORE_PROPERTY="health_score" # your custom field
export HUBSPOT_RENEWAL_STAGE_IDS="appointmentscheduled,qualifiedtobuy"
export HUBSPOT_RENEWAL_HEALTH_THRESHOLD="60" # below = at risk
```
The renewal stage IDs are pipeline-specific. Look them up in HubSpot → Settings → Pipelines.
### 4. Register with Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"hubspot-cs": {
"command": "python",
"args": ["-m", "hubspot_cs_mcp.server"],
"env": {
"HUBSPOT_TOKEN": "pat-na1-...",
"HUBSPOT_PORTAL_ID": "12345678",
"HUBSPOT_HEALTH_SCORE_PROPERTY": "health_score",
"HUBSPOT_RENEWAL_STAGE_IDS": "appointmentscheduled,qualifiedtobuy",
"HUBSPOT_RENEWAL_HEALTH_THRESHOLD": "60"
}
}
}
}
```
Restart Claude Desktop. You should see ~12 tools registered under `hubspot-cs`.
### 5. Sanity-check
Ask Claude: "Show me at-risk renewals in the next ninety days." Compare the output against the equivalent query in HubSpot's UI. Tune the `HUBSPOT_RENEWAL_HEALTH_THRESHOLD` and stage IDs until they match.
## Watch-outs
- **Private App tokens bypass user-level permissions.** Anyone with access to the MCP client sees every record the token can reach. Document this with your security team.
- **Health-score field drift.** Teams change the formula every quarter. Update `HUBSPOT_HEALTH_SCORE_PROPERTY` and the threshold when the formula changes.
- **Aging-ticket queries can return thousands of rows.** The helper paginates and caps at 500 by default. Tune for your portal volume.
- **Cross-object joins are slow.** A deal-to-tickets traversal across a thousand deals takes minutes — HubSpot's association API is the bottleneck.
## Limits and TODOs (before production use)
- [ ] Add request-level retries with exponential backoff (HubSpot returns 429 readily under sustained load).
- [ ] Write integration tests against a HubSpot sandbox portal.
- [ ] Add structured logging via `python-json-logger`.
- [ ] Wire optional Sentry / OpenTelemetry export.
- [ ] Validate every helper query against the actual portal's pipeline configuration on first run, fail loud if the configured stage IDs do not exist.