<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sbier060</title>
    <description>The latest articles on DEV Community by sbier060 (@sbier060).</description>
    <link>https://dev.to/sbier060</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4215140%2F3e75b618-c348-419d-98c3-bb3ceab39524.png</url>
      <title>DEV Community: sbier060</title>
      <link>https://dev.to/sbier060</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sbier060"/>
    <language>en</language>
    <item>
      <title>Send SMS from Claude in 30 Seconds, 61% Cheaper Than Twilio (Demo 🚀)</title>
      <dc:creator>sbier060</dc:creator>
      <pubDate>Thu, 29 Oct 2026 12:15:15 +0000</pubDate>
      <link>https://dev.to/sbier060/send-sms-from-claude-in-30-seconds-61-cheaper-than-twilio-demo--51pn</link>
      <guid>https://dev.to/sbier060/send-sms-from-claude-in-30-seconds-61-cheaper-than-twilio-demo--51pn</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR: &lt;a href="https://jointextkit.com" rel="noopener noreferrer"&gt;TextKit&lt;/a&gt; is an SMS API that Claude can use over MCP. A text costs $0.0032, against Twilio's $0.0083: 61% less, excluding carrier fees. Try it in one command: &lt;code&gt;claude mcp add --transport http textkit https://mcp.jointextkit.com&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem with most texting APIs is that you have to jump through hoops to send one text. You sit down with a calculator to work out what it will cost, fill out forms for the carriers, and so on. What I wanted was something that lets me say: Claude, send this text.&lt;/p&gt;

&lt;h2&gt;
  
  
  💸 61% cheaper than Twilio
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;TextKit&lt;/th&gt;
&lt;th&gt;Twilio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Per text (US, per segment)&lt;/td&gt;
&lt;td&gt;$0.0032&lt;/td&gt;
&lt;td&gt;$0.0083&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000 texts a month&lt;/td&gt;
&lt;td&gt;$32.00&lt;/td&gt;
&lt;td&gt;$83.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone verification&lt;/td&gt;
&lt;td&gt;$0.025&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone number, per month&lt;/td&gt;
&lt;td&gt;$0.95&lt;/td&gt;
&lt;td&gt;$1.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A send that fails&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Prices exclude carrier fees, which both pass through at cost. Twilio's prices are from its &lt;a href="https://www.twilio.com/en-us/sms/pricing/us" rel="noopener noreferrer"&gt;SMS&lt;/a&gt; and &lt;a href="https://www.twilio.com/en-us/verify/pricing" rel="noopener noreferrer"&gt;Verify&lt;/a&gt; pricing pages, read October 24, 2026. US and Canada only.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ The 30-second version
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http textkit https://mcp.jointextkit.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;/mcp&lt;/code&gt;, pick TextKit and sign in. Then ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Text +15005550006 "Hello from Claude."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That number is our sandbox, so nothing reaches a real phone until you say so. Claude shows you exactly what it is about to send, and asks first:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4dfmnxa2bsef7v7wolnt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4dfmnxa2bsef7v7wolnt.jpg" alt="Claude asks to use TextKit's Send message tool, showing the text and the number" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🦷 The demo: a dentist's office, run from a chat
&lt;/h2&gt;

&lt;p&gt;Here is a day of texting for a small dental office, asked in plain English. Each request maps to tools on the server, and all of them work in the sandbox.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Buy a number in area code 512 and text +15005550006 "Your cleaning is tomorrow at 10. Reply C to confirm."&lt;/p&gt;

&lt;p&gt;Import the patients in this CSV, tag them spring-cleaning, and tell me how many have an opt-in.&lt;/p&gt;

&lt;p&gt;Send everyone tagged spring-cleaning "We have Saturday openings this month." Do a dry run first and show me the count and cost.&lt;/p&gt;

&lt;p&gt;When someone triggers appointment_booked, wait an hour and text them a confirmation, unless appointment_cancelled arrives first.&lt;/p&gt;

&lt;p&gt;How did yesterday's broadcast do? Show delivered, failed, replies and opt-outs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The patients land in your contacts, tagged:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsfosbip9vh8b3nrn2tlc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsfosbip9vh8b3nrn2tlc.jpg" alt="Six patients imported and tagged spring-cleaning in the TextKit console" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dry run comes back before anything is sent (trimmed; a sandbox send costs $0):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"batch_validation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"counts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rows"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"invalid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"duplicates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"opted_out"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"landline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"segments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"encoding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GSM-7"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"estimated_cost_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the confirmation flow is waiting as a draft until you turn it on:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvyvh3hudxrqmyqmnzzs6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvyvh3hudxrqmyqmnzzs6.jpg" alt="The appointment confirmation automation in the TextKit console" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🛡️ But isn't it dangerous to let an agent text people?
&lt;/h2&gt;

&lt;p&gt;It would be, so the server is built to be careful. Here is the first text from the demo. It was 7:55 AM where the number lives, so TextKit held it until quiet hours ended:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zkol2ajhog8gs31sc7w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zkol2ajhog8gs31sc7w.jpg" alt="Claude reports the text is queued until quiet hours end at 8 AM Eastern" width="799" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The rest of the rules work the same way. Test keys never reach a real phone. Before a broadcast, Claude does a dry run that shows how many people you would reach, what it would cost and who would be skipped, and nothing goes out until you confirm. People who reply STOP are blocked from every future send. And you can give Claude a key that can only do what you allow.&lt;/p&gt;

&lt;p&gt;Each tool is one API call made with your key, so your key's scopes, rate limits and send checks apply as usual.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔌 Connect it anywhere
&lt;/h2&gt;

&lt;p&gt;The server is &lt;code&gt;https://mcp.jointextkit.com&lt;/code&gt;. Sign in once with OAuth or use an API key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code:&lt;/strong&gt; the command above, then &lt;code&gt;/mcp&lt;/code&gt; to sign in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude.ai and Claude Desktop:&lt;/strong&gt; Settings → Connectors → Add custom connector, URL &lt;code&gt;https://mcp.jointextkit.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT:&lt;/strong&gt; add a custom MCP server with the URL &lt;code&gt;https://mcp.jointextkit.com/chatgpt&lt;/code&gt; and OAuth. That URL has every tool except Verify and API keys, because ChatGPT does not allow one-time codes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor, VS Code, Cline&lt;/strong&gt; and any MCP client that can send a header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"textkit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.jointextkit.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer ssms_sk_test_..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is also in the official MCP registry as &lt;code&gt;com.jointextkit/textkit&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Going live
&lt;/h2&gt;

&lt;p&gt;To text actual customers you need either a &lt;a href="https://jointextkit.com/10dlc" rel="noopener noreferrer"&gt;10DLC registration&lt;/a&gt; or a &lt;a href="https://jointextkit.com/toll-free-verification" rel="noopener noreferrer"&gt;verified toll-free number&lt;/a&gt;. We take care of the 10DLC registration for you. In the meantime, you can only send texts to your own verified numbers.&lt;/p&gt;

&lt;p&gt;When you want SMS inside your own app, ask Claude to create a key and store it as &lt;code&gt;TEXTKIT_API_KEY&lt;/code&gt;, then point it at the &lt;a href="https://jointextkit.com/docs/quickstarts" rel="noopener noreferrer"&gt;quickstart for your stack&lt;/a&gt;. Each one opens with a prompt written for agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn
&lt;/h2&gt;

&lt;p&gt;What would you have Claude text first? Tell me in the comments. I read every one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I wrote this post with help from Claude. Docs: &lt;a href="https://jointextkit.com/docs/mcp" rel="noopener noreferrer"&gt;jointextkit.com/docs/mcp&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>claude</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
