Building Production-Ready CRM Integration for ChatGPT using Model Context Protocol

hubspot · Tech · 2025 · source Agentic: yes · promotional bias: med · source-backed · extracted with prompt 0.5.5 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Enterprise CRM connector for ChatGPT Deep Research using remote MCP

HubSpot needed to expose CRM data and search tools to ChatGPT Deep Research for over 250,000 businesses without local setup, while preserving enterprise security, user-level permissions, horizontal scalability, automatic tool registration, and model-reliable query generation.

Constraints:

Architecture

HubSpot built a homegrown remote MCP server in Java and Dropwizard. ChatGPT connects through a remote MCP endpoint, users authenticate through OAuth, and each HTTP request maps to a stateless ephemeral MCP session. CHIRP service discovery lets teams expose existing RPCs as MCP tools with @ChirpTool annotations. A dedicated mcp.hubspot.com gateway handles CRM search, associations, and property fetching with runtime intersection of app scopes and user permissions. A compact token-based query DSL gives the model predictable examples for CRM search while avoiding ambiguous features that would reduce reliability.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  chatgpt-deep-research[ChatGPT Deep Research] --> remote-mcp-server[Remote MCP server]
  remote-mcp-server --> oauth-flow[OAuth flow]
  oauth-flow --> access-token-parser[Access token parser]
  access-token-parser --> user-permission-intersection[User permission intersection]
  remote-mcp-server --> streamable-http-transport[Streamable HTTP transport]
  streamable-http-transport --> ephemeral-mcp-session[Ephemeral MCP session]
  ephemeral-mcp-session --> mcp-java-sdk[MCP Java SDK]
  remote-mcp-server --> mcp-gateway[MCP Gateway]
  mcp-gateway --> chirp-service-discovery[CHIRP service discovery]
  chirp-service-discovery --> annotated-rpc-services[Annotated RPC services]
  annotated-rpc-services --> internal-crm-apis[Internal CRM APIs]
  remote-mcp-server --> crm-gateway-api[CRM gateway API]
  user-permission-intersection --> crm-gateway-api
  crm-gateway-api --> query-dsl-parser[Query DSL parser]
  query-dsl-parser --> crm-search-tool[CRM search tool]
  crm-search-tool --> internal-crm-apis
  user-permission-intersection --> internal-crm-apis
  internal-crm-apis --> hubspot-crm-records[HubSpot CRM records]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
ChatGPT Deep Research AI client that discovers and invokes HubSpot MCP tools for CRM deep research. Remote MCP server
Remote MCP server HubSpot-hosted MCP endpoint that exposes CRM tools to ChatGPT without local installation. ChatGPT Deep Research, OAuth flow, Streamable HTTP transport, MCP Gateway, MCP Java SDK
OAuth flow Trusted browser authentication flow that grants scoped, user-level access for the connector. Remote MCP server, Access token parser, User permission intersection
Access token parser Extracts client_id, hub_id, user_id, and scopes from OAuth access tokens. OAuth flow, User permission intersection
User permission intersection Computes the intersection of app permissions and user-specific permissions before forwarding calls to internal CRM APIs. Access token parser, CRM gateway API, Internal CRM APIs
Streamable HTTP transport Custom Dropwizard/JAX-RS transport that supports MCP over stateless HTTP without SSE long-lived sessions. Remote MCP server, Ephemeral MCP session, MCP Java SDK
Ephemeral MCP session Per-request MCP session created for a single HTTP call and bound to the HTTP response. Streamable HTTP transport, MCP Java SDK
MCP Java SDK Protocol implementation extended by HubSpot to support their Dropwizard backend and Streamable HTTP needs. Remote MCP server, Streamable HTTP transport, Ephemeral MCP session
MCP Gateway Service that discovers CHIRP-annotated tools, converts RPCs to MCP spec-compliant tools, and registers them with the SDK. Remote MCP server, CHIRP service discovery, Annotated RPC services
CHIRP service discovery HubSpot internal RPC discovery layer used to find services deployed with @ChirpTool annotations. MCP Gateway, Annotated RPC services
Annotated RPC services Internal HubSpot microservices whose RPC methods are marked as AI-ready MCP tools. CHIRP service discovery, MCP Gateway, Internal CRM APIs
CRM gateway API Dedicated mcp.hubspot.com API for CRM search, associations, and property fetching with MCP-specific user-permission enforcement. Remote MCP server, User permission intersection, Query DSL parser, Internal CRM APIs
Query DSL parser Parses compact key[:operator]:value query strings generated by the AI model into CRM search operations. CRM gateway API, CRM search tool
CRM search tool MCP search tool that supports object searches, filters, associations, pagination, and sorting through the query DSL. Query DSL parser, Internal CRM APIs
Internal CRM APIs HubSpot internal services that enforce CRM record, team, unassigned-record, and field-level access restrictions. User permission intersection, Annotated RPC services, CRM search tool, HubSpot CRM records
HubSpot CRM records Contacts, companies, tickets, deals, associations, and properties queried by the Deep Research Connector. Internal CRM APIs

