@telkit/mcp 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +138 -2
- package/main.js +65852 -0
- package/package.json +23 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PEKKA AS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,139 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @telkit/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Telkit's MCP server (Model Context Protocol) for developers and coding agents such as Claude Code
|
|
6
|
+
and Cursor. It helps you set up and test a Telkit integration: your agent reads the guides, looks up
|
|
7
|
+
any operation of the API with its fields and error codes, sends a test SMS or e-mail, and reads
|
|
8
|
+
the message, the event log, the API log and your webhooks. It speaks the API under `/v2` through
|
|
9
|
+
`@telkit/sdk` 1.0, where an operation has one name everywhere: `sms.send` is `POST /v2/sms` and
|
|
10
|
+
`telkit.sms.send(…)`.
|
|
11
|
+
|
|
12
|
+
**Test keys only.** The server starts only with a test key (`tk_test_…`); any other key stops it
|
|
13
|
+
before anything happens. A test key's sends are simulated and free, so nothing reaches a real
|
|
14
|
+
recipient and nothing costs. One exception, Telkit's own rule for every test key: an SMS to the
|
|
15
|
+
confirmed mobile number of a member of the company, or an e-mail to a member's sign-in address, also
|
|
16
|
+
arrives for real and free, at most 5 SMS units (a long SMS counts each of its parts) and 5 e-mails a
|
|
17
|
+
day. An e-mail's answer says `testCopy: true` when a recipient is such a member, and it stays
|
|
18
|
+
`true` when the day's limit stops the copy; an SMS answer has no such field.
|
|
19
|
+
|
|
20
|
+
Create a test key in Telkit's dashboard under Developers › API keys. Give it the scopes the tools
|
|
21
|
+
need: `sms:send`, `sms:read`, `email:send`, `email:read`, `events:read`, `webhooks:manage` and
|
|
22
|
+
`usage:read`.
|
|
23
|
+
|
|
24
|
+
## Connect it
|
|
25
|
+
|
|
26
|
+
The server runs over stdio with `npx @telkit/mcp` (Node 20 or newer) or `bunx @telkit/mcp`, and
|
|
27
|
+
reads the key from `TELKIT_API_KEY`.
|
|
28
|
+
|
|
29
|
+
**Claude Code:**
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
claude mcp add --env TELKIT_API_KEY=tk_test_… --transport stdio telkit -- npx -y @telkit/mcp
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Cursor** (`.cursor/mcp.json` in the project, or `~/.cursor/mcp.json`):
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"telkit": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["-y", "@telkit/mcp"],
|
|
43
|
+
"env": { "TELKIT_API_KEY": "tk_test_…" }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`TELKIT_API_URL` points the server at another API origin than `https://api.telkit.no` (a proxy, a
|
|
50
|
+
local server).
|
|
51
|
+
|
|
52
|
+
## Tools
|
|
53
|
+
|
|
54
|
+
Look up (bundled with the package, no network and no key needed):
|
|
55
|
+
|
|
56
|
+
| Tool | What it answers |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `find_guide` | The developer guides as markdown (Norwegian): a search, or one guide in full by its slug |
|
|
59
|
+
| `describe_operation` | One operation by its name (`sms.send`, `tools.smsCampaigns.create`), its method and path (`POST /v2/sms`) or words: the SDK call, input fields, answer, error codes with their sentences. The core of the API comes first, then the rest of `/v2`, then the tools under `/v2/tools` |
|
|
60
|
+
| `describe_event` | The events webhooks deliver and the event log keeps, with each one's `data` fields |
|
|
61
|
+
|
|
62
|
+
Test (each one call of `@telkit/sdk` with your test key):
|
|
63
|
+
|
|
64
|
+
| Tool | Calls |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `send_test_sms` | `telkit.sms.send`, `POST /v2/sms` |
|
|
67
|
+
| `send_test_email` | `telkit.email.send`, `POST /v2/email` |
|
|
68
|
+
| `get_message` | `telkit.sms.get` or `telkit.email.get`, `GET /v2/sms/{id}`, `GET /v2/email/{id}` |
|
|
69
|
+
| `list_events` | `telkit.events.list`, `GET /v2/events` |
|
|
70
|
+
| `list_api_requests` | `telkit.account.requests.list`, `GET /v2/account/requests` |
|
|
71
|
+
| `set_up_webhook` | `telkit.webhooks.create`, `POST /v2/webhooks` |
|
|
72
|
+
| `list_webhooks` | `telkit.webhooks.list`, `GET /v2/webhooks` |
|
|
73
|
+
| `send_test_event` | `telkit.webhooks.test` to one webhook (`POST /v2/webhooks/{id}/test`), or `telkit.events.sendTest` to the whole application (`POST /v2/events/test`) |
|
|
74
|
+
|
|
75
|
+
A call answers `{ data, error }`. The tool result is the `data` as JSON; an error comes back as a
|
|
76
|
+
tool result marked as an error, with the API's `code` and `message`, the HTTP status, `retryable`,
|
|
77
|
+
`meta` and the `requestId` (and `issues` when the input could not be read). A call whose answer
|
|
78
|
+
never arrived is `network_error`, with `commit: "unknown"` and the `idempotencyKey` when it may
|
|
79
|
+
have acted.
|
|
80
|
+
|
|
81
|
+
## Invariants
|
|
82
|
+
|
|
83
|
+
- **Test keys only, checked at start** (`src/environment.ts`) and again where the SDK client is
|
|
84
|
+
made (`telkitClientOf`), so a program that builds the server itself is held to it too: the server
|
|
85
|
+
mints test-mode keys
|
|
86
|
+
under `tk_test_` and live keys and client tokens under `tk_` (`backend/server/src/access.ts`).
|
|
87
|
+
The check is a product rule, not the wall: a test key cannot act live on the server either.
|
|
88
|
+
- **One SDK call per test tool**, through `@telkit/sdk` 1.0 (`src/server.ts`), never hand-written
|
|
89
|
+
HTTP. Every call sends `telkit-client: telkit-mcp/<version>`, so the API log names this server.
|
|
90
|
+
- **The key never shows in an answer**: the server is given the key it started with and takes it
|
|
91
|
+
out of every tool result, whatever the API answered; what the runtime threw (`cause`) is left
|
|
92
|
+
out of an error. The one secret an answer does hold is a new webhook's signing secret from
|
|
93
|
+
`set_up_webhook`, which the API shows once and the developer must store.
|
|
94
|
+
- **The catalog is bundled and generated** (`src/generated/catalog.ts`, by `scripts/catalog.ts`),
|
|
95
|
+
from these sources, and nothing in it is written by hand:
|
|
96
|
+
- the operations, their fields, error codes and events from the two `/v2` OpenAPI documents the
|
|
97
|
+
SDK's `generate` writes (`client/sdk/src/generated/v2/openapi.json` and `tools/openapi.json`),
|
|
98
|
+
held to the server's committed snapshots (`backend/server/api-snapshots/api.json` and
|
|
99
|
+
`tools.json`): the script stops when a document and its snapshot name different operations,
|
|
100
|
+
routes or codes, and `tests/unit/server.test.ts` holds the catalog to the snapshots. An
|
|
101
|
+
operation's name is its id. An upload door is one operation, as the SDK calls it;
|
|
102
|
+
- an idempotency key, `identity`, a list and the file fields per operation from the SDK's own
|
|
103
|
+
generated facts (`client/sdk/src/generated/v2/facts.ts`), the table `createTelkit()` is built
|
|
104
|
+
from;
|
|
105
|
+
- the order from the docs' reference (`coreOperations` in
|
|
106
|
+
`client/web/src/features/api-docs/reference-groups.ts`, read as text): the core of the API in
|
|
107
|
+
the contract's order, then the rest of `/v2` by building block, then the tools;
|
|
108
|
+
- the error sentences from the server's own catalog (checked against the documents'
|
|
109
|
+
descriptions; a code the server's catalog lacks takes its sentence from the descriptions, and
|
|
110
|
+
22 framework upload and webhook codes have none: at run time the API's own `message` is what a
|
|
111
|
+
tool shows);
|
|
112
|
+
- the guides from `guides/llms.txt` and `guides/llms-full.txt`, the web app's two files for
|
|
113
|
+
agents, kept in this package so `generate` needs no running web app (the typecheck's generate
|
|
114
|
+
step and the publish build run it as it is).
|
|
115
|
+
|
|
116
|
+
Bundled, a lookup answers offline and describes the API version the bundled SDK calls.
|
|
117
|
+
`bun run --cwd client/mcp generate` runs after `api:snapshot` (the typecheck runs it too). After
|
|
118
|
+
the docs change, fetch the guides again from a running web app and commit the two files:
|
|
119
|
+
`bun run --cwd client/mcp generate --docs-origin http://localhost:10665`. A guide that calls the
|
|
120
|
+
SDK by a name the catalog lacks turns `tests/unit/server.test.ts` red, and so does a page of the
|
|
121
|
+
docs (`client/web/src/content/docs/entries.ts`) without a bundled guide: the guides are stale.
|
|
122
|
+
- **`mcpVersion`** in `src/server.ts` equals `version` in `package.json`
|
|
123
|
+
(`tests/unit/server.test.ts`).
|
|
124
|
+
|
|
125
|
+
## How to test
|
|
126
|
+
|
|
127
|
+
`bun run test client/mcp/tests/unit` (no network). The journey against the running dev API
|
|
128
|
+
(`http://localhost:10660`, it mints its own test key as the dev person `ada`):
|
|
129
|
+
`bun run test:integration client/mcp/tests/integration`. Build: `bun run --cwd client/mcp build`
|
|
130
|
+
(it runs the SDK's and this package's `generate` first),
|
|
131
|
+
then `TELKIT_API_KEY=tk_test_… node client/mcp/dist/main.js`.
|
|
132
|
+
|
|
133
|
+
## Publish a release
|
|
134
|
+
|
|
135
|
+
The workspace's `package.json` stays private; npm receives only the build in `dist/` (`main.js`
|
|
136
|
+
with `@telkit/sdk` and the catalog bundled, the MCP SDK and zod as dependencies). Raise `version`
|
|
137
|
+
in `package.json` and `mcpVersion` in `src/server.ts` together, commit, then
|
|
138
|
+
`bun scripts/sdk-publish.ts --commit <the released commit> --package mcp` from the repository root
|
|
139
|
+
(add `--publish` to publish), as for `@telkit/sdk` (`client/sdk/README.md`, «Publish a release»).
|