ooligo
mcp-server

Gong MCP server for conversation and deal-risk questions

Difficulty
advanced
Setup time
60min
For
revops · gtm-engineer · sales-enablement
RevOps

Stack

A read-only Model Context Protocol server that gives Claude scoped access to your Gong account: call discovery, tracker definitions, per-call analyzed signals, per-rep interaction stats, and one derived tool that reports which risk trackers fired on which calls — split by whether the customer said it or your own rep did. The scaffold lives in the artifact bundle at apps/web/public/artifacts/mcp-server-gong-revops/, which ships README.md, pyproject.toml, and src/gong_revops_mcp/server.py, installable with pip install -e ..

Start with what the API does not have, because it determines the shape of everything else. Gong’s public API exposes no read endpoint for deal-board data. The CRM endpoints (GET /v2/crm/entities) return only objects you previously uploaded through a registered generic CRM integration, and Gong’s documentation marks that endpoint as development-phase verification. So a server that promises “ask Claude about your Gong deals” is doing one of three things: wrapping the UI, reading your CRM instead, or guessing. This one derives deal risk from conversations and says so — deal_risk_digest returns tracker hits with a note telling you to join call_id to your CRM for stage, amount, and close date.

When to use this

Reach for it when a recurring RevOps question currently costs a human ten minutes of clicking: which accounts raised pricing pushback last week, which calls a competitor got named on, whether the reps on a struggling segment are monologuing. Those are joins across Gong’s own data that the UI makes you do by eye. Two roles get the most out of it. The RevOps lead running a weekly pipeline review asks in natural language and pastes a structured answer into the deck. The GTM engineer who writes a throwaway script against /v2/calls/extensive every time someone asks a new question now has the contentSelector, the cursor pagination, the rate limiter, and the speaker attribution already wired.

It is also the right pattern if you already run the Salesforce RevOps MCP server or the Clari one and want the conversation layer in the same chat surface, so a question can cross from “what did the customer say” to “what stage is it in” without a tab switch. That crossing is the actual payoff — neither system answers it alone.

When NOT to use this

  • Gong already ships an official MCP server. Gong announced MCP support in 2026 and documents a Gong-hosted MCP server available on any Gong plan, configured by a technical administrator, with access governed by seat tier. It lets Claude, ChatGPT, and Microsoft Copilot ask about accounts and deals and pull Gong’s own AI-generated insights. Try it first. It is first-party, needs no process to host, and respects Gong’s seat-tier permissions, which this scaffold does not. Build the self-hosted version when you need a fixed, auditable tool surface — a contentSelector you control, a transcript kill-switch, a page cap, speaker-attributed tracker output — or when your admin will not enable the hosted server.
  • You cannot get an admin to mint an API key. Credentials come from Company Settings → Ecosystem → API and only a technical administrator can create them. There is no per-user key.
  • Per-user call visibility is load-bearing for you. One account-level key sees every call in the workspaces it covers, regardless of which human is chatting. If your Gong instance restricts who can hear whose calls, this server bypasses that. Run it per-analyst with narrowly scoped keys, or do not run it.
  • You want verbatim transcripts in the model by default. They are off here, and the design assumes that is correct. If your workflow is transcript-first, you will fight the scaffold.
  • One or two questions a month. The Gong UI’s own filters are faster than a setup you have to maintain.

What it exposes

Six read tools, no writes. The public API’s write surface is call upload and generic-CRM object upload; neither belongs behind a chat prompt, and read-only removes the whole class of “the model misread me and changed the system of record” failure.

  • find_callsGET /v2/calls. Metadata only: id, title, start, duration, direction, Gong URL. Scope the question here first.
  • list_trackersGET /v2/settings/trackers. Tracker definitions only. Gong returns no match counts from this endpoint, which surprises people; occurrence counts come from the extensive call endpoint.
  • call_signalsPOST /v2/calls/extensive. The workhorse: parties, tracker matches, tracker occurrences, Spotlight brief, key points, auto call outcome, topics, talk time, per-person interaction stats, public comments.
  • call_transcriptPOST /v2/calls/transcript. Off unless GONG_ALLOW_TRANSCRIPTS=true, capped at 3 calls, requires a justification.
  • rep_interaction_statsPOST /v2/stats/interaction. Longest monologue, longest customer story, interactivity, patience, question rate.
  • deal_risk_digest — derived. Joins tracker definitions to occurrences over a date range and buckets each hit as customer, internal, or unattributed.

Engineering posture

Speaker attribution is the whole point of the digest. “Pricing Pushback” said by your own rep is a rep-behavior signal. Said by the customer, it is a deal signal. A tracker count that adds them together moves for the wrong reasons and produces a risk number nobody can act on. deal_risk_digest reads content.trackerOccurrences, looks each speakerId up in the call’s parties array, and splits on party affiliation. That is why the server requests occurrences and not just counts, and it is the one thing a generic Gong wrapper will not do for you.

Media is never requested. The contentSelector in server.py is fixed, not caller-controlled, and omits media. The key does not hold api:calls:read:media-url. So the server never mints Gong’s 8-hour signed audio/video links — a link that outlives the conversation it appeared in is a leak waiting for a screenshot.

