SMS.ir MCP server
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
SMS.ir MCP server
A local Model Context Protocol server that exposes a curated, safety-gated set of tools for the SMS.ir Panel V2 API. Built with Python + FastMCP.
stdio transport for Codex / Claude Desktop / Claude Code
streamable HTTP transport for local development and testing
Read operations work out of the box; every send is billable and blocked by default behind a confirmation flag and a server-side kill switch.
Phone numbers, message text, API keys and OTP codes are masked in logs.
Built from the SMS.ir Panel V2 Postman collection (not included in this repo —
it embeds a real API key). The normalized API description lives in
docs/API.md and docs/openapi.yaml.
1. Setup
Requires Python 3.10+ (developed and tested on CPython 3.12).
cd C:\Users\Kasra\Documents\sms.ir-mcp
# create the project-local virtual environment
py -3.12 -m venv .venv
# install runtime deps (pinned)
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
# ...or install with the package + dev/test extras
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"Related MCP server: przypominamy-mcp
2. Configuration
All configuration comes from environment variables. For local use, copy the example env file and fill it in — it is git-ignored and never committed:
copy .env.example .env
notepad .envVariable | Required | Default | Purpose |
| yes | – | SMS.ir Panel API key, sent as the |
| no | – | Fallback sender line for send tools |
| no |
| Kill switch. Must be |
| no |
| API base URL (host-allowlisted) |
| no |
| Allow a non- |
| no |
| Per-request timeout |
| no |
| Retries for transient failures (429 / 5xx / network) |
| no |
| Client-side rate limit |
| no |
| Upper bound accepted for |
| no |
|
|
| no |
| Path to the env file to auto-load |
Real environment variables always override values from the env file.
3. Running
# stdio (what MCP clients launch)
.\.venv\Scripts\python.exe -m sms_ir_mcp --transport stdio
# streamable HTTP for local testing (http://127.0.0.1:8000/mcp)
.\.venv\Scripts\python.exe -m sms_ir_mcp --transport http --host 127.0.0.1 --port 8000For a quick connectivity + auth check that never spends credit, call the
health_check tool (or get_balance) from any connected client — both are
GET /v1/credit under the hood.
4. Tools
Read-only tools are always available. Write tools require confirm=true
and SMSIR_ALLOW_SEND=true; the destructive tool requires confirm=true.
Tool | Kind | API | Description |
| read |
| Remaining SMS credit |
| read |
| Sender line numbers / virtual numbers |
| read |
| Delivery report/status for one sent message |
| read |
| Per-recipient results for a bulk pack (paginated) |
| read |
| Sent messages, |
| read |
| Bulk packs, |
| read |
| Inbound messages, |
| read |
| Newest inbound message containing a parseable one-time code (heuristic) |
| read |
| Reachability + auth check, never billable; also returns effective config |
| admin | – | Re-read |
| billable |
| One text to one or more recipients |
| billable |
| Templated OTP/verification message |
| billable |
| A distinct text per recipient |
| destructive |
| Cancel a not-yet-sent scheduled pack |
Every tool returns {"ok": true, "data": …, …} on success or
{"ok": false, "error": {"code": …, "message": …}} on failure. Error codes:
config_error, validation_error, confirmation_required, send_disabled,
auth_error, rate_limited, transient_error, api_error, internal_error.
Examples
// check balance
get_balance() -> {"ok": true, "data": {"credit": 45210}}
// read the latest OTP received on a given number
extract_latest_otp({"mobile": "9821000"})
-> {"ok": true, "data": {"otp": "834122", "matched": true, "from": "*****1000", ...}}
// attempt a send without confirming -> refused, nothing sent
send_sms({"message_text": "Hi", "mobiles": ["09121234567"]})
-> {"ok": false, "error": {"code": "confirmation_required", ...}}
// confirmed send, but kill switch still off -> refused, nothing sent
send_sms({"message_text": "Hi", "mobiles": ["09121234567"], "confirm": true})
-> {"ok": false, "error": {"code": "send_disabled", ...}}
// edited .env to set SMSIR_ALLOW_SEND=true -> apply it without restarting
reload_config()
-> {"ok": true, "data": {"config": {"allow_send": true, ...}, "changed": ["allow_send"]}}
// with SMSIR_ALLOW_SEND=true AND confirm=true -> actually sends (billable)
send_sms({"message_text": "Hi", "mobiles": ["09121234567"],
"line_number": "30007732000000", "confirm": true})
-> {"ok": true, "data": {"packId": "…", "messageIds": [123], "cost": 1.0}, "recipients": 1}5. Safety model
Billable operations (
send_sms,send_verification_code,send_personalized_sms) need both:confirm=truein the tool call, andSMSIR_ALLOW_SEND=truein the server environment. With the kill switch off, a confirmed call still sends nothing.
Destructive operation (
cancel_scheduled_send) needsconfirm=true.No arbitrary base URLs: only
api.sms.iris accepted unlessSMSIR_ALLOW_CUSTOM_BASE_URL=true. HTTPS is enforced.No header injection: callers cannot set request headers; only typed, validated fields are forwarded.
Timeouts + bounded retries + client-side rate limiting on every request.
Masking: API keys, phone numbers, message bodies and OTP values are masked in log output.
No admin endpoints: only the operations in the Postman collection are exposed; nothing for account/config management.
6. Client registration
Your real API key goes in .env in this folder — never in a client config
file. Each config below only points the client at this server and its .env.
Codex CLI (installed)
codex mcp add sms-ir `
--env SMSIR_ENV_FILE=C:\Users\Kasra\Documents\sms.ir-mcp\.env `
-- C:\Users\Kasra\Documents\sms.ir-mcp\.venv\Scripts\python.exe -m sms_ir_mcp --transport stdio
codex mcp list # sms-ir should appear
codex mcp get sms-irManual equivalent: docs/codex_config.example.toml.
Claude Code (installed)
This repo ships a project-scoped .mcp.json. Open Claude Code in
this directory and approve the sms-ir server when prompted:
cd C:\Users\Kasra\Documents\sms.ir-mcp
claude
/mcp # shows sms-ir and its toolsTo register it at user scope instead:
claude mcp add sms-ir --scope user `
--env SMSIR_ENV_FILE=C:\Users\Kasra\Documents\sms.ir-mcp\.env `
-- C:\Users\Kasra\Documents\sms.ir-mcp\.venv\Scripts\python.exe -m sms_ir_mcp --transport stdioClaude Desktop (not installed)
When installed, merge docs/claude_desktop_config.example.json
into %APPDATA%\Claude\claude_desktop_config.json (back it up first; keep other
servers).
7. Development
.\.venv\Scripts\python.exe -m ruff check src tests
.\.venv\Scripts\python.exe -m ruff format --check src tests
.\.venv\Scripts\python.exe -m pytestTests cover request construction, auth header, envelope parsing, error normalization, retries/rate-limiting, argument validation, masking, OTP extraction, mocked integration for every tool (using the Postman example payloads), OpenAPI-vs-collection consistency, and MCP tool discovery.
8. First live test (after you provide a credential)
Nothing in this repo has made a billable call. To run the first real send, which you explicitly authorize:
Put your key in
.env:SMSIR_API_KEY=<your real key> SMSIR_DEFAULT_LINE_NUMBER=<your approved line> SMSIR_ALLOW_SEND=trueVerify connectivity without spending anything — from a connected client call
health_check(orget_balance).Then, and only then, make the first billable call. Exact tool call:
send_sms({ "message_text": "SMS.ir MCP test", "mobiles": ["<your own mobile>"], "line_number": "<your approved line>", "confirm": true })Codex phrasing: "Use the sms-ir server's send_sms tool to send 'SMS.ir MCP test' to from line , with confirm true."
9. Troubleshooting
Symptom | Cause / fix |
| No key in env or |
| Wrong/rotated key, or key lacks Panel API access |
|
|
Edited | The server reads config once at startup. Call |
| Re-call the tool with |
| Use 10–15 digits, optional leading |
| Client-side limiter tripped; raise |
| Network/5xx after retries; check connectivity and SMS.ir status |
Client shows no tools | Wrong |
| SMS.ir rejected the request; |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Quote, send and track SMS, campaigns, contacts and Verify codes, with a confirmation before sending.
Send SMS, manage contacts and groups, and read delivery reports. OAuth 2.1 SureSMS login.
Authenticated Samva email and WhatsApp tools, including public documentation and template discovery.
Transactional email API & AI agent safety runtime with 12 scoped tools and SpendGuard.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables sending SMS, querying delivery reports, and managing senders and blacklists through the iletiMerkezi SMS API.1114 npm2MIT
- AlicenseNot gradedqualityBmaintenanceEnables sending and managing SMS, voice messages, contacts, templates, blacklists, and account reports through the przypominamy.com REST API, with key-scoped authorization and safety confirmations for destructive actions.MIT
- AlicenseBqualityCmaintenanceEnables secure, typed access to the HestiaCP server management API via MCP, with explicit allowlists for read-only operations and opt-in mutation/destructive tools.381MIT
- AlicenseNot gradedqualityBmaintenanceEnables read-only access to Kalshi Trade API v2 for exchange status, markets, cash, positions, fills, and resting orders, with optional mutating order tools gated behind a safe mode and explicit confirmation.MIT