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. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| 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'.
page: 1-indexed. Agencies with more than |
| 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_trackerB | 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. One of
VALID_SOURCE_TYPES: 'all', 'landing_url', 'landing_params',
'offline', 'web_referrer', 'direct', 'search',
'google_ad_extension' (what Google Ads call extensions use),
'mobile_ad_extension', 'google_my_business', plus the
production-observed 'facebook_all' and 'bing_all'.
Ignored for type='session'.
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, and answer 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_submissionsA | List form submissions captured by CallRail's Form Tracking. Paginated. Filterable by company and date window. Args:
account_id: CallRail account ID. Auto-resolves if omitted.
company_id: Filter to one company. Omit for all companies.
days: Lookback in days (default 7). Ignored if Returns:
JSON string with |
| list_text_messagesA | List SMS/text message conversations sent to or received via CallRail trackers. Paginated. Filterable by company and date window. Receiving SMS works on standard accounts. Outbound SMS sending
requires CallRail's A2P SMS API permission (returns 403 otherwise);
see Args:
account_id: CallRail account ID. Auto-resolves if omitted.
company_id: Filter to one company. Omit for all companies.
days: Lookback in days (default 7). Ignored if Returns:
JSON string with |
| list_usersA | List all users on the account. Returns a single page of up to
Args: account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string with |
| get_call_recordingA | Get the recording URL for a call. Returns a short-lived signed URL. Fetch and use it within a few minutes before it expires. Recording must be enabled on the company (CallRail UI > Settings > Account). Calls placed BEFORE recording was enabled have no recording even if it's enabled now; CallRail does not retroactively record. Args: call_id: 'CAL...' id. account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string with |
| get_call_transcriptA | Get the AI transcript for a call. Requires CallRail Conversation Intelligence (CallScribe) to be enabled on the company at the time the call was placed. If CallScribe was enabled AFTER the call, no transcript exists; CallRail does not retroactively transcribe. ⚠️ As of CallRail's 2026-05-21 API change, transcript data requires
a Premium Conversation Intelligence subscription; without it,
the endpoint 404s (and the Args: call_id: 'CAL...' id. account_id: CallRail account ID. Auto-resolves if omitted. Returns: JSON string with the transcription including segments (text per speaker turn), per-segment confidence scores, and durations. |
| 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, 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_tagsA | Append tags to a call WITHOUT replacing existing ones. Reads the call's current tags first, merges the new ones in, then
PUTs the combined list. Use this when you want to add labels (e.g.
'lead', 'spam', 'follow-up') without losing prior tags. To fully
replace tags, use Auto-creates company-level tags for any name not already in the
system (CallRail's default behavior). Empty/whitespace-only entries
are silently filtered, so Args: call_id: 'CAL...' id. tags: Tag names to add. Strings only; non-strings are dropped with a warning. De-duplicated. Max 100 tags per request. account_id: CallRail account ID. Auto-resolves if omitted. Returns: JSON string with the updated call object (showing the merged tag list). Errors if no valid tags remain after cleaning. |
| 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_tagsC | 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 24 CallRail-supported colors (see VALID_TAG_COLORS): gray1-2, blue1-2, cyan1-2, purple1-2, pink1-4, red1-2, orange1-4, yellow1-2, green1-4. 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 the 24 CallRail-supported colors (see VALID_TAG_COLORS): gray1-2, blue1-2, cyan1-2, purple1-2, pink1-4, red1-2, orange1-4, yellow1-2, green1-4. |
| delete_tagA | Delete a tag definition from the account. Removes it from any calls or form submissions that had it applied. This is a HARD delete; the tag is gone permanently along with its
historical applications. To preserve history, prefer renaming or
disabling via Args: tag_id: Numeric tag ID. CallRail tag IDs are integers (NOT the string-prefixed format other entities use). Must match ^[0-9]+$ (string or numeric forms accepted). account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string |
| 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: 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_companyA | Update mutable settings on a company. Pass None to leave a field unchanged; only fields with explicit values are sent in the PUT body. CRITICAL: Any boolean toggle you set will OVERRIDE current state.
If a company has CallScribe enabled and you call
Empty-string Args:
company_id: 'COM...' id.
name: New display name. Empty string rejected. Max 255 chars.
time_zone: IANA tz string (e.g. 'America/New_York').
callscore_enabled: Lead-scoring AI feature. PAID add-on.
lead_scoring_enabled: Older lead-scoring system.
swap_exclude_jquery: Skip jQuery initialization in DNI script.
callscribe_enabled: Conversation Intelligence (transcripts +
keyword spotting). PAID feature.
keyword_spotting_enabled: DEPRECATED by CallRail. Accepted for
compatibility but has no effect.
swap_exclude_jquery: DEPRECATED by CallRail (the DNI script no
longer needs jQuery). Accepted but has no effect.
form_capture: Enable CallRail Form Tracking on this company.
Sent as CallRail's Returns: JSON string with the updated company object. |
| delete_companyA | Soft-delete a company. Status flips to 'disabled', records retained. Mirrors Returns: |
| get_userA | Get full detail for one user on the account. Args: user_id: 'USR...' id. account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string with the user object: id, email, first_name,
last_name, role ('admin' | 'manager' | 'reporting'),
accepted_at (null if invitation pending), time_zone, and
|
| 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_submissionA | Get full detail for one form submission, including all submitted field data. Useful for retrieving the original form payload after seeing a
submission ID via Args: submission_id: 'FOR...' id. account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string with the form submission: submitted_at, customer
details, source/UTM attribution, landing page URL, referrer,
and |
| 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 |
| get_tagB | 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 REAL PHONES. CallRail dials US and Canadian numbers only (CallRail does not support outbound to the UK or Australia via this endpoint). You must pass Args:
caller_id: The number shown to the recipient. Must be one of your
CallRail tracking numbers or a verified Outbound Caller ID.
E.164 format.
business_phone_number: The FIRST leg CallRail dials (your agent's
phone). E.164 format.
customer_phone_number: The SECOND leg, bridged in once the
business leg answers. E.164 format.
confirm_dialing: REQUIRED. Set True to actually dial. Returns an
error envelope if False (default).
recording_enabled: Record this call.
outbound_greeting_text: Text-to-speech greeting played to the
customer.
outbound_greeting_recording_url: Public URL of an audio greeting,
used instead of Returns: The call object CallRail creates (id, etc.). NOTE (v1.2.0): earlier versions sent |
| create_notificationB | 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_notificationA | Update a notification rule. Pass None to leave a field unchanged; only fields with explicit values are sent in the PUT body. Notification rules trigger emails / desktop pushes / SMS when calls
or form submissions match conditions. Use this to rewire targets,
change triggering events, or silence a noisy rule without deleting
it (set all Args:
notification_id: Notification rule ID.
name: Display name for the rule.
alert_type: Common values: 'all_calls', 'first_time_callers',
'missed_calls', 'voicemails', 'all_texts',
'first_time_texters', 'all_form_submissions' (same set as
Returns: JSON string with the updated notification rule. |
| delete_notificationA | Delete a notification rule. The rule is gone. To keep but mute
it, prefer Args: notification_id: Notification rule ID. account_id: CallRail account ID. Auto-resolves if omitted. Returns:
JSON string |
| 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. |
| list_leadsA | List leads (unique people) across calls, forms, and texts. A lead is CallRail's deduplicated person record: one entry per
customer regardless of how many times they called / submitted /
texted. Use Args: account_id: Auto-resolves if omitted. company_id: Filter to one company. per_page: Page size (max 250). page: 1-indexed. Returns:
JSON string with |
| get_lead_timelineA | Get a lead's full cross-channel activity timeline: every call, form submission, and text thread from that person in one response, with first-touch/last-touch attribution. This replaces the manual "search calls by number + search forms by email" dance when reconstructing a customer's history. Args:
lead_id: 'PER...' lead id (from Returns:
JSON string with |
| list_sms_threadsA | List SMS threads. Unlike Args: account_id: Auto-resolves if omitted. company_id: Filter to one company. per_page: Page size (max 250). page: 1-indexed. Returns:
JSON string with |
| get_sms_threadA | Get one SMS thread's lead-management record (notes, value, tags,
lead_qualification, state). For the message transcript itself use
Args:
thread_id: Thread id (from |
| update_sms_threadA | Update an SMS thread's lead-management fields. This is the texting
equivalent of Args:
thread_id: Thread id (from |
| call_statsA | Server-side call aggregation via CallRail's /calls/summary.json. One request instead of paginating every call. Prefer this over
Args:
group_by: Dimension to group by. One of: 'source', 'keywords',
'campaign', 'referrer', 'landing_page', 'company'.
days: Lookback (default 30). Ignored if Returns:
JSON string with |
| call_timeseriesA | Call volume over time via CallRail's /calls/timeseries.json. One request for a trend line instead of client-side bucketing. CallRail refuses any request whose result set would exceed 200 data
points. With the default daily interval that caps the window at ~200
days; use Args:
days: Lookback (default 30). Ignored if Returns:
JSON string with |
| form_statsA | Server-side form-submission totals via /forms/summary.json. Args:
days: Lookback (default 30). Ignored if Returns:
JSON string with |
| get_call_page_viewsA | Get the visitor's page-view history behind a call: which pages
they browsed (with timestamps) before and around dialing. Pairs
with Args: call_id: 'CAL...' id. account_id: Auto-resolves if omitted. per_page: Page size (max 250). page: 1-indexed. Returns:
JSON string with |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 57 tools
Most tools target distinct resources with clear CRUD separation, but several pairs overlap in purpose: list_text_messages vs list_sms_threads, call_summary vs call_stats, and get_sms_thread vs get_text_message. The descriptions carefully explain the differences, so a careful agent can disambiguate, but the boundaries are not self-evident from tool names alone.
The CRUD tools follow a consistent list_/get_/create_/update_/delete_ pattern, but analytics and utility tools break it with noun-style names (call_summary, call_stats, usage_summary, form_stats, spam_detector) and non-standard verb forms (search_calls_by_number, bulk_update_calls, add_call_tags, remove_call_tags). The mixed conventions remain readable but lack a single predictable pattern.
With 57 tools, this server is well beyond the 'too many' threshold and into the extreme range. Even for a broad API, the surface is overwhelming and includes many granular variants (four summary/stats tools, three SMS-listing tools, and seven tag-related tools) that could be consolidated.
Coverage is broad across companies, trackers, calls, forms, SMS threads, tags, users, notifications, leads, and analytics. However, there are notable gaps: create_text_message is referenced in list_text_messages but does not exist as a tool, form submissions have no delete operation, and account-level get/update is missing. Agents can work around most gaps but may hit dead ends.