@honkio/mcp 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +145 -48
  2. package/dist/auth.d.ts +40 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +98 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/client.d.ts +21 -0
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +57 -19
  9. package/dist/client.js.map +1 -1
  10. package/dist/http.d.ts +51 -0
  11. package/dist/http.d.ts.map +1 -0
  12. package/dist/http.js +248 -0
  13. package/dist/http.js.map +1 -0
  14. package/dist/index.d.ts +0 -9
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +19 -46
  17. package/dist/index.js.map +1 -1
  18. package/dist/log.d.ts +10 -0
  19. package/dist/log.d.ts.map +1 -0
  20. package/dist/log.js +10 -0
  21. package/dist/log.js.map +1 -0
  22. package/dist/prompts.d.ts +1 -1
  23. package/dist/prompts.d.ts.map +1 -1
  24. package/dist/prompts.js +19 -18
  25. package/dist/prompts.js.map +1 -1
  26. package/dist/rateLimit.d.ts +50 -0
  27. package/dist/rateLimit.d.ts.map +1 -0
  28. package/dist/rateLimit.js +85 -0
  29. package/dist/rateLimit.js.map +1 -0
  30. package/dist/resources.d.ts +1 -1
  31. package/dist/resources.d.ts.map +1 -1
  32. package/dist/resources.js +4 -4
  33. package/dist/resources.js.map +1 -1
  34. package/dist/server.d.ts +7 -0
  35. package/dist/server.d.ts.map +1 -0
  36. package/dist/server.js +46 -0
  37. package/dist/server.js.map +1 -0
  38. package/dist/toolMeta.d.ts +20 -0
  39. package/dist/toolMeta.d.ts.map +1 -0
  40. package/dist/toolMeta.js +75 -0
  41. package/dist/toolMeta.js.map +1 -0
  42. package/dist/tools.d.ts +1 -1
  43. package/dist/tools.d.ts.map +1 -1
  44. package/dist/tools.js +222 -181
  45. package/dist/tools.js.map +1 -1
  46. package/package.json +16 -7
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  Model Context Protocol (MCP) server for [HonkIO](https://honkio.ca), the Canadian SMS API. It lets an AI agent send SMS, run phone verification, manage Canadian numbers, and handle CASL compliance through natural language.
4
4
 
5
- 38 tools, 4 resources, and 5 guided prompts, all backed by the live HonkIO REST API.
5
+ 41 tools, 4 resources, and 5 guided prompts, all backed by the live HonkIO REST API. Use it two ways: point your client at the hosted endpoint at `https://mcp.honkio.ca/mcp`, or run it locally with `npx`. Both talk to the same API with the same key.
6
6
 
7
7
  ---
8
8
 
9
9
  ## Requirements
10
10
 
11
- - **Node.js 20 or newer**
12
11
  - A HonkIO account and API key
12
+ - For the local `npx` route only: **Node.js 20 or newer**
13
13
 
14
14
  ---
15
15
 
@@ -30,55 +30,97 @@ Live sending also requires that the account owner has completed phone verificati
30
30
 
31
31
  ## 2. Connect your AI tool
32
32
 
33
- There is nothing to install. `npx` fetches the server on first use and caches it.
33
+ There are two ways in. The hosted endpoint needs nothing installed and is the right choice for claude.ai connectors, the Claude Messages API, and any client that speaks Streamable HTTP. The local route runs the same server on your machine through `npx`.
34
34
 
35
- In every example below, put your own key in `HONKIO_API_KEY`.
35
+ In every example below, put your own key where it says `mk_test_YOUR_KEY_HERE`.
36
36
 
37
- ### Claude Code
37
+ ### Hosted endpoint
38
38
 
39
- From inside your project:
39
+ The key travels in a header on every request, so never paste it into a file you commit. The JSON examples read it from an environment variable.
40
+
41
+ **Claude Code**
40
42
 
41
43
  ```sh
42
- claude mcp add honkio \
43
- --env HONKIO_API_KEY=mk_test_YOUR_KEY_HERE \
44
- -- npx -y @honkio/mcp
44
+ claude mcp add --transport http honkio https://mcp.honkio.ca/mcp \
45
+ --header "Authorization: Bearer mk_test_YOUR_KEY_HERE"
46
+ ```
47
+
48
+ Prefer to sign in rather than paste a key? Add the endpoint without a header and run `/mcp` inside Claude Code: a browser window opens on honkio.ca where you approve the connection and choose live or test mode. The connection shows up on your API keys page as `OAuth: Claude Code`, and revoking it there disconnects the agent.
49
+
50
+ ```sh
51
+ claude mcp add --transport http honkio https://mcp.honkio.ca/mcp
45
52
  ```
46
53
 
47
- 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](#keeping-your-key-out-of-git)):
54
+ Or in a shared `.mcp.json`, with the key coming from `HONKIO_API_KEY` in your shell:
48
55
 
49
56
  ```json
50
57
  {
51
58
  "mcpServers": {
52
59
  "honkio": {
53
- "command": "npx",
54
- "args": ["-y", "@honkio/mcp"],
55
- "env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
60
+ "type": "http",
61
+ "url": "https://mcp.honkio.ca/mcp",
62
+ "headers": { "Authorization": "Bearer ${HONKIO_API_KEY}" }
56
63
  }
57
64
  }
58
65
  }
59
66
  ```
60
67
 
61
- ### Claude Desktop
62
-
63
- Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
68
+ **Cursor** (`.cursor/mcp.json` or `~/.cursor/mcp.json`)
64
69
 
65
70
  ```json
66
71
  {
67
72
  "mcpServers": {
68
73
  "honkio": {
69
- "command": "npx",
70
- "args": ["-y", "@honkio/mcp"],
71
- "env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY_HERE" }
74
+ "url": "https://mcp.honkio.ca/mcp",
75
+ "headers": { "Authorization": "Bearer mk_test_YOUR_KEY_HERE" }
72
76
  }
73
77
  }
74
78
  }
75
79
  ```
76
80
 
77
- Restart Claude Desktop afterwards.
81
+ **VS Code** (`.vscode/mcp.json`)
82
+
83
+ ```json
84
+ {
85
+ "servers": {
86
+ "honkio": {
87
+ "type": "http",
88
+ "url": "https://mcp.honkio.ca/mcp",
89
+ "headers": { "Authorization": "Bearer mk_test_YOUR_KEY_HERE" }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ **Claude Messages API** (no MCP client needed)
96
+
97
+ ```json
98
+ {
99
+ "model": "claude-opus-5",
100
+ "max_tokens": 1024,
101
+ "messages": [{ "role": "user", "content": "List my HonkIO phone numbers." }],
102
+ "mcp_servers": [
103
+ { "type": "url", "url": "https://mcp.honkio.ca/mcp", "name": "honkio", "authorization_token": "mk_test_YOUR_KEY_HERE" }
104
+ ],
105
+ "tools": [{ "type": "mcp_toolset", "mcp_server_name": "honkio" }]
106
+ }
107
+ ```
108
+
109
+ Send that with the `anthropic-beta: mcp-client-2025-11-20` header. The endpoint also accepts the key as `X-API-Key` if your client cannot set `Authorization`.
78
110
 
79
- ### Cursor
111
+ ### Local with npx
80
112
 
81
- Edit `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` globally:
113
+ `npx` fetches the server on first use and caches it. Needs Node.js 20 or newer.
114
+
115
+ **Claude Code**
116
+
117
+ ```sh
118
+ claude mcp add honkio \
119
+ --env HONKIO_API_KEY=mk_test_YOUR_KEY_HERE \
120
+ -- npx -y @honkio/mcp
121
+ ```
122
+
123
+ Or in `.mcp.json` (keep the real key out of git, see [Keeping your key out of git](#keeping-your-key-out-of-git)):
82
124
 
83
125
  ```json
84
126
  {
@@ -92,9 +134,11 @@ Edit `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` globally:
92
134
  }
93
135
  ```
94
136
 
95
- ### VS Code (GitHub Copilot)
137
+ **Claude Desktop**: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows), same `mcpServers` block as above, then restart Claude Desktop.
96
138
 
97
- Edit `.vscode/mcp.json` in your workspace:
139
+ **Cursor**: `.cursor/mcp.json` or `~/.cursor/mcp.json`, same `mcpServers` block.
140
+
141
+ **VS Code** (`.vscode/mcp.json`)
98
142
 
99
143
  ```json
100
144
  {
@@ -128,22 +172,38 @@ To check the server outside any AI tool:
128
172
  HONKIO_API_KEY=mk_test_YOUR_KEY npx -y @honkio/mcp
129
173
  ```
130
174
 
131
- 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.
175
+ 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.
176
+
177
+ To check the hosted endpoint outside any AI tool:
178
+
179
+ ```sh
180
+ curl -s https://mcp.honkio.ca/healthz
181
+ curl -s -i -X POST https://mcp.honkio.ca/mcp | head -3
182
+ ```
183
+
184
+ The first returns `{"ok":true,"version":"..."}`. The second, with no key, returns `401` and a `WWW-Authenticate: Bearer` header, which is the endpoint telling you where the key goes.
132
185
 
133
186
  ---
134
187
 
135
188
  ## Environment variables
136
189
 
137
- | Variable | Required | Description |
138
- |---|---|---|
139
- | `HONKIO_API_KEY` | Yes | Your API key (`mk_live_…` or `mk_test_…`). The server refuses to start without it. |
140
- | `HONKIO_API_URL` | No | Override the API base URL. Defaults to `https://api.honkio.ca`. Only needed for self-hosting or local development. |
190
+ | Variable | Used by | Required | Description |
191
+ |---|---|---|---|
192
+ | `HONKIO_API_KEY` | local `npx` | Yes | Your API key (`mk_live_…` or `mk_test_…`). The stdio server refuses to start without it. The hosted endpoint takes the key from the request header instead. |
193
+ | `API_URL` | both | No | Override the API base URL. Defaults to `https://api.honkio.ca`. Only needed for self-hosting or local development. The pre-1.5 name `HONKIO_API_URL` still works. |
194
+ | `PORT` | hosted | No | Port for `honkio-mcp-http`. Defaults to `8080`. |
195
+ | `MCP_ALLOWED_ORIGINS` | hosted | No | Comma-separated browser origins allowed to call the endpoint. Empty by default, which refuses any request carrying an `Origin` header. Command-line and server-side clients send none and are unaffected. |
196
+ | `MCP_RATE_LIMIT_PER_MINUTE` | hosted | No | Requests per minute allowed from one client address. Default `300`. Beyond it the endpoint answers `429` with `Retry-After`. |
197
+ | `MCP_AUTH_FAILURES_PER_MINUTE` | hosted | No | Refused requests (bad or missing key, bad Origin, malformed body) per minute allowed from one client address before the address is locked out for the rest of the minute. Default `10`. |
198
+ | `MCP_TRUSTED_PROXIES` | hosted | No | How many proxy hops in front of the process append to `X-Forwarded-For`. The client address is read that many entries from the right. Railway's edge is one hop, the default. Set `0` when nothing sits in front. |
199
+ | `MCP_SERVICE_KEY` | hosted | No | This service's key at the HonkIO API (the API's `MCP_SERVICE_KEY`). Lets the endpoint accept OAuth access tokens, so clients can sign in instead of pasting a key. Unset means API keys only. |
200
+ | `MCP_PUBLIC_URL` | hosted | No | The public URL access tokens are bound to. Default `https://mcp.honkio.ca/mcp`. |
141
201
 
142
202
  ### Keeping your key out of git
143
203
 
144
204
  `.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`.
145
205
 
146
- If a key does leak, revoke it immediately at <https://honkio.ca/dashboard/keys> — a revoked key stops working at once.
206
+ If a key does leak, revoke it immediately at <https://honkio.ca/dashboard/keys>. A revoked key stops working at once.
147
207
 
148
208
  ---
149
209
 
@@ -152,11 +212,11 @@ If a key does leak, revoke it immediately at <https://honkio.ca/dashboard/keys>
152
212
  ### Messages
153
213
  | Tool | Description |
154
214
  |---|---|
155
- | `send_sms` | Send an SMS from one of your numbers. Enforces CASL consent unless overridden. |
215
+ | `send_sms` | Send an SMS from one of your numbers. Enforces CASL consent unless overridden. Pass `idempotency_key` when retrying. A reserved exchange (555-XXXX, N11, test codes) is refused for free with `422 RESERVED_DESTINATION`. |
156
216
  | `list_messages` | List messages, filterable by number, status, direction and date. |
157
217
  | `get_message` | Full detail for one message, including delivery status and cost. |
158
218
 
159
- Both directions are billed: sending an SMS charges per segment, and receiving one on a provisioned number charges a flat per-message cost — `get_pricing` returns both figures. Inbound charges happen automatically whenever someone texts your number, independent of any tool call.
219
+ Both directions are billed: sending an SMS charges per segment, and receiving one on a provisioned number charges a flat per-message cost. `get_pricing` returns both figures. Inbound charges happen automatically whenever someone texts your number, independent of any tool call.
160
220
 
161
221
  ### Phone verification (OTP)
162
222
  | Tool | Description |
@@ -166,7 +226,7 @@ Both directions are billed: sending an SMS charges per segment, and receiving on
166
226
  | `get_verification` | Status of a single verification attempt. |
167
227
  | `list_verifications` | List verification attempts. |
168
228
 
169
- 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.
229
+ 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.
170
230
 
171
231
  ### Pricing
172
232
  | Tool | Description |
@@ -194,7 +254,7 @@ Prices are set at runtime and change without a release. Read them rather than ha
194
254
  | `record_opt_out` | Record an opt-out manually. |
195
255
  | `list_opt_outs` | List opt-out records. |
196
256
 
197
- ### DNCL — not available yet
257
+ ### DNCL: not available yet
198
258
  | Tool | Description |
199
259
  |---|---|
200
260
  | `check_dncl` | Returns `501 DNCL_COMING_SOON`. |
@@ -215,13 +275,23 @@ CRTC Do Not Call List checking is not live. `dncl_exemptions` on `send_sms` is a
215
275
  | `discard_webhook_dead_letter` | Drop a dead-lettered delivery. |
216
276
  | `reactivate_webhook` | Re-enable a webhook disabled by repeated failures. |
217
277
 
278
+ ### Sending limits
279
+
280
+ | Tool | What it does |
281
+ |---|---|
282
+ | `get_send_limit` | Daily cap (rolling 24 h), usage, the per-recipient cap (`recipient_rate_per_hour` / `recipient_rate_per_day`), probation status, any active pause, and past volume requests. |
283
+ | `request_send_limit` | File a "request a higher volume" for staff review once probation has ended. |
284
+ | `get_topup_allowance` | How much credit can be added right now under the balance and 30-day top-up caps. |
285
+
286
+ New accounts can send 250 live messages per rolling 24 hours; 30 days after the first live send they can request more. Identical messages to many recipients, per-number rate, link shorteners, and unusually high opt-out or failure rates are also limited. See [honkio.ca/docs#limits](https://honkio.ca/docs#limits). Refused sends return `DAILY_LIMIT_REACHED`, `FANOUT_LIMIT_REACHED`, `NUMBER_RATE_LIMITED`, `RECIPIENT_RATE_LIMITED` (30 an hour / 100 a day to one number), `SENDING_PAUSED`, `UNDELIVERABLE_NUMBER` (three consecutive carrier failures list a number for 90 days), `NOT_A_MOBILE_NUMBER` (a landline or VoIP destination, refused before sending), `RESERVED_DESTINATION` (a reserved exchange such as 555-XXXX, N11 or a carrier test code, refused in both modes) or `LINK_SHORTENER_BLOCKED` with details.
287
+
218
288
  ### Account and keys
219
289
  | Tool | Description |
220
290
  |---|---|
221
- | `whoami` | Identify the account the API key belongs to — id, name, balance, status. |
291
+ | `whoami` | Identify the account the API key belongs to: id, name, balance, status. |
222
292
  | `get_account` | Account detail and credit balance. |
223
293
  | `update_account` | Update the account name. |
224
- | `get_usage` | Usage for a billing period. |
294
+ | `get_usage` | Usage for a billing period, including live delivery health (`delivery`: delivered, failed, undelivered, pending, `failureRatePct`; `byNumber`: the same per sending number). |
225
295
  | `create_api_key` | Issue a new live or test key. |
226
296
  | `rotate_api_key` | Replace a key, invalidating the old value. |
227
297
  | `revoke_api_key` | Revoke a key immediately. |
@@ -265,10 +335,10 @@ Guided multi-step workflows:
265
335
  ```
266
336
  Find me an available Toronto (416) number and tell me what it costs before buying anything.
267
337
 
268
- Check whether +15145559876 has valid CASL consent, and if it does, text them that
338
+ Check whether +1514XXXXXXX has valid CASL consent, and if it does, text them that
269
339
  their appointment is confirmed for 2pm tomorrow.
270
340
 
271
- Start a phone verification for +16045551111, then check the code 123456 against it.
341
+ Start a phone verification for +1604XXXXXXX, then check the code 123456 against it.
272
342
 
273
343
  Set up a webhook at https://myapp.ca/webhooks/honkio for delivery receipts and
274
344
  inbound messages.
@@ -283,21 +353,21 @@ Show me any webhook deliveries that failed and ended up in the dead-letter queue
283
353
  Two tools move real money on a live key:
284
354
 
285
355
  - **`provision_phone_number`** charges the first month's rent plus a one-time activation fee, together, and starts monthly rent. Rent keeps accruing until you call `release_phone_number`; the activation fee is not refunded on release.
286
- - **`send_sms`** and **`start_verification`** charge per SMS part against your balance, counted the way the carrier splits the body (typographic quotes and dashes are smart-encoded to GSM-7; emoji force Unicode parts). The charge is settled to the carrier's part count after the send, a send the carrier rejects costs nothing, and a body over 10 parts is refused with `422 MESSAGE_TOO_LONG` before any charge. `start_verification` adds a per-verification surcharge on top. `get_pricing` tells you what each costs right now.
356
+ - **`send_sms`** and **`start_verification`** charge per SMS part against your balance, counted the way the carrier splits the body (typographic quotes and dashes are smart-encoded to GSM-7; emoji force Unicode parts). The charge is settled to the carrier's part count after the send. A send the carrier rejects outright costs nothing, and so does a send to a reserved exchange (555-XXXX and similar), which is refused here; a message the carrier accepts but cannot deliver keeps its charge. A body over 10 parts is refused with `422 MESSAGE_TOO_LONG` before any charge. `start_verification` adds a per-verification surcharge on top. `get_pricing` tells you what each costs right now.
287
357
 
288
- A third charge is not tool-triggered at all: **inbound SMS is billed per segment** the moment a carrier delivers it to one of your provisioned numbers, whether or not you ever call a tool. Traffic to a number you provisioned draws down your balance on its own (STOP/START/HELP replies are not charged), and a received message is debited even when the balance cannot cover it — the balance goes negative and sends are frozen until the next top-up.
358
+ A third charge is not tool-triggered at all: **inbound SMS is billed per segment** the moment a carrier delivers it to one of your provisioned numbers, whether or not you ever call a tool. Traffic to a number you provisioned draws down your balance on its own (STOP/START/HELP replies are not charged), and a received message is debited even when the balance cannot cover it: the balance goes negative and sends are frozen until the next top-up.
289
359
 
290
- 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.
360
+ 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.
291
361
 
292
- 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.
362
+ 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.
293
363
 
294
364
  ---
295
365
 
296
366
  ## Canadian compliance
297
367
 
298
- - **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.
299
- - **DNCL** — CRTC Do Not Call List checking is not available yet and is not enforced.
300
- - **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](https://honkio.ca/legal/privacy) for the full disclosure. Use `request_erasure` for right-to-erasure requests.
368
+ - **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.
369
+ - **DNCL**: CRTC Do Not Call List checking is not available yet and is not enforced.
370
+ - **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](https://honkio.ca/legal/privacy) for the full disclosure. Use `request_erasure` for right-to-erasure requests.
301
371
 
302
372
  ---
303
373
 
@@ -306,7 +376,7 @@ A test-mode send still comes back with status `DELIVERED`, because it simulates
306
376
  | Symptom | Cause and fix |
307
377
  |---|---|
308
378
  | `Error [UNAUTHORIZED]` | Key is wrong, revoked, or `HONKIO_API_KEY` never reached the server. Check the `env` block in your config. |
309
- | 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`. |
379
+ | 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`, since GUI apps do not always inherit your shell's `PATH`. |
310
380
  | 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. |
311
381
  | `npm ERR! 404 @honkio/mcp` | Usually an npm registry override or a private proxy. Check `npm config get registry`. |
312
382
  | `Error [PAYMENT_REQUIRED]` | The account needs an initial top-up before live use. |
@@ -330,9 +400,36 @@ npm run typecheck # types only
330
400
  npm run build # compile to dist/
331
401
  ```
332
402
 
333
- 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`.
403
+ Point a local checkout at your own API with `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`.
404
+
405
+ `dist/` is gitignored and the published tarball is built from it, so `prepublishOnly` rebuilds on every `npm publish`, so never publish without letting it run.
406
+
407
+ ### Running the hosted entry yourself
408
+
409
+ The same package ships `honkio-mcp-http`, the process behind `mcp.honkio.ca`:
410
+
411
+ ```sh
412
+ PORT=8080 API_URL=https://api.honkio.ca npx -y -p @honkio/mcp honkio-mcp-http
413
+ ```
414
+
415
+ It answers `GET /healthz` and `POST /mcp`, verifies each caller's key against the API once a minute, rate-limits each client address (see the environment table), and serves both the 2025 handshake protocol and the 2026-07-28 revision. There is a `Dockerfile` and a `railway.toml` in this directory for hosting it.
416
+
417
+ ### Publishing to the MCP Registry
418
+
419
+ `server.json` describes both the npm package and the hosted endpoint for the official registry under the `ca.honkio/mcp` namespace. Publishing needs the DNS-verified namespace once, then one command per release:
420
+
421
+ ```sh
422
+ # once: generate a keypair and publish the public half at the apex of honkio.ca
423
+ openssl genpkey -algorithm Ed25519 -out mcp-registry.pem
424
+ openssl pkey -in mcp-registry.pem -pubout -outform DER | tail -c 32 | base64
425
+ # -> TXT record on honkio.ca: v=MCPv1; k=ed25519; p=<that base64>
426
+
427
+ # each release, after npm publish and a matching version in server.json
428
+ npx -y @modelcontextprotocol/mcp-publisher login dns --domain honkio.ca --private-key "$(openssl pkey -in mcp-registry.pem -outform DER | tail -c 32 | xxd -p -c 64)"
429
+ npx -y @modelcontextprotocol/mcp-publisher publish
430
+ ```
334
431
 
335
- `dist/` is gitignored and the published tarball is built from it, so `prepublishOnly` rebuilds on every `npm publish` — never publish without letting it run.
432
+ The `serverJson` test pins `server.json` to `package.json`, so a version bump that forgets one of them fails `npm test`.
336
433
 
337
434
  ## License
338
435
 
package/dist/auth.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+ import type { AuthInfo } from '@modelcontextprotocol/server';
3
+ /** OAuth access tokens minted by the API's authorization server. */
4
+ export declare const isAccessToken: (credential: string) => boolean;
5
+ /** The key from `Authorization: Bearer` or, as the API also accepts, `X-API-Key`. Null when absent or not a HonkIO key. */
6
+ export declare function extractApiKey(headers: IncomingHttpHeaders): string | null;
7
+ export type VerifyResult = {
8
+ status: 'ok';
9
+ authInfo: AuthInfo;
10
+ accountId: string;
11
+ isTestMode: boolean;
12
+ } | {
13
+ status: 'invalid';
14
+ } | {
15
+ status: 'unavailable';
16
+ };
17
+ export interface KeyVerifierOptions {
18
+ apiBaseUrl: string;
19
+ /** Cache lifetime for both good and rejected keys. Default 60 s. */
20
+ ttlMs?: number;
21
+ /** Cap on cached keys; the oldest entry is dropped past it. Default 10,000. */
22
+ maxEntries?: number;
23
+ /** Clock, injectable for tests. */
24
+ now?: () => number;
25
+ /** This service's key at the API (MCP_SERVICE_KEY). Without it access tokens are refused outright, since the API would refuse them too. */
26
+ serviceKey?: string;
27
+ }
28
+ export declare class KeyVerifier {
29
+ private readonly cache;
30
+ private readonly apiBaseUrl;
31
+ private readonly ttlMs;
32
+ private readonly maxEntries;
33
+ private readonly now;
34
+ private readonly serviceKey;
35
+ constructor(opts: KeyVerifierOptions);
36
+ get size(): number;
37
+ verify(key: string): Promise<VerifyResult>;
38
+ private toResult;
39
+ }
40
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAK7D,oEAAoE;AACpE,eAAO,MAAM,aAAa,GAAI,YAAY,MAAM,KAAG,OAA0C,CAAC;AAE9F,2HAA2H;AAC3H,wBAAgB,aAAa,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAYzE;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GAC5E;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC;AAI9B,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2IAA2I;IAC3I,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAEpC,IAAI,EAAE,kBAAkB;IAQpC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA8BhD,OAAO,CAAC,QAAQ;CAmBjB"}
package/dist/auth.js ADDED
@@ -0,0 +1,98 @@
1
+ /**
2
+ * API-key auth for the hosted MCP endpoint.
3
+ *
4
+ * The endpoint is an OAuth-shaped resource server in name only: the bearer
5
+ * token is a HonkIO API key, and the authority that decides whether it is
6
+ * valid is the REST API. verify() asks GET /v1/accounts/me and remembers the
7
+ * answer for a minute, so a chatty agent costs one lookup per key per minute
8
+ * rather than one per tool call.
9
+ */
10
+ import { createHash } from 'node:crypto';
11
+ import { HonkioClient, HonkioError } from './client.js';
12
+ const KEY_PATTERN = /^(mk_(live|test)_[A-Za-z0-9]+|hk_at_[A-Za-z0-9_-]+)$/;
13
+ /** OAuth access tokens minted by the API's authorization server. */
14
+ export const isAccessToken = (credential) => credential.startsWith('hk_at_');
15
+ /** The key from `Authorization: Bearer` or, as the API also accepts, `X-API-Key`. Null when absent or not a HonkIO key. */
16
+ export function extractApiKey(headers) {
17
+ const auth = headers.authorization;
18
+ if (typeof auth === 'string' && auth.startsWith('Bearer ')) {
19
+ const key = auth.slice('Bearer '.length).trim();
20
+ return KEY_PATTERN.test(key) ? key : null;
21
+ }
22
+ const xKey = headers['x-api-key'];
23
+ if (typeof xKey === 'string') {
24
+ const key = xKey.trim();
25
+ return KEY_PATTERN.test(key) ? key : null;
26
+ }
27
+ return null;
28
+ }
29
+ export class KeyVerifier {
30
+ cache = new Map();
31
+ apiBaseUrl;
32
+ ttlMs;
33
+ maxEntries;
34
+ now;
35
+ serviceKey;
36
+ constructor(opts) {
37
+ this.apiBaseUrl = opts.apiBaseUrl;
38
+ this.ttlMs = opts.ttlMs ?? 60_000;
39
+ this.maxEntries = opts.maxEntries ?? 10_000;
40
+ this.now = opts.now ?? Date.now;
41
+ this.serviceKey = opts.serviceKey;
42
+ }
43
+ get size() {
44
+ return this.cache.size;
45
+ }
46
+ async verify(key) {
47
+ const hash = createHash('sha256').update(key).digest('hex');
48
+ const now = this.now();
49
+ const hit = this.cache.get(hash);
50
+ if (hit && hit.expiresAt > now)
51
+ return this.toResult(key, hit);
52
+ const token = isAccessToken(key);
53
+ if (token && !this.serviceKey)
54
+ return { status: 'invalid' };
55
+ let verdict;
56
+ try {
57
+ const me = await new HonkioClient({ apiKey: key, baseUrl: this.apiBaseUrl, serviceKey: token ? this.serviceKey : undefined }).getCurrentAccount();
58
+ verdict = { accountId: me.account.id };
59
+ }
60
+ catch (err) {
61
+ if (err instanceof HonkioError && (err.status === 401 || err.status === 403)) {
62
+ verdict = 'invalid';
63
+ }
64
+ else {
65
+ return { status: 'unavailable' };
66
+ }
67
+ }
68
+ const entry = { expiresAt: now + this.ttlMs, verdict };
69
+ if (this.cache.size >= this.maxEntries) {
70
+ const oldest = this.cache.keys().next().value;
71
+ if (oldest !== undefined)
72
+ this.cache.delete(oldest);
73
+ }
74
+ this.cache.set(hash, entry);
75
+ return this.toResult(key, entry);
76
+ }
77
+ toResult(key, entry) {
78
+ if (entry.verdict === 'invalid')
79
+ return { status: 'invalid' };
80
+ const credential = isAccessToken(key) ? 'token' : 'key';
81
+ // Test mode is a property of the key behind a token; the API decides. For logs only.
82
+ const isTestMode = credential === 'key' && key.startsWith('mk_test_');
83
+ const accountId = entry.verdict.accountId;
84
+ return {
85
+ status: 'ok',
86
+ accountId,
87
+ isTestMode,
88
+ authInfo: {
89
+ token: key,
90
+ clientId: accountId,
91
+ scopes: [],
92
+ expiresAt: Math.floor(entry.expiresAt / 1000),
93
+ extra: { accountId, isTestMode, credential },
94
+ },
95
+ };
96
+ }
97
+ }
98
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -4,6 +4,10 @@
4
4
  export interface HonkioClientOptions {
5
5
  apiKey: string;
6
6
  baseUrl?: string;
7
+ /** Account id already known for this key, so the first account-scoped call does not look it up. */
8
+ accountId?: string;
9
+ /** Sent as X-MCP-Service-Key. Required when the credential is an OAuth access token: the API honours those only from this service. */
10
+ serviceKey?: string;
7
11
  }
8
12
  export declare class HonkioError extends Error {
9
13
  readonly status: number;
@@ -13,7 +17,16 @@ export declare class HonkioError extends Error {
13
17
  export declare class HonkioClient {
14
18
  private readonly apiKey;
15
19
  private readonly baseUrl;
20
+ private accountId;
21
+ private readonly serviceKey;
16
22
  constructor(options: HonkioClientOptions);
23
+ /**
24
+ * The account this key belongs to, looked up once per client instance. A
25
+ * stdio process has one key for its whole life; an HTTP request builds a
26
+ * fresh client per call, seeded from the verifier's cache, so neither ever
27
+ * asks the API twice.
28
+ */
29
+ currentAccountId(): Promise<string>;
17
30
  private request;
18
31
  sendMessage(params: {
19
32
  from: string;
@@ -21,6 +34,8 @@ export declare class HonkioClient {
21
34
  body: string;
22
35
  skip_consent_check?: boolean;
23
36
  dncl_exemptions?: string[];
37
+ /** Sent as the Idempotency-Key header, not in the body. */
38
+ idempotency_key?: string;
24
39
  }): Promise<Record<string, unknown>>;
25
40
  listMessages(query?: {
26
41
  from?: string;
@@ -152,6 +167,12 @@ export declare class HonkioClient {
152
167
  from?: string;
153
168
  to?: string;
154
169
  }): Promise<Record<string, unknown>>;
170
+ getSendLimit(): Promise<Record<string, unknown>>;
171
+ requestSendLimit(params: {
172
+ requested_limit?: number;
173
+ reason: string;
174
+ }): Promise<Record<string, unknown>>;
175
+ getTopupAllowance(accountId: string): Promise<Record<string, unknown>>;
155
176
  createApiKey(accountId: string, params?: {
156
177
  mode?: 'live' | 'test';
157
178
  label?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}