CallRail MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CALLRAIL_API_KEY | No | Your CallRail API key. Alternatively, you can store it in a file at ~/.config/callrail/api-key.txt or set CALLRAIL_API_KEY_FILE to a custom path. | |
| CALLRAIL_API_KEY_FILE | No | Path to a file containing the CallRail API key. Defaults to ~/.config/callrail/api-key.txt if not set. |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_accountsA | List CallRail accounts accessible to this API key. Most users have one account per agency. The returned |
| list_companiesA | List companies (client businesses) under a CallRail account. Args: account_id: CallRail account ID. Auto-resolves if omitted. per_page: Page size (max 250). status: Filter by status. Defaults to None (returns all). Common values: 'active' (excludes disabled/soft-deleted), 'disabled'. |
| list_trackersA | List tracking phone numbers (trackers). Each tracker maps a pool of phone numbers to a traffic source (Google Ads, Organic, Direct, etc.). Args: account_id: Auto-resolves if omitted. company_id: Filter to one company. per_page: Page size (max 250). page: 1-indexed. status: Filter by status. Defaults to None (returns all, including soft-deleted/disabled). Common values: 'active', 'disabled'. |
| get_trackerA | Get full detail for a specific tracker. Args: tracker_id: 'TRK...' id. account_id: Auto-resolves if omitted. |
| create_trackerA | ⚠️ Create a new tracking phone number (tracker). THIS COSTS MONEY. CallRail charges per provisioned number — typical pricing as of 2026:
Most plans bundle 5–10 numbers; provisioning beyond your bundle adds overage charges. Some plans prorate partial-month usage, so creating and immediately deleting can still produce a small charge depending on your contract. You must pass Args:
name: Display name for the tracker (e.g. "Google Ads Call Extension").
company_id: 'COM...' id of the company this tracker belongs to.
destination_number: Where calls forward to, e.g. "+14129548337".
confirm_billing: REQUIRED — set True to acknowledge the per-number
cost. Returns an error envelope if False (default).
type: 'source' (single number tied to one traffic source) or 'session'
(DNI pool that swaps numbers per visitor). Default 'source'.
source_type: For type='source', which traffic source. Must be one of:
'all', 'direct', 'offline', 'google_my_business',
'google_ad_extension' (this is what Google Ads call-extension uses).
Ignored for type='session' (use 'all').
area_code: 3-digit area code to provision the local number from
(e.g. '412'). Ignored if Returns the created tracker including its newly-provisioned tracking_numbers. |
| update_trackerA | Update a tracker's mutable settings: name, destination, whisper, greeting, SMS. Args: tracker_id: 'TRK...' id. account_id: Auto-resolves if omitted. name: New display name. destination_number: Where calls forward (e.g. "+14129548337"). Updates the call_flow's destination too. whisper_message: New whisper text. greeting_text: New automated greeting. If supplied, you must also supply destination_number — CallRail's PUT /trackers replaces the entire call_flow object, so updating only greeting_text would silently zero out the destination, breaking the tracker. sms_enabled: Toggle SMS on/off. Field-level rules:
- NOTE: Setting |
| delete_trackerA | Delete (disable) a tracker. Soft-removes it from active trackers; the tracker keeps its call history but stops receiving new calls. The underlying phone number is released. Args: tracker_id: 'TRK...' id. account_id: Auto-resolves if omitted. Returns: An object with |
| list_callsA | List calls. Paginated. Filterable by company, date window, source, answered status. Args:
account_id: Auto-resolves if omitted.
company_id: Filter to one company. Omit for all companies.
days: Lookback in days (default 7). Ignored if |
| get_callA | Get full detail for a specific call. Args: call_id: CallRail call id (prefix 'CAL...'). account_id: Auto-resolves if omitted. fields: Comma-separated extra fields (see list_calls for common names). |
| call_summaryA | Summarize calls over a date window. Returns counts: total, answered/missed, first-time/repeat callers, total
duration, and breakdowns by Note: requires |
| list_form_submissionsC | List form submissions captured by CallRail's Form Tracking. |
| list_text_messagesC | List SMS/text message conversations. |
| list_usersC | List users on the account. |
| get_call_recordingB | Get the recording URL for a call (if recording is enabled on the company). |
| get_call_transcriptC | Get the AI transcript for a call (requires CallRail Conversation Intelligence). |
| search_calls_by_numberA | Find calls from/to a specific phone number. Matches on the last 10 digits
of the stored Args: phone_number: Any format — will be normalized to digits-only. Must contain at least 7 digits to avoid false positives. account_id: Auto-resolves. company_id: Optional company filter. days: Lookback window (default 90). |
| update_callA | Update an existing call: notes, tags, spam flag, customer name, lead status. Args:
call_id: 'CAL...' id of the call to update.
account_id: Auto-resolves if omitted.
note: Replace the call's note text.
tags: REPLACE the call's tag list with this set of tag names.
(Use Note: Empty-string fields (e.g. Length caps (rejected pre-network):
- |
| add_call_tagsB | Append tags to a call without replacing existing ones. Empty/whitespace-only tag names are silently filtered out so that a
request like |
| remove_call_tagsA | Remove specific tags from a call (case-sensitive on tag name). Idempotent — removing a tag that isn't attached succeeds silently. Empty/whitespace-only entries in the input list are ignored. |
| update_form_submissionA | Update an existing form submission: notes, tags, value, spam, lead status. Args:
submission_id: CallRail form-submission id (prefix 'FOR...').
account_id: Auto-resolves if omitted.
note, tags, value, spam, lead_status: same semantics as Empty-string fields (e.g. Length caps (rejected pre-network):
- |
| list_tagsA | List all tags in the account, or filtered to one company. |
| create_tagA | Create a new tag scoped to one company. Args: name: Tag display name. company_id: Required — tags are per-company in CallRail. account_id: Auto-resolves if omitted. color: One of the 10 CallRail-supported colors: 'red1', 'red2', 'orange1', 'yellow1', 'green1', 'blue1', 'purple1', 'pink1', 'gray1', 'gray2'. If omitted, CallRail defaults to 'gray1'. |
| update_tagA | Rename or recolor a tag. Args: tag_id: Numeric tag id. account_id: Auto-resolves if omitted. name: New display name. color: One of: 'red1', 'red2', 'orange1', 'yellow1', 'green1', 'blue1', 'purple1', 'pink1', 'gray1', 'gray2'. |
| delete_tagB | Delete a tag. Removes it from any calls/form submissions it was on. |
| usage_summaryA | Per-company cost-attribution summary for the current cycle. Aggregates active trackers + per-company call minutes and projects what each client is contributing to the agency's CallRail bill. Useful for:
Pricing assumes Call Tracking Starter ($50 base + 5 numbers + 250 mins bundled; $3/local number, $5/toll-free number, $0.05/local minute, $0.08/toll-free minute over bundle). Edit PRICING_* constants in server.py if you're on a different plan. Args:
account_id: Auto-resolves if omitted.
days: Lookback window in days (default 30 = roughly one cycle).
Ignored if Returns:
- Cost shares sum exactly to |
| call_eligibility_checkA | Audit whether a specific call is/was eligible to count as a Google Ads conversion. Useful for "where did my conversion go" debugging. Checks:
Args: call_id: 'CAL...' id. google_ads_min_duration_seconds: Threshold to check duration against. Defaults to 60 (Google's UI default). Override if you've lowered it on a specific conversion action. account_id: Auto-resolves if omitted. Returns: Verdict + each criterion's pass/fail + suggested remediation when eligibility fails. |
| compare_periodsA | Compare current N-day window vs the previous N-day window. Returns per-company minute / call deltas + agency-wide totals. Useful for "is Malick growing?", "did we lose Stewart traffic this month?", catching invoice surprises before they hit. Args: days: Window length on each side (default 30 = roughly one cycle). Cap: 365 (don't ask for "5-year delta" — likely a typo). account_id: Auto-resolves if omitted. Returns: A breakdown showing current vs previous totals, % deltas, and per-company growth/shrink. Sorted by absolute minute change. Implementation: pulls call data for both windows in one tool call. Tracker counts use current-snapshot for both periods (CallRail doesn't expose historical tracker counts) — only minute deltas reflect actual period-over-period change. |
| bulk_update_callsA | Apply the same update to every call matching a filter. Useful for: "tag every Bing call this month as low-priority",
"mark all <30s unanswered calls from this number as spam",
"add a note to every call from a specific landing page". Replaces
dozens of sequential Safety: Args:
company_id, days, source, answered: filter — same semantics as
Returns:
- If dry_run: Performance note: when |
| spam_detectorA | Heuristically identify likely-spam calls and (optionally) tag them. Spam scoring (additive): +2 if duration < 10 seconds +1 if not answered +1 if first_call AND duration < 30 seconds +1 if same caller appears >=3 times in window (likely auto-dialer) A call scoring >= 3 is flagged as likely spam. Args:
company_id: Restrict to one company (recommended).
days: Lookback window (1-90; 90 is hard-capped to avoid memory
blowup on high-volume clients — full call list is materialized
for scoring before truncating the response).
auto_tag: If True, ADD Returns: - score breakdown by call - histogram of caller phone numbers (so you can spot a single dialer hammering you) - if auto_tag: count tagged + failures |
| get_companyA | Get full detail for one company. Args: company_id: 'COM...' id. account_id: Auto-resolves if omitted. Note: Returns the disabled record (with |
| create_companyA | Create a new company (client) under the account. Useful for new-client onboarding. CallRail bills per number, not per
company — creating a company is free; provisioning trackers under
it is what costs money (see Args: name: Display name (e.g. "Smith & Co Roofing"). Required. time_zone: IANA TZ. Default 'America/New_York' (matches your existing companies). Common: 'America/Los_Angeles', 'America/Chicago', 'America/Denver'. callscore_enabled: CallRail CallScore™ AI scoring (paid feature). Pass None (default) to inherit account-level default. lead_scoring_enabled: Manual lead-status workflow. None=inherit. swap_exclude_jquery: Skip jQuery-driven phone swaps. None=inherit. callscribe_enabled: Conversation Intelligence transcripts (paid). None=inherit. keyword_spotting_enabled: Real-time keyword detection in calls. None=inherit. form_capture: Enable CallRail Form Tracking. None=inherit. account_id: Auto-resolves if omitted. Note: Optional booleans default to None (inherit account-level
defaults) rather than False. Sending |
| update_companyB | Update mutable settings on a company. Pass None to leave unchanged. Empty-string |
| delete_companyA | Soft-delete a company. Status flips to 'disabled', records retained. Mirrors Returns: |
| get_userB | Get full detail for one user. Args: user_id: 'USR...' id. |
| create_userA | Invite a new user. CallRail emails them an account-creation link. Args: email: Recipient email. CallRail sends an invite. first_name, last_name: Display name. role: Default 'reporting' (read-only). Common values: 'admin', 'manager', 'reporting', 'analyst'. Other plan-specific roles may exist; we don't reject unknown values, just warn. company_ids: List of 'COM...' company IDs the user can access. Empty/None = account-wide (admins typically). account_id: Auto-resolves if omitted. Note: This sends an invitation email. Don't run experimentally. |
| update_userA | Update mutable user fields. Pass None to leave unchanged. Args: user_id: 'USR...' id. company_ids: REPLACES the user's company access list (additive modification not exposed; for additive use the CallRail UI). |
| delete_userA | Remove a user from the account. CallRail's DELETE on users is typically a hard-remove (unlike companies/trackers which soft-delete). The user loses access immediately. Returns: |
| get_form_submissionC | Get full detail for one form submission. Args: submission_id: 'FOR...' id. |
| get_text_messageA | Get full detail for one SMS conversation, including all messages. Args:
conversation_id: Short alphanumeric conversation id (e.g. '8hw3p').
Returned by |
| list_webhooksA | List webhook subscriptions on the account or one company. Args: company_id: Filter to webhooks attached to one company. per_page: Page size (max 250). page: 1-indexed. account_id: Auto-resolves if omitted. |
| get_webhookA | Get full detail for one webhook subscription. Args: webhook_id: Webhook id (CallRail-assigned). |
| get_tagA | Get full detail for one tag. Args: tag_id: Numeric tag id. account_id: Auto-resolves if omitted. |
| list_integrationsA | List integrations attached to one company (GMB, Google Ads, Facebook, Slack, Webhooks, etc.). Args: company_id: 'COM...' id. Required — the integrations endpoint returns 400 without it (account-level listing isn't supported). per_page: Page size (max 250). page: 1-indexed. account_id: Auto-resolves if omitted. |
| get_integrationA | Get full detail for one integration. Args: integration_id: Numeric integration id (from list_integrations). account_id: Auto-resolves if omitted. |
| create_form_submissionA | Manually create a form submission (e.g. backfill an offline lead). Useful when you receive a lead through a non-CallRail-tracked channel (paper form, in-person, etc.) and want it visible in CallRail with proper attribution + lead-status workflow. Args:
company_id: 'COM...' id. Required.
referrer / referring_url / landing_page_url: All three required
(CallRail enforces "either session_id or all 3 of these").
Use the original web context if known, or "(direct)" /
"https://offline" placeholders for in-person leads.
form_url: URL of the form page if applicable.
form_data: Dict of form-field values (e.g.
|
| create_outbound_callA | ⚠️ Place an outbound call. THIS ACTUALLY DIALS A REAL PHONE. CallRail will dial You must pass Args:
from_number: Your end of the call (typically your tracking number,
e.g. Returns: The call object CallRail creates (id, etc.). |
| create_notificationA | Create a notification rule (who gets pinged on which event). Args: name: Display name for this rule. user_id: 'USR...' id of the user being notified. alert_type: Trigger event. Common values: 'all_calls', 'first_time_callers', 'missed_calls', 'voicemails', 'all_texts', 'first_time_texters', 'all_form_submissions'. Plan-specific types may exist. company_id, tracker_id: Optional scope filters. send_email / send_desktop / send_push: Channel toggles. call_enabled / sms_enabled: Trigger toggles for mixed-event rules. email: Override email address (defaults to user's email). account_id: Auto-resolves if omitted. |
| update_notificationC | Update a notification rule. Pass None to leave fields unchanged. |
| delete_notificationC | Delete a notification rule. |
| list_notificationsA | List notification rules on the account. Args: company_id, user_id: Optional filters. per_page: Page size (max 250). page: 1-indexed. account_id: Auto-resolves if omitted. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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/pghdma/callrail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server