protogrid

Search / com.jointextkit/textkit

TextKit

R0· no sign-in

SMS for developers: send and receive texts, verify phones, and buy US and Canada numbers.

v1.0.2 · active · repository · website · descriptor JSON · versions

An agent can connect right now, no human step.Remote endpoint, no authentication, reachable on the last probe.
Quality60needs work
Trust96of 100
Uptime, 30 days100%
Latency p50392 ms

Connect

8 clients · secrets stay placeholders
{
  "mcpServers": {
    "textkit": {
      "type": "http",
      "url": "https://mcp.jointextkit.com"
    }
  }
}
claude mcp add --transport http textkit https://mcp.jointextkit.com
[mcp_servers.textkit]
url = "https://mcp.jointextkit.com"
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "textkit": {
      "type": "remote",
      "url": "https://mcp.jointextkit.com",
      "enabled": true
    }
  }
}
{
  "mcpServers": {
    "textkit": {
      "type": "http",
      "url": "https://mcp.jointextkit.com"
    }
  },
  "deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=textkit&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vbWNwLmpvaW50ZXh0a2l0LmNvbSJ9"
}
{
  "servers": {
    "textkit": {
      "type": "http",
      "url": "https://mcp.jointextkit.com"
    }
  }
}
{
  "mcpServers": {
    "textkit": {
      "httpUrl": "https://mcp.jointextkit.com"
    }
  }
}
extensions:
  "textkit":
    enabled: true
    name: "textkit"
    type: streamable_http
    uri: "https://mcp.jointextkit.com"
    timeout: 300

Quality 60 / 100needs work

protocol75 · weight 25
  • warn
    protocol.modernnewest supported version is 2025-03-26; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
  • n/a
    protocol.statelessonly applies to 2026-07-28 servers
  • pass
    protocol.transportstreamable HTTP
  • n/a
    protocol.list_ttlonly applies to 2026-07-28 servers
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene64 · weight 30
  • warn
    tools.descriptions6 of 152 tools have a description under 20 characters
  • warn
    tools.description_length1 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • pass
    tools.annotations152 of 152 tools declare readOnlyHint or destructiveHint
  • pass
    tools.directory_hintsevery tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
  • fail
    tools.token_costabout 30,013 tokens to load every tool, a large share of an agent's context
  • warn
    tools.api_dump152 tools, 65% named like REST operations: looks like an API mapped one endpoint per tool
stability25 · weight 15
  • warn
    stability.changes105 tool changes in 30 days
  • fail
    stability.rug_pull3 tools kept their name but changed most of their description in 30 days; review before trusting them
dependenciesn/a · weight 15
  • n/a
    deps.known_vulns, deps.mcp_sdk_version, deps.resolvableno npm or PyPI package

152 tools, about 30,013 tokens to load them all · tool set 010afc0935c3 · tools last changed 2026-11-05 · checked 2026-11-07 17:28 UTC

