HonkIO MCP Server
Model Context Protocol (MCP) server for HonkIO, the Canadian SMS API. It lets an AI agent send SMS, run phone verification, manage Canadian numbers, and handle CASL compliance through natural language.
38 tools, 4 resources, and 5 guided prompts, all backed by the live HonkIO REST API.
Requirements
- Node.js 20 or newer
- A HonkIO account and API key
1. Get an API key
Sign in at https://honkio.ca/dashboard/keys and copy a key:
mk_test_… | Test | Messages are simulated as delivered. No SMS is sent and nothing is charged. |
mk_live_… | Live | Real SMS, real Canadian numbers, real charges against your balance. |
Start with a test key. Every tool works in test mode, so an agent can exercise the whole surface for free. Switch to a live key only when you want real delivery.
Live sending also requires that the account owner has completed phone verification, and that you have provisioned at least one number to send from.
2. Connect your AI tool
There is nothing to install. npx fetches the server on first use and caches it.
In every example below, put your own key in HONKIO_API_KEY.
Claude Code
From inside your project:
claude mcp add honkio \
--env HONKIO_API_KEY=mk_test_YOUR_KEY_HERE \
-- npx -y @honkio/mcp
Or commit a .mcp.json at the project root to share it with your team (keep the real key out of git — see Keeping your key out of git):
{
"mcpServers": {
"honkio": {
"command": "npx",
"args": ["-y", "@honkio/mcp"],
"env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
}
}
}
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"honkio": {
"command": "npx",
"args": ["-y", "@honkio/mcp"],
"env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
}
}
}
Restart Claude Desktop afterwards.
Cursor
Edit .cursor/mcp.json in your project, or ~/.cursor/mcp.json globally:
{
"mcpServers": {
"honkio": {
"command": "npx",
"args": ["-y", "@honkio/mcp"],
"env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
}
}
}
VS Code (GitHub Copilot)
Edit .vscode/mcp.json in your workspace:
{
"servers": {
"honkio": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@honkio/mcp"],
"env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
}
}
}
3. Confirm it works
Ask your agent:
List my HonkIO phone numbers.
- A list (or an empty list) means you are connected.
Error [UNAUTHORIZED]: Invalid or missing API key. means the key is wrong, missing, or has been revoked.
To check the server outside any AI tool:
HONKIO_API_KEY=mk_test_YOUR_KEY npx -y @honkio/mcp
It should start and wait silently on stdin — an MCP server speaks JSON-RPC over stdio, so no output is the healthy state. Press Ctrl-C to exit. If it exits immediately with an error, the message tells you what is wrong.
Environment variables
HONKIO_API_KEY | Yes | Your API key (mk_live_… or mk_test_…). The server refuses to start without it. |
HONKIO_API_URL | No | Override the API base URL. Defaults to https://api.honkio.ca. Only needed for self-hosting or local development. |
Keeping your key out of git
.mcp.json and .vscode/mcp.json are usually committed. An API key pasted into one is a live credential in your repository history. Either keep those files untracked, or reference an environment variable your shell already exports and add the file to .gitignore.
If a key does leak, revoke it immediately at https://honkio.ca/dashboard/keys — a revoked key stops working at once.
Tools
Messages
send_sms | Send an SMS from one of your numbers. Enforces CASL consent unless overridden. |
list_messages | List messages, filterable by number, status, direction and date. |
get_message | Full detail for one message, including delivery status and cost. |
Phone verification (OTP)
start_verification | Send a one-time code to a phone number. |
check_verification | Submit a code to verify it. |
get_verification | Status of a single verification attempt. |
list_verifications | List verification attempts. |
On a live key, verification is billed per message segment plus a per-verification surcharge — get_pricing returns the current figure. On a test key nothing is sent and nothing is charged, and the code is always 000000, padded to the requested length. Every verification carries a mode of LIVE or TEST, so you never have to infer which happened.
Pricing
get_pricing | Current per-segment SMS cost, verification upcharge, and phone-number upfront/monthly rent, in CAD cents. |
Prices are set at runtime and change without a release. Read them rather than hardcoding them.
Phone numbers
search_phone_numbers | Search available Canadian numbers by area code. |
provision_phone_number | Purchase a number. Charges an upfront fee plus monthly rent. |
list_phone_numbers | List the numbers on your account. |
get_phone_number | Detail for one number. |
release_phone_number | Release a number and stop its recurring rent. |
CASL compliance
record_consent | Record express or implied consent. |
list_consents | List consent records. |
check_consent | Check whether a number has valid consent. |
revoke_consent | Revoke consent for a number. |
record_opt_out | Record an opt-out manually. |
list_opt_outs | List opt-out records. |
DNCL — not available yet
check_dncl | Returns 501 DNCL_COMING_SOON. |
batch_check_dncl | Returns 501 DNCL_COMING_SOON. |
CRTC Do Not Call List checking is not live. dncl_exemptions on send_sms is accepted but not yet acted upon.
Webhooks
create_webhook | Register an endpoint for delivery receipts and inbound messages. |
list_webhooks | List registered webhooks. |
update_webhook | Change a webhook's URL or subscribed events. |
delete_webhook | Remove a webhook. |
list_webhook_deliveries | Delivery attempts for a webhook, for debugging. |
list_webhook_dead_letters | Deliveries that exhausted their retries. |
replay_webhook_dead_letter | Retry a dead-lettered delivery. |
discard_webhook_dead_letter | Drop a dead-lettered delivery. |
reactivate_webhook | Re-enable a webhook disabled by repeated failures. |
Account and keys
whoami | Identify the account the API key belongs to — id, name, balance, status. |
get_account | Account detail and credit balance. |
update_account | Update the account name. |
get_usage | Usage for a billing period. |
create_api_key | Issue a new live or test key. |
rotate_api_key | Replace a key, invalidating the old value. |
revoke_api_key | Revoke a key immediately. |
account_id is optional on all of these. Omit it and the server resolves your account from the API key, so "show my usage for this month" just works. Pass one explicitly only if you are deliberately targeting a different account. Use whoami if you want to see the id itself.
PIPEDA
request_erasure | Execute a right-to-erasure request for a phone number. |
Resources
Readable by MCP clients that support resources:
honkio://messages | 20 most recent messages |
honkio://phone-numbers | Your provisioned numbers |
honkio://consents | Active CASL consent records |
honkio://webhooks | Registered webhook endpoints |
Prompts
Guided multi-step workflows:
send_compliant_sms | Check consent, then send |
provision_canadian_number | Search, then purchase |
setup_webhooks | Register event notifications |
compliance_audit | Full compliance check on a number |
handle_erasure_request | Process a PIPEDA erasure request |
Things to try
Find me an available Toronto (416) number and tell me what it costs before buying anything.
Check whether +15145559876 has valid CASL consent, and if it does, text them that
their appointment is confirmed for 2pm tomorrow.
Start a phone verification for +16045551111, then check the code 123456 against it.
Set up a webhook at https://myapp.ca/webhooks/honkio for delivery receipts and
inbound messages.
Show me any webhook deliveries that failed and ended up in the dead-letter queue.
Spending money by accident
Two tools move real money on a live key:
provision_phone_number charges an upfront fee and starts monthly rent. Rent keeps accruing until you call release_phone_number.
send_sms and start_verification charge per segment against your balance. start_verification adds a per-verification surcharge on top. get_pricing tells you what each costs right now.
Agents act on instructions that can be vaguer than you intended. If you are exploring, use a test key — the tools behave the same and charge nothing.
A test-mode send still comes back with status DELIVERED, because it simulates a successful delivery. That is not a claim that a phone received anything. The mode field on the response — LIVE or TEST — is the one that tells you whether an SMS actually left the building.
Canadian compliance
- CASL — commercial messages need consent on record. Use
record_consent before sending; send_sms enforces it unless you pass skip_consent_check. Express consent does not expire; implied consent expires two years after the last transaction.
- DNCL — CRTC Do Not Call List checking is not available yet and is not enforced.
- PIPEDA — customer data is stored in Canada (
ca-central-1). Request processing currently runs on infrastructure outside Canada, so data crosses the border in transit; see the privacy policy for the full disclosure. Use request_erasure for right-to-erasure requests.
Troubleshooting
Error [UNAUTHORIZED] | Key is wrong, revoked, or HONKIO_API_KEY never reached the server. Check the env block in your config. |
| Tools do not appear in the agent | The client did not start the server. Restart the client, and check that npx is on its PATH — GUI apps do not always inherit your shell's PATH. |
| First start is slow, or times out once | npx downloads the package on first use. Run npx -y @honkio/mcp once in a terminal to warm the cache, then restart your client. |
npm ERR! 404 @honkio/mcp | Usually an npm registry override or a private proxy. Check npm config get registry. |
Error [PAYMENT_REQUIRED] | The account needs an initial top-up before live use. |
Error [ACCOUNT_NOT_VERIFIED] | Live sending needs the account owner's phone verified. Do it in the dashboard. |
501 DNCL_COMING_SOON | Expected. DNCL checking is not live yet. |
| Server starts then exits silently | That is normal when nothing is attached to stdin. It only means something is wrong if it prints an error. |
Development
To work on the server rather than just use it:
git clone https://github.com/jeffcaldwellca/honkio
cd honkio/mcp
npm install
npm run dev
npm run typecheck
npm run build
Point a local checkout at your own API with HONKIO_API_URL=http://localhost:3000, and at a local build by using node /path/to/honkio/mcp/dist/index.js as the command in your client config instead of npx.
dist/ is gitignored and the published tarball is built from it, so prepublishOnly rebuilds on every npm publish — never publish without letting it run.
License
MIT