Skip to main content
Glama
Dialpad MCP server

Dialpad MCP server

README.md
# Dialpad MCP server

An MCP server for the [Dialpad API v2](https://developers.dialpad.com/reference). It lets Claude look up Dialpad users, offices, departments, call centers, call history, transcripts, contacts, phone numbers and analytics exports. It can also make the few changes Cititec's automations already make: contact sync, notification messages, and pausing a call event subscription.

It uses the same framework as Cititec's other MCP servers: TypeScript, `@modelcontextprotocol/sdk`, a stdio transport and a fail-closed HTTP transport, vitest tests, tsup and a Docker image.

## Tools

Reads send `GET` to a fixed path. IDs are checked and URL-encoded, and no tool accepts a free-form path. List tools return one page with a `next_cursor`. Each item is trimmed to its main fields (`full: true` returns every field), and every response is capped at 60,000 characters.

**Sensitive** tools return personal information (call logs, transcripts, contacts, exports) or internal URLs. Make them available to administrators only.

| Tool | Dialpad API | Sensitive |
|------|-------------|-----------|
| `dialpad_get_company` | `GET /company` | |
| `dialpad_list_users` | `GET /users` (email, number, name prefix, state, admin) | |
| `dialpad_get_user` | `GET /users/{id}` | |
| `dialpad_list_offices` / `dialpad_get_office` | `GET /offices`, `/offices/{id}` | |
| `dialpad_list_departments` / `dialpad_get_department` | `GET /departments`, `/departments/{id}` | |
| `dialpad_list_callcenters` / `dialpad_get_callcenter` | `GET /callcenters`, `/callcenters/{id}` | |
| `dialpad_get_callcenter_status` | `GET /callcenters/{id}/status` (live queue status) | |
| `dialpad_list_calls` | `GET /call` (start time range, target) | yes |
| `dialpad_get_call` | `GET /call/{id}` (Dialpad allows 10 a minute) | yes |
| `dialpad_get_call_transcript` | `GET /transcripts/{call_id}` | yes |
| `dialpad_list_contacts` / `dialpad_get_contact` | `GET /contacts`, `/contacts/{id}` | yes |
| `dialpad_list_numbers` / `dialpad_get_number` | `GET /numbers`, `/numbers/{number}` (company admin key) | |
| `dialpad_create_stats_export` | `POST /stats`: starts a report job and changes no Dialpad data | yes |
| `dialpad_get_stats_export` | `GET /stats/{id}`: status and download link | yes |
| `dialpad_list_call_subscriptions` / `dialpad_get_call_subscription` | `GET /subscriptions/call`, `/subscriptions/call/{id}` | |
| `dialpad_list_webhooks` | `GET /webhooks`: the signing secret is never returned | yes |

### Write tools

Only the changes Cititec's N8N workflows already make are included. Each one is a single request, so on the MCP host the proposal an administrator approves is exactly what is sent.

| Tool | Dialpad API | Used by (N8N) |
|------|-------------|---------------|
| `dialpad_create_contact` | `POST /contacts` | Autotask contact sync |
| `dialpad_update_contact` | `PATCH /contacts/{id}` | Autotask contact sync |
| `dialpad_delete_contact` | `DELETE /contacts/{id}` (destructive) | Autotask webhook handler |
| `dialpad_send_sms` | `POST /sms` to a channel or up to 10 numbers | workflow alerts to a Dialpad channel; texts from the call-to-ticket workflow |
| `dialpad_update_call_subscription` | `PATCH /subscriptions/call/{id}` (`enabled`, `call_states` only) | call-to-ticket workflow |

Not included: calls, call control, users, offices, number assignment, routing and the rest of Dialpad's admin API.

### Where the endpoint details come from

Paths, methods, parameters, call states and response fields were checked against Dialpad's OpenAPI spec, `dialpad_api_spec.json` in [dialpad/dialpad-python-sdk](https://github.com/dialpad/dialpad-python-sdk) (MIT). A few filters appear only on the newer reference at developers.dialpad.com, not in that spec: `first_name`/`last_name` for users, `name_search` for offices, `name` for contacts and `area_code` for numbers. Dialpad publishes no official MCP server or TypeScript SDK.

## Authentication

Dialpad uses an API key sent as `Authorization: Bearer <key>`. Create it in Dialpad under **Admin Settings > My Company > Authentication > API keys**. The number tools need a company admin key. Dialpad has no read-only keys, so read-only access depends on which tools are exposed, not on the key.

| Transport | Where the key comes from |
|-----------|--------------------------|
| stdio (default) | `DIALPAD_API_KEY` |
| HTTP, `AUTH_MODE=env` | `DIALPAD_API_KEY` |
| HTTP, `AUTH_MODE=gateway` (the image default) | `X-Dialpad-Api-Key` header on every request; no fallback to the environment |

The HTTP transport refuses to start without a real `CONDUIT_S2S_SECRET` and checks the `X-Gateway-S2S` header on every `/mcp` request. `MCP_ALLOW_INSECURE_DEV=1` is for local development only: it skips the check and listens on 127.0.0.1. See `.env.example`.

## Rate limits

Dialpad allows 20 requests per second per company, and 1200 per minute on most endpoints. Some limits are lower: call details 10 a minute, contact create 100 a minute, SMS 100 a minute (800 on Tier 1), stats exports about 200 an hour. A 429 is reported as a rate-limit error, not as a bad key.

## Running on the Cititec MCP host

The host starts the image over stdio with the service's env file. The host adds the `cititec_change_status` tool itself and turns `write_tools` into proposals; this image does neither. Suggested `control.json` lists:

- `read_tools`: every tool in the first table. Admin-gate the sensitive ones by giving them only to users who need call and contact data.
- `write_tools`: the five write tools, with a key in the `-rw.env` file. Leave them out if Claude should only read.

## Development

```bash
npm ci
npm run lint    # type check
npm run build
npm test
```

Local run over stdio: `DIALPAD_API_KEY=... node dist/index.js`.

On Cititec workstations ThreatLocker must allow `esbuild.exe` (used by tsup and vitest) before `build` and `test` run.

## License

Apache-2.0. The HTTP transport, gateway check, logger and build setup come from WYRE Technology's `unifi-mcp`. See `NOTICE`.

TDQS

A3.7/5.0

Scored across 27 tools

Disambiguation4/5

Most tools map cleanly to one resource+action (get_call vs get_call_transcript vs list_calls, create_stats_export vs get_stats_export pairs are obvious). The only soft overlaps are call_subscriptions versus webhooks and get_callcenter vs get_callcenter_status, but the descriptions draw clear lines between them. An agent should rarely misselect here.

Naming Consistency5/5

Every tool uses the dialpad_ prefix plus a consistent verb_noun snake_case pattern (get_/list_/create_/update_/delete_/send_). Singular vs plural on get vs list matches the resource cardinality and stays predictable throughout.

Tool Count3/5

27 tools is heavy, though the domain (users, offices, departments, call centers, calls, contacts, analytics exports, subscriptions, webhooks, SMS) is genuinely broad so nearly every tool maps to a distinct resource. Still, the surface is large enough that it exceeds a comfortable working set and could be consolidated (e.g. subscriptions/webhooks, callcenter status).

Completeness4/5

Read coverage across the platform is thorough and contacts get full CRUD plus SMS send and subscription toggling, so core workflows are supported. Gaps remain: no message/text history listing despite SMS sending, no webhook create/delete, no number assignment/management, and no write operations for users/offices/departments/call centers.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues