{
  "markdown": "<!-- mcp-name: io.github.pghdma/callrail-mcp -->\n\n# callrail-mcp\n\n[![PyPI version](https://img.shields.io/pypi/v/callrail-mcp.svg)](https://pypi.org/project/callrail-mcp/)\n[![Python versions](https://img.shields.io/pypi/pyversions/callrail-mcp.svg)](https://pypi.org/project/callrail-mcp/)\n[![CI](https://github.com/pghdma/callrail-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/pghdma/callrail-mcp/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![MCP](https://img.shields.io/badge/MCP-compatible-blue)](https://modelcontextprotocol.io/)\n[![Available on CodeGuilds](https://img.shields.io/badge/Available_on-CodeGuilds-6366f1)](https://codeguilds.dev/packages/callrail-mcp)\n\nA [Model Context Protocol](https://modelcontextprotocol.io/) server that exposes the [CallRail REST API v3](https://apidocs.callrail.com/) to any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.).\n\nCreated by **[Steve Japalucci](https://github.com/pghdma)** — Founder of [Pittsburgh Digital Marketing Agency (PGHDMA)](https://pghdma.com).\n\n## What you can ask Claude to do\n\nOnce installed, any MCP-aware assistant can answer things like:\n\n**Reporting**\n- *\"Pull last week's calls for Alan Construction, grouped by source\"*\n- *\"Show me every missed call from Google Ads this month\"*\n- *\"Find any calls from 412-555-1234 across all clients in the last 90 days\"*\n- *\"Get the transcript for call CAL019abc...\"*\n\n**Agency cost attribution** *(new in v0.4)*\n- *\"Why is my CallRail bill $174? Break it down by client\"*\n- *\"Which client is the biggest minute user this cycle?\"*\n\n**Conversion debugging** *(new in v0.4)*\n- *\"Why didn't this call convert in Google Ads? CAL019...\"*\n- *\"Is this 58-second call eligible to count as a Google Ads conversion?\"*\n\n**Tag + tracker management**\n- *\"Tag this call as 'lead' and add a note\"*\n- *\"Provision a new Google Ads call-extension tracker for Renaissance in area code 412\"* *(requires `confirm_billing=True` — costs ~$3/mo)*\n\n## Installation\n\n```bash\n# Recommended: pipx for isolated CLI install\npipx install callrail-mcp\n\n# Or with pip\npip install callrail-mcp\n```\n\nTo install from source (latest unreleased):\n\n```bash\npipx install git+https://github.com/pghdma/callrail-mcp.git\n```\n\n## Auth\n\nGet an API key at **Settings → API Keys** in your CallRail account. You need Account Admin permission to create one.\n\nProvide it one of two ways:\n\n### Option 1: environment variable (recommended for most setups)\n\n```bash\nexport CALLRAIL_API_KEY=\"your_key_here\"\n```\n\n### Option 2: key file\n\n```bash\nmkdir -p ~/.config/callrail\necho \"your_key_here\" > ~/.config/callrail/api-key.txt\nchmod 600 ~/.config/callrail/api-key.txt\n```\n\nOr override with `CALLRAIL_API_KEY_FILE=/path/to/key.txt`.\n\n## Configure your MCP client\n\n### Claude Code / Claude Desktop (`~/.claude.json` or `claude_desktop_config.json`)\n\n```json\n{\n  \"mcpServers\": {\n    \"callrail\": {\n      \"command\": \"callrail-mcp\",\n      \"env\": {\n        \"CALLRAIL_API_KEY\": \"your_key_here\"\n      }\n    }\n  }\n}\n```\n\nIf you installed via pipx, `callrail-mcp` will be on your PATH automatically. Otherwise, point `command` at the full path to the executable.\n\n### Cursor / other clients\n\nThe server speaks standard MCP stdio. Any client that supports stdio MCP servers will work — just run `callrail-mcp` as the command.\n\n## Available tools\n\n**59 tools total** — ~95% of CallRail's REST API v3 surface. Read tools, write tools, tracker provisioning, agency aggregation, account management (Companies/Users CRUD), notifications, integrations discovery, outbound calls, offline-lead backfill via `create_form_submission`, and (new in v1.1) leads, SMS-thread lead management, server-side analytics, and per-call page views.\n\n### Read tools\n\n| Tool | Purpose |\n|---|---|\n| `list_accounts` | List accessible CallRail accounts |\n| `list_companies` | List companies (clients) under an account. Optional `status=\"active\"` filter |\n| `list_trackers` | List tracking phone numbers + their source mapping. Optional `status=\"active\"` filter |\n| `get_tracker` | Full detail for one tracker |\n| `list_calls` | Paginated call list — filter by company / date / source / answered |\n| `get_call` | Full detail for a specific call |\n| `call_summary` | Aggregate stats (total, answered, by source, duration) for a window |\n| `list_form_submissions` | CallRail Form Tracking submissions |\n| `list_text_messages` | SMS conversations |\n| `list_users` | Account users |\n| `get_call_recording` | Recording URL (if recording enabled) |\n| `get_call_transcript` | Conversation Intelligence transcript |\n| `search_calls_by_number` | Find calls by phone number across a window |\n| `list_tags` | List tags in account or filtered to one company |\n\n### Write tools *(v0.2+)*\n\n| Tool | Purpose |\n|---|---|\n| `update_call` | Update note, tags, spam flag, customer name, lead status |\n| `add_call_tags` / `remove_call_tags` | Additive/subtractive tag changes (preserves existing) |\n| `update_form_submission` | Same field surface as `update_call`, **plus** `value` (numeric, supported on form submissions but NOT on calls — CallRail returns 500) |\n| `create_tag` / `update_tag` / `delete_tag` | Full CRUD on the per-company tag taxonomy |\n\n### Tracker provisioning *(v0.3+)*\n\n| Tool | Purpose |\n|---|---|\n| `create_tracker` | Provision a new tracking number. **Requires `confirm_billing=True`** as a safety guard against accidental AI provisioning |\n| `update_tracker` | Update mutable settings: name, destination, whisper, greeting, SMS |\n| `delete_tracker` | Soft-delete a tracker (releases the phone number, preserves history) |\n\n### Account management *(v0.6+)*\n\n| Tool | Purpose |\n|---|---|\n| `get_company` / `create_company` / `update_company` / `delete_company` | Full company (client) CRUD. Free — CallRail bills per number, not per company. Soft-delete semantics |\n| `get_user` / `create_user` / `update_user` / `delete_user` | Full user CRUD. `create_user` invites by email; common roles: admin / manager / reporting / analyst |\n| `get_tag` | Single tag detail (completes tag CRUD) |\n| `get_form_submission` | Single form-submission detail (was list+update only) |\n| `get_text_message` | Single SMS conversation detail with all messages |\n| `create_form_submission` *(v0.7)* | Manually create a form submission (backfill walk-in / paper-form / offline leads) |\n\n### Notifications + Integrations *(v0.7+)*\n\n| Tool | Purpose |\n|---|---|\n| `list_notifications` / `create_notification` / `update_notification` / `delete_notification` | Full per-user alert-rule CRUD (who gets pinged on which call/text/form event) |\n| `list_integrations(company_id)` / `get_integration` | Discover GMB / Google Ads / Facebook / Slack / Webhook integrations attached to a company |\n| `list_webhooks` / `get_webhook` | Read webhook subscriptions (write CRUD blocked by CallRail account permissions — see \"Out of scope\" below) |\n\n### Outbound calling *(v0.7+)*\n\n| Tool | Purpose |\n|---|---|\n| `create_outbound_call` | Place an outbound call (CallRail dials your tracker first, then bridges to recipient). **Requires `confirm_dialing=True`** as a safety guard — actually dials a real phone, costs minutes, has legal implications |\n\nValidation is strict: phone-number format, area code (`^\\d{3}$`), `pool_size` ∈ [1, 50] (safety cap to prevent accidental 5-figure provisioning bills), name/whisper/greeting length caps, source-type enum (12 values: the 10 documented at apidocs.callrail.com plus `facebook_all` / `bing_all` which are proven in production but still absent from the docs). Tag colors validate against the full documented 24-color set.\n\n### Leads & server-side analytics *(v1.1+)*\n\n| Tool | Purpose |\n|---|---|\n| `list_leads` / `get_lead_timeline` | CallRail's deduplicated person records + full cross-channel history (calls + forms + texts) per lead, with first/last-touch attribution |\n| `list_sms_threads` / `get_sms_thread` / `update_sms_thread` | SMS-thread lead management — tag / note / qualify texting leads like calls (`update_sms_thread` closes the texting write gap) |\n| `call_stats` | Server-side call aggregation (`/calls/summary.json`) — grouped totals by source / keywords / campaign / referrer / landing_page / company in ONE request instead of paginating every call |\n| `call_timeseries` | Per-day call-volume trend line (`/calls/timeseries.json`) |\n| `form_stats` | Server-side form-submission totals |\n| `get_call_page_views` | The visitor's page-view journey behind a call — pairs with `call_eligibility_check` for conversion debugging |\n\n### Agency aggregation *(v0.4+)*\n\n| Tool | Purpose |\n|---|---|\n| `usage_summary` | Per-company cost-attribution breakdown for the cycle. Returns minutes used, active numbers, estimated $ cost share — sorted by biggest cost driver. Useful for \"which client is burning my CallRail budget\" |\n| `call_eligibility_check` | Audit whether a specific call qualifies as a Google Ads conversion. Checks `gclid` presence, answered-status, duration vs. Google's threshold (default 60s), and source. Useful for \"where did my conversion go\" debugging |\n| `compare_periods` *(v0.5)* | Compare current N-day window vs previous N-day window. Per-company minute/call deltas + biggest mover. Catches traffic trends before they hit the invoice |\n| `bulk_update_calls` *(v0.5)* | Apply a single update (tag / note / lead_status / spam) to every call matching a filter. `dry_run=True` by default; surfaces truncation at 500-cap. Replaces dozens of sequential `update_call` invocations |\n| `spam_detector` *(v0.5)* | Heuristically flag likely-spam calls (short duration, unanswered, repeat-caller patterns). Optional `auto_tag=True` adds `auto_detected_spam` tag. Deliberately does NOT set `spam=True` (that would hide the call from default GETs) |\n\nAll tools accept `account_id` optionally — if omitted, the first accessible account is auto-resolved. Most accept `company_id` to filter to a single client.\n\n## How this compares to CallRail's official MCP server\n\nCallRail now offers an official hosted MCP server (documented at\n[apidocs.callrail.com](https://apidocs.callrail.com/#mcp)) — OAuth 2.0,\n~30 tools, with the server URL \"provided by your CallRail account team.\"\nIt's a good option if you want a fully managed remote server.\n\nThis project remains different on purpose:\n\n| | callrail-mcp (this project) | Official CallRail MCP |\n|---|---|---|\n| Install | `pip install callrail-mcp` — running in 2 minutes | URL provisioned by your CallRail account team |\n| Hosting | Local stdio (your API key never leaves your machine) | Hosted remote (OAuth) |\n| Tools | 59 | ~30 |\n| Agency tooling | `usage_summary` cost attribution, `compare_periods`, `spam_detector`, `bulk_update_calls`, `call_eligibility_check` | Not offered |\n| Safety guards | `confirm_billing` / `confirm_dialing` / `dry_run` defaults, strict input validation | — |\n| Source | MIT, open, auditable | Closed |\n\nBoth speak the same underlying REST API v3. If you're an agency running\nClaude against multiple client accounts and want cost attribution and\nbulk workflows, this project is built for exactly that.\n\n## Out of scope (deliberately not implemented)\n\nThe following CallRail capabilities are **NOT in this MCP**, by design.\nPRs welcome if you have an account that supports them — or open an\nissue and we'll prioritize.\n\n### Blocked by CallRail account permissions (returns 403)\n\nThese endpoints exist but require account upgrades / additional\npermissions our standard CallRail account doesn't have. Verified live\n2026-04-24:\n\n- **Send SMS** (`POST /text-messages.json`) — needs A2P SMS\n  registration / dedicated SMS API permission. CallRail enforces\n  TCPA-compliance keywords (STOP / CANCEL / UNSUBSCRIBE) on outbound\n  text messages.\n- **Webhook integration create / update / delete** (`POST /integrations.json`\n  with `type=Webhook`) — needs Integration-Admin permission. CallRail\n  manages webhooks via the Integrations framework, not a standalone\n  endpoint.\n\n### Not exposed by CallRail's REST API (UI-only on standard plans)\n\nThese have no API equivalent at all — managed exclusively via the\nCallRail web UI:\n\n- **Outbound Caller IDs** — verification flow for outbound caller\n  identification.\n- **Numbers** — account-level number ownership, porting, transfers.\n- **Call Flows** — IVR builder / call routing tree configuration.\n- **Custom Fields CRUD** — custom data columns are readable as part\n  of call/form responses but the schema management endpoint isn't\n  exposed.\n- **Do Not Call list** — DNC number management.\n\n### Will work on if/when\n\nEither CallRail upgrades the API or the user upgrades their account\npermissions, the above can be added without breaking changes — we'd\njust expose them as new MCP tools.\n\n### Rich field selection\n\nThe CallRail API returns a lean default payload. Ask for more fields on `list_calls` / `get_call` / `list_form_submissions` via the `fields` parameter:\n\n```\nfields=company_name,source_name,keywords,landing_page_url,device,first_call,value,tags,note,gclid,fbclid,utm_source,utm_medium,utm_campaign,utm_content,utm_term,referrer_domain\n```\n\nSee the [CallRail API docs](https://apidocs.callrail.com/) for the full field catalog per resource.\n\n## Examples\n\n### Claude Code\n\n```\n> List companies under our CallRail account.\n\n(Claude calls list_companies → returns clients with IDs and primary numbers)\n\n> Pull today's calls for company COM019ab... — include source and keyword.\n\n(Claude calls list_calls with company_id, days=1, fields=\"source,keywords,landing_page_url\")\n\n> Why is my CallRail bill $174 this month? Break it down by client.\n\n(Claude calls usage_summary → returns per-company cost share, sorted by biggest user)\n\n> Why didn't this call show up as a conversion in Google Ads? CAL019dbf79...\n\n(Claude calls call_eligibility_check → returns gclid/duration/answered checks\n + targeted reason like \"duration 58s under Google Ads minimum (60s)\")\n\n> Provision a new Google-Ads-call-extension tracker for Alan Construction in 412.\n\n(Claude calls create_tracker — refuses unless you also pass confirm_billing=True\n since it incurs a ~$3/mo charge)\n```\n\n### Direct Python usage\n\nThe `CallRailClient` is also usable as a library:\n\n```python\nfrom callrail_mcp.client import CallRailClient\n\ncr = CallRailClient()  # picks up CALLRAIL_API_KEY\naid = cr.resolve_account_id()\nfor call in cr.paginate(f\"a/{aid}/calls.json\", {\"per_page\": 250}, items_key=\"calls\"):\n    print(call[\"id\"], call.get(\"source\"), call.get(\"customer_name\"))\n```\n\n## Running the server directly\n\nFor debugging or to verify your key works:\n\n```bash\npython -m callrail_mcp\n```\n\nThe server speaks MCP stdio. It will wait for JSON-RPC messages on stdin. Ctrl-C to exit.\n\nTo smoke-test the API key without running the MCP loop:\n\n```python\npython -c \"from callrail_mcp.client import CallRailClient; c=CallRailClient(); print(c.get('a.json'))\"\n```\n\n## Rate limits\n\nCallRail allows 60 requests/minute per API key. The client retries 429 responses using the `Retry-After` header, and 5xx responses with exponential backoff (max 3 retries by default). For heavy pagination, prefer the built-in `paginate()` helper which uses `per_page=100` by default.\n\n## Development\n\n```bash\ngit clone https://github.com/pghdma/callrail-mcp\ncd callrail-mcp\npython -m venv .venv && source .venv/bin/activate\npip install -e \".[dev]\"\npytest\n```\n\n## Contributing\n\nContributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, test conventions, and release flow. Please file issues via [GitHub Issues](https://github.com/pghdma/callrail-mcp/issues) and follow the [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Security\n\nIf you discover a security vulnerability, please report it privately per [SECURITY.md](SECURITY.md) instead of opening a public issue.\n\n## Author\n\n**[Steve Japalucci](https://github.com/pghdma)** — Founder of [Pittsburgh Digital Marketing Agency](https://pghdma.com). Reach out at [s@pghdma.com](mailto:s@pghdma.com).\n\n## License\n\nMIT — see [LICENSE](LICENSE). Copyright © 2026 Steve Japalucci / Pittsburgh Digital Marketing Agency.\n\n## Disclaimer\n\nThis project is an independent open-source integration and is **not affiliated with, endorsed by, or officially supported by CallRail**. \"CallRail\" is a trademark of CallRail, Inc. All product names, logos, and brands are property of their respective owners.\n",
  "bytes": 16373,
  "sha": "9404cc7c127b93d478c5aefc136d9ca712e924f43d0b70511cb81e7e35716404",
  "repo_slug": "pghdma/callrail-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_pghdma_callrail_mcp_3b167593/readme"
}