HubSpot CRM MCP Server
About
HubSpot CRM MCP server: contacts, deals, pipelines. Idempotent writes and a full audit trail.
Details
- Author
- amin-ale
- Categories
- Marketing, Other
Jump to
Setup
Install HubSpot CRM MCP Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/amin-ale/hubspot-mcp-server
Follow the installation instructions in the repository README, then restart your MCP client.
HubSpot CRM MCP server: contacts, deals, pipelines. Idempotent writes and a full audit trail.
HubSpot CRM MCP server for Claude Desktop and any MCP client, free-tier compatible. 15 tools over contacts, deals, and pipelines, authenticated with either a HubSpot private-app token or a full OAuth app. Writes are idempotent, so a retried tool call replays its first result instead of creating a duplicate record, and every tool call is written to a PII-redacted audit trail, including the calls denied for a missing scope and the calls that errored.
Related:QuickBooks Online MCP Server·MCP Audit Gateway·What production MCP actually requires
HubSpot runs a hosted MCP server of its own, with wider object coverage than this one. It is built for self-hosting: you run the process, the source is short enough to read in a sitting, and the audit trail, the cache, and the credentials never leave your infrastructure.
The rest is what a REST wrapper usually leaves out. It prompts for the exact missing scope instead of leaking a raw403, retries rate limits with backoff, serves record reads from a local cache (TTL plus write-invalidation, with a signature-verified webhook handler you can wire to your own HTTP ingress for out-of-band changes), walks cursor pagination, and returns per-item results when a batch partially fails.
flowchart TD Agent["MCP client / agent"] -->|"stdio (JSON-RPC)"| Server["FastMCP server<br/>server.py"] Server --> Service["CrmService<br/>scope checks · audit · orchestration"] Service --> Cache["LocalCache<br/>TTL + write invalidation"] Service --> Idem["Idempotency store"] Service --> Audit["Audit log<br/>PII redaction"] Service --> Client["HubSpotClient<br/>retries · pagination · error mapping"] Client --> Auth["Token provider<br/>private-app · OAuth refresh"] Client -->|HTTPS| HubSpot["HubSpot CRM API"] Ingress["Your HTTP ingress<br/>(optional, host-provided)"] -->|"signed v3 payload"| Processor["WebhookProcessor<br/>verify_signature"] Processor -->|"invalidate(object)"| Cache
The stdio server speaks JSON-RPC only; it does not listen for webhooks.WebhookProcessorandverify_signatureare shipped as a tested component you mount on your own HTTP ingress (seeWebhook cache invalidation).
Every tool carries MCP annotations (readOnlyHint,destructiveHint,idempotentHint,openWorldHint), a described input schema, and an output schema.
Run it without installing anything permanent:
Either form speaks MCP over stdio on stdin and stdout. Authenticate witheithera private-app token (HUBSPOT_PRIVATE_APP_TOKEN)oran OAuth app (HUBSPOT_CLIENT_ID+HUBSPOT_CLIENT_SECRET+HUBSPOT_REFRESH_TOKEN). The server auto-detects which is present.
Credentials are resolved lazily. The server starts and answersinitializeandtools/listwith nothing configured, which is what lets a directory or a sandbox introspect it; the first tool call is where a missing credential turns into an actionable error.
Add to your MCP host config (for example Claude Desktop'sclaude_desktop_config.json):
{ "mcpServers": { "hubspot": { "command": "uvx", "args": ["mcp-hubspot"], "env": { "HUBSPOT_PRIVATE_APP_TOKEN": "pat-na1-..." } } } }
docker build -t mcp-hubspot . docker run --rm -i -e HUBSPOT_PRIVATE_APP_TOKEN=pat-na1-... mcp-hubspot
uv venv uv pip install -e ".[dev]" cp .env.example .env # then fill in your HubSpot credentials uv run mcp-hubspot
For the OAuth flow,mcp_crm.auth.build_authorization_url(...)builds the consent URL with the scopes the tools need; exchange the returned code for a refresh token and setHUBSPOT_REFRESH_TOKEN.
The stdio server does not receive webhooks. To invalidate the cache on changes made outside this process (edits in the HubSpot UI, other integrations), mountWebhookProcessoron your own HTTP endpoint and verify HubSpot's v3 signature withverify_signature(using theHUBSPOT_WEBHOOK_SECRETyou configure). Point it at the sameLocalCacheyourCrmServiceuses:
from mcp_crm.webhooks import WebhookProcessor, verify_signature processor = WebhookProcessor(cache) def handle_hubspot_webhook(request): ok = verify_signature( secret=webhook_signing_secret, method="POST", uri=request.url, body=request.raw_body, signature=request.headers["X-HubSpot-Signature-v3"], timestamp=request.headers["X-HubSpot-Request-Timestamp"], ) if not ok: return 401 processor.process(request.json()) return 200
verify_signaturerejects tampered bodies, wrong secrets, and stale timestamps;WebhookProcessor.processmaps each subscription to the object it invalidates and reports what it touched.
- Cache scope.Only object-detail reads (crm_get_contact,crm_get_deal) and the pipeline list are cached; list/search results are query-dependent and left uncached to avoid serving stale result sets. Writes invalidate the relevant object immediately. For out-of-band changes, a signature-verifiedWebhookProcessorships as a component you mount on your own HTTP ingress (seeWebhook cache invalidation); the stdio server itself does not listen for webhooks.
- Idempotency is client-side.HubSpot's create endpoints are not natively idempotent, so a key (supplied or derived from the payload) is stored and replayed. This makes at-least-once tool retries safe without duplicating records. The store lives in the process, so it covers retries within a session rather than across restarts, andcrm_batch_create_contactsdeliberately does not use it; both facts are stated in the tool descriptions.
- Scope prompting happens twice.The service pre-checks granted scopes (via token introspection) for a fast, actionable error, and the HTTP client also maps a server-sideMISSING_SCOPES403to the same typed error (belt and suspenders).
- Credentials load lazily.Nothing reads a token at import or at startup. A missing credential surfaces as a typed error on the first tool call, and that failure is audited like any other, so the server is still introspectable in a sandbox with an empty environment.
- Backoff and clocks are injectable.Retry sleep, RNG jitter, and time sources are constructor parameters, which is why the whole suite runs offline in well under a second.
Every external HubSpot call is served by an in-memory fake (tests/fake_hubspot.py) backed by JSON fixtures (tests/fixtures/), wired in throughhttpx.MockTransport. No network, no credentials, deterministic.
Regenerate the comparison document (CI also checks it stays in sync):
uv run python scripts/generate_comparison.py
server.jsondescribes this package for the Model Context Protocol registry (io.github.amin-ale/hubspot-crm-mcp, PyPImcp-hubspot, stdio transport)..mcp.jsonis the minimal client config for tools that auto-detect MCP servers from a repository root.
This is a client for HubSpot data you own or are authorized to access. Point it only at HubSpot accounts you control or have written permission to operate. The audit log redacts emails and phone numbers before writing records; treat exported audit logs as sensitive regardless. Behaviour documented here is point-in-time against the included fixtures, not a guarantee about any live HubSpot account.
I build MCP servers and API integrations that survive a senior-dev code review: auth, retries, idempotency, and audit trails included, not bolted on later. Portfolio and contact:https://amin-ale.github.io/portfolio-site·amin.ale.business@gmail.com.
Free MCP that drives an audit of your marketing. Your AI connects, adsOS digs through your ads, email and site, and hands back a growth plan you can run today.
Customer Intelligence & Segmentation
Find Which next customer to call and how much will be worth it
Operate and customize a tenant-isolated AI CRM for customers, sales, jobs, marketing, reviews, workflows, documents, and workspace pages.
Find and enrich B2B leads, run multi-channel outreach and manage the sales pipeline — 27 annotated tools.
Find buyers and book more meetings without your AI Assistant
Salesforce integration using OAuth2. Write operations disabled by default per integration. 700+ tools covering SOQL, SOSL, REST, and CRUD, individually selectable. Requires a DataGrout account.
Built for the next generation of intelligent experiences, ActiveCampaign's remote MCP server makes it easy for AI agents to understand, store, and use customer context across tools, channels, and workflows.
Authless Remote MCP Server on Cloudflare
An example of a remote MCP server deployable on Cloudflare Workers without authentication.
A read-only MCP server for Salesforce Data Cloud, powered by CData.
The Feedspace MCP server lets AI assistants read, manage, and display your reviews and testimonials through natural language. Instead of navigating dashboards, simply ask your AI assistant to filter reviews, create widgets, build Wall of Love pages, and more
Access and manage HubSpot CRM data through a standardized interface using the HubSpot API.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



