# Send SMS from a LlamaIndex agent

Source: https://jointextkit.com/integrations/llamaindex
Index: https://jointextkit.com/llms.txt

Turn TextKit's MCP server into LlamaIndex tools with `McpToolSpec` and hand
them to a `FunctionAgent`, so the agent can send texts and read delivery.

## 1. Get a test key

Create a test key on the [API keys](/console) page of the console. It starts
`ssms_sk_test_`, runs everything in the [sandbox](/docs/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

```bash
pip install llama-index-tools-mcp llama-index-llms-openai
```

```python
import asyncio
import os

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec


async def main():
    client = BasicMCPClient(
        "https://mcp.jointextkit.com",
        headers={"Authorization": f"Bearer {os.environ['TEXTKIT_API_KEY']}"},
    )
    spec = McpToolSpec(client=client, allowed_tools=["send_message", "get_message"])
    tools = await spec.to_tool_list_async()

    agent = FunctionAgent(
        tools=tools,
        llm=OpenAI(model="gpt-5-mini"),
        system_prompt="You send SMS with TextKit. Confirm the number and wording first.",
    )
    response = await agent.run('Text +15005550006 "Your order shipped."')
    print(response)


asyncio.run(main())
```

`BasicMCPClient` picks Streamable HTTP for an `https` URL that does not end
in `/sse`, and passes `headers` on every request. `allowed_tools` keeps the
agent to the two tools above; leave it out to load all of them. Any LlamaIndex
LLM with function calling works in place of the one shown. 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](/docs/mcp) 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](/docs/numbers) and
[register your use case](/docs/compliance) 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](/docs/authentication) it needs.

## Sources

- [LlamaIndex: Using MCP tools with LlamaIndex](https://developers.llamaindex.ai/python/framework/module_guides/mcp/llamaindex_mcp/)
- [llama-index-tools-mcp: BasicMCPClient source (headers argument)](https://github.com/run-llama/llama_index/blob/main/llama-index-integrations/tools/llama-index-tools-mcp/llama_index/tools/mcp/client.py)
- [LlamaIndex: Tools](https://developers.llamaindex.ai/python/framework/module_guides/deploying/agents/tools/)
