@yugabytedb/meko-mcp 2.2.0 → 2.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.
- package/README.md +168 -61
- package/assets/hooks-handlers/lib/capture-cleanup-cli.js +2134 -0
- package/assets/hooks-handlers/lib/capture-notices.js +224 -14
- package/assets/hooks-handlers/lib/capture-state.js +206 -1
- package/assets/hooks-handlers/lib/capture-status-cli.js +6 -2
- package/assets/hooks-handlers/lib/capture.js +1364 -139
- package/assets/hooks-handlers/lib/checkpoint-timer.js +445 -18
- package/assets/hooks-handlers/lib/journal-bridge.js +218 -0
- package/assets/hooks-handlers/lib/kiro-handler.js +26 -4
- package/assets/hooks-handlers/lib/opencode-handler.js +643 -0
- package/assets/hooks-handlers/lib/opencode-normalizer.js +145 -0
- package/assets/hooks-handlers/lib/terminal-handoff.js +10 -1
- package/assets/opencode-plugin/meko.js +213 -0
- package/assets/scripts/meko-statusline.sh +102 -19
- package/assets/skills/meko-mcp-tools/SKILL.md +59 -16
- package/assets/skills/meko-mcp-tools/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +15 -7
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +275 -19
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +7 -4
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +39 -11
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +10 -6
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +44 -29
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +79 -14
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +47 -1
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +6 -39
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +57 -21
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +4 -4
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +8 -6
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +284 -38
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +32 -10
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +16 -12
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +46 -31
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +79 -14
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +69 -1
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +93 -14
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +44 -12
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +14 -10
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +17 -5
- package/bin/create-meko-setup.mjs +186 -30
- package/lib/autofix.mjs +100 -0
- package/lib/browser-login.mjs +495 -0
- package/lib/capture-cleanup.mjs +63 -0
- package/lib/clients/claude-code.mjs +1 -0
- package/lib/clients/codex.mjs +80 -35
- package/lib/clients/common.mjs +7 -0
- package/lib/clients/index.mjs +2 -0
- package/lib/clients/kiro.mjs +5 -5
- package/lib/clients/opencode.mjs +537 -0
- package/lib/config.mjs +68 -1
- package/lib/installer.mjs +18 -2
- package/lib/migrate/adapters/claude-code.mjs +11 -2
- package/lib/migrate/adapters/codex.mjs +9 -2
- package/lib/migrate/adapters/memory-md.mjs +27 -8
- package/lib/migrate/adapters/opencode.mjs +148 -0
- package/lib/migrate/claude-parser.mjs +153 -9
- package/lib/migrate/datapack.mjs +254 -16
- package/lib/migrate/id.mjs +195 -13
- package/lib/migrate/mcp-client.mjs +59 -1
- package/lib/migrate/opencode-normalizer.mjs +132 -0
- package/lib/migrate/orchestrator.mjs +294 -78
- package/lib/migrate/progress.mjs +239 -5
- package/lib/migrate/registry.mjs +72 -0
- package/lib/migrate.mjs +97 -9
- package/lib/validate.mjs +111 -22
- package/package.json +5 -5
- package/scripts/bundle-assets.mjs +4 -0
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
# Complete Tool Catalog and Decision Tree
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**28 Meko data tools covered by this skill.** These are the tools available in production, grouped as: Retrieval (1), Memory (8), Conversation (6), Knowledge Base (4), Datapack (6), Artifacts (2), Observability (1). Combined Meko + AMP endpoints may expose additional infrastructure tools; those are outside this skill's scope.
|
|
4
4
|
|
|
5
5
|
## Quick health check before using tools
|
|
6
6
|
|
|
7
7
|
Before starting a session, verify that the Meko MCP tools are working:
|
|
8
8
|
|
|
9
9
|
1. `memory_search(query="test", agent_id="<your-session-agent-id>", conversation_id="<session-conversation-id>")` — Confirms memory subsystem is up. Use the `agent_id` and `conversation_id` from the SessionStart `additionalContext`. May fail with "connection already closed" — see `tools-troubleshooting.md`.
|
|
10
|
-
2. `
|
|
10
|
+
2. `datapack_search(conversation_id="<session-conversation-id>", limit=1)`: confirms Meko API connectivity and returns one datapack your token has access to. On a server without `datapack_search`, call `datapack_list(conversation_id="<session-conversation-id>")` instead.
|
|
11
11
|
|
|
12
12
|
## Decision tree: which tool do I need?
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
User wants to...
|
|
16
|
+
├── Ask "what do you know about X?" --------> context_search (read; memory + KB + past conversations in one call)
|
|
16
17
|
├── Search personal context? ---------------> memory_search (read)
|
|
17
18
|
├── Search shared datapack knowledge? ------> knowledgebase_search (read)
|
|
18
|
-
├── Add
|
|
19
|
-
│
|
|
19
|
+
├── Add a file to a knowledge base? --------> knowledgebase_upload_document (write)
|
|
20
|
+
│ └── Check its indexing progress? -------> knowledgebase_document_status (read)
|
|
21
|
+
├── Delete ONE knowledge-base file? --------> knowledgebase_delete_document (destructive — confirm with the user first)
|
|
20
22
|
├── Store or recall information?
|
|
21
23
|
│ ├── Store a fact/preference/entity? -----------> memory_add (write)
|
|
22
24
|
│ ├── Store a full conversation (multi-turn)? ---> conversation_create + conversation_add_message (write)
|
|
@@ -27,50 +29,63 @@ User wants to...
|
|
|
27
29
|
│ ├── Upload a generated file (report, CSV, PDF)? -> artifact_put (write)
|
|
28
30
|
│ └── Retrieve a previously uploaded file? -------> artifact_get (read)
|
|
29
31
|
└── Manage datapacks?
|
|
32
|
+
├── Find a datapack id by name? -------> datapack_search(query=...) (read)
|
|
30
33
|
└── CRUD datapack? --------------------> datapack_create/list/describe/update/delete
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
Agent /
|
|
36
|
+
Agent lifecycle and KB **index / source lifecycle** (creating indexes, adding sources, re-indexing) are managed outside the MCP surface — typically in the Meko control-plane UI. Single KB files are handled here: adding one (`knowledgebase_upload_document`, then `knowledgebase_document_status`) and deleting one (`knowledgebase_delete_document`).
|
|
34
37
|
|
|
35
|
-
##
|
|
38
|
+
## Retrieval Tools (1)
|
|
36
39
|
|
|
37
40
|
| Tool | Purpose |
|
|
38
41
|
|------|---------|
|
|
39
|
-
| `
|
|
42
|
+
| `context_search(query, conversation_id, agent_id=None, datapack_id=None, limit=10, force_source="auto")` | Default first call for open-ended recall. Queries memory, the knowledge base, and the conversation-history cache in parallel and returns each source in its own bucket: `{"results": {"memory": [...], "knowledge_base": [...], "conversation": {"hits": [...], "thread": [...]}}, "token_savings": {...}}`. A bucket is `null` only when that source wasn't queried: `force_source` excluded it, or the server couldn't build a query vector for it. An empty bucket is ambiguous: either that source found nothing relevant, or it failed. `context_search` turns a failed source into an empty list and records the error only in the trace. Before you tell the user nothing is stored about X, confirm with `memory_search` or `knowledgebase_search`, which return errors. `force_source` is `"auto"` (all three), `"memory"`, `"knowledge_base"`, or `"conversation"`; any other value returns `invalid_force_source`. `limit` bounds the memory and KB buckets only; the conversation bucket returns up to 10 hits plus a thread of whole turns. The conversation bucket is datapack-wide. It returns embedded turns from every user and agent on the datapack, and each hit carries its author's `user_id`. Don't present a hit as this user's own history. |
|
|
43
|
+
|
|
44
|
+
## Knowledge Base Tools (4)
|
|
45
|
+
|
|
46
|
+
| Tool | Purpose |
|
|
47
|
+
|------|---------|
|
|
48
|
+
| `knowledgebase_search(query, conversation_id, datapack_id, agent_id=None, limit=10)` | Hybrid (semantic + keyword) search across KB chunks and promoted memories. `datapack_id` is REQUIRED (no default). Each hit has `id`, `chunk_text`, `document_id`, `metadata_filters`, `distance`, and `match_type` (`semantic`, `keyword`, or `hybrid`). |
|
|
49
|
+
| `knowledgebase_delete_document(document_id, conversation_id, datapack_id="")` | Permanently delete ONE KB file (chunks + metadata; stored-file delete is best-effort — check `s3_deleted`). Irreversible: confirm with the user first. `document_id` comes from `knowledgebase_search` hits (no filename in hits — echo the id + chunk text). Owner/maintainer/uploader only (status 403 otherwise); status 409 while still indexing — wait and retry. |
|
|
50
|
+
| `knowledgebase_upload_document(filename, size, content_hash, conversation_id, content_head_base64, datapack_id=None, agent_id=None)` | Requests a presigned S3 URL for a file (does not upload bytes itself — the caller POSTs to the returned `url`/`fields`). Returns `{datapack_id, url, fields, key, already_uploaded}` (fresh upload) or `{datapack_id, url: "", key, already_uploaded: true, existing_filename}` (dedup). Accepted extensions: pdf/txt/text/md/json/csv/xml/html/htm; `content_head_base64` (base64 of the file's first 3072 bytes, or the whole file if shorter) is **required** and is always sniffed against the extension before requesting the URL — a missing/blank value is rejected as `content_head_base64_required`, this check cannot be skipped. Idempotent by content hash. |
|
|
51
|
+
| `knowledgebase_document_status(document_key, conversation_id, datapack_id=None, agent_id=None)` | Poll indexing progress for a file uploaded via `knowledgebase_upload_document`, using its returned `key` (passed here as `document_key`). `state` is one of `awaiting_upload`/`indexing` (non-terminal) or `completed`/`failed`/`abandoned`/`oversized` (terminal). |
|
|
40
52
|
|
|
41
53
|
## Memory Tools (8)
|
|
42
54
|
|
|
43
55
|
| Tool | Purpose |
|
|
44
56
|
|------|---------|
|
|
45
|
-
| `memory_add(text,
|
|
46
|
-
| `memory_search(query,
|
|
47
|
-
| `memory_get_by_id(memory_id,
|
|
48
|
-
| `memory_get_all(
|
|
49
|
-
| `memory_update(memory_id, text,
|
|
50
|
-
| `memory_delete_by_id(memory_id,
|
|
51
|
-
| `memory_delete_all(
|
|
57
|
+
| `memory_add(text, conversation_id, agent_id=None, run_id=None, metadata=None, messages=None, datapack_id=None)` | Store fact/preference/entity as long-term memory |
|
|
58
|
+
| `memory_search(query, conversation_id, agent_id=None, limit=10, datapack_id=None, run_id=None)` | Hybrid search across memories (semantic + keyword + entity boost). Drops rows below a server-configured similarity floor (default 0.2), so a weak query can return an empty list. `conversation_id` is required but only nests the trace. It must be a 32-hex id: `""` currently fails (MEKO-707), so pass a freshly generated one if you have no conversation yet. `run_id` filters to one conversation's memories. |
|
|
59
|
+
| `memory_get_by_id(memory_id, conversation_id, agent_id=None, datapack_id=None)` | Direct pgvector row lookup by UUID. Preferred over `memory_search` for exact-id verification. Returns `not_found` for a missing id and for an id that belongs to another account. |
|
|
60
|
+
| `memory_get_all(conversation_id, agent_id=None, run_id=None, datapack_id=None, promoted=False)` | Recent window (about 20 rows) of the user's memories across every agent, plus the true `total`. Not a complete listing. `promoted=True` returns the recent window of promoted memories instead. `run_id` is ignored. |
|
|
61
|
+
| `memory_update(memory_id, text, conversation_id, agent_id=None, datapack_id=None)` | Overwrite memory text. Returns `memory_is_promoted` for a promoted memory (edit those in the Cloud UI Learnings tab). |
|
|
62
|
+
| `memory_delete_by_id(memory_id, conversation_id, agent_id=None, datapack_id=None)` | Delete a single memory. Returns `memory_is_promoted` for a promoted memory. |
|
|
63
|
+
| `memory_delete_all(conversation_id, agent_id=None, run_id=None, datapack_id=None)` | Delete all memories in the **passed `agent_id`'s bucket** (destructive). Unlike reads, this is agent-scoped: omitting `agent_id` deletes only the `meko_agent` bucket. `run_id` narrows it to one conversation; a malformed value returns `invalid_run_id`. |
|
|
52
64
|
| `memory_promote(conversation_id, memory_ids, agent_id=None, datapack_id=None)` | Promote private memories into the datapack's shared knowledge base (moves them out of mem0, then evicts from mem0 — one-way). Owners/maintainers only; viewers/contributors get 403. |
|
|
53
65
|
|
|
54
66
|
## Conversation Tools (6)
|
|
55
67
|
|
|
56
68
|
| Tool | Purpose |
|
|
57
69
|
|------|---------|
|
|
58
|
-
| `conversation_create(agent_id, run_id=None, title=None, metadata=None, session_id="")` | Create conversation container (Langfuse session) |
|
|
59
|
-
| `conversation_add_message(conversation_id,
|
|
60
|
-
| `conversation_get(conversation_id, agent_id, include_messages=False, limit=100, offset=0)` | Retrieve conversation, optionally with messages |
|
|
61
|
-
| `conversation_list(agent_id=None, limit=20, offset=0, conversation_id="", datapack_id=None)` | List the user's conversations within a datapack (`agent_id` does not filter — trace attribution only). `datapack_id` (UUID) is optional — defaults to the pinned/tenant datapack; use `
|
|
62
|
-
| `conversation_update(conversation_id, agent_id, title=None, metadata=None)` | Update title or metadata |
|
|
63
|
-
| `conversation_delete(conversation_id, agent_id)` | Delete entire conversation (destructive) |
|
|
70
|
+
| `conversation_create(agent_id=None, run_id=None, title=None, metadata=None, session_id="", datapack_id=None)` | Create conversation container (Langfuse session) |
|
|
71
|
+
| `conversation_add_message(conversation_id, input, output, agent_id=None, reasoning=None, metadata=None, seed=None, datapack_id=None, plan=None)` | Add a message turn (Langfuse trace). `output` is required. The response may include `extracted_memories` and, when the turn wasn't embedded for conversation search, `conversation_search_skipped` (`quota_exceeded` or `datapack_opted_out`). |
|
|
72
|
+
| `conversation_get(conversation_id, agent_id=None, include_messages=False, limit=100, offset=0, datapack_id=None)` | Retrieve conversation, optionally with messages |
|
|
73
|
+
| `conversation_list(agent_id=None, limit=20, offset=0, conversation_id="", datapack_id=None)` | List the user's conversations within a datapack (`agent_id` does not filter — trace attribution only). `datapack_id` (UUID) is optional — defaults to the pinned/tenant datapack; use `datapack_search(query=...)` to look it up. `conversation_id` optional (omit for browse). |
|
|
74
|
+
| `conversation_update(conversation_id, agent_id=None, title=None, metadata=None, datapack_id=None)` | Update title or metadata |
|
|
75
|
+
| `conversation_delete(conversation_id, agent_id=None, datapack_id=None)` | Delete entire conversation (destructive) |
|
|
64
76
|
|
|
65
|
-
## Datapack Management Tools (
|
|
77
|
+
## Datapack Management Tools (6)
|
|
66
78
|
|
|
67
79
|
| Tool | Purpose |
|
|
68
80
|
|------|---------|
|
|
69
|
-
| `datapack_create(name)` | Create new datapack |
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
81
|
+
| `datapack_create(name, conversation_id)` | Create new datapack |
|
|
82
|
+
| `datapack_search(conversation_id, query="", name="", limit=20, cursor="", grant="", sort="created", include_total=False, datapack_id=None)` | Find datapacks and page through them. Returns `{datapacks, has_more, next_cursor, total}`. Use `query` for part of a name, `name` for an exact name, and `cursor` (the previous page's `next_cursor`) for the next page. `limit` is 1-100. `grant` is `owner` or `shared`; `sort` is `created` (newest first) or `name`. Pass `include_total=True` only when you must show "N of M". Rows carry no connection fields and no counts. Servers older than this tool don't have it; use `datapack_list` there. |
|
|
83
|
+
| `datapack_list(conversation_id, datapack_id=None, query="", limit=0)` | Return datapacks as one array. Fine for a small account. `query` filters by part of a name; more than 100 matches return a `too_many_datapacks` error. `limit` returns the first matches (at most 100) without saying whether more exist. With neither, an account that can see more than 1000 datapacks (the server default limit) gets a `too_many_datapacks` error; use `datapack_search` then. `conversation_id` is required for trace nesting. |
|
|
84
|
+
| `datapack_describe(conversation_id, datapack_id="", include_status=False)` | Describe a datapack by UUID (default datapack if omitted). Returns `memory_count`, `collective_memory_count` (promoted), `learnings_count` (awaiting a promotion decision), `knowledge_base_file_count`, `knowledge_chunk_count`, and `shared_knowledge_count`. `knowledge_base_file_count` and `shared_knowledge_count` are `null` when the status endpoint is unreachable; `knowledge_count` is a deprecated alias of `knowledge_chunk_count`. |
|
|
85
|
+
| `datapack_update(datapack_id, conversation_id, name=None, description=None, conversation_search_opt_out=None)` | Rename a datapack, update its description, and/or opt out of (or back into) conversation-search caching. Pass at least one field. Opt-out is owner/maintainer only. |
|
|
86
|
+
| `datapack_delete(datapack_id, conversation_id)` | Delete datapack by UUID (irreversible) |
|
|
87
|
+
|
|
88
|
+
All six datapack tools reject an empty `conversation_id` with `conversation_id_required`.
|
|
74
89
|
|
|
75
90
|
## Artifact Tools (2)
|
|
76
91
|
|
|
@@ -98,10 +113,10 @@ Some things the Meko platform can do are not wired into the MCP tool surface tod
|
|
|
98
113
|
| Langfuse project-key generation | `yugabyte/meko` API server | REST: `POST /datapacks/:datapack_id/langfuse/project-keys` |
|
|
99
114
|
| Account / billing / tier management | Meko UI only | Not available via MCP or public REST |
|
|
100
115
|
|
|
101
|
-
The MCP-exposed `datapack_create` / `datapack_list` / `datapack_describe` / `datapack_update` / `datapack_delete` tools above are a deliberate subset — the common CRUD that an agent reasonably needs mid-conversation. Anything involving agent or KB lifecycle is control-plane territory.
|
|
116
|
+
The MCP-exposed `datapack_create` / `datapack_search` / `datapack_list` / `datapack_describe` / `datapack_update` / `datapack_delete` tools above are a deliberate subset — the common CRUD that an agent reasonably needs mid-conversation. Anything involving agent or KB lifecycle is control-plane territory.
|
|
102
117
|
|
|
103
|
-
For
|
|
118
|
+
For a file already on disk or generated mid-conversation, requesting a URL with `knowledgebase_upload_document` and POSTing to it gets it into the KB without leaving MCP for a human's help. The UI upload path (Datapack → Actions → **Add Knowledge**, PDF/TXT/MD/JSON/CSV/XML/HTML, 5MB Free / 50MB Standard / 60MB Pro+ each, 10/batch) remains the way for a human to add files directly. `knowledgebase_search` queries the resulting index either way.
|
|
104
119
|
|
|
105
120
|
## Common Parameter Patterns
|
|
106
121
|
|
|
107
|
-
Memory and KB tools accept optional `datapack_id` to target a specific datapack. `agent_id` attributes writes
|
|
122
|
+
Memory and KB tools accept optional `datapack_id` to target a specific datapack. A `datapack_id` your account can't access returns `datapack_access_denied`. `agent_id` attributes writes. Conversations are agent-owned: `conversation_get`, `conversation_add_message`, `conversation_update`, and `conversation_delete` return `agent_id_mismatch` for any value other than the creating agent's. `agent_id` does **not** filter memory reads (`memory_search`/`memory_get_all`) or `conversation_list`, which return all your agents' rows for the user. `memory_delete_all` is the exception on the memory side: it deletes only the passed `agent_id`'s bucket. See `tools-agent-id-conventions.md`.
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
# Knowledge Base / RAG workflow
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
MCP exposes four KB tools: `knowledgebase_search` (retrieval),
|
|
4
|
+
`knowledgebase_upload_document` and `knowledgebase_document_status` (add a
|
|
5
|
+
file and track its indexing), and `knowledgebase_delete_document` (remove ONE
|
|
6
|
+
uploaded file). Creating, listing or renaming a knowledge base itself still
|
|
7
|
+
happens out of band — through the **Meko UI** (`cloud.mekodata.ai`).
|
|
6
8
|
|
|
7
9
|
## Decision table
|
|
8
10
|
|
|
9
11
|
| Situation | Use this | Why |
|
|
10
12
|
|---|---|---|
|
|
11
|
-
| Search an existing KB | `knowledgebase_search` |
|
|
12
|
-
| Add
|
|
13
|
-
|
|
|
13
|
+
| Search an existing KB | `knowledgebase_search` | Retrieval over the indexed chunks |
|
|
14
|
+
| Add a file to a KB | `knowledgebase_upload_document` + one direct S3 POST | Requests a presigned URL, then you POST the file to it; no need to leave MCP |
|
|
15
|
+
| Track a file's indexing progress | `knowledgebase_document_status` | Poll with the `key` from the upload response, passed here as `document_key`, until `state` is terminal |
|
|
16
|
+
| Add documents to a KB from the Cloud UI instead | **Meko UI** — Datapack → Actions → **Add Knowledge** | File-upload dialog (PDF/TXT/MD/JSON/CSV/XML/HTML, 5 MB Free / 50 MB Standard / 60 MB Pro+ each, 10/batch). Same index either way — this is the human-facing path, not required when an agent can upload directly |
|
|
17
|
+
| Delete ONE uploaded file | `knowledgebase_delete_document` | Destructive; `document_id` from search hits; confirm with the user first |
|
|
18
|
+
| Anything else (list / rename / re-index / source lifecycle) | **UI** | No MCP tools for the rest of KB lifecycle |
|
|
14
19
|
|
|
15
20
|
## knowledgebase_search — the one you'll actually call
|
|
16
21
|
|
|
@@ -23,7 +28,7 @@ knowledgebase_search(
|
|
|
23
28
|
limit=10)
|
|
24
29
|
```
|
|
25
30
|
|
|
26
|
-
Required: `query`, `
|
|
31
|
+
Required: `query`, `conversation_id`, `datapack_id`.
|
|
27
32
|
Unlike the memory tools, `datapack_id` has no default here — you must
|
|
28
33
|
pass it explicitly. `agent_id` is **ignored for filtering** on this
|
|
29
34
|
tool (KB results are team-shared on the datapack), but you still pass
|
|
@@ -37,10 +42,12 @@ Populated KB:
|
|
|
37
42
|
{
|
|
38
43
|
"results": [
|
|
39
44
|
{
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
45
|
+
"id": "<chunk id>",
|
|
46
|
+
"chunk_text": "<chunk text>",
|
|
47
|
+
"document_id": "<KB document id; pass to knowledgebase_delete_document>",
|
|
48
|
+
"metadata_filters": {},
|
|
49
|
+
"distance": 0.31,
|
|
50
|
+
"match_type": "semantic" | "keyword" | "hybrid",
|
|
44
51
|
...
|
|
45
52
|
},
|
|
46
53
|
...
|
|
@@ -49,9 +56,64 @@ Populated KB:
|
|
|
49
56
|
}
|
|
50
57
|
```
|
|
51
58
|
|
|
59
|
+
Lower `distance` is closer. Promoted memories appear as hits whose `metadata_filters.source` is `"memory"`. Hits carry no filename, so show the user the `document_id` and chunk text when they need to identify a file.
|
|
60
|
+
|
|
52
61
|
Empty or nonexistent KB: `{"results": [], "count": 0}` (no error,
|
|
53
62
|
just an empty array).
|
|
54
63
|
|
|
64
|
+
## knowledgebase_upload_document — putting a file in
|
|
65
|
+
|
|
66
|
+
This tool never touches the file's bytes itself — it only requests a
|
|
67
|
+
presigned S3 URL. **You POST the file to that URL yourself**, as a
|
|
68
|
+
second step:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
knowledgebase_upload_document(
|
|
72
|
+
filename="report.pdf",
|
|
73
|
+
size=42000,
|
|
74
|
+
content_hash="<sha256 hex of the file's bytes>",
|
|
75
|
+
conversation_id="<uuid from conversation_create>",
|
|
76
|
+
agent_id="<your agent_id>",
|
|
77
|
+
content_head_base64="<base64 of the file's first ~4KB>")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Build the POST from every key in the response's `fields`, not a hand-picked list:
|
|
81
|
+
a missing signed field such as `x-amz-security-token` makes S3 answer 403. Use
|
|
82
|
+
the Python, curl, or PowerShell snippet under `knowledgebase_upload_document`
|
|
83
|
+
in `tools-cookbook.md`. Confirm with the user first: the file becomes visible to
|
|
84
|
+
every datapack member.
|
|
85
|
+
|
|
86
|
+
Required: `filename`, `size` (the exact byte count — the URL accepts no
|
|
87
|
+
other length), `content_hash`, `conversation_id`, `content_head_base64`. `content_hash` is the SHA-256 hex digest of the
|
|
88
|
+
file's bytes, computed by you (e.g. `sha256sum`) — it becomes part of
|
|
89
|
+
the S3 key, so it also drives the dedup check. A response with
|
|
90
|
+
`already_uploaded: true` means identical content already exists; skip
|
|
91
|
+
the S3 POST entirely, there is nothing left to upload. Otherwise POST
|
|
92
|
+
as above: every key in `fields` as a form field (in order), then the
|
|
93
|
+
bytes last as a field named `"file"`. Meko registers the object once
|
|
94
|
+
it lands, so no separate confirm call is needed after the POST. Accepted extensions:
|
|
95
|
+
pdf, txt, text, md, json, csv, xml, html, htm; `content_head_base64` is
|
|
96
|
+
always sniffed against the extension before requesting the URL,
|
|
97
|
+
rejecting an obvious mismatch immediately instead of waiting for the
|
|
98
|
+
watcher — a missing/blank value is rejected as
|
|
99
|
+
`content_head_base64_required`, this sniff cannot be skipped.
|
|
100
|
+
Ingestion is asynchronous — save the response's `key` (as
|
|
101
|
+
`document_key`) and poll `knowledgebase_document_status`.
|
|
102
|
+
|
|
103
|
+
## knowledgebase_document_status — tracking it
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
knowledgebase_document_status(
|
|
107
|
+
document_key="<the upload response's `key`>",
|
|
108
|
+
conversation_id="<uuid from conversation_create>",
|
|
109
|
+
agent_id="<your agent_id>")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`state` covers the whole lifecycle: `awaiting_upload` and `indexing`
|
|
113
|
+
are non-terminal (poll again); `completed`, `failed`, `abandoned`, and
|
|
114
|
+
`oversized` are terminal. `NOT_FOUND` means the `document_key` doesn't
|
|
115
|
+
belong to this datapack.
|
|
116
|
+
|
|
55
117
|
## UI ingestion — what the user sees
|
|
56
118
|
|
|
57
119
|
From `cloud.mekodata.ai`:
|
|
@@ -59,11 +121,14 @@ From `cloud.mekodata.ai`:
|
|
|
59
121
|
1. Open a datapack (`/datapacks/<name>`).
|
|
60
122
|
2. Click **Actions** → **Add Knowledge**.
|
|
61
123
|
3. Drag-and-drop or browse for files. Supported: PDF, TXT, MD, JSON,
|
|
62
|
-
|
|
124
|
+
CSV, XML, HTML. Per-file limit 5 MB (Free) / 50 MB (Standard) / 60 MB (Pro+). Up to 10 files per batch.
|
|
63
125
|
4. The UI handles upload, storage, and index build. The user does not
|
|
64
126
|
pick a bucket or provide credentials.
|
|
65
127
|
5. Search results from `knowledgebase_search` become available once
|
|
66
128
|
indexing completes.
|
|
67
129
|
|
|
68
|
-
If a
|
|
69
|
-
point them at this flow.
|
|
130
|
+
If a *human* asks you "how do I add a document to my knowledge base?",
|
|
131
|
+
point them at this flow. If *you* (the agent) have the file's bytes —
|
|
132
|
+
already on disk, or generated mid-conversation — call
|
|
133
|
+
`knowledgebase_upload_document` directly instead of describing the UI
|
|
134
|
+
flow to yourself.
|
|
@@ -7,7 +7,7 @@ These patterns are extracted from real agent sessions. Follow them to avoid wast
|
|
|
7
7
|
1. **Never retry the identical failed call more than once.** If it fails twice with the same error, it's not transient — diagnose the cause.
|
|
8
8
|
2. **Distinguish transient vs persistent failures.** "Connection already closed" is transient (retry once). "Permission denied" is persistent (stop, don't retry).
|
|
9
9
|
3. **Don't guess parameters sequentially.** If a tool fails with one parameter format, don't try 4 variations. Check this skill's docs for the correct format first.
|
|
10
|
-
4. **Use your session's `agent_id` consistently on writes** (the SessionStart-injected value), and on `conversation_get`
|
|
10
|
+
4. **Use your session's `agent_id` consistently on writes** (the SessionStart-injected value), and on every conversation call (`conversation_get`, `conversation_add_message`, `conversation_update`, `conversation_delete`). Conversations are owned by the creating `agent_id`; a wrong value returns `agent_id_mismatch`. Memory reads and `conversation_list` are unaffected by `agent_id`. Don't switch write forms mid-session.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -26,6 +26,22 @@ These patterns are extracted from real agent sessions. Follow them to avoid wast
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## Connection errors: `[Errno 111] Connection refused`
|
|
30
|
+
|
|
31
|
+
**Affects:** any tool, intermittently. Reports show `memory_add`, `conversation_create`, `memory_search`, and `context_search` failing this way while identical calls succeed minutes later.
|
|
32
|
+
|
|
33
|
+
**What it means:** the request reached no listening server, usually a server instance that was restarting or scaling. It is not a timeout and not a rejected argument.
|
|
34
|
+
|
|
35
|
+
**What to do:** wait a few seconds and retry once. Retry `conversation_add_message` only with a `seed`, and never retry `conversation_create` (see the table below). If the retry also fails, report the failure. For a write, tell the user it was not saved; don't let a failed write pass silently.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## `memory_search` hangs or times out
|
|
40
|
+
|
|
41
|
+
`memory_search` can stall for minutes under backend load while other tools respond. Don't raise the client timeout; that only makes the stall longer. Retry once. If it stalls again, report that the search failed, and if the user needs an answer now, try `context_search` or `memory_get_by_id` for a known id. `memory_get_all` only returns a recent window, so it can't replace a search.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
29
45
|
## An error payload is a FAILED search, never an empty one
|
|
30
46
|
|
|
31
47
|
Quota errors, rate-limit errors, and tool refusals come back as an error object with **no `results` key** — reading `response.get("results", [])` first silently converts "you were refused" into "the store is empty." Follow SKILL.md operating contract 1: report it as "search failed: `<error code>` — findings unknown," never as "no results."
|
|
@@ -47,6 +63,36 @@ Bursts of requests on one token return:
|
|
|
47
63
|
|
|
48
64
|
---
|
|
49
65
|
|
|
66
|
+
## Quota errors that look like auth errors
|
|
67
|
+
|
|
68
|
+
`free_tier_limit_reached` can arrive with HTTP 403, and automatic capture that hits a cap shows up as capture failing with 403. Read the error code, not the status. A quota error means the account reached a lifetime cap (see `tools-known-limitations.md`). Don't rotate keys or reinstall. Tell the user which tool hit the cap and that upgrading the plan lifts it.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Datapack and ownership errors
|
|
73
|
+
|
|
74
|
+
| Error | Meaning | What to do |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `datapack_access_denied` | The `datapack_id` isn't a UUID, or it isn't owned by or shared with your account. The access check also fails closed on a transient server database error. | Retry once. If it repeats, stop; don't switch to another datapack. If the id came from a pin, ask the user to re-pin with the select-datapack skill. |
|
|
77
|
+
| `datapack_id_required` | The call couldn't resolve a datapack. Conversation reads and writes (including `conversation_list`), `datapack_describe`, `knowledgebase_upload_document`, `knowledgebase_document_status`, and `knowledgebase_delete_document` return it. | Pass the pinned `datapack_id`. Don't drop the parameter to make the call pass. |
|
|
78
|
+
| `not_found` from `memory_get_by_id`, `memory_update`, or `memory_delete_by_id` | The memory doesn't exist **or** belongs to another account. The server returns the same error for both on purpose. | Check the id came from a search in this datapack. |
|
|
79
|
+
| `memory_is_promoted` | The memory was promoted to shared knowledge and is read-only through MCP. | Point the user at the Cloud UI Learnings tab. |
|
|
80
|
+
| `read_only_access` | You're a viewer on this datapack. Viewers can't write conversations or memories, call `memory_promote`, `artifact_put`, or `track_token_usage`, or delete a conversation someone else started. | Don't retry, and don't switch datapacks to get around it. Tell the user; an owner or maintainer can change their role. |
|
|
81
|
+
| `role_lookup_failed` | The server couldn't read your role for this datapack, so it refused the write. | Retry. |
|
|
82
|
+
| `invalid_run_id` | `memory_delete_all` got a `run_id` that isn't a conversation id. | Pass the conversation UUID, or omit `run_id`. |
|
|
83
|
+
| `embedder_error` from `knowledgebase_search` | The server couldn't resolve the embedding setup for this datapack's index. | Report it; retrying won't help. |
|
|
84
|
+
| `invalid_force_source` from `context_search` | `force_source` isn't `auto`, `memory`, `knowledge_base`, or `conversation`. | Omit `force_source`. |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Conversation writes fail right after `conversation_create`
|
|
89
|
+
|
|
90
|
+
`conversation_add_message` has intermittently returned `not_found`, or `agent_id_mismatch` naming agent `'None'`, seconds after `conversation_create` returned that id. It shows up most with several parallel subagents writing to one conversation. Retry once with the same `seed` after a few seconds. If it still fails, don't create a new conversation for the same work: save the durable findings with `memory_add` and tell the user the transcript is incomplete.
|
|
91
|
+
|
|
92
|
+
On a long conversation that has worked before, `not_found` can instead mean the trace grew too large to load. See `tools-known-limitations.md`.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
50
96
|
## agent_id errors
|
|
51
97
|
|
|
52
98
|
On the Cloud multi-tenant schema, `agent_id` is a TEXT column value — not a PostgreSQL identifier — so arbitrary strings are accepted.
|
|
@@ -4,7 +4,7 @@ On Cloud Meko, every write and every personal read carries a `user_id` that iden
|
|
|
4
4
|
|
|
5
5
|
## The default behavior: automatic user_id from cognito
|
|
6
6
|
|
|
7
|
-
On Cloud, the server resolves your `user_id`
|
|
7
|
+
On Cloud, the server resolves your `user_id` from the cognito account attached to your MCP session (the API key or OAuth token).
|
|
8
8
|
|
|
9
9
|
This is the common case for Claude Code / Claude Desktop / Cursor:
|
|
10
10
|
|
|
@@ -18,43 +18,11 @@ memory_add(
|
|
|
18
18
|
|
|
19
19
|
A second person signing into the same Cloud datapack with their own account gets their own `user_id` automatically — they can never read your un-promoted memories via MCP, and you can never read theirs.
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## No tool takes a user_id argument
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
`user_id` always comes from the credentials on your MCP session. No Meko MCP tool accepts a `user_id` (or `app_id`) argument, and the server rejects unknown arguments, so adding one makes the call fail.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
# Serving Alice
|
|
27
|
-
memory_add(
|
|
28
|
-
text="Alice prefers email communication. Has Pro plan.",
|
|
29
|
-
agent_id="support-bot",
|
|
30
|
-
user_id="alice_123",
|
|
31
|
-
conversation_id="<conv>")
|
|
32
|
-
|
|
33
|
-
# Serving Bob — completely separate partition, same cognito account
|
|
34
|
-
memory_add(
|
|
35
|
-
text="Bob prefers Slack. On Enterprise plan.",
|
|
36
|
-
agent_id="support-bot",
|
|
37
|
-
user_id="bob_456",
|
|
38
|
-
conversation_id="<conv>")
|
|
39
|
-
|
|
40
|
-
# Search only returns Alice's memories
|
|
41
|
-
memory_search(
|
|
42
|
-
query="communication preference",
|
|
43
|
-
agent_id="support-bot",
|
|
44
|
-
user_id="alice_123",
|
|
45
|
-
conversation_id="<conv>")
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This is rarely relevant for Claude Code / Desktop / Cursor — those are single-human clients, and the automatic cognito user_id is the right behavior. It matters for autonomous multi-user agents built on top of the Meko API.
|
|
49
|
-
|
|
50
|
-
## Gotcha — mixing scoped and unscoped calls
|
|
51
|
-
|
|
52
|
-
If you pass `user_id="alice"` on writes but omit it on searches, the search falls back to the auto cognito user_id and **will not find** Alice's memories. They're in a different partition. Pick a convention for a given agent and stick to it:
|
|
53
|
-
|
|
54
|
-
- Claude Code / Desktop / Cursor: omit `user_id`, rely on the auto cognito value.
|
|
55
|
-
- Multi-user autonomous agents: pass `user_id` consistently on every write and read.
|
|
56
|
-
|
|
57
|
-
Mixing creates invisible data.
|
|
25
|
+
An agent that serves several end users behind one Meko account can't partition memory per end user with `user_id`. `agent_id` doesn't work either: it attributes rows but doesn't filter reads. Give each end user or tenant that must not see the others' content a separate datapack, and pass that `datapack_id` on every call.
|
|
58
26
|
|
|
59
27
|
## How user_id relates to agent_id and the Shared Knowledge split
|
|
60
28
|
|
|
@@ -62,7 +30,7 @@ Mixing creates invisible data.
|
|
|
62
30
|
|---|---|---|
|
|
63
31
|
| Personal memories (`memory_add`, `memory_search`, `memory_get_all`) | `(datapack_id, user_id)` | Enforced on every read. `agent_id` is not applied — one user sees all their own memories across every agent, but cannot see another user's un-promoted memories. |
|
|
64
32
|
| Conversation listing (`conversation_list`) | `(datapack_id, user_id)` | Enforced. `agent_id` is not applied — you see all your own conversations across every agent. |
|
|
65
|
-
| Conversation fetch (`conversation_get`) | `(datapack_id, user_id, agent_id)` | Enforced. Agent-owned: pass the creating `agent_id` or you get `agent_id_mismatch`. Cross-user reads require promotion. |
|
|
33
|
+
| Conversation fetch and writes (`conversation_get`, `conversation_add_message`, `conversation_update`, `conversation_delete`) | `(datapack_id, user_id, agent_id)` | Enforced. Agent-owned: pass the creating `agent_id` or you get `agent_id_mismatch`. Cross-user reads require promotion. |
|
|
66
34
|
| Team Shared Knowledge (`knowledgebase_search`) | `(datapack_id)` only | **Not used** — `user_id` is stripped when a memory is promoted to Knowledge. All team members on the datapack see the same Shared Knowledge. |
|
|
67
35
|
|
|
68
36
|
Personal content crosses the `user_id` boundary through `memory_promote` or the Cloud UI's "Promote to Knowledge" action. The MCP path requires exact memory UUIDs, explicit user confirmation, and an owner/maintainer role; it moves the records into team-visible Shared Knowledge and evicts the private copies.
|
|
@@ -72,9 +40,8 @@ Personal content crosses the `user_id` boundary through `memory_promote` or the
|
|
|
72
40
|
| Parameter | Identifies | Typical value | Required? |
|
|
73
41
|
|---|---|---|---|
|
|
74
42
|
| `datapack_id` | Which datapack's DB/Langfuse project | `"c038ba7b-..."` (UUID) | Optional on most tools (default datapack if omitted). **Required** on `knowledgebase_search`. |
|
|
75
|
-
| `user_id` | The cognito account
|
|
43
|
+
| `user_id` | The cognito account | Resolved from your credentials | Not a tool argument |
|
|
76
44
|
| `agent_id` | Which agent wrote / is reading | `"claude_code:<repo>"`, `"claude_desktop"`, `"cursor:<repo>"`, `"meko_agent"` (common bucket) | Optional (empty/missing → `meko_agent` server-side); pass the per-session value verbatim for project-scoped reads/writes. Ignored on `knowledgebase_search`. |
|
|
77
|
-
| `app_id` | Optional application/product sub-scope | `"second_brain"`, `"helpdesk"` | Optional |
|
|
78
45
|
| `run_id` | A conversation id, used as a read/delete filter against the row's `meko_conversation_id` | `"374c70f3b95745ac92724d98475cc2d6"` | Optional. On `memory_add` it is trace metadata only and does not scope the write — see `tools-agent-id-conventions.md`. |
|
|
79
46
|
|
|
80
47
|
See `tools-agent-id-conventions.md` for the full `agent_id` model.
|