MCP server
@simhook/mcp is an MCP server over stdio. Add it to a client and the agent gets eight tools for texting through your phone, with the same limits and the same signed audit trail as everything else on the account.
Setup
- Pair a phone and create an API key with the
send,read, anddevicesscopes. - Add the server to your client.
Claude Desktop, Cursor, and most others (claude_desktop_config.json, .cursor/mcp.json, and so on):
{
"mcpServers": {
"simhook": {
"command": "npx",
"args": ["-y", "@simhook/mcp"],
"env": { "SIMHOOK_API_KEY": "sh_..." }
}
}
}
Claude Code:
claude mcp add simhook -e SIMHOOK_API_KEY=sh_... -- npx -y @simhook/mcp
Self-hosting? Add SIMHOOK_BASE_URL with your API origin.
Tools
| Tool | What it does |
|---|---|
send_sms |
Sends a text to one or more numbers and reports the outcome per recipient. Waits up to wait_seconds for the phone. |
get_send_status |
Follows up on a send that was still pending. |
list_messages |
Sent and received messages, filtered by direction, status, phone, send, text, and time. Paginated. |
get_message |
One message with its delivery state. |
wait_for_incoming_sms |
Blocks until a text arrives, optionally from a given number or containing given text. |
list_devices |
Paired phones with online state, SIMs, and battery. |
get_account |
Plan, limits, usage, and lifetime totals. |
count_sms_segments |
Estimates how many SMS parts a text needs. No API call. |
Every tool returns readable text plus structured content for clients that use it.
Behaviour worth knowing
- Sends count against the plan. The server tells agents to follow a pending send with
get_send_statusrather than sending again. - Waiting tools stop at 55 seconds per call to stay under common client timeouts. The reply includes a
sincevalue to continue waiting with. - API errors come back as tool errors with the API’s error code, so the agent can explain a limit or a bad number instead of failing silently.
- stdout carries the protocol; diagnostics go to stderr.
- A key with only the
readscope makes a read-only server: the agent can watch for texts but not send any.
In your own code
import { createServer } from "@simhook/mcp";
import { Simhook } from "@simhook/sdk";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = createServer({ client: new Simhook({ apiKey: "sh_..." }) });
await server.connect(new StdioServerTransport());