Skip to main content
Glama
graybern

Gong MCP Server

by graybern
README.md
# Gong MCP Server

A local [stdio MCP](https://modelcontextprotocol.io) server that exposes two
read-only tools — `list_calls` and `get_transcript` — so an MCP client (Claude
Code, Claude Desktop, etc.) can look up a Gong call by customer/date and pull
its transcript **without ever seeing the Gong API key**.

The API key is fetched from 1Password on the first tool call (one `op` call,
so one 1Password prompt per server session), held only in memory,
and used solely as HTTP Basic-auth against `api.gong.io`. It is never logged,
never written to disk, and never returned from any tool call.

> **Note:** This project was generated by Claude (Anthropic) and reviewed
> before publishing. Treat it as a starting point — review the code and its
> security properties yourself before using it against production data.

## Tools

| Tool | Purpose | Returns |
|---|---|---|
| `list_calls` | List calls started within a date range (max 31 days). | Per-call `call_id`, `title`, `start_time`, `account_name`, `participants_summary`. |
| `get_transcript` | Download one call's transcript by `call_id`. | Transcript text inline, or — if `output_path` is given — a write-status summary only (the server writes the file itself, so the text never round-trips through the model). |

Only these two read endpoints are wrapped. No write/admin Gong endpoints are exposed.

## Requirements

- Python 3.10+
- The [1Password CLI](https://developer.1password.com/docs/cli/) (`op`), installed, on `PATH`, and signed in
- A Gong API key (access key + access key secret) stored in 1Password

## Install

```bash
git clone <your-repo-url> mcp-gong
cd mcp-gong
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

This installs a `gong-mcp-server` console script (the MCP entry point).

## 1Password setup (required before the tools will work)

`secrets.py` fetches the Gong API key from 1Password via a single `op` CLI
call the first time a tool is used — not at process startup, because Claude
Desktop launches, kills and relaunches the server every time the app opens,
and each launch that touched 1Password cost an authorization prompt. **Every
tool call fails if the key isn't there** — it does not fall back to a
hardcoded or stubbed key.

### Expected item shape

Gong's Basic-auth API needs two values — an access key and an access key
secret — so create a 1Password item with this shape:

| Attribute | Default | Description |
|---|---|---|
| Vault | `Employee` | The 1Password vault containing the item |
| Item title | `Gong API Key` | The item's title (matched exactly by `op item get`) |
| Field label | `username` | The field holding the Gong access key |
| Field label | `credential` | The field holding the Gong access key secret |

Both fields should contain just the raw value (no prefix, no JSON wrapper).
This matches 1Password's standard "API Credential" item type, whose two
built-in fields are already labeled `username` and `credential`.

If this item doesn't exist, the first tool call fails with a message
naming exactly which vault/item/field it looked for. **Do not work around this
by hardcoding a key.**

### Overriding the vault/item/fields

The values above are defaults, not fixed — override any of them without
touching code, in order of priority:

1. **Environment variables** (highest priority):
   ```bash
   export GONG_OP_VAULT="Eng"
   export GONG_OP_ITEM="Gong API Key"
   export GONG_OP_ACCESS_KEY_FIELD="username"
   export GONG_OP_ACCESS_KEY_SECRET_FIELD="credential"
   ```
2. **Config file** (JSON), pointed to by `GONG_OP_CONFIG_FILE`:
   ```bash
   export GONG_OP_CONFIG_FILE="$HOME/.config/gong-mcp/op-item.json"
   ```
   ```json
   {
     "vault": "Eng",
     "item": "Gong API Key",
     "access_key_field": "username",
     "access_key_secret_field": "credential"
   }
   ```
   Any key can be omitted to fall back to the next source.
3. **Built-in defaults** (`Employee` / `Gong API Key` / `username` / `credential`).

Environment variables take precedence over the config file, which takes
precedence over the defaults.

## Configuring your MCP client

Copy `.mcp.json.example` to your client's MCP config (e.g. `.mcp.json` for
Claude Code) and point `command` at the installed console script. Using the
absolute path to the script inside your virtualenv is the most reliable:

```json
{
  "mcpServers": {
    "gong": {
      "command": "/absolute/path/to/mcp-gong/.venv/bin/gong-mcp-server",
      "args": []
    }
  }
}
```

`.mcp.json` is gitignored so machine-specific paths never get committed.

## Development

Run the test suite (no network or real credentials required — the 1Password
CLI and Gong API are both mocked):

```bash
pip install -e ".[dev]"
pytest -q
```

## Security notes

- The Gong API key lives only in memory for the life of the process and is
  never logged, persisted, or exposed through a tool response.
- The server shells out to `op` using an argument list (no shell string), so
  there is no shell-injection surface.
- The only network destination is `https://api.gong.io`.
- `get_transcript`'s optional `output_path` writes to an arbitrary local path
  the caller supplies (parent directories are created). Point it only at
  locations you intend to write to.

## Attribution

Generated by Claude (Anthropic) and reviewed prior to publication.

## License

MIT — see [LICENSE](LICENSE).