Data flow

A HubSpot customer connects ChatGPT to HubSpot through OAuth. ChatGPT calls the remote MCP server over Streamable HTTP. HubSpot creates an ephemeral MCP session for the HTTP request, discovers available tools through the MCP Gateway and CHIRP annotations, parses model-generated CRM search queries through the token DSL, intersects app scopes with the user's CRM permissions, forwards the constrained request to internal CRM APIs, and returns the result through the MCP response.

4 supporting quotes
“they can access capabilities through their browser using trusted and reliable authentication flows like OAuth”article, stated
“custom transport provider to bridge Dropwizard's JAX-RS async processing with the MCP SDK. Every HTTP call corresponds to a single ephemeral session: public class StreamableMcpServerTransportProvider implements McpServerTransportProvider { private volatile McpServerSession.Factory”article, stated
“request) { ... } Behind the scenes, our MCP server periodically polls for new or updated services deployed with these annotations. The system then fetches their specifications and automatically converts each RPC to a MCP spec-compliant tool. Finally, these wrapped RPCs are registered with”article, stated
“intersect the app's permissions with the user's permissions, and send that info to the internal service to respect the permissions of the user. If we were to send the entire user, then we'd be opening up the app to have more permissions than the user who”article, stated

Why this architecture

HubSpot built the connector in-house because remote MCP needed to inherit existing CI/CD, auto-scaling, observability, region-aware routing, Java/Dropwizard stack, OAuth model, and permission semantics. Stateless Streamable HTTP matched tool-call workloads and scaling constraints better than SSE. CHIRP-based discovery let hundreds of teams publish tools without central bottlenecks, while a constrained DSL made AI-generated CRM queries reliable.

4 supporting quotes
“we could leverage enterprise-grade CI/CD, auto-scaling, observability, and even region-aware API call routing”article, stated
“It also gave us direct control over how MCP interacts with our existing scopes model for OAuth, allowing us to ensure user-level permissions were respected throughout any interactions with our MCP tools. This wasn't just about checking boxes. It was about”article, stated
“SSE requires long-lived connections. which can be challenging for load balancers to handle reliably, especially in environments like ours where servers are frequently scaled up or down. Third, managing stateless HTTP requests is far simpler than managing”article, stated
“AI models excel at pattern matching, so a consistent, example-rich DSL will outperform a more flexible but ambiguous query language every time.”article, stated

Models used: ChatGPT Deep Research · Model Context Protocol · MCP Java SDK · Dropwizard · CHIRP · Cloudflare Workers · OAuth

Scale

Alternatives considered (roads not taken)

Keep the local MCP server model

Rejected because: Local setup required Private App Access Tokens and MCP-client configuration, limiting adoption to technical developers.

3 supporting quotes
“that approach required users to manually create Private App Access Tokens and configure their MCP clients, which introduced technical complexity and limited adoption to tech-savvy developers. Our new remote MCP server changes everything. It represents a”article, stated
“App Access Tokens and configure their MCP clients, which introduced technical complexity and limited adoption to tech-savvy developers. Our new remote MCP server changes everything. It represents a major leap forward from local servers by eliminating the need”article, stated
“eliminating the need for users to install or run anything on their machines. Instead, they can access capabilities through their browser using trusted and reliable authentication flows like”article, stated

Buy a turnkey remote MCP solution

Rejected because: HubSpot wanted direct integration with its own CI/CD, scaling, observability, routing, OAuth scopes, and permission model.

3 supporting quotes
“(Buy): Use a third-party solution, e.g., Cloudflare's turnkey MCP solution”article, stated
“the decision to build in-house became clear once we considered what hosting our own infrastructure could enable.”article, stated
“something that could evolve with our platform and unlock experiences in the future that third-party solutions simply couldn't match. ## Laying the Foundation: Streamable HTTP MCP Server Our MCP server is built with the Java MCP SDK . We chose”article, stated

