Send SMS from a LangChain agent

Load TextKit's tools into a LangChain agent through LangChain's MCP adapter, in Python or JavaScript, so the agent can send texts and read back delivery.

1. Get a test key

Create a test key on the API keys page of the console. It starts ssms_sk_test_, runs everything in the sandbox, and texts no real phone except your own verified one. Put it in your environment as TEXTKIT_API_KEY:

bash
export TEXTKIT_API_KEY=ssms_sk_test_...

2. Connect the MCP server (Python)

Since LangChain 1.4 the adapter ships in langchain.mcp and is built on FastMCP. A FastMCP Client with auth set to your key sends it as Authorization: Bearer:

bash
pip install "langchain[mcp]"
python
import asyncio
import os

from fastmcp.client import Client
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter


async def main():
    client = Client("https://mcp.jointextkit.com", auth=os.environ["TEXTKIT_API_KEY"])
    async with MCPAdapter(client) as adapter:
        tools = await adapter.list_tools()
        agent = create_agent("claude-sonnet-5", tools)
        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": 'Text +15005550006 "Your order shipped."'}]}
        )
        print(result["messages"][-1].content)


asyncio.run(main())

Install your model provider's LangChain package alongside it. LangChain marks the langchain.mcp namespace as beta.

Or in JavaScript

bash
npm install langchain @langchain/mcp-adapters@^2.0.0 @langchain/core @langchain/langgraph
typescript
import { MCPAdapter } from '@langchain/mcp-adapters';
import { createAgent } from 'langchain';

const adapter = new MCPAdapter({
  servers: {
    textkit: {
      url: 'https://mcp.jointextkit.com',
      headers: { Authorization: `Bearer ${process.env.TEXTKIT_API_KEY}` },
    },
  },
});

try {
  const tools = await adapter.listTools();
  const agent = createAgent({ model: 'claude-sonnet-5', tools });
  const result = await agent.invoke({
    messages: [{ role: 'user', content: 'Text +15005550006 "Your order shipped."' }],
  });
  console.log(result.messages.at(-1)?.content);
} finally {
  await adapter.close();
}

A url defaults to Streamable HTTP, which is what the TextKit server speaks. The server exposes 142 tools: messages, verification, numbers, contacts, segments, broadcasts, automations and account reads. Each one is a single API call with your key, so the key's scopes, rate limits and send checks apply unchanged. The full list is on the MCP server page.

3. Check the sandbox run

+15005550006 is a sandbox number that always ends delivered, so the agent's tool call returns a message with an id starting msg_ and nothing reaches a phone. The message also shows in the console's message log, tagged Test. Ask for a text to your own number instead and, once that number is verified under Settings, it really arrives (up to 10 a day, ending "- via TextKit sandbox").

Go live

Swap the test key for a live one (ssms_sk_live_). A live text needs a number on your account: buy one and register your use case with the carriers. When the account has one number, from is optional and the text goes out from it. To limit what an agent can do with a live key, give it one with only the scopes it needs.

Sources

More in integrations