Transcripts are a kill-switch, not a prompt. call_transcript checks an env flag before it runs and caps at three calls. Trusting a justification string alone leaves full verbatim customer speech one confident misread away from the context window. The flag makes “are we allowing this at all?” a deployment decision instead of a per-question one.

Pagination is capped and the cap is reported. GONG_MAX_PAGES defaults to 5, so a tool call reads at most 500 records and returns truncated: true when it stopped early. A model that silently sees half the data confidently answers the wrong question.

Requests are serialized, not retried. Gong throttles at 3 requests/second and 10,000 requests/day by default, returning 429 with a Retry-After header. The scaffold waits 0.34s between requests rather than firing concurrently and reacting to 429s, because a reactive retry storm still spends daily quota on requests that were always going to fail.

Cost reality

Three lines, plus one that is not a line.

  • Claude subscription. What you already pay — Pro at $20/user/month, Max at $100–200/user/month, or API consumption. The server changes nothing here.
  • Self-hosting. A local Python process per Claude Desktop user: zero infrastructure cost. As a shared service, a small VM at roughly $20–50/month on any cloud.
  • Gong API quota. Free with your Gong contract, not metered in dollars, but finite: 3 requests/second and 10,000 requests/day per company by default, raisable by contacting Gong support. Budget it. A deal_risk_digest over 90 days in a workspace with 4,000 calls is 40 pages of 100 = 40 requests. Ten such questions a day is 400 requests, comfortably inside the ceiling. The thing that breaks the budget is an unbounded cursor loop, which is what GONG_MAX_PAGES exists to prevent.
  • Gong seats. Gong does not publish list pricing; it is quoted per seat with a platform fee. Whatever you pay is unchanged by this server — it adds no seats.

Token cost is dominated by response payloads, which is why server.py slims every response before returning it. call_signals over 20 calls returns briefs and key points rather than full content and lands in the low tens of thousands of tokens. One call_transcript on a 45-minute call is comparable on its own, which is the real argument for leaving transcripts off.

Versus the alternatives

  • Gong’s official MCP server. Covered above: try it first. First-party, any plan, seat-tier permissions, nothing to host. Pick the self-hosted scaffold when you need a tool surface you can read in one file and pin, or when the hosted server is not enabled for you.
  • A community Gong MCP server. Several exist on GitHub and in MCP directories, most wrapping calls and transcripts. Faster to install than reading this scaffold. The trade-off is that “wraps calls and transcripts” usually means transcripts on by default, no page cap, and tracker counts without speaker attribution — the three choices this scaffold makes differently on purpose.
  • A throwaway script against /v2/calls/extensive. Maximum control, and every team rebuilds Basic auth, the account-specific base URL, cursor pagination, the rate limiter, and the parties join by hand. This scaffold is roughly 450 lines with all of that already wired.
  • Gong’s own UI and Spotlight. Faster for a single call and the data is already there. It cannot join Gong data to the rest of your Claude context, which is the only reason to run any of this. If you are unsure whether an MCP server or a Skill is the right shape for your problem, read Claude Skill vs MCP server.

Watch-outs

The README documents all seven; the load-bearing five:

  • A wrong base URL returns 401, not 404. Gong’s API base URL is account-specific and https://api.gong.io is a common default, not a universal one. Teams lose an afternoon debugging credentials that were fine. Guard: _raise_for_gong intercepts 401 and names the base URL it actually used, listing base-URL-mismatch as the first cause before credentials.
  • A renamed tracker reads as good news. deal_risk_digest matches tracker names exactly, so a tracker renamed in Gong stops matching and the digest reports zero risk. Guard: partial — run list_trackers first and paste real names into GONG_RISK_TRACKERS; the shipped defaults are placeholders that match nothing in most workspaces. Emitting a warning when a configured name matches no live tracker is TODO #3 in the README.
  • Interaction stats punish low call volume. Gong’s stats derive only from calls with Whisper enabled, so a rep with three recorded calls is statistically indistinguishable from a rep with a real problem. Guard: rep_interaction_stats returns that caveat inline in every response, so the model repeats it instead of coaching on noise; join find_calls counts before showing the numbers to a manager.
  • Silent truncation. A cursor loop stopped at the page cap looks identical to a complete answer. Guard: every paged tool returns truncated: true when it stopped early, and find_calls is the cheap way to check volume before asking an expensive question.
  • Consent drift. A customer who consented to being recorded did not thereby consent to being summarized by a third-party model. Guard: transcripts are off by default and media URLs are never minted; check your DPA before flipping GONG_ALLOW_TRANSCRIPTS.

Stack

  • Gong — conversation intelligence, trackers, Spotlight briefs, interaction stats
  • MCP Python SDKmcp>=1.2.0; provides Server, stdio_server, and the tool-registry decorators
  • httpx — async REST client against your account’s Gong API host, Basic auth with base64("key:secret")
  • Claude Desktop or Claude Code — natural-language interface and tool caller
  • GONG_ALLOW_TRANSCRIPTS — the env-level lock deciding whether verbatim customer speech reaches the model at all
  • GONG_MAX_PAGES — the quota guard that also makes incompleteness visible to the model

Files in this artifact

Download all (.zip)