Use SSE long-lived connections

Rejected because: The connector focused on tool calls, and long-lived connections complicate load balancing and autoscaling.

3 supporting quotes
“didn’t immediately need the server-to-client notification support provided by SSE connections, our use case focused only on tool calls. Second, SSE requires long-lived connections. which can be challenging for load balancers to handle reliably, especially”article, stated
“SSE requires long-lived connections. which can be challenging for load balancers to handle reliably, especially in environments like ours where servers are frequently scaled up or down. Third, managing stateless HTTP requests is far simpler than managing”article, stated
“managing stateless HTTP requests is far simpler than managing sessions. When we began prototyping, we discovered that the Java SDK did not support the newly standardized [Streamable”article, stated

Overhaul all public APIs for user-level permissions at once

Rejected because: A broad change would be enormous and potentially breaking for many existing integrations.

3 supporting quotes
“originally designed to enforce user-level permissioning, we didn't want to overhaul our entire public API infrastructure all at once. HubSpot has thousands of public APIs that hundreds of teams at HubSpot contribute to, all of which depend on a shared middleware library for authentication and”article, stated
“Modifying that system to enforce user-specific access across the board would be an enormous undertaking — and a potentially breaking change for many of our existing applications. For example, the original app installer may no longer be with the company, and”article, stated
“permissions without breaking existing installs. But for now, we took a pragmatic approach: we spun up a dedicated gateway API at mcp.hubspot.com to handle CRM search, associations, and property fetching — fully instrumented to respect user permissions in the context”article, stated

Expose a fully flexible query language

Rejected because: The AI model generates more reliable queries when the syntax is predictable, example-rich, and constrained.

“We intentionally kept certain features simple—no boolean OR logic, no nested expressions, no relative date syntax like "last week"”article, stated
“these constraints actually make the model more reliable at generating valid queries. The key insight is that AI models excel at pattern matching, so a consistent, example-rich DSL will outperform a more flexible but ambiguous query language every time. The”article, stated

Patterns

tool-use-orchestration (agent-control)

HubSpot exposes CRM search and internal RPCs as MCP tools that ChatGPT can discover and invoke automatically through the remote MCP server.

3 supporting quotes
“## Implementing Streamable HTTP for MCP A remote MCP is essentially an HTTP API spec that allows an LLM to discover and invoke endpoints automatically. Currently, [Streamable HTTP](https:”article, stated
“automatically discovers and registers MCP tools across our entire infrastructure”article, stated
“their MCP tools become immediately available to AI agents – no manual configuration, no gateway redeployments, no coordination needed.”article, stated

privacy-preserving-processing (security)

The connector intersects app scopes with user-specific permissions so ChatGPT cannot query CRM data beyond what the connected user could access in HubSpot.

3 supporting quotes
“For example, when a user connects to HubSpot from within ChatGPT, they must not be able to query data they don’t have access to. The actions taken via ChatGPT should reflect the same permissions and access controls the user would experience in HubSpot’s native UI.”article, stated
“The actions taken via ChatGPT should reflect the same permissions and access controls the user would experience in HubSpot’s native UI.”article, stated
“permissions](https://knowledge.hubspot.com/properties/restrict-view-edit-access-for-properties) Given the complexity, we can't reasonably store all this in an access token; which is why we need to intersect the app's permissions with the user's permissions, and send that info to the internal”article, stated

safety-policy-enforcement (security)

HubSpot omits write and sensitive-property scopes from the Deep Research Connector and forwards only constrained user permissions to internal APIs.

“We intentionally omitted scopes for write access or access to sensitive properties, as they aren’t required for Deep Research use cases.”article, stated
“only grant access to what the integration is using, rather than having one monolithic "scope"”article, stated

structured-output-contract (tool-interface)

HubSpot designs a token-based DSL with key[:operator]:value tokens, examples, and helpful errors so AI models can generate valid CRM searches.

3 supporting quotes
“Each search query consists of space-separated tokens following a key[:operator]:value pattern.”article, stated
“providing comprehensive examples in your tool descriptions dramatically improves the model's ability to generate correct queries.”article, stated
“Ensure you return helpful errors to help the model correct itself.”article, stated

latency-optimization (production-operations)

HubSpot uses stateless HTTP and ephemeral sessions for tool-call workloads, accepting only a few dozen milliseconds of permission-overhead where security requires it.

3 supporting quotes
“The result? Full MCP protocol compliance within a stateless HTTP environment.”article, stated
“Every HTTP call corresponds to a single ephemeral session: public class StreamableMcpServerTransportProvider implements McpServerTransportProvider { private volatile McpServerSession.”article, stated
“can be a few dozen milliseconds slower due to computing user and account permissions at runtime.”article, stated

observability-tracing (production-operations)

HubSpot chose in-house hosting partly to reuse enterprise observability, CI/CD, autoscaling, and region-aware routing for the MCP server.

“enterprise-grade CI/CD, auto-scaling, observability, and even region-aware API call routing”article, stated

guardrails-io-filtering (governance)

HubSpot plans governance around distributed tool registration so hundreds of teams can expose tools without fragmenting the customer-facing interface.

“we will be implementing governance and guardrails to ensure customers always experience a cohesive, unified interface”article, stated
“rapid innovation at the edges with strategic coordination at the center.”article, stated

Tradeoffs

Build the MCP server in-house

Chose HubSpot Java/Dropwizard infrastructure over A turnkey third-party MCP solution.

Rationale: In-house hosting preserved direct control over OAuth, permissions, CI/CD, autoscaling, observability, and routing at the cost of more engineering work.

3 supporting quotes
“the decision to build in-house became clear once we considered what hosting our own infrastructure could enable.”article, stated
“direct control over how MCP interacts with our existing scopes model for OAuth”article, stated
“For many companies, this would've been the obvious choice. However, our infrastructure team had already been prototyping an MCP server by extending the [MCP Java SDK](https:”article, implied

Use stateless HTTP transport

Chose Streamable HTTP with ephemeral sessions over SSE long-lived sessions.

Rationale: The connector only needed tool calls, and stateless requests fit HubSpot's load balancing and autoscaling constraints.

3 supporting quotes
“First, we didn’t immediately need the server-to-client notification support provided by SSE connections, our use case focused only on tool calls. Second, SSE requires long-lived connections.”article, stated
“managing stateless HTTP requests is far simpler than managing sessions.”article, stated
“The result? Full MCP protocol compliance within a stateless HTTP environment.”article, stated

Phase user-level permissions

Chose Dedicated MCP gateway API for CRM data over Immediate user-permission enforcement across all public APIs.

Rationale: The gateway enabled secure ChatGPT access without breaking existing API integrations or coordinating a massive platform migration.

“we took a pragmatic approach: we spun up a dedicated gateway API at mcp.hubspot.com”article, stated
“this rollout takes time. We need to build the infrastructure to support this, and coordinate and roll out with hundreds of teams”article, stated

Pay runtime permission overhead

Chose Precise app/user/account permission intersection over Faster but coarser access checks.

Rationale: The AI agent can generate nondeterministic CRM queries, so security precision was worth a few dozen milliseconds.

3 supporting quotes
“can be a few dozen milliseconds slower due to computing user and account permissions at runtime.”article, stated
“This is a tradeoff we were willing to make in order to ensure user-level permissions were precisely enforced”article, stated
“datasets being queried by the deep research agent is nondeterministic.”article, stated

Use a constrained query DSL

Chose Predictable token syntax and examples over Maximum search-language flexibility.

Rationale: A consistent DSL better matches model pattern generation and improves valid-query rates.

3 supporting quotes
“We designed a token-based DSL that balances power with simplicity (also cited in [OpenAI documentation](https://platform.”article, stated
“these constraints actually make the model more reliable at generating valid queries.”article, stated
“a consistent, example-rich DSL will outperform a more flexible but ambiguous query language every time.”article, stated

Enable self-service tool publication

Chose @ChirpTool annotations and gateway polling over Central manual MCP tool registration.

Rationale: Self-service annotations let teams expose tools immediately without coordination, while governance remains necessary to keep the interface cohesive.

3 supporting quotes
“Teams just deploy and update their services, and their MCP tools become immediately available to AI agents”article, stated
“no manual configuration, no gateway redeployments, no coordination needed.”article, stated
“governance and guardrails to ensure customers always experience a cohesive, unified interface”article, stated

Gotchas (what bit them)

Local MCP setup blocked non-technical adoption.

Root cause: Users had to create Private App Access Tokens and configure local MCP clients manually.

Resolution: Move to a remote MCP server with browser-based OAuth access.

3 supporting quotes
“manually create Private App Access Tokens and configure their MCP clients”article, stated
“introduced technical complexity and limited adoption to tech-savvy developers.”article, stated
“eliminating the need for users to install or run anything on their machines.”article, stated

The MCP Java SDK did not yet support the newly standardized Streamable HTTP protocol.

Root cause: The standard was evolving faster than the SDK implementation.

Resolution: Implement a custom transport provider that bridges Dropwizard async responses to MCP sessions.

3 supporting quotes
“the Java SDK did not support the newly standardized Streamable HTTP transport protocol.”article, stated
“Fortunately, the SDK was written to support custom transport protocols, which allowed us to implement [Streamable HTTP](https:”article, stated
“we implemented a custom transport provider to bridge Dropwizard's JAX-RS async processing with the MCP SDK.”article, stated

SSE would have added operational complexity for a tool-call-only workload.

Root cause: Long-lived SSE sessions are harder for load balancers and autoscaled servers, and server-to-client notifications were not needed.

Resolution: Use stateless Streamable HTTP and one ephemeral MCP session per request.

3 supporting quotes
“we didn’t immediately need the server-to-client notification support provided by SSE connections”article, stated
“SSE requires long-lived connections. which can be challenging for load balancers to handle reliably”article, stated
“Every HTTP call corresponds to a single ephemeral session: public class StreamableMcpServerTransportProvider implements McpServerTransportProvider { private volatile McpServerSession.”article, stated

Existing API token semantics were not sufficient for user-facing AI agents.

Root cause: HubSpot historically decoupled API tokens from granular user identities for background sync and automated workflows.

Resolution: Use user-level OAuth apps and replay the intersection of app and user permissions to internal APIs.

3 supporting quotes
“The API token is not the user. There are also various integration touchpoints within HubSpot that may ultimately trigger calls to 3rd parties and calls back to HubSpot, and we don't want the original installer to be conflated with another user that triggered some action.”article, stated
“most of our public APIs do not enforce user-level permissions, whereas our native UI does.”article, stated
“Replay those permissions to internal APIs where user permissions are respected for data within the CRM”article, stated

Too-flexible CRM query syntax would reduce model reliability.

Root cause: Boolean OR, nested expressions, and relative dates add ambiguity that LLMs may generate inconsistently.

Resolution: Use a consistent token DSL with examples and helpful errors.

3 supporting quotes
“no boolean OR logic, no nested expressions, no relative date syntax like "last week"”article, stated
“these constraints actually make the model more reliable at generating valid queries.”article, stated
“The model can still make mistakes. Ensure you return helpful errors to help the model correct itself.”article, stated

Distributed tool ownership can mirror the org chart to customers.

Root cause: Hundreds of teams can expose tools independently, which creates speed but risks fragmentation.

Resolution: Add governance and guardrails around self-service tool publication.

“While this distributed approach lets every team own their AI story and innovate independently, we will be implementing governance and guardrails to ensure customers always experience a cohesive, unified interface rather than a fragmented reflection of our org chart. It's the best of both worlds:”article, stated
“rapid innovation at the edges with strategic coordination at the center.”article, stated

Evaluation

The article does not describe a formal benchmark suite, but it provides production validation criteria: MCP protocol compliance over stateless HTTP, OAuth/user-permission correctness, service discovery without manual gateway redeploys, model-valid query DSL generation, helpful error-driven self-correction, and precise access control for nondeterministic AI queries.

Metrics: MCP protocol compliance · OAuth consent flow success · User permission enforcement · Runtime permission-computation overhead · Tool discovery coverage · Gateway redeploy avoidance · Valid query DSL generation · Helpful error self-correction · Autoscaling compatibility · Region-aware routing compatibility

4 supporting quotes
“Full MCP protocol compliance within a stateless HTTP environment.”article, stated
“no manual configuration, no gateway redeployments, no coordination needed.”article, stated
“Ensure you return helpful errors to help the model correct itself.”article, stated
“This is a tradeoff we were willing to make in order to ensure user-level permissions were precisely enforced since the APIs and datasets being queried by the deep research agent is nondeterministic.”article, stated

Outcomes

The source reports 250,000+ businesses, hundreds of teams, thousands of public APIs, contacts/companies/deals/tickets scope coverage, a few dozen milliseconds of permission overhead, and build time measured in weeks.

4 supporting quotes
“HubSpot has become the first CRM to launch a Deep Research Connector with ChatGPT”article, stated
“the first third-party MCP connector available in the ChatGPT Registry built with a remote Model Context Protocol (MCP) server.”article, stated
“eliminating the need for users to install or configure anything locally.”article, stated
“implemented a complex protocol as a secure, customer-ready feature in a matter of weeks.”article, stated