Tool changes

  • update_integrationchangeddescription, input schema
    before

    Rename, pause or resume (status), or change an integration's settings or credentials (left-out credentials keep the stored ones). eventTriggers (Mixpanel) maps Mixpanel events to TextKit events; changing only those does not re-test credentials or resync.

    after · 80% of words in common

    Rename, pause or resume (status), or change an integration's settings or credentials (left-out credentials keep the stored ones). eventTriggers (Mixpanel) maps Mixpanel events to TextKit events; exportEvents: false stops sending text events to Mixpanel (on by default); changing only those does not re-test credentials or resync.

  • connect_integrationchangedinput schema
  • track_eventchangeddescription, input schema
    before

    Record something a customer did (e.g. signed_up, cart_abandoned, trial_ending), by user_id and/or phone. It starts or advances any active automation listening for that event.

    after · 73% of words in common

    Record something a customer did (e.g. signed_up, cart_abandoned, trial_ending), by user_id and/or phone. It starts or advances any active automation listening for that event. external_id (their Mixpanel distinct_id, when not user_id) puts the texts it starts on their Mixpanel profile.

  • send_batchchangeddescription, input schema
    before

    Send one message to many people (a broadcast or campaign): pick recipients by segment_id, tags, contact_ids, or an explicit recipients list. Opted-out numbers, numbers without marketing consent, and people unsubscribed from topic_id are removed before sending. dry_run: true sends nothing and returns the count, cost, rejected rows and consent. scheduled_at sends at one instant; send_at_local (like 2026-11-10T17:00) sends at that time on each person's own clock.no_opt_in (recipients the send will skip for having no opt-in). Leave out `from` and TextKit picks a number approved for `category` (marketing unless you say otherwise), one per recipient; `sender` shows them, and with none approved it answers 400 and sends nothing. scheduled_at sends later (up to 30 days). shorten_links: true tracks link clicks: suggest it whenever the text has a link. With a live key it texts real people.

    after · 92% of words in common

    Send one message to many people (a broadcast or campaign): pick recipients by segment_id, tags, contact_ids, or an explicit recipients list. Opted-out numbers, numbers without marketing consent, and people unsubscribed from topic_id are removed before sending. dry_run: true sends nothing and returns the count, cost, rejected rows and consent. scheduled_at sends at one instant; send_at_local (like 2026-11-10T17:00) sends at that time on each person's own clock.no_opt_in (recipients the send will skip for having no opt-in). Leave out `from` and TextKit picks a number approved for `category` (marketing unless you say otherwise), one per recipient; `sender` shows them, and with none approved it answers 400 and sends nothing. scheduled_at sends later (up to 30 days). shorten_links: true tracks link clicks: suggest it whenever the text has a link. Each recipient can carry external_id (their Mixpanel distinct_id) so the text's events land on their Mixpanel profile. With a live key it texts real people.

  • send_messagechangedinput schema
  • create_schedulechangedinput schema
  • preview_automationchangeddescription, input schema
    before

    See an automation's texts exactly as they would go out, without sending: works on drafts. Pass sample event properties (e.g. {"amount": 9.99}) and optionally `to` for a contact's merge fields. Returns each send_sms step's final text (brand and opt-out wording added as we would), segments, encoding, estimated cost, and merge fields that would come out empty.

    after · 85% of words in common

    See an automation's texts exactly as they would go out, without sending: works on drafts. Pass sample event properties (e.g. {"amount": 9.99}) and optionally `to` for a contact's merge fields. Returns each send_sms step's final text (brand and opt-out wording added as we would), segments, encoding, estimated cost, merge fields that would come out empty, and, for an optimal-user-time step with `to`, next_send: when it would go for that person and why.

  • update_automationchangedinput schema
  • create_automationchangeddescription, input schema
    before

    Create a triggered text flow (as a draft): when trigger.event is tracked, run steps such as send_sms, wait, wait_for_event, and condition branches. Example: on cart_abandoned, wait 3600s, then if checkout_completed was not received send a reminder. For events that repeat, trigger.cooldown_seconds stops the same person starting it again for that long. Merge fields like {{plan}} fill from the trigger event's properties; `issues` names any no tracked event carries. Leave out `from` and TextKit picks a number approved for `category` (marketing, transactional for alerts, otp for codes) when it sends; `sender` shows the numbers, and `issues` says so when none is approved yet. Pass `from` only to pin a number. Drafts send nothing until activated.

    after · 74% of words in common

    Create a triggered text flow (as a draft): when trigger.event is tracked, run steps such as send_sms, wait, wait_for_event, and condition branches. Example: on cart_abandoned, wait 3600s, then if checkout_completed was not received send a reminder. A send_sms step with send_time: "optimal_user_time" and max_wait_seconds (60 to 86400, required) waits for the hour that person usually replies or clicks, 10am their time with no history, inside quiet hours: recommend it for marketing and lifecycle texts, leave it off anything time-sensitive, and it is refused for one-time codes and order or shipping texts. For events that repeat, trigger.cooldown_seconds stops the same person starting it again for that long. Merge fields like {{plan}} fill from the trigger event's properties; `issues` names any no tracked event carries. Leave out `from` and TextKit picks a number approved for `category` (marketing, transactional for alerts, otp for codes) when it sends; `sender` shows the numbers, and `issues` says so when none is approved yet. Pass `from` only to pin a number. Drafts send nothing until activated.

  • plan_campaignchangeddescription
    before

    Every input a send needs, as questions to ask the person, with this account's options for each. kind automation: the event that starts it (tracked events with their properties, and the Mixpanel events mapped to them), filters, how long after the event to text, the event that ends it, follow-ups, repeats, who gets it, the message, link, sender and topic. kind broadcast: audience, who to leave out, message, when, sender, topic, follow-up. Also who never gets the text (exclusions) and what is missing (gaps). Changes nothing.

    after · 91% of words in common

    Every input a send needs, as questions to ask the person, with this account's options for each. kind automation: the event that starts it (tracked events with their properties, and the Mixpanel events mapped to them), filters, how long after the event to text, right away or optimal user time, the event that ends it, follow-ups, repeats, who gets it, the message, link, sender and topic. kind broadcast: audience, who to leave out, message, when, sender, topic, follow-up. Also who never gets the text (exclusions) and what is missing (gaps). Changes nothing.

