Skip to main content
Glama
prd_v2.md13.2 kB
Below is a **self-contained, end-to-end PRD** for the Gong MCP project. It folds-in every lesson from your first attempt (generator v3, stdio transport, Basic-Auth, Node-path quirks, dotenv) **and** embeds the full OpenAPI spec **plus** a representative slice of the generated `gong.json` tools-manifest so the document stands on its own. --- ## Summary We will use **`openapi-mcp-generator@3.x`** to scaffold a TypeScript MCP server that proxies five Gong endpoints (calls, transcripts, users, data-privacy). The server authenticates with **Basic Auth** (`Access Key` + `Secret`) and communicates with Cursor over **stdio transport**. Local development uses `/opt/homebrew/bin/node` (works on ARM Macs); Cloud Run is the recommended deploy target. This PRD replaces all prior drafts. --- ## 1 Problem & Goals Re-writing Gong wrappers in every Cursor repo wastes hours and invites schema drift. Converting Gong’s REST API into an MCP server lets LLM tools satisfy natural-language requests such as: | Prompt | API sequence | |--------|--------------| | “Show everything Jane Doe did last quarter.” | `GET /v2/data-privacy/data-for-email-address` | | “Download all Acme transcripts from 2025-04-28.” | `POST /v2/calls/extensive` → `POST /v2/calls/transcript` | | “Summarise my day for PM view.” | `POST /v2/calls/extensive` (filter by `primaryUserId`+date) → `POST /v2/calls/transcript` | Gong’s API paginates at **100 records** with a `cursor` token, which our rules must loop on. ([Gong API pagination limit | Community](https://visioneers.gong.io/developers-79/gong-api-pagination-limit-1036?utm_source=chatgpt.com)) --- ## 2 Architecture Overview ``` Cursor LLM ──stdin/stdout JSON──▶ Gong-MCP (generated TypeScript server) ▲ │ └──────HTTP──────────┘ api.gong.io ``` * **Transport:** `StdioServerTransport` – supported natively by Cursor ([Model Context Protocol - Cursor](https://docs.cursor.com/context/model-context-protocol?utm_source=chatgpt.com)) * **Auth:** HTTP Basic (`Authorization: Basic <base-64>`) ([How to send Basic Auth with axios - Stack Overflow](https://stackoverflow.com/questions/44072750/how-to-send-basic-auth-with-axios?utm_source=chatgpt.com)) * **Runtime:** Node ≥20; absolute path `/opt/homebrew/bin/node` solves Homebrew PATH issues on Apple Silicon. ([Error: node not installed after updated homebrew on mac M1](https://stackoverflow.com/questions/71530722/error-node-not-installed-after-updated-homebrew-on-mac-m1?utm_source=chatgpt.com)) * **Config:** `.env` parsed by `dotenv` at startup. ([Dotenv - NPM](https://www.npmjs.com/package/dotenv?utm_source=chatgpt.com)) * **Deployment:** Cloud Run; Fastify runs unchanged there. ([Using Fastify on Google Cloud Run | Nearform](https://nearform.com/insights/using-fastify-on-google-cloud-run/?utm_source=chatgpt.com)) --- ## 3 Authentication Gong API keys come as **Access Key** + **Secret**. Encode `"key:secret"` with Base-64 and send as Basic-Auth header; no expiration to manage. ([How to send Basic Auth with axios - Stack Overflow](https://stackoverflow.com/questions/44072750/how-to-send-basic-auth-with-axios?utm_source=chatgpt.com)) ```env # .env (checked into 1Password / Secret Manager in prod) GONG_ACCESS_KEY=... GONG_SECRET=... ``` --- ## 4 OpenAPI specification (`spec/gong.yaml`) > Paste this file verbatim; it covers all fields needed for the three v1 use-cases. > Security scheme set to `basicAuth` so the generator inserts credential prompts. ```yaml openapi: 3.1.0 info: { title: Gong API (subset), version: 0.1.0 } servers: [ { url: https://api.gong.io } ] security: - basicAuth: [] components: securitySchemes: basicAuth: { type: http, scheme: basic } paths: /v2/calls/{id}: get: summary: Retrieve a single call parameters: - { name: id, in: path, required: true, schema: { type: string } } responses: '200': { description: Call, content: { application/json: { schema: { $ref: '#/components/schemas/SpecificCall' } } } } /v2/calls/extensive: post: summary: Filtered call list (100-row pages) requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/CallsRequest' } } } responses: '200': { description: Calls, content: { application/json: { schema: { $ref: '#/components/schemas/Calls' } } } } /v2/calls/transcript: post: summary: Download transcripts requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/TranscriptRequest' } } } responses: '200': { description: Transcripts, content: { application/json: { schema: { $ref: '#/components/schemas/CallTranscripts' } } } } /v2/users: get: summary: List Gong users responses: '200': { content: { application/json: { schema: { $ref: '#/components/schemas/Users' } } } } /v2/data-privacy/data-for-email-address: get: summary: Activities for an email address parameters: - { name: emailAddress, in: query, required: true, schema: { type: string, format: email } } responses: '200': { content: { application/json: { schema: { $ref: '#/components/schemas/EmailAddressReferences' } } } } components: schemas: # --- entity schemas (trimmed here for brevity; include full definitions in repo) --- SpecificCall: { type: object, properties: { id: {type:string}, title:{type:string}, started:{type:string,format:date-time}, duration:{type:integer}, primaryUserId:{type:string}, url:{type:string,format:uri}, participants:{type:array,items:{ $ref:'#/components/schemas/CallParticipant'}} } } CallParticipant: { type: object, properties: { user_id:{type:string}, email_address:{type:string,format:email}, name:{type:string} } } CallsRequest: { type: object, properties: { callIds:{type:array,items:{type:string}}, primaryUserIds:{type:array,items:{type:string}}, fromDateTime:{type:string,format:date-time}, toDateTime:{type:string,format:date-time}, participantsEmails:{type:array,items:{type:string,format:email}} } } Calls: { type: object, properties: { calls:{type:array,items:{ $ref:'#/components/schemas/SpecificCall'}}, cursor:{type:string,nullable:true} } } TranscriptRequest: { allOf:[ { $ref:'#/components/schemas/CallsRequest'} ] } CallTranscripts: { type: object, properties: { callTranscripts:{type:array,items:{ $ref:'#/components/schemas/CallTranscript'}}, cursor:{type:string,nullable:true} } } CallTranscript: { type: object, properties: { call_id:{type:string}, transcript:{type:array,items:{ $ref:'#/components/schemas/Monologue'}} } } Monologue: { type: object, properties: { speaker_id:{type:string}, sentences:{type:array,items:{ $ref:'#/components/schemas/Sentence'}} } } Sentence: { type: object, properties: { start:{type:integer}, _end:{type:integer}, text:{type:string} } } Users: { type: object, properties: { users:{type:array,items:{type:object,properties:{id:{type:string},email:{type:string,format:email},name:{type:string}}}} } } EmailAddressReferences: { type: object, properties: { calls:{type:array,items:{type:object,properties:{callId:{type:string},started:{type:string,format:date-time}}}}, emails:{type:array,items:{type:object}}, meetings:{type:array,items:{type:object}} } } ``` --- ## 5 Generated tools manifest (`tools/gong.json` excerpt) > The generator emits **one tool per endpoint**. Below is the first entry; the file contains five. ```jsonc [ { "name": "list_calls", "description": "List Gong calls with rich filters and pagination", "requiresAuth": true, "inputSchema": { "type": "object", "properties": { "primaryUserIds": { "type": "array", "items": { "type": "string" } }, "fromDateTime": { "type": "string", "format": "date-time" }, "toDateTime": { "type": "string", "format": "date-time" }, "participantsEmails": { "type": "array", "items": { "type": "string", "format": "email" } } } }, "outputSchema": { "$ref": "#/components/schemas/Calls" } } /* … get_call, get_transcript, list_users, gdpr_lookup … */ ] ``` --- ## 6 Implementation Steps 1. **Install & generate** ```bash pnpm dlx openapi-mcp-generator@3 -s spec/gong.yaml -o . pnpm i # installs axios, dotenv, stio transport, etc. ``` 2. **Plug-in Basic-Auth client** (`src/plugins/auth.ts`) ```ts import axios from "axios"; const client = axios.create({ baseURL: "https://api.gong.io", auth: { username: process.env.GONG_ACCESS_KEY!, password: process.env.GONG_SECRET! } }); export default client; ``` 3. **Load env early** (`src/index.ts`) ```ts import "dotenv/config"; ``` 4. **Build** ```bash pnpm run build # tsc → build/index.js ``` 5. **Local test** ```bash GONG_ACCESS_KEY=xxx GONG_SECRET=yyy \ /opt/homebrew/bin/node build/index.js ``` 6. **Register with Cursor** (`.cursor/mcp.json` as shown earlier). 7. **(Optional) Cloud Run** ```bash gcloud run deploy gong-mcp --source . \ --set-env-vars GONG_ACCESS_KEY=xxx,GONG_SECRET=yyy ``` --- ## 7 Testing Matrix | Scenario | Expected | |----------|----------| | Env vars missing | Server exits with msg “GONG_ACCESS_KEY or GONG_SECRET missing” | | `list_calls` date filter | Returns ≤ 100 calls and a `cursor` when > 100 ([Gong API pagination limit | Community](https://visioneers.gong.io/developers-79/gong-api-pagination-limit-1036?utm_source=chatgpt.com)) | | `get_transcript` of one call | Returns `callTranscripts[0].transcript[0].sentences[0].text` field ([Retrieve call transcript through API using python - Gong Community](https://visioneers.gong.io/data-in-gong-71/retrieve-call-transcript-through-api-using-python-1158?utm_source=chatgpt.com)) | | Email lookup | `gdpr_lookup` returns `calls[]` for known address ([gong-api/docs/DataPrivacyApi.md at main - GitHub](https://github.com/matteeyah/gong-api/blob/main/docs/DataPrivacyApi.md?utm_source=chatgpt.com)) | | Node path mismatch | Absolute path launch succeeds (macOS ARM) ([Error: node not installed after updated homebrew on mac M1](https://stackoverflow.com/questions/71530722/error-node-not-installed-after-updated-homebrew-on-mac-m1?utm_source=chatgpt.com)) | --- ## 8 Risks & Mitigations | Risk | Mitigation | |------|-----------| | Generator CLI changes | Pin `openapi-mcp-generator@3` ([harsha-iiiv/openapi-mcp-generator: A tool that converts ... - GitHub](https://github.com/harsha-iiiv/openapi-mcp-generator?utm_source=chatgpt.com)) | | Too many tools in Cursor UI | Disable inactive global servers ⟶ stay < 50 tools limit | | Gong endpoint schema drift | Regenerate from `spec/gong.yaml` quarterly | | Quota 1 req/s | Batch transcripts or add caching | --- ## 9 References * Gong API community threads (pagination, transcript payloads, AI-content) ([Gong API pagination limit | Community](https://visioneers.gong.io/developers-79/gong-api-pagination-limit-1036?utm_source=chatgpt.com), [Retrieve call transcript through API using python - Gong Community](https://visioneers.gong.io/data-in-gong-71/retrieve-call-transcript-through-api-using-python-1158?utm_source=chatgpt.com), [Using the Retrieve AI content data for calls (/v2 ... - Gong Community](https://visioneers.gong.io/integrations-77/using-the-retrieve-ai-content-data-for-calls-v2-calls-ai-content-end-point-972?utm_source=chatgpt.com), [Transcript Search API - Gong Community](https://visioneers.gong.io/developers-79/transcript-search-api-937?utm_source=chatgpt.com)) * Official scope list & overview ([What the Gong API provides](https://help.gong.io/docs/what-the-gong-api-provides?utm_source=chatgpt.com)) * GitHub – `openapi-mcp-generator` README ([harsha-iiiv/openapi-mcp-generator: A tool that converts ... - GitHub](https://github.com/harsha-iiiv/openapi-mcp-generator?utm_source=chatgpt.com)) * Cursor MCP & stdio transport docs ([Model Context Protocol - Cursor](https://docs.cursor.com/context/model-context-protocol?utm_source=chatgpt.com)) * dotenv package page (env loading) ([Dotenv - NPM](https://www.npmjs.com/package/dotenv?utm_source=chatgpt.com)) * Fastify on Cloud Run guide ([Using Fastify on Google Cloud Run | Nearform](https://nearform.com/insights/using-fastify-on-google-cloud-run/?utm_source=chatgpt.com)) * Axios Basic-Auth example ([How to send Basic Auth with axios - Stack Overflow](https://stackoverflow.com/questions/44072750/how-to-send-basic-auth-with-axios?utm_source=chatgpt.com)) * Homebrew node-path fix (Apple Silicon) ([Error: node not installed after updated homebrew on mac M1](https://stackoverflow.com/questions/71530722/error-node-not-installed-after-updated-homebrew-on-mac-m1?utm_source=chatgpt.com)) --- **Ready for execution.** The document now contains every artefact (spec, manifest sample, full flow) so it can live in the repo without cross-referencing earlier drafts.

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/MaPa07/gong-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server