@sawala/kodena-mcp 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/README.md +268 -0
- package/dist/server.js +28152 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# @sawala/kodena-mcp
|
|
2
|
+
|
|
3
|
+
Drive the Kodena API from any [MCP](https://modelcontextprotocol.io)-capable
|
|
4
|
+
AI agent — Claude Desktop, Claude Code, Cursor, Continue.dev, Zed, and any
|
|
5
|
+
other host that speaks the Model Context Protocol.
|
|
6
|
+
|
|
7
|
+
The server runs as a short-lived Node process on the user's machine,
|
|
8
|
+
spawned by the MCP host. It reuses the credentials written by the
|
|
9
|
+
`@sawala/kodena` CLI, talks JSON-RPC over stdio with the host, and makes
|
|
10
|
+
HTTPS calls to `api.sawala.cloud` on the user's behalf.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
┌─────────────────────┐ stdio JSON-RPC ┌──────────────────┐
|
|
14
|
+
│ Claude Desktop / │ ───────────────────────────────▶ │ kodena-mcp │
|
|
15
|
+
│ Claude Code / │ ◀─────────────────────────────── │ (node process │
|
|
16
|
+
│ Cursor / … │ │ on your laptop) │
|
|
17
|
+
└─────────────────────┘ └─────────┬────────┘
|
|
18
|
+
│ HTTPS
|
|
19
|
+
▼
|
|
20
|
+
┌──────────────────┐
|
|
21
|
+
│ api.sawala.cloud │
|
|
22
|
+
└──────────────────┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
1. **Log in once** via the CLI (writes `~/.kodena/credentials`):
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npm i -g @sawala/kodena
|
|
31
|
+
kodena login
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. **Wire the MCP server into your host.** Pick the snippet for your tool below.
|
|
35
|
+
|
|
36
|
+
3. **Ask the agent in plain English.** "List my Kodena scripts."
|
|
37
|
+
"What's my org handle?" "Deploy `./.open-next` to `my-blog`."
|
|
38
|
+
|
|
39
|
+
## Host configuration
|
|
40
|
+
|
|
41
|
+
### Claude Desktop
|
|
42
|
+
|
|
43
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
44
|
+
or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"kodena": {
|
|
50
|
+
"command": "npx",
|
|
51
|
+
"args": ["-y", "@sawala/kodena-mcp"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Restart Claude Desktop. The "kodena" server appears in the MCP servers
|
|
58
|
+
list with 18 tools available (or 8, in read-only mode — see below).
|
|
59
|
+
|
|
60
|
+
### Claude Code
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
claude mcp add kodena -- npx -y @sawala/kodena-mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Cursor
|
|
67
|
+
|
|
68
|
+
Edit `~/.cursor/mcp.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"kodena": {
|
|
74
|
+
"command": "npx",
|
|
75
|
+
"args": ["-y", "@sawala/kodena-mcp"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Local-build testing
|
|
82
|
+
|
|
83
|
+
To point a host at a locally built binary (e.g. for development against
|
|
84
|
+
`main`):
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"kodena": {
|
|
90
|
+
"command": "node",
|
|
91
|
+
"args": ["/absolute/path/to/cli/packages/kodena-mcp/dist/server.js"]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Authentication
|
|
98
|
+
|
|
99
|
+
The server reads `~/.kodena/credentials` (written by `kodena login`) on
|
|
100
|
+
every tool call — so `kodena org use <slug>` in a separate terminal
|
|
101
|
+
takes effect on the very next call without restarting the host.
|
|
102
|
+
|
|
103
|
+
For non-interactive environments (CI runners, sandboxed agents), pass
|
|
104
|
+
the token via the MCP server's env:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"mcpServers": {
|
|
109
|
+
"kodena": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["-y", "@sawala/kodena-mcp"],
|
|
112
|
+
"env": {
|
|
113
|
+
"KODENA_API_TOKEN": "koda_…",
|
|
114
|
+
"KODENA_ORG": "acme"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The server NEVER writes to `~/.kodena/credentials` or `~/.kodena/config` —
|
|
122
|
+
token minting and org/project switching remain the CLI's job. To see the
|
|
123
|
+
context the server is using (with the token redacted), an agent can read
|
|
124
|
+
the `kodena://config` resource.
|
|
125
|
+
|
|
126
|
+
## Tools
|
|
127
|
+
|
|
128
|
+
### Read (always safe)
|
|
129
|
+
|
|
130
|
+
| Tool | API | Description |
|
|
131
|
+
| --- | --- | --- |
|
|
132
|
+
| `kodena_whoami` | `GET /me` | Identity + active org/project context |
|
|
133
|
+
| `kodena_list_orgs` | `GET /me/orgs` | Memberships, with active + scope flags |
|
|
134
|
+
| `kodena_list_projects` | `GET /projects` | Projects in the active org |
|
|
135
|
+
| `kodena_list_scripts` | `GET /kodena/scripts` | Scripts in the active org, with resolved public URLs |
|
|
136
|
+
| `kodena_get_script` | `GET /kodena/scripts/:slug` | Single script's full row |
|
|
137
|
+
| `kodena_check_slug_available` | `GET /kodena/scripts/slug-available` | Availability check before create |
|
|
138
|
+
| `kodena_get_org_handle` | `GET /kodena/org-handle` | Active org's claimed handle, or null |
|
|
139
|
+
| `kodena_get_custom_domain_status` | `GET /kodena/scripts/:slug/custom-domain-status` | SSL/DNS provisioning state |
|
|
140
|
+
|
|
141
|
+
### Write (non-destructive)
|
|
142
|
+
|
|
143
|
+
| Tool | API | Description |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| `kodena_create_script` | `POST /kodena/scripts` | Reserve a new slug (no code uploaded yet) |
|
|
146
|
+
| `kodena_update_script` | `PATCH /kodena/scripts/:slug` | Update metadata (currently: `name`) |
|
|
147
|
+
| `kodena_set_org_handle` | `PUT /kodena/org-handle` | Claim the org's immutable handle |
|
|
148
|
+
|
|
149
|
+
### Destructive / deploy
|
|
150
|
+
|
|
151
|
+
Every tool here is flagged `destructiveHint: true`; the host surfaces a
|
|
152
|
+
confirmation prompt before invoking. `kodena_delete_script` additionally
|
|
153
|
+
carries `irreversibleHint: true` AND requires an input-level
|
|
154
|
+
`confirm: true` literal — both must agree.
|
|
155
|
+
|
|
156
|
+
| Tool | API | Description |
|
|
157
|
+
| --- | --- | --- |
|
|
158
|
+
| `kodena_deploy_script` | `POST /kodena/scripts/:slug/deploy` | Upload a worker bundle from local paths (10 MiB worker, 100 MiB assets). Supports `dryRun: true` to confirm bundle size first. |
|
|
159
|
+
| `kodena_set_custom_domain` | `POST .../custom-domain` | Attach a hostname (`openWorldHint`: affects DNS) |
|
|
160
|
+
| `kodena_remove_custom_domain` | `DELETE .../custom-domain` | Detach (`openWorldHint`) |
|
|
161
|
+
| `kodena_delete_script` | `DELETE /kodena/scripts/:slug` | `irreversibleHint`; requires `confirm: true` |
|
|
162
|
+
| `kodena_rebuild_assets_manifest` | `POST .../assets/rebuild-manifest` | Resync manifest with stored objects |
|
|
163
|
+
| `kodena_patch_assets` | `POST .../assets/patch` | Add/replace specific asset files (10 MiB per file, 25 MiB aggregate) |
|
|
164
|
+
| `kodena_rehydrate_script` | `POST .../rehydrate` | Re-push stored bundle to Cloudflare |
|
|
165
|
+
|
|
166
|
+
## Resources
|
|
167
|
+
|
|
168
|
+
| URI | Description |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `kodena://config` | Merged view of `~/.kodena/credentials` + `~/.kodena/config` + relevant `KODENA_*` env vars. The bearer token is replaced by `"REDACTED"` (or `"(none)"` when absent). |
|
|
171
|
+
| `kodena://scripts/{slug}/manifest` | Read-only snapshot of a script's row, including its asset manifest. Replace `{slug}` with the script slug. |
|
|
172
|
+
|
|
173
|
+
## Prompts
|
|
174
|
+
|
|
175
|
+
| Name | Argument | Description |
|
|
176
|
+
| --- | --- | --- |
|
|
177
|
+
| `deploy-current-project` | optional `slug` | Walk the agent through: read config → list scripts → check `./.open-next/worker.js` → dry-run deploy → confirm → deploy. |
|
|
178
|
+
|
|
179
|
+
## Read-only mode
|
|
180
|
+
|
|
181
|
+
For agents you don't fully trust, set `KODENA_MCP_READ_ONLY=1` in the
|
|
182
|
+
MCP server's env:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"mcpServers": {
|
|
187
|
+
"kodena": {
|
|
188
|
+
"command": "npx",
|
|
189
|
+
"args": ["-y", "@sawala/kodena-mcp"],
|
|
190
|
+
"env": { "KODENA_MCP_READ_ONLY": "1" }
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`tools/list` will then expose only the 8 read tools; the 10 write/destructive
|
|
197
|
+
tools are not registered at all. `tools/call` on any of them returns
|
|
198
|
+
`-32602 InvalidInput "Unknown tool"`.
|
|
199
|
+
|
|
200
|
+
## Error codes
|
|
201
|
+
|
|
202
|
+
The server uses JSON-RPC's implementation-defined range:
|
|
203
|
+
|
|
204
|
+
| Code | Meaning | Common causes |
|
|
205
|
+
| --- | --- | --- |
|
|
206
|
+
| `-32001` | Unauthenticated | `~/.kodena/credentials` missing; expired/revoked token (re-run `kodena login`) |
|
|
207
|
+
| `-32002` | Not found | Script slug doesn't exist; manifest URI for a deleted script |
|
|
208
|
+
| `-32003` | Forbidden | Token scoped to a different org; insufficient permissions |
|
|
209
|
+
| `-32602` | Invalid params | Schema violation (bad slug, missing field); unknown tool name |
|
|
210
|
+
| `-32000` | Generic | Other backend errors (5xx, unexpected shapes) |
|
|
211
|
+
|
|
212
|
+
## Troubleshooting
|
|
213
|
+
|
|
214
|
+
**"Not logged in" on every tool call.** Run `kodena login` in a terminal,
|
|
215
|
+
then try again — the server picks up the new credentials on the next call.
|
|
216
|
+
|
|
217
|
+
**Claude Desktop shows "kodena: server disconnected".** Open the host's
|
|
218
|
+
MCP log panel. The most common cause is a stray write to stdout from
|
|
219
|
+
something other than JSON-RPC; this server routes all human-readable
|
|
220
|
+
output to stderr, so the culprit is usually a corrupt npm cache or a
|
|
221
|
+
shell rc-file that prints to stdout. Try `npx --yes --cache /tmp/npx-kodena-mcp @sawala/kodena-mcp --version`
|
|
222
|
+
to confirm the binary itself is clean.
|
|
223
|
+
|
|
224
|
+
**`npx -y` is slow on first start.** Expected — npx downloads the
|
|
225
|
+
package on cold start. Warm cache should be under 2s. To eliminate
|
|
226
|
+
the download entirely, install globally: `npm i -g @sawala/kodena-mcp`
|
|
227
|
+
and use `"command": "kodena-mcp"`.
|
|
228
|
+
|
|
229
|
+
**Deploy fails with "Worker module is N bytes; max 10485760".** Your
|
|
230
|
+
built `worker.js` is over the 10 MiB cap. The CLI's `bundle.ts` enforces
|
|
231
|
+
this server-side; the limit comes from Cloudflare. Lazy-load heavy
|
|
232
|
+
dependencies or split into multiple scripts.
|
|
233
|
+
|
|
234
|
+
## Development
|
|
235
|
+
|
|
236
|
+
This package lives in the [`sawala-tech/cli`](https://github.com/sawala-tech/cli)
|
|
237
|
+
monorepo:
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
git clone https://github.com/sawala-tech/cli
|
|
241
|
+
cd cli
|
|
242
|
+
npm ci
|
|
243
|
+
npm --workspace packages/kodena-mcp run typecheck
|
|
244
|
+
npm --workspace packages/kodena-mcp run test
|
|
245
|
+
npm --workspace packages/kodena-mcp run build
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Inspect the built server with the official MCP Inspector:
|
|
249
|
+
|
|
250
|
+
```sh
|
|
251
|
+
npx @modelcontextprotocol/inspector ./packages/kodena-mcp/dist/server.js
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Architecture
|
|
255
|
+
|
|
256
|
+
This server reuses the `@sawala/kodena` CLI's library layer verbatim —
|
|
257
|
+
`api.ts`, `resolve.ts`, `credentials.ts`, `config.ts`, `bundle.ts` —
|
|
258
|
+
via relative imports across the workspace. Auth, scope checks, deploy
|
|
259
|
+
bundling, and var validation are NOT re-implemented. If the CLI's
|
|
260
|
+
library layer is refactored, the MCP server moves with it.
|
|
261
|
+
|
|
262
|
+
The plan that drove this implementation lives at
|
|
263
|
+
[`docs/plan/kodena/PLAN-kodena-mcp-server.md`](https://github.com/sawala-tech/sawala-cloud/blob/main/docs/plan/kodena/PLAN-kodena-mcp-server.md)
|
|
264
|
+
in the `sawala-cloud` repo.
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT. See [`LICENSE`](../../LICENSE).
|