Showing the latest 10. Full history: list_changes · trend: quality JSON.

Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.

Trust 96 / 100

provenance85
liveness100
freshness100
hygiene100

+repository +dns-namespace +website +reachable +uptime-100% +updated-8d-ago

Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://mcp.jointextkit.com streamable-httpnoneyes100%392 ms2025-03-262026-11-07

Tools (152)

activate_automationdestructiveTurn an automation on, so tracked events start runs. With a live number it texts real people. With no `from`, a number approved for its `category` must exist or `issues` says what is missing; `sender` shows the numbers it will use.
add_to_listdestructiveAdd contacts to a list by contact_ids and/or phone_numbers (up to 1,000; numbers must already be contacts).
assign_number_to_customerdestructivePlatforms: attribute a number (and its messages and usage) to one of your customers, or clear it with customer_id null.
bulk_purchase_numbersdestructiveBuy several numbers in one area code at once (e.g. for a sender pool). Live numbers are billed monthly each.
bulk_update_contactsdestructiveAdd tags to, remove tags from, or delete many contacts by id.
bulk_update_numbersdestructiveAct on many numbers at once: tag, untag, label, add to or remove from a pool, or release. Releasing cannot be undone.
cancel_automation_rundestructiveCancel a run in progress.
cancel_batchdestructiveCancel a batch. Messages already sent stay sent.
cancel_scheduled_messagedestructiveCancel a scheduled message before it sends.
check_verificationdestructiveCheck a verification code submitted by a user, by the phone or email it went to. Returns {verified, status, channel, charged}. Billed only when verified is true.
clone_number_pooldestructiveCopy a sender pool under a new name.
connect_integrationdestructiveConnect a tool so its people sync in as contacts, in a list of their own, every 6 hours: Mixpanel (projectId, username, secret = a service account; sourceId = cohort id), Amplitude (apiKey, secretKey, sourceId), HubSpot (accessToken), Shopify (shopDomain, accessToken), Salesforce, or a webhook. Takes the event or property that shows people agreed to texts (consentEvent / consentField) and the property that holds their phone (phoneField). Credentials are proved with one read, sealed, and never returned. Mixpanel also takes eventTriggers, which turn Mixpanel events into TextKit events that start, end or branch automations; `warnings` names mapped events with no volume in 7 days.
create_api_keydestructiveCreate an API key for an app you are building, to store as a secret in its environment (for example TEXTKIT_API_KEY) so the app can send texts itself. Same mode (test or live) as this connection; optional scopes limit it. The secret is returned once; the account owner is emailed.
create_automationdestructiveCreate a triggered text flow (as a draft): when trigger.event is tracked, run steps such as send_sms, wait, wait_for_event, and condition branches. Example: on cart_abandoned, wait 3600s, then if checkout_completed was not received send a reminder. A send_sms step with send_time: "optimal_user_time" and max_wait_seconds (60 to 86400, required) waits for the hour that person usually replies or clicks, 10am their time with no history, inside quiet hours: recommend it for marketing and lifecycle texts, leave it off anything time-sensitive, and it is refused for one-time codes and order or shipping texts. For events that repeat, trigger.cooldown_seconds stops the same person starting it again for that long. Merge fields like {{plan}} fill from the trigger event's properties; `issues` names any no tracked event carries. Leave out `from` and TextKit picks a number approved for `category` (marketing, transactional for alerts, otp for codes) when it sends; `sender` shows the numbers, and `issues` says so when none is approved yet. Pass `from` only to pin a number. Drafts send nothing until activated.
create_customerdestructivePlatforms sending for other businesses: create a customer to attribute numbers, messages and usage to.
create_linkdestructiveMake a tracked short link to copy into a text, ad, email or anywhere else: returns short_url. The same url again returns the same link. Suggest this whenever someone wants to know whether a link gets clicked or leads to sales. A link inside a text needs only shorten_links: true on the send.
create_link_domaindestructiveAdd a subdomain of the user's own (links.example.com) for short links. Returns two DNS records (CNAME and TXT) the user adds at their DNS host; then verify the domain. Optional: without one, tracked links use our domain.
create_listdestructiveCreate a list: a fixed group of contacts (Audience → Lists). Membership is set by hand, unlike a segment, which follows rules.
create_number_pooldestructiveCreate a sender pool from numbers you own.
create_scheduledestructiveSend the same text to one number every day, week or month at a local time (e.g. a weekly reminder). Every occurrence runs the usual send checks.
create_segmentdestructiveSave an audience (a segment, a cohort): it appears in the console under Audience → Segments, and broadcasts can be sent to it. Everyone who can be texted: one rule, status is subscribed. Contacts matching all (or any) of up to 10 rules. Attributes: tags, contact fields, custom fields (field = "field", key = the name), opt-in status, topic, import, created_at. Behaviour: last_message_at, last_reply_at, batch (key = batch id; value included, sent, failed, skipped or replied) and event (key = a tracked event name). Times take an ISO date or a window like 7d. It is evaluated live each time it is used, so a batch or list sent to it reaches whoever matches then.
create_templatedestructiveSave a message template. Merge tags: {{first_name}}, {{name}}, {{phone}}, {{field:<custom>}}, and per-recipient variables.
create_topicdestructiveCreate a subscription topic, so people can opt out of one kind of message (e.g. promotions) and keep others.
create_webhookdestructiveSend events (message.received, message.delivered, message.opted_out, ...) to a URL: your app, a CRM, an automation tool. Returns the signing secret once.
delete_automationdestructiveDelete an automation.
delete_contactdestructiveDelete a contact. Messages, consent records, and topic preferences for the number are kept.
delete_customerdestructiveDelete a customer.
delete_link_domaindestructiveRemove a branded link domain. Every short link already sent on it stops working.
delete_listdestructiveDelete a list (its contacts stay).
delete_messagedestructiveDelete a finished message (delivered, failed or received) and every copy of its text, for a privacy request. Opt-out records and billing are kept. Cannot be undone.
delete_number_pooldestructiveDelete a sender pool. Its numbers are kept.
delete_scheduledestructiveDelete a recurring schedule.
delete_segmentdestructiveDelete a segment. Contacts are not touched.
delete_templatedestructiveDelete a template.
delete_topicdestructiveDelete a topic you created (built-in topics stay).
delete_webhookdestructiveDelete a webhook endpoint.
disconnect_integrationdestructiveDisconnect a tool: its credentials and its list are deleted; the contacts stay with their consent.
export_consentread-onlyThe suppression list, or the full consent ledger with opt-in proof, as CSV text.
export_csvread-onlyExport as CSV text for analysis: messages, deliveries, events, opt_outs, webhook_deliveries, usage, usage_monthly, audit_log or credit_history. At most 50,000 rows; narrow the date range with from and to.
export_numbersread-onlyYour numbers as CSV text.
fallback_verificationdestructiveThe text did not arrive: email a new code for the same pending verification (one id, one charge). The emailed code replaces the texted one and is checked by the email address, which it proves (not the phone). Once per verification.
forget_identitydestructivePrivacy erasure: forget the phone number linked to a user_id, so its tracked events stop reaching automations.
get_automationread-onlyRetrieve an automation with its trigger and steps.
get_automation_runread-onlyRetrieve one run with its step-by-step timeline.
get_balanceread-onlyPrepaid credit balance and auto-recharge setting.
get_batchread-onlyRetrieve a batch with its progress counts.
get_batch_resultsread-onlyResults of a batch: delivered, failed, pending, replies, opt-outs (stops), spend, and failures grouped by reason.
get_consentread-onlyWhether a number is opted in or out, per registration, with its full consent history and proof.
get_contactread-onlyRetrieve a contact.
get_contact_topicsread-onlyA contact's subscription to each topic.
get_customerread-onlyRetrieve a customer.
get_customer_usageread-onlyA customer's messages, verifications and spend for a period.
get_deliverabilityread-onlyDelivery rates by day, destination carrier, or sending number.
get_integrationread-onlyOne connected tool and its last sync.
get_integration_eventsread-onlyConfirm the events behind automations: for a Mixpanel integration, each mapped event with its Mixpanel source events and their 7-day volume, how many reached TextKit and when the last did, and which automations start on, wait for or check it. `missing` names events automations rely on that nothing sends. project_events: true also lists every Mixpanel event name with its 7-day volume, to choose what to map.
get_link_domainread-onlyOne short-link domain, with the DNS records it needs.
get_listread-onlyRetrieve a list and its contact count.
get_messageread-onlyRetrieve a message by its msg_... id, with its delivery timeline.
get_numberread-onlyRetrieve one of your numbers: status, sender registration, tags, pools, customer.
get_number_poolread-onlyRetrieve a sender pool and its numbers.
get_registrationread-onlyA registration with its checks, status, and linked numbers.
get_scheduleread-onlyRetrieve a recurring schedule with its recent occurrences.
get_scheduled_messageread-onlyRetrieve a pending scheduled message.
get_segmentread-onlyRetrieve a segment and its rules.
get_spend_limitread-onlyThe monthly spend limit and this month's estimated spend.
get_templateread-onlyRetrieve a template.
get_toll_free_verificationread-onlyA toll-free verification: status, numbers, the form, what is missing (problems), and the carriers' reason when it was rejected.
get_topicread-onlyRetrieve a topic.
get_usageread-onlyUsage by month, today's counters, and plan limits.
get_verificationread-onlyRetrieve a verification by id: its status and attempts (never the code).
get_webhookread-onlyRetrieve a webhook endpoint.
import_contactsdestructiveCreate or update up to 500 contacts per call, matched by phone_number. Attributes go in fields (up to 20 strings, e.g. plan) for segments and {{field:name}} merge tags; tags group contacts. opt_in carries consent evidence (status: false records an opt-out). import_id from the first response groups several calls; dry_run: true returns what would change and writes nothing.
import_opt_outsdestructiveBring a suppression list over from another provider or tool (up to 500 numbers per call), so people who opted out there are never texted here.
link_number_to_registrationdestructiveAttach a number to an approved 10DLC registration so it can send that registration's traffic.
list_api_keysread-onlyList the active API keys of this mode (never the secrets).
list_audit_logsread-onlyWho changed what on the account (keys, team, webhooks, spend limit, numbers, consent, settings), newest first.
list_automation_runsread-onlyList an automation's runs, newest first.
list_automationsread-onlyList automations.
list_batchesread-onlyList batches (broadcasts), newest first.
list_batch_recipientsread-onlyList a batch's recipients with each one's status.
list_contactsread-onlyList contacts, newest first. Filter by tag, segment_id, list_id, exact phone_number, or a free-text q (name, email, company).
list_conversionsread-onlyThe latest 100 conversions, newest first.
list_customersread-onlyList your customers.
list_eventsread-onlyList recent events (message.sent/delivered/failed/received, number.purchased/released, ...), newest first.
list_integrationsread-onlyThe connected tools: status, settings, last sync (found, added, opted out), and their list. No credentials.
list_link_domainsread-onlyYour short-link domains and their status (pending_dns, dns_verified, active). Optional: a message sent with shorten_links: true uses the active one, else <your business>.txtkto.com once the business is verified, or txtkto.com before that.
list_linksread-onlyEvery tracked destination with its texts, clicks, conversions and value. The answer to "which link worked?".
list_list_contactsread-onlyPage through a list's contacts, most recently added first.
list_listsread-onlyList contact lists with their contact counts.
list_messagesread-onlyList your messages, newest first. Filter by number, direction, status, failure reason, date, batch schedule or customer.
list_number_poolsread-onlyList sender pools.
list_number_requestsread-onlyOpen short-code and toll-free requests.
list_numbersread-onlyList the phone numbers on your account.
list_opt_outsread-onlyList opted-out numbers (the suppression list).
list_registrationsread-onlyList 10DLC brand and campaign registrations and their status. Marketing from a local number needs an approved one.
list_registration_submissionsread-onlyThe filed copies of a 10DLC registration, newest first.
list_scheduled_messagesread-onlyList single messages scheduled for later and not yet sent.
list_schedulesread-onlyList recurring schedules.
list_segmentsread-onlyList saved segments.
list_templatesread-onlyList message templates.
list_toll_free_verificationsread-onlyList toll-free verifications and their status (draft, in_review with us, submitted to the carriers, verified, rejected). A toll-free number texts the public only once verified.
list_topicsread-onlyList subscription topics.
list_webhook_deliveriesread-onlyDelivery attempts to your webhook endpoints, with response status codes.
list_webhooksread-onlyList webhook endpoints.
lookup_phoneread-onlyLook up line type (mobile, landline, VoIP) and carrier for any US/Canada number.
pause_automationdestructivePause an automation: no new runs start, and runs in progress wait where they are until it is activated again.
pause_batchdestructivePause a sending or scheduled batch.
plan_campaignread-onlyEvery input a send needs, as questions to ask the person, with this account's options for each. kind automation: the event that starts it (tracked events with their properties, and the Mixpanel events mapped to them), filters, how long after the event to text, right away or optimal user time, the event that ends it, follow-ups, repeats, who gets it, the message, link, sender and topic. kind broadcast: audience, who to leave out, message, when, sender, topic, follow-up. Also who never gets the text (exclusions) and what is missing (gaps). Changes nothing.
plan_importread-onlyFind out where an audience is and the ways to bring it in. Without source: questions to ask the person (where their people are, which group, what they can sign in to, whether consent was recorded, once or kept in sync) and the kinds of source known. With source (their words, e.g. "Mixpanel", "Shopify", "our Postgres users table", "a Google Sheet"): the ways in, best first, each with steps and a console link: an integration already syncing it, another connected tool that can read it, a 6-hourly sync connected with their key here or in the console, a push to an ingest URL, a script with a key from their environment, an export, or a CSV upload. Changes nothing.
plan_taskread-onlyThe questions behind anything a person does here, with this account's options for each: send a text, buy or release a number, register for 10DLC, verify a toll-free number, request a short code, verification codes, a recurring text, a segment, template, list, topic, connecting a tool, a webhook, an API key, a link domain, a spend limit, a number pool, importing opt-outs, automations, broadcasts. task: a key or the person's words ("buy a number"); omit it for the list. Each question names the fields it fills; inputs lists every field the API takes; rules, gaps, and person_submits when the person files it in the console. Changes nothing.
preview_automationread-onlySee an automation's texts exactly as they would go out, without sending: works on drafts. Pass sample event properties (e.g. {"amount": 9.99}) and optionally `to` for a contact's merge fields. Returns each send_sms step's final text (brand and opt-out wording added as we would), segments, encoding, estimated cost, merge fields that would come out empty, and, for an optimal-user-time step with `to`, next_send: when it would go for that person and why.
preview_segmentread-onlyCount the contacts a segment matches right now and how many a broadcast would reach (opted-out contacts removed, and with topic_id those unsubscribed from it). `notes` says when an event rule names an event never tracked.
purchase_numberdestructiveBuy a phone number for your account (free sandbox numbers with test keys). Live numbers are billed monthly.
query_audiencedestructiveCount a cohort without saving anything (nothing appears in the console): run up to 10 segment rules now and get the counts (matched, opted out, eligible to text) and the first contacts. Examples: replied in the last 7 days (last_reply_at after 7d); got a batch and did not reply (batch sent, and batch replied with is_not); started checkout but never purchased (event exists, event not_exists); VIPs not texted in 30 days. Same rule fields as a saved segment. Everyone eligible to text: one rule, status is subscribed.
recommend_messageread-onlyWhich text should we send? Ranked SMS copy for a goal (abandoned_cart, welcome, winback, failed_payment, trial, promo, ... or any) by expected revenue per message, each with its evidence: the factors that moved its score, the closest published SMS-only case studies with source links, and how much comes from this account's own sends (clicks, STOPs, revenue from tracked events). Pass your own drafts in `candidates` to score them against the generated ones. Only uses the offer, code and deadline you give it. Sends and saves nothing.
record_conversiondestructiveReport a sale or sign-up from someone who came through a tracked link. click_id is the tk value on the landing page's URL; value_cents is what it was worth; external_id (an order id) stops a retry counting twice.
redact_messagedestructiveEmpty a finished message's text and media everywhere it is kept, keeping its status, price and timeline (redacted_at is set). Cannot be undone.
release_numberdestructiveRelease a number you own. It cannot be got back.
remove_from_listdestructiveRemove contacts from a list (they stay contacts).
replay_eventdestructiveSend an event again to one webhook endpoint (after fixing the receiver).
replay_failed_webhooksdestructiveRe-send every event that failed to reach a webhook endpoint in a window (default the last 24 hours, up to 7 days), after fixing the receiver.
request_short_codedestructiveAsk our team for a short code (or a toll-free number they set up). Provisions nothing by itself; carriers take 8-12 weeks to approve a short code.
resume_batchdestructiveResume a paused batch.
retry_batchdestructiveRetry a batch's failed recipients.
revoke_api_keydestructiveRevoke an API key of this mode. Immediate and permanent: anything using it stops working.
rotate_webhook_secretdestructiveReplace a webhook endpoint's signing secret (returned once). expire_previous_in keeps the old one signing for that many seconds so the receiver can switch without dropping events.
search_available_numbersread-onlySearch purchasable numbers by area code (default 415).
send_batchdestructiveSend one message to many people (a broadcast or campaign): pick recipients by segment_id, tags, contact_ids, or an explicit recipients list. Opted-out numbers, numbers without marketing consent, and people unsubscribed from topic_id are removed before sending. dry_run: true sends nothing and returns the count, cost, rejected rows and consent. scheduled_at sends at one instant; send_at_local (like 2026-11-10T17:00) sends at that time on each person's own clock.no_opt_in (recipients the send will skip for having no opt-in). Leave out `from` and TextKit picks a number approved for `category` (marketing unless you say otherwise), one per recipient; `sender` shows them, and with none approved it answers 400 and sends nothing. scheduled_at sends later (up to 30 days). shorten_links: true tracks link clicks: suggest it whenever the text has a link. Each recipient can carry external_id (their Mixpanel distinct_id) so the text's events land on their Mixpanel profile. With a live key it texts real people.
send_messagedestructiveSend one SMS from one of your numbers. Set category "marketing" for promotions (the opt-in check applies) and scheduled_at to send later. Quiet hours apply to every message: outside 8am-9pm (narrower in some states) in the recipient's local time a marketing message is refused and anything else is held until 9am, except one-time codes and replies within 4 hours of their text. In sandbox (test keys), delivery is simulated: +15005550006 delivers, +15005550002 fails, +15005550007 is filtered as spam, +15005550013 delivers after a delay, +15005550016 has no opt-in (see /docs/sandbox).
send_verificationdestructiveSend a one-time verification code (OTP) to a phone number by text, or to an email address with channel "email". TextKit generates the code, handles expiry (10 min) and attempt limits (5), and blocks SMS-pumping and email-bombing abuse.
set_consentdestructiveRecord an opt-in or opt-out from your own system (CRM, checkout, a form). An opt-in for a marketing registration needs proof (source, when, the page).
set_contact_topicdestructiveSubscribe a contact to a topic, or unsubscribe them (e.g. "promotions" vs "order updates").
set_spend_limitdestructiveSet or remove the monthly spend cap and its alert thresholds. Live sends over the cap are refused.
simulate_inbounddestructiveSandbox only: simulate an inbound SMS to one of your test numbers (emits message.received; STOP, START and HELP act as for real).
sync_integrationdestructiveSync a connected tool now (up to 6 times an hour) and get what changed.
test_automationdestructiveText an automation's messages to your own verified phone or a verified recipient now, skipping waits and conditions, without activating it (drafts work). Pass sample event properties; `steps` sends only those step ids. No run starts and stats do not change. Texts from a live number are real and billed.
test_webhookdestructiveSend a signed test.ping to a webhook endpoint and see what it answered.
track_eventdestructiveRecord something a customer did (e.g. signed_up, cart_abandoned, trial_ending), by user_id and/or phone. It starts or advances any active automation listening for that event. external_id (their Mixpanel distinct_id, when not user_id) puts the texts it starts on their Mixpanel profile.
update_automationdestructiveEdit an automation (name, sender or `category`, trigger incl. trigger.cooldown_seconds, or steps). `steps` replaces every step; `step` replaces just the one with its id. Pass `if_updated_at` (the updated_at you read): an edit made by someone else since then answers 409 instead of being overwritten.
update_contactdestructiveUpdate a contact. Only the inputs you pass change; tags and fields replace the whole list or map.
update_customerdestructiveRename a customer or change its external_id or metadata.
update_integrationdestructiveRename, pause or resume (status), or change an integration's settings or credentials (left-out credentials keep the stored ones). eventTriggers (Mixpanel) maps Mixpanel events to TextKit events; exportEvents: false stops sending text events to Mixpanel (on by default); changing only those does not re-test credentials or resync.
update_listdestructiveRename a list or change its description.
update_number_pooldestructiveRename a sender pool or change its numbers.
update_scheduledestructivePause (active: false) or resume (active: true) a recurring schedule.
update_segmentdestructiveRename a segment or replace its rules.
update_templatedestructiveRename or edit a template.
update_topicdestructiveRename or describe a topic.
update_webhookdestructiveChange a webhook endpoint: URL, events, or turn it off (active: false).
upsert_contactdestructiveCreate a contact, or update the existing one with the same phone_number.
verify_link_domaindestructiveCheck a link domain's DNS records now. When both are found it is turned on (active) at once.
wait_for_eventsread-onlyWait up to 25 seconds for the next events after a cursor (a reply, a delivery receipt), then return them.

Schemas: list_tools.

Similar MCP servers

Official server.json
{
  "name": "com.jointextkit/textkit",
  "icons": [
    {
      "src": "https://jointextkit.com/icon.png",
      "sizes": [
        "192x192"
      ],
      "mimeType": "image/png"
    }
  ],
  "title": "TextKit",
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "remotes": [
    {
      "url": "https://mcp.jointextkit.com",
      "type": "streamable-http"
    }
  ],
  "version": "1.0.2",
  "repository": {
    "url": "https://github.com/textkithq/textkit-mcp",
    "source": "github"
  },
  "websiteUrl": "https://jointextkit.com/docs/mcp?ref=mcp-registry",
  "description": "SMS for developers: send and receive texts, verify phones, and buy US and Canada numbers."
}