CodaPhone

Business texting for AI agents: send texts, read threads, manage contacts and run campaigns.

Should I use this

Quality & Safety

A
Description quality
100%
Schema completeness
88%
Naming quality
97%
Poisoning risk
80%
Permission match
100%
Protocol compliance
100%

Findings (2)

  • HIGHTool poisoning patterns detected
  • INFOTool description contains placeholder or incomplete textin provision_number

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~1,931Tokens (tool definitions)
~996 BTypical response size
Moderate attention impact (1.51% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "mcp": {
      "url": "https://mcp.codaphone.app"
    }
  }
}

Remote endpoints

https://mcp.codaphone.appstreamable-http

What it can do

Tool inventory

Tools (14)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟡get_account

Get the current CodaPhone account: its name and mode (live/test), the active number (if any), the current plan and its monthly/daily send caps, usage so far, and remaining automation credits. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢search_numbers(country, kind, areaCode)

Search available phone numbers to provision. Optionally filter by country, number kind (local or tollfree), and a 3-digit area code. Returns candidate numbers with a formatted display, city/region, and monthly price. Does not buy anything. Requires the 'numbers' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "country": {
      "type": "string",
      "description": "ISO country code, e.g. US (default US)."
    },
    "kind": {
      "type": "string",
      "enum": [
        "local",
        "tollfree"
      ],
      "description": "Number type (default local)."
    },
    "areaCode": {
      "type": "string",
      "description": "Preferred 3-digit area code, e.g. 415 (local only)."
    }
  },
  "additionalProperties": false
}
🟢provision_number(msisdn, kind, label, registration)

Provision (set up) a phone number for the account from a candidate returned by search_numbers. Provide the exact msisdn in +1XXXXXXXXXX form and the number kind; optional label and business registration details may be included. An account can hold one active number. Requires the 'numbers' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "msisdn": {
      "type": "string",
      "description": "The number to set up, in +1XXXXXXXXXX form."
    },
    "kind": {
      "type": "string",
      "enum": [
        "local",
        "tollfree"
      ],
      "description": "Number type (default local)."
    },
    "label": {
      "type": "string",
      "description": "Friendly label for the number."
    },
    "registration": {
      "type": "object",
      "description": "Optional business details for the number.",
      "properties": {
        "legal_name": {
          "type": "string"
        },
        "address_line1": {
          "type": "string"
        },
        "address_line2": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "region": {
          "type": "string"
        },
        "postal_code": {
          "type": "string"
        },
        "country": {
          "type": "string"
        },
        "mobile": {
          "type": "string"
        },
        "website": {
          "type": "string"
        }
      },
      "additionalProperties": false
    }
  },
  "required": [
    "msisdn"
  ],
  "additionalProperties": false
}
🟡send_message(body, to, name, thread_id)

Send an SMS from the account's number. Provide the message 'body', and either 'to' (a recipient phone number, with optional 'name' to save the contact) or an existing 'thread_id' to reply within a conversation. Opted-out contacts are blocked and free-send/plan limits apply automatically. Requires the 'send' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "body": {
      "type": "string",
      "description": "The message text to send."
    },
    "to": {
      "type": "string",
      "description": "Recipient phone number, e.g. +14155550100 (omit if using thread_id)."
    },
    "name": {
      "type": "string",
      "description": "Optional name to save for a new contact when using 'to'."
    },
    "thread_id": {
      "type": "string",
      "description": "Reply inside this existing conversation instead of 'to'."
    }
  },
  "required": [
    "body"
  ],
  "additionalProperties": false
}
🟢get_message_status(message_id)

Get one message by id, including its delivery status, direction, body, segment count, and timestamp. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "message_id": {
      "type": "string",
      "description": "The message id."
    }
  },
  "required": [
    "message_id"
  ],
  "additionalProperties": false
}
🟢list_threads(limit, offset)

List the account's conversation threads (the inbox), most recent first, with unread counts and last-message previews. Supports limit/offset pagination. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "description": "Max threads to return (default 50)."
    },
    "offset": {
      "type": "integer",
      "description": "Number of threads to skip (default 0)."
    }
  },
  "additionalProperties": false
}
🟢get_thread(thread_id)

Get one conversation thread by id together with its messages. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "thread_id": {
      "type": "string",
      "description": "The thread id."
    }
  },
  "required": [
    "thread_id"
  ],
  "additionalProperties": false
}
🟢mark_thread_read(thread_id)

Mark a conversation thread as read (clears its unread count) and return the account's new total inbox unread count. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "thread_id": {
      "type": "string",
      "description": "The thread id to mark read."
    }
  },
  "required": [
    "thread_id"
  ],
  "additionalProperties": false
}
🟢list_contacts(search, list_id, sort, limit, offset)

List the account's contacts with opt-in status and timezone. Optionally filter by a search term or a list id, choose a sort, and paginate with limit/offset. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "search": {
      "type": "string",
      "description": "Filter by name or number."
    },
    "list_id": {
      "type": "string",
      "description": "Only contacts in this list."
    },
    "sort": {
      "type": "string",
      "description": "Sort order, e.g. recent or name (default recent)."
    },
    "limit": {
      "type": "integer",
      "description": "Max contacts to return (default 500)."
    },
    "offset": {
      "type": "integer",
      "description": "Number of contacts to skip (default 0)."
    }
  },
  "additionalProperties": false
}
🟡add_contacts(msisdn, name, list_id, opt_in_source)

Add a contact to the account. Provide the phone number (msisdn) and optionally a name, a list_id to file it under, and an opt_in_source note. Adds one contact per call. Requires the 'contacts' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "msisdn": {
      "type": "string",
      "description": "Contact phone number, e.g. +14155550100."
    },
    "name": {
      "type": "string",
      "description": "Contact name."
    },
    "list_id": {
      "type": "string",
      "description": "Optional list to add the contact to."
    },
    "opt_in_source": {
      "type": "string",
      "description": "How the contact opted in (record-keeping)."
    }
  },
  "required": [
    "msisdn"
  ],
  "additionalProperties": false
}
🟢list_campaigns

List the account's bulk-messaging campaigns with their status and progress counts, plus the remaining automation credit balance. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢get_campaign(campaign_id)

Get one campaign by id, including its base message, audience, schedule, pacing, and send/failed/skipped counts. Requires the 'read' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "campaign_id": {
      "type": "string",
      "description": "The campaign id."
    }
  },
  "required": [
    "campaign_id"
  ],
  "additionalProperties": false
}
🟡create_campaign(name, base_message)

Create a new bulk-messaging campaign with a name and an optional base message. After creating, use run_campaign to generate variations, set the audience, schedule, and launch it. Requires the 'campaigns' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Campaign name."
    },
    "base_message": {
      "type": "string",
      "description": "The base message text (optional; can be set later)."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
🟡run_campaign(campaign_id, action, base_message, count, variations, ...)

Advance a campaign through its lifecycle. Provide the campaign_id and an action: - generate: create message variations (optional base_message, count) - variations: save edited variations (variations: [{body, active}]) - audience: set the recipient list (list_id) - schedule: set send time/pacing (schedule_at, pace_seconds, daily_ceiling) - launch: start sending (or start at the scheduled time) - pause / resume / cancel: control a running campaign Sends honor opt-outs, sending hours, credits, and plan caps automatically. Requires the 'campaigns' scope.

Input Schema

{
  "type": "object",
  "properties": {
    "campaign_id": {
      "type": "string",
      "description": "The campaign id."
    },
    "action": {
      "type": "string",
      "enum": [
        "generate",
        "variations",
        "audience",
        "schedule",
        "launch",
        "pause",
        "resume",
        "cancel"
      ],
      "description": "The lifecycle action to run."
    },
    "base_message": {
      "type": "string",
      "description": "generate: base message to vary from."
    },
    "count": {
      "type": "integer",
      "description": "generate: how many variations."
    },
    "variations": {
      "type": "array",
      "description": "variations: the edited variations to save.",
      "items": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "list_id": {
      "type": "string",
      "description": "audience: the contact list to send to."
    },
    "schedule_at": {
      "type": "string",
      "description": "schedule: ISO timestamp to start, or null for send-now."
    },
    "pace_seconds": {
      "type": "integer",
      "description": "schedule: seconds between sends."
    },
    "daily_ceiling": {
      "type": "integer",
      "description": "schedule: max sends per day (<= plan cap)."
    }
  },
  "required": [
    "campaign_id",
    "action"
  ],
  "additionalProperties": false
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded14 tools