@yugabytedb/meko-mcp 2.3.0 → 2.5.1

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 (42) hide show
  1. package/README.md +88 -35
  2. package/assets/hooks-handlers/lib/capture-cleanup-cli.js +735 -74
  3. package/assets/hooks-handlers/lib/capture-notices.js +94 -1
  4. package/assets/hooks-handlers/lib/capture-state.js +111 -0
  5. package/assets/hooks-handlers/lib/capture.js +130 -4
  6. package/assets/hooks-handlers/lib/checkpoint-timer.js +394 -8
  7. package/assets/hooks-handlers/lib/opencode-handler.js +29 -6
  8. package/assets/scripts/meko-statusline.sh +17 -1
  9. package/assets/skills/meko-mcp-tools/SKILL.md +6 -5
  10. package/assets/skills/meko-mcp-tools/references/_sections.md +1 -1
  11. package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +194 -10
  12. package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +6 -3
  13. package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +11 -6
  14. package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +4 -4
  15. package/assets/skills/meko-mcp-tools/references/tools-overview.md +19 -14
  16. package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +69 -8
  17. package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +3 -1
  18. package/assets/skills/meko-mcp-tools-desktop/SKILL.md +8 -7
  19. package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +4 -4
  20. package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +1 -1
  21. package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +194 -10
  22. package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +10 -5
  23. package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +4 -4
  24. package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +19 -14
  25. package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +68 -8
  26. package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +3 -1
  27. package/assets/skills/meko-select-datapack-desktop/SKILL.md +91 -12
  28. package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +39 -7
  29. package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +8 -6
  30. package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +13 -1
  31. package/bin/create-meko-setup.mjs +152 -35
  32. package/lib/autofix.mjs +100 -0
  33. package/lib/browser-login.mjs +495 -0
  34. package/lib/clients/codex.mjs +1 -24
  35. package/lib/clients/common.mjs +25 -0
  36. package/lib/clients/opencode.mjs +6 -1
  37. package/lib/migrate/datapack.mjs +254 -16
  38. package/lib/migrate/mcp-client.mjs +34 -0
  39. package/lib/migrate/orchestrator.mjs +1 -1
  40. package/lib/migrate.mjs +2 -6
  41. package/lib/validate.mjs +111 -22
  42. package/package.json +5 -5
package/README.md CHANGED
@@ -6,19 +6,41 @@ Reduces manual setup to a single command.
6
6
 
7
7
  ## What this installer authenticates with
8
8
 
9
- The installer configures **API-key authentication only**. Every supported
10
- client sends `Authorization: Bearer <your-api-key>` on the wire, plus the
9
+ Every client the installer configures authenticates with a Meko API key. Each
10
+ one sends `Authorization: Bearer <your-api-key>` on the wire, plus the
11
11
  `User-Agent` the Cloud WAF requires. Most adapters store the header value in
12
12
  client config. Codex stores `bearer_token_env_var = "MEKO_API_KEY"` and resolves
13
13
  the key from its runtime environment; Claude Desktop passes the same variable
14
- through `mcp-remote` header interpolation.
15
-
16
- Cloud Meko also accepts a browser **OAuth** flow, but that path is out of scope
17
- here: you turn it on inside a client's own UI, and it uses no API key. Don't
18
- configure both against the same client — see [Two authentication
19
- modes](../README.md#two-authentication-modes--pick-one-dont-mix-them) for the
20
- comparison and the failure modes, including why OAuth with a loopback callback
21
- still fails against the DEV environment.
14
+ through `mcp-remote` header interpolation. Capture hooks use the same key.
15
+
16
+ You don't need to have a key already. The installer gets one in this order:
17
+
18
+ 1. `--api-key <key>`.
19
+ 2. The `MEKO_API_KEY` environment variable, for any MCP URL, local ones
20
+ included. `--local` ignores it, and so does a `--yes` rerun that reuses the
21
+ URL an earlier `--local` install registered: the docker-compose dev stack
22
+ takes no key.
23
+ 3. **Browser sign-in (the default, Cloud only).** The installer opens the Meko sign-in page,
24
+ and after you sign in it creates a key named `Meko installer (<host>)
25
+ <timestamp>`. It uses the MCP server's OAuth flow with a `localhost`
26
+ callback, then calls the server's `POST /api-keys`. The OAuth session is
27
+ discarded; only the key is kept.
28
+
29
+ Sign in with the same method you use for the Meko console. If the browser
30
+ signs in as a user with no Meko account (for example Google here, email and
31
+ password in the console), the server refuses to create a key, and the
32
+ installer tells you how to retry or fall back to `--api-key`.
33
+
34
+ The new key counts toward your 10 active keys and expires after 365 days. You
35
+ can revoke it at cloud.mekodata.ai > **Settings > API Keys**. Use `--no-browser`
36
+ to print the sign-in URL instead of opening a browser, for example over SSH.
37
+ Runs with no terminal attached (CI, scripts, redirected stdin) skip sign-in and
38
+ require a key, with or without `--yes`.
39
+
40
+ Separately, some clients can run their own browser **OAuth** flow against Cloud
41
+ Meko, configured in the client's own UI with no API key. The installer doesn't
42
+ set that up. Don't configure both against the same client; see [Two
43
+ authentication modes](../README.md#two-authentication-modes--pick-one-dont-mix-them).
22
44
 
23
45
  **Note:** The server accepts the key only as `Authorization: Bearer …` on the
24
46
  wire. An `API_KEY` or `MEKO_API_KEY` environment variable does nothing unless
@@ -48,7 +70,7 @@ Claude Desktop has two install paths: a one-click `.mcpb` Desktop Extension down
48
70
  npx @yugabytedb/meko-mcp
49
71
  ```
50
72
 
51
- The installer walks you through connection type, URL, API key, and skills installation with guided prompts.
73
+ The installer walks you through connection type and URL, signs you in through your browser to create an API key (unless you pass `--api-key` or set `$MEKO_API_KEY`), then asks about skills.
52
74
 
53
75
  **Local one-liner (docker-compose stack already running):**
54
76
 
@@ -88,7 +110,7 @@ You can also combine both: install via `.mcpb` for the MCP wiring, then run Opti
88
110
 
89
111
  **Option A — Desktop Extension (`.mcpb`), one-click:**
90
112
 
91
- 1. Download `meko-<version>.mcpb` from the [GitHub Releases page](https://github.com/yugabyte/meko-mcp-server/releases) (e.g. `meko-1.1.0.mcpb`).
113
+ 1. Download `meko-<version>.mcpb` from the [GitHub Releases page](https://github.com/yugabyte/meko-mcp-server/releases) (e.g. `meko-2.5.0.mcpb`). From 2.5.0, the `.mcpb`, the npm installer, and the public plugin share one version number.
92
114
  2. Open **Claude Desktop > Settings > Extensions > Install from file** and select the file (or drag the file onto that pane).
93
115
  3. When prompted, paste your Meko MCP URL and API key.
94
116
  4. Quit and relaunch Claude Desktop.
@@ -136,7 +158,13 @@ npx @yugabytedb/meko-mcp --client all --local --yes
136
158
 
137
159
  Each client is installed sequentially. A failure on one does not abort the others — the command exits with status 2 on partial success, 1 on total failure.
138
160
 
139
- **CI / non-interactive (Cloud Meko):**
161
+ **Cloud Meko (signs in through your browser):**
162
+
163
+ ```bash
164
+ npx @yugabytedb/meko-mcp --url https://mcp.mekodata.ai/mcp --client claude-code
165
+ ```
166
+
167
+ **CI / non-interactive (Cloud Meko, existing API key):**
140
168
 
141
169
  ```bash
142
170
  npx @yugabytedb/meko-mcp \
@@ -145,6 +173,17 @@ npx @yugabytedb/meko-mcp \
145
173
  --yes
146
174
  ```
147
175
 
176
+ **Meko Local (the `meko` server, which requires its client token):**
177
+
178
+ ```bash
179
+ MEKO_API_KEY="$(meko token)" npx @yugabytedb/meko-mcp \
180
+ --url http://127.0.0.1:7778/mcp \
181
+ --yes
182
+ ```
183
+
184
+ Passing the key through `MEKO_API_KEY` keeps it off the command line, where
185
+ `ps` would show it.
186
+
148
187
  ## What It Does
149
188
 
150
189
  The installer performs up to 5 steps (some are skippable via flags):
@@ -155,13 +194,13 @@ The installer performs up to 5 steps (some are skippable via flags):
155
194
  | 2 | Set hook environment vars | Writes `MEKO_MCP_URL` and `MEKO_API_KEY` into `~/.claude/settings.json` under the `env` key. Also prunes any stale Meko hook entries in `settings.json.hooks` that point at a prior install path (e.g. a previous `npx` cache or homebrew-global copy) so only the current install's hooks fire. |
156
195
  | 3 | Register public plugin marketplace | `claude plugin marketplace add https://github.com/yugabyte/meko-skills.git --scope user` |
157
196
  | 4 | Install skills plugin | `claude plugin install meko-agent-skills --scope user` |
158
- | 5 | Validate setup | Config check via `claude mcp list`, MCP `initialize` handshake, `tools/list` verification, and a canary `datapack_list` call |
197
+ | 5 | Validate setup | Config check via `claude mcp list`, MCP `initialize` handshake, `tools/list` verification, and a canary `datapack_search` call (`datapack_list` on older servers) |
159
198
 
160
199
  ### Post-install validation (canary)
161
200
 
162
- Step 5 includes a **canary call** that invokes the read-only `datapack_list` tool and asserts the response is a non-empty JSON array of datapack records. This proves the part of the stack that connectivity + `tools/list` don't cover: the API token authenticated as a real Meko identity, the tenant resolver found an account for it, and datapack routing wired up the user's actual workspace. A successful `tools/list` only proves the server speaks MCP — it says nothing about whether a Meko tool call would actually find the user's data.
201
+ Step 5 includes a **canary call** that invokes the read-only `datapack_search(limit=1)` tool and asserts it returns at least one datapack. On a server whose `tools/list` has no `datapack_search`, it calls `datapack_list` instead and asserts a non-empty JSON array; `datapack_search` reads one page whatever the account size, where `datapack_list` reads the whole account. This proves the part of the stack that connectivity + `tools/list` don't cover: the API token authenticated as a real Meko identity, the tenant resolver found an account for it, and datapack routing wired up the user's actual workspace. A successful `tools/list` only proves the server speaks MCP — it says nothing about whether a Meko tool call would actually find the user's data.
163
202
 
164
- The canary used to do a `memory_add` → `memory_get_by_id` → `memory_delete_by_id` round-trip, but mem0's LLM fact-extractor is non-deterministic for synthetic test text — for the same input it sometimes returned `results: []` (no facts extracted) while still adding graph relations, which the installer reported as "no memory id" and surfaced as a validation failure even when the server was healthy. `datapack_list` is a single SQL read with no LLM in the path and returns deterministically.
203
+ The canary used to do a `memory_add` → `memory_get_by_id` → `memory_delete_by_id` round-trip, but mem0's LLM fact-extractor is non-deterministic for synthetic test text — for the same input it sometimes returned `results: []` (no facts extracted) while still adding graph relations, which the installer reported as "no memory id" and surfaced as a validation failure even when the server was healthy. Both datapack tools are a single SQL read with no LLM in the path and return deterministically.
165
204
 
166
205
  `--no-canary` skips the canary entirely. The `initialize` and `tools/list` checks still run. Use this when you've already proved the round-trip in a prior step (CI, pre-flight smoke).
167
206
 
@@ -203,7 +242,7 @@ The canary used to do a `memory_add` → `memory_get_by_id` → `memory_delete_b
203
242
  - Steering file: `~/.kiro/steering/meko.md` or `.kiro/steering/meko.md`. It follows hook capture when the session-start marker is present and falls back to agent-driven persistence only when hooks are disabled, untrusted, or a different CLI 2.x agent is selected. See [Kiro notes](#kiro-notes).
204
243
  - **OpenCode CLI/TUI 1.18.x**
205
244
  - User plugin: `$OPENCODE_CONFIG_DIR/plugins/meko.js` when set, otherwise `~/.config/opencode/plugins/meko.js`; project plugin: `<project>/.opencode/plugins/meko.js`.
206
- - Stable runtime and private environment: `$OPENCODE_CONFIG_DIR/meko/` when set, otherwise `~/.config/opencode/meko/`, or `<project>/.opencode/meko/`. `opencode-hook-env.json` is mode 0600 and contains the MCP URL, API key, server name, User-Agent, hook client, stable Node executable, and watermark dir. Automatic capture uses the server-default datapack in this release. `--datapack` applies only to `--migrate`. OpenCode does not read `pin-<slug>.json` (no SessionStart, and `meko-select-datapack` is not installed).
245
+ - Stable runtime and private environment: `$OPENCODE_CONFIG_DIR/meko/` when set, otherwise `~/.config/opencode/meko/`, or `<project>/.opencode/meko/`. `opencode-hook-env.json` is mode 0600 and contains the MCP URL, API key, server name, User-Agent, hook client, stable Node executable, and watermark dir. Edits to this file reach the next capture attempt, including the retries of a running capture timer. Removing `MEKO_MCP_URL` or `MEKO_API_KEY` from the file, as `--uninstall` does, also removes it from a running timer's next attempt. Automatic capture uses the server-default datapack in this release. `--datapack` applies only to `--migrate`. OpenCode does not read `pin-<slug>.json` (no SessionStart, and `meko-select-datapack` is not installed).
207
246
  - Skill: `$OPENCODE_CONFIG_DIR/skills/meko-mcp-tools/` when set, otherwise `~/.config/opencode/skills/meko-mcp-tools/`, or `<project>/.opencode/skills/meko-mcp-tools/`.
208
247
  - The plugin mutates OpenCode's resolved configuration at runtime with a native remote MCP entry (`type: remote`, `enabled: true`, `oauth: false`). It does **not** edit `opencode.json` or `opencode.jsonc`; validation runs `opencode debug config` and verifies the resolved entry.
209
248
  - Restart OpenCode after install. Reinstall upgrades installer-owned assets while preserving durable capture state and user-owned collisions.
@@ -231,14 +270,15 @@ Usage:
231
270
  |------|-------------|---------|
232
271
  | `--client <list>` | Target client(s): one or more of `claude-code`, `claude-desktop`, `cursor`, `codex`, `kiro`, `opencode`. Comma-separated, or `all`. `codex` covers both the OpenAI Codex CLI and the Codex Desktop App (they share `~/.codex/config.toml`); `kiro` covers both the Kiro IDE and `kiro-cli` (they share `~/.kiro/settings/mcp.json`). OpenCode is version-gated to CLI/TUI 1.18.x. Aliases: `claude` → `claude-code`, `kiro-cli` / `kiro-ide` → `kiro`. | `claude-code` |
233
272
  | `--url <url>` | MCP server URL (from cloud.mekodata.ai > Datapacks > Connect) | Shared existing endpoint, otherwise production; conflicts prompt or require `--url` under `--yes` |
234
- | `--api-key <key>` | API key for Cloud Meko authentication. If a Cloud `--url` is supplied without this flag, the installer falls back to `$MEKO_API_KEY`, then to an interactive prompt on a TTY. Only fails hard when running under `--yes` or with no TTY attached. | _(interactive prompt or `$MEKO_API_KEY` env)_ |
235
- | `--local` | Use local Meko at `http://localhost:8000/mcp` (no API key needed) | `false` |
273
+ | `--api-key <key>` | Use an existing Meko API key (Cloud, or Meko Local's client token) instead of signing in. Without this flag, the installer falls back to `$MEKO_API_KEY` for any URL (not with `--local`), then, for Cloud URLs only, to browser sign-in, which creates a key. A Cloud URL with no key fails hard when no TTY is attached, with or without `--yes`; a local URL installs without one. | _(`$MEKO_API_KEY`, else browser sign-in for Cloud)_ |
274
+ | `--no-browser` | Print the sign-in URL instead of opening a browser. | `false` |
275
+ | `--local` | Use local Meko at `http://localhost:8000/mcp` (no API key; ignores `$MEKO_API_KEY`) | `false` |
236
276
  | `--scope <scope>` | Config scope: `user` or `project` (`claude-desktop` uses user scope config) | `user` |
237
277
  | `--name <name>` | MCP server name in config | `meko` |
238
278
  | `--cursor-hook-mode <mode>` | Cursor hook strategy: `native` or `claude-compat` | `native` |
239
279
  | `--skip-skills` | Skip plugin marketplace and skills installation (steps 3-4) | `false` |
240
280
  | `--skip-validation` | Skip post-install validation (step 5) | `false` |
241
- | `--no-canary` | Skip the canary `datapack_list` call. Basic connectivity + tools/list still run. | `false` |
281
+ | `--no-canary` | Skip the canary `datapack_search` / `datapack_list` call. Basic connectivity + tools/list still run. | `false` |
242
282
  | `--dry-run` | Show what would be done without making changes | `false` |
243
283
  | `--uninstall` | Remove Meko MCP server, skills, env vars, and marketplace entry | `false` |
244
284
  | `--verbose` | Show detailed output (API keys are always redacted) | `false` |
@@ -252,7 +292,9 @@ Capture health flags (durable outbox / recovery — Capture V2):
252
292
  |------|-------------|---------|
253
293
  | `--capture-status` | Report aggregate conversation-capture health from `~/.claude/meko-capture` (or `MEKO_WATERMARK_DIR`). Exit `0` = healthy\|catching_up, `2` = degraded_retrying, `3` = blocked_action_required. | `false` |
254
294
  | `--json` | With `--capture-status`, print machine-readable JSON matching the capture-health cache shape. Also accepted by `--capture-cleanup`. | `false` |
255
- | `--capture-cleanup <action>` | Inspect and clean up stuck capture on this machine. Actions: `status`, `stop`, `resume`, `drain`, `discard`, `repair`. See [Clean up stuck capture](../OPERATIONS.md#clean-up-stuck-capture). Exit `0` = done, `1` = error, `2` = partly done. | |
295
+ | `--no-autofix` | Turn off automatic capture repair. The capture timer otherwise runs `--capture-cleanup fix` every 30 minutes (`MEKO_AUTOFIX_INTERVAL`) when a session is stuck. Saved for every client; a reinstall keeps it. | `false` |
296
+ | `--autofix` | Turn automatic capture repair back on. | `false` |
297
+ | `--capture-cleanup <action>` | Inspect and clean up stuck capture on this machine. Actions: `status`, `fix`, `stop`, `resume`, `drain`, `discard`, `repair`. Start with `fix`. See [Clean up stuck capture](../OPERATIONS.md#clean-up-stuck-capture). Exit `0` = done, `1` = error, `2` = partly done. | |
256
298
  | `--session <id>` | With `--capture-cleanup`, act on one session. Repeatable; a unique prefix of the ID is enough. A bare ID after the action works too: `--capture-cleanup drain c0acdeb2`. | |
257
299
  | `--all` | With `--capture-cleanup`, act on every session. `drain` and `discard` need `--session` or `--all`. | `false` |
258
300
  | `--max-exchanges <n>` | With `--capture-cleanup drain`, stop after sending this many exchanges in total. | `200` |
@@ -323,7 +365,7 @@ Dry run:
323
365
 
324
366
  ### Why the migrator drives memory extraction
325
367
 
326
- The Meko MCP server does **not** currently auto-extract memories on `conversation_add_message` (that call only writes to Langfuse). See [yugabyte/meko#120](https://github.com/yugabyte/meko/issues/120) — auto-extraction on the live write path was deferred because of LLM cost, but batch extraction for *previously-existing* conversations was explicitly endorsed. Until #120 lands, the migrator closes that gap itself by calling `memory_add(messages=...)` once per paired turn.
368
+ The Meko MCP server does **not** currently auto-extract memories on `conversation_add_message` (that call only writes to Langfuse). See [yugabyte/agentic-cloud#120](https://github.com/yugabyte/agentic-cloud/issues/120) — auto-extraction on the live write path was deferred because of LLM cost, but batch extraction for *previously-existing* conversations was explicitly endorsed. Until #120 lands, the migrator closes that gap itself by calling `memory_add(messages=...)` once per paired turn.
327
369
 
328
370
  `--no-extract` skips step 3 above, turning migration into conversation-only replay. Use it when you're re-running for any reason other than seeding memories, when extraction cost is a concern, or if / when #120 lands (the migrator will be updated to default to `--no-extract` then).
329
371
 
@@ -397,6 +439,14 @@ auth skipped: 0 (calls dropped on a mid-run 401/403; re-run to re
397
439
  - **`--yes` without `--with-migrate`**: install succeeds silently and prints a one-line tip pointing at `create-meko-setup --migrate`. No migration is started.
398
440
  - **`--yes --with-migrate`**: install succeeds, then the detached migration is started automatically. Progress via `--migrate-status`.
399
441
 
442
+ ### Destination datapack
443
+
444
+ `--datapack <name|id>` picks the datapack the migration writes to; without it the migration uses `meko_default_datapack`, or the server's own default when that row isn't visible. The resolved destination is printed before the run starts.
445
+
446
+ - A name is looked up with `datapack_search(name=...)`, preferring a datapack you own over a shared one with the same name. A miss lists similar names.
447
+ - A UUID is looked up with `datapack_describe`, so any datapack the API key can open resolves, however many the account has.
448
+ - On a server whose `tools/list` has no `datapack_search`, both are matched against the `datapack_list` response instead.
449
+
400
450
  ### Idempotency, resume, and state
401
451
 
402
452
  - Per-run logs: `~/.meko/migrate/<run-id>/log.ndjson` (one JSON object per line). `tail -f | jq .` is a reasonable debug loop. This is the file the start banner points at, and the only one with run diagnostics in it.
@@ -412,7 +462,7 @@ auth skipped: 0 (calls dropped on a mid-run 401/403; re-run to re
412
462
  ### What does NOT get migrated (v1)
413
463
 
414
464
  - Slash-command skills, hooks, and `.claude/settings.json` — those remain in Claude Code's own config; Meko has no equivalent tool.
415
- - Knowledge-base documents — KB ingestion is UI-only (Datapack → Actions → Add Knowledge); not exposed via MCP.
465
+ - Knowledge-base documents — this migration doesn't re-upload old KB files; add them via `knowledgebase_upload_document` or the UI (Datapack → Actions → Add Knowledge) after migrating.
416
466
  - Transcripts from unregistered coding agents (for example Aider, Continue.dev, or Windsurf).
417
467
  - `user_id` is left null on every call (the server fills it from the API key). Multi-user routing is a follow-up.
418
468
 
@@ -442,8 +492,8 @@ Cursor previously had a hybrid hook mode that also wrote Claude-compatible hooks
442
492
  **Never use the `mcp-remote` bridge with Kiro.** Kiro speaks remote MCP natively, so the installer registers `{ url, headers }` directly.
443
493
 
444
494
  What was measured against `https://mcp.mekodata.ai` before 2026-09-24. Production
445
- now accepts loopback redirects on `/register`, `/authorize`, and `/token`; DEV
446
- (`mcp.mekodev.com`) still refuses them. The `mcp-remote` findings below still
495
+ now accepts loopback redirects on `/register`, `/authorize`, and `/token`, and a
496
+ 2026-10-07 re-measure found DEV (`mcp.mekodev.com`) accepts them too ([#277](https://github.com/yugabyte/meko-mcp-server/issues/277)). The `mcp-remote` findings below still
447
497
  apply, because an API key behind the bridge is never sent.
448
498
 
449
499
  - `mcp-remote@0.1.38` reads no auth env var (its only `process.env` reference is `MCP_REMOTE_CONFIG_DIR`), so `MEKO_API_KEY` is never sent; headers come only from `--header`. It therefore connects unauthenticated and begins OAuth.
@@ -460,7 +510,7 @@ Confirmed on `kiro-cli` 2.18.1 itself. Its DCR registration is:
460
510
 
461
511
  so against Cloud Meko it fails with `Dynamic registration failed: Registration failed: HTTP 403 Forbidden`. Its first `POST /mcp` also goes out with **no `User-Agent`**, which trips a second HTML-403 rule independently. With Mode 1 headers and a valid `mko_tkn_…` key it connects and lists all 23 tools — no OAuth, no 403.
462
512
 
463
- Both surfaces are verified against Cloud Meko with a real key. On the **Kiro IDE** (1.0.337), the installer's config produces `[meko] Connected` in its `Kiro - MCP Logs` output. On **`kiro-cli`** (2.18.1) the agent enumerates all 23 tools. The steering file is confirmed to reach the model, not just disk: asked with tools disabled what its Meko steering requires, the agent answered that it must call `memory_add` when the user states a durable fact and that this "explicitly overrides the meko-mcp-tools skill", which assumes capture hooks are running.
513
+ Both surfaces are verified against Cloud Meko with a real key. On the **Kiro IDE** (1.0.337), the installer's config produces `[meko] Connected` in its `Kiro - MCP Logs` output. On **`kiro-cli`** (2.18.1) the agent enumerated all 23 tools the server had at the time; production now lists 42, including 14 `amp_*` tools. The steering file is confirmed to reach the model, not just disk: asked with tools disabled what its Meko steering requires, the agent answered that it must call `memory_add` when the user states a durable fact and that this "explicitly overrides the meko-mcp-tools skill", which assumes capture hooks are running.
464
514
 
465
515
  One naming correction worth knowing, since it has caused confusion: **`Q DEV CLI` is not an OAuth client id.** It is the MCP `initialize` handshake's `clientInfo.name` (`"clientInfo":{"name":"Q DEV CLI","version":"1.0.0"}`); the string appears nowhere in the `kiro-cli` binary's OAuth path, and its actual DCR `client_name` is `kiro`. There is nothing named `Q DEV CLI` to allowlist. See [#277](https://github.com/yugabyte/meko-mcp-server/issues/277).
466
516
 
@@ -481,12 +531,12 @@ Uninstall removes only files carrying installer ownership markers: the three sta
481
531
  | | Cloud Meko | Local Meko |
482
532
  |---|-----------|-----------|
483
533
  | **URL** | `https://mcp.mekodata.ai/mcp` (or the endpoint shown by cloud.mekodata.ai) | `http://localhost:8000/mcp` |
484
- | **Authentication** | Requires `--api-key` or `$MEKO_API_KEY` env var | None |
534
+ | **Authentication** | Browser sign-in creates an API key, or pass `--api-key` / `$MEKO_API_KEY` | None |
485
535
  | **MCP registration** | Includes `-H "Authorization: Bearer <key>"` header | No auth header |
486
536
  | **Hook env vars** | Both `MEKO_MCP_URL` and `MEKO_API_KEY` written to settings | Only `MEKO_MCP_URL` written |
487
537
  | **Infrastructure** | Hosted, no local setup needed | Requires `docker compose up -d` running the Meko stack |
488
538
  | **Use case** | Production, team collaboration | Development, testing |
489
- | **Flag** | `--url <url> --api-key <key>` | `--local` |
539
+ | **Flag** | `--url <url>` (optionally `--api-key <key>`) | `--local` |
490
540
 
491
541
  The installer auto-detects cloud vs local based on the URL: any URL containing `localhost` or `127.0.0.1` is treated as local (no API key required). All other URLs are cloud and require authentication.
492
542
 
@@ -558,7 +608,7 @@ Re-running the installer is idempotent but not inert. A re-run:
558
608
 
559
609
  ### Updating the skills plugin (Claude Code)
560
610
 
561
- The `meko-agent-skills` plugin is distributed via the Claude Code plugin marketplace and versions independently of the installer npm package. Re-running the installer now picks up the latest skill definitions automatically: it probes `claude plugin list` and, when the plugin is already present, calls
611
+ The `meko-agent-skills` plugin is distributed via the Claude Code plugin marketplace from yugabyte/meko-skills, not npm. It also carries the Claude Code capture hooks. From 2.5.0, the plugin, the installer, and the `.mcpb` share one version number. Re-running the installer now picks up the latest skill definitions automatically: it probes `claude plugin list` and, when the plugin is already present, calls
562
612
 
563
613
  ```bash
564
614
  claude plugin update meko-agent-skills@meko-agent-skills --scope <scope>
@@ -725,10 +775,11 @@ Three known causes:
725
775
  - **No `User-Agent` header.** The WAF refuses any request without one. Add
726
776
  `User-Agent: meko-mcp-installer/1.0`. The installer always does; hand-written
727
777
  configs and some native MCP clients don't.
728
- - **An OAuth callback on a loopback address (DEV only).** The DEV WAF refuses
729
- any `redirect_uri` pointing at an internal host, so dynamic client
730
- registration fails there for any client that registers such a callback,
731
- including IDEs. Production accepts these callbacks as of 2026-09-24. Tracked in
778
+ - **An OAuth callback on a loopback address (DEV, historically).** The DEV WAF
779
+ refused any `redirect_uri` pointing at an internal host, so dynamic client
780
+ registration failed there for any client that registers such a callback,
781
+ including IDEs. Production accepts these callbacks as of 2026-09-24, and a
782
+ 2026-10-07 re-measure didn't reproduce the DEV block. Tracked in
732
783
  [#277](https://github.com/yugabyte/meko-mcp-server/issues/277).
733
784
  - **Message text that looks like a path.** Capture writes containing `../` or
734
785
  absolute paths can trip a traversal rule. Tracked in
@@ -745,7 +796,7 @@ API-key checks:
745
796
  - If using `$MEKO_API_KEY` env var, ensure it is exported in the current shell.
746
797
  - Confirm the key environment matches the URL: PATs minted on `app.mekodev.com` only validate against `mcp.mekodev.com`; PATs minted on `cloud.mekodata.ai` only validate against `mcp.mekodata.ai`.
747
798
  - The installer normalizes API keys (trims surrounding whitespace and a single matching pair of quotes) so a paste with a trailing newline or a literal `"…"` from a `.env` file is fine — but your raw shell variable might still be contaminated. Echo it (`echo "[$MEKO_API_KEY]"`) and check the brackets bracket the key tightly with no extra characters.
748
- - Re-run the installer interactively to re-enter the key.
799
+ - Re-run the installer in a terminal without `--api-key` and with `$MEKO_API_KEY` unset to sign in through the browser and create a new key, or pass a new key with `--api-key`.
749
800
 
750
801
  ### Plugin marketplace already registered
751
802
 
@@ -774,7 +825,7 @@ cp ~/.claude/settings.json.bak ~/.claude/settings.json
774
825
  Missing core tools: memory_search, memory_get_by_id, conversation_create. Found 0 tool(s) total.
775
826
  ```
776
827
 
777
- The MCP server responded but does not expose the expected tools (`memory_search`, `memory_get_by_id`, `conversation_create`, `datapack_list`). This usually means a server version mismatch. Update the MCP server or check which datapack is connected. `memory_get_by_id` is used by the canary round-trip for direct-row verification (see [Post-install validation](#post-install-validation-canary-round-trip) above), so an older server that exposes `memory_search` but not `memory_get_by_id` will fail the canary check.
828
+ The MCP server responded but does not expose the expected tools (`memory_search`, `memory_get_by_id`, `conversation_create`, `datapack_list`). This usually means a server version mismatch. Update the MCP server or check which datapack is connected. The canary itself calls `datapack_search`, or `datapack_list` on a server without it (see [Post-install validation](#post-install-validation-canary) above).
778
829
 
779
830
  ### DNS lookup failed
780
831
 
@@ -862,6 +913,8 @@ node installer/bin/create-meko-setup.mjs --uninstall --verbose
862
913
  |---|----------|-------|-----------------|
863
914
  | M1 | Fresh local install | `node installer/bin/create-meko-setup.mjs --local --yes` with docker stack running | All 5 steps pass, validation shows 3 green checks |
864
915
  | M2 | Fresh cloud install | Run interactively, provide Cloud Meko URL + API key | MCP registered with `Authorization: Bearer` header, env vars set, validation passes |
916
+ | M2b | Browser sign-in | In a terminal with `$MEKO_API_KEY` unset, run `--url https://mcp.mekodata.ai/mcp` without `--api-key` and sign in | A key is created through `POST /api-keys`; validation passes |
917
+ | M2c | No terminal, no key | Pipe stdin (or run under CI) with no `--api-key` and no `$MEKO_API_KEY` | Exits with "API key is required for Cloud Meko" |
865
918
  | M3 | Existing config | Run installer when `meko` MCP is already registered | Prompts to overwrite; answering No keeps existing config |
866
919
  | M4 | No claude CLI | Run on a machine without `claude` in PATH | Exits with error message and install link |
867
920
  | M5 | Server unreachable | Install with `--skip-validation`, then re-run without it | Install succeeds; validation warns about connectivity |