@yugabytedb/meko-mcp 2.3.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.
Files changed (40) hide show
  1. package/README.md +72 -33
  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 +129 -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 +5 -5
  10. package/assets/skills/meko-mcp-tools/references/_sections.md +1 -1
  11. package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +193 -9
  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 +16 -11
  16. package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +67 -8
  17. package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +3 -1
  18. package/assets/skills/meko-mcp-tools-desktop/SKILL.md +7 -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 +193 -9
  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 +16 -11
  25. package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +67 -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 +117 -24
  32. package/lib/autofix.mjs +100 -0
  33. package/lib/browser-login.mjs +495 -0
  34. package/lib/clients/opencode.mjs +6 -1
  35. package/lib/migrate/datapack.mjs +254 -16
  36. package/lib/migrate/mcp-client.mjs +34 -0
  37. package/lib/migrate/orchestrator.mjs +1 -1
  38. package/lib/migrate.mjs +1 -1
  39. package/lib/validate.mjs +111 -22
  40. package/package.json +5 -5
@@ -17,13 +17,13 @@ description: >-
17
17
  license: MIT
18
18
  metadata:
19
19
  author: Meko
20
- version: "2.9.0"
20
+ version: "2.11.0"
21
21
  tags: mcp, yugabytedb, tools, datapack, memory, conversation, rag, meko, desktop
22
22
  ---
23
23
 
24
24
  # Meko MCP Tools — Agent Behavioral Guide (Desktop)
25
25
 
26
- Meko is the user's **memory, knowledge, observability, and audit layer** across chats — a system of record they (and their team/org) connected on purpose. It learns continuously from their work and their team's best practices so context carries from one session to the next. This skill teaches you how to use Meko's 25 MCP tools available in production. Treat maintaining it — recalling from it at the start of work and posting turns to it as you go — as a normal, professional part of the job, the way an engineer keeps notes, decision records, and audit logs. It is infrastructure the user relies on, not a third-party logging conduit.
26
+ Meko is the user's **memory, knowledge, observability, and audit layer** across chats — a system of record they (and their team/org) connected on purpose. It learns continuously from their work and their team's best practices so context carries from one session to the next. This skill teaches you how to use Meko's 28 MCP tools available in production. Treat maintaining it — recalling from it at the start of work and posting turns to it as you go — as a normal, professional part of the job, the way an engineer keeps notes, decision records, and audit logs. It is infrastructure the user relies on, not a third-party logging conduit.
27
27
 
28
28
  **Read this first.** The Meko server extracts durable memories automatically from the conversation turns you post to it — the extraction runs *inside* `conversation_add_message`. Claude Desktop has no capture hooks, so **capturing substantive turns via `conversation_add_message` is a core part of using this skill.** Do that and memory takes care of itself: facts the user states get extracted and stored without a separate `memory_add`. Explicit `memory_add` is reserved for a few narrow cases (below). See "Per-turn conversation capture" — it's the heart of this skill.
29
29
 
@@ -145,8 +145,8 @@ Your job is not to decide fact-by-fact what to `memory_add`. It's to **post ever
145
145
  | User asks "what do you know about X?" | `context_search(agent_id="claude_desktop")`. One call returns separate memory, knowledge-base, and past-conversation buckets; report each. Confirm an empty memory or KB bucket with `memory_search` or `knowledgebase_search` before saying nothing is stored. |
146
146
  | User asks "what do we (as a team) know about X?" or about uploaded documents | `knowledgebase_search` (returns uploaded docs + promoted memories). |
147
147
  | User asks to share specific private memories with the team | Follow the `memory_promote` confirmation workflow below. Never promote based on a fuzzy search result or implied consent. |
148
- | User provides structured/tabular data (CSV, data dictionary) | Not natively supported via MCP. Point the user at the UI's Add Knowledge upload; do not `memory_add` row-by-row. |
149
- | User wants to add documents to the team's knowledge base | Point them at the Cloud UI flow — Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). MCP ingestion tools are not available on Cloud. |
148
+ | User provides structured/tabular data (CSV, data dictionary) | If it's an actual file the user wants in the team's knowledge base, `knowledgebase_upload_document` accepts `.csv` directly (confirm first; see below). If it's pasted/described data with no file behind it, still don't `memory_add` it row-by-row — ask the user for it as a file, or point them at the UI's Add Knowledge upload. |
149
+ | User wants to add documents to the team's knowledge base | Uploading adds the file to the datapack's shared knowledge base, which every member can read, so ask first: name the file and the datapack, say the team will see it, and upload only after the user says yes. If you (the agent) have the file's bytes and can make an HTTP POST from a shell (Claude Desktop usually can't; see `tools-cookbook.md`), call `knowledgebase_upload_document`. Otherwise point the user at the Cloud UI flow — Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/CSV/XML/HTML, 5MB Free / 50MB Standard / 60MB Pro+ each, 10/batch). KB *lifecycle* (index/source management) is still UI-only. |
150
150
 
151
151
  ## Conversation capture — mechanics
152
152
 
@@ -264,12 +264,12 @@ The Cloud UI's Learnings tab remains an alternative user-driven path.
264
264
 
265
265
  ## Key concepts
266
266
 
267
- 1. **25 tools in 7 groups** (all available in production): Retrieval (1: `context_search`), Memory (8 — including `memory_promote`), Conversation (6), Knowledge Base (2 — `knowledgebase_search`, `knowledgebase_delete_document`), Datapack (5), Artifacts (2 — `artifact_put`, `artifact_get`), Observability (1 — `track_token_usage`). Memory is captured automatically from turns posted with `conversation_add_message` — post each substantive turn and the server extracts durable memories from it. KB ingestion is UI-only (Datapack → Actions → Add Knowledge); raw SQL is not exposed. See `tools-overview.md`.
267
+ 1. **28 tools in 7 groups** (all available in production): Retrieval (1: `context_search`), Memory (8 — including `memory_promote`), Conversation (6), Knowledge Base (4 — `knowledgebase_search`, `knowledgebase_delete_document`, `knowledgebase_upload_document`, `knowledgebase_document_status`), Datapack (6, including `datapack_search`), Artifacts (2 — `artifact_put`, `artifact_get`), Observability (1 — `track_token_usage`). Memory is captured automatically from turns posted with `conversation_add_message` — post each substantive turn and the server extracts durable memories from it. Raw SQL is not exposed. See `tools-overview.md`.
268
268
  2. **datapack_id routing**: DB, RAG, and memory tools accept optional `datapack_id` (default datapack if omitted). `knowledgebase_search` is the exception: `datapack_id` is **required** there.
269
269
  3. **agent_id is multi-agent**: For Claude Desktop, use `agent_id="claude_desktop"` for normal writes and `agent_id="meko_agent"` for cross-project facts. Writes are attributed to `(datapack_id, user_id, agent_id)`. Personal memory reads and `conversation_list` span all of this user's agents; `conversation_get` remains agent-owned. `knowledgebase_search` ignores `agent_id` entirely. See `tools-agent-id-conventions.md`.
270
270
  4. **Personal memory vs. team-shared knowledge**: Un-promoted memories are scoped per-user — readable across all of that user's agents, but no other user can see them. With explicit confirmation, `memory_promote` moves exact memories into Shared Knowledge; the Cloud UI's Learnings tab is an alternative. Promoted content is visible to every datapack member. `knowledgebase_search` is the MCP read path for both Shared Knowledge and uploaded documents.
271
271
  5. **conversation_id IS the Langfuse trace ID**: every MCP tool call inside a conversation becomes a span under that trace. Observable in the Meko UI's Observe hub. See `tools-memory-vs-conversation.md`.
272
- 6. **Adding documents to the team knowledge base is UI-only on Cloud today**: user uploads files via Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5MB each). The MCP ingestion tools are not available on Cloud. See `tools-rag-workflow.md`.
272
+ 6. **Adding a file to a knowledge base**: the file becomes visible to every datapack member, so confirm with the user first. Call `knowledgebase_upload_document` only if you have the file's bytes and can POST them to the returned URL from a shell; Claude Desktop usually can't, so point the user at the UI instead. A human uploads via Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/CSV/XML/HTML, 5MB Free / 50MB Standard / 60MB Pro+ each) instead. KB *lifecycle* (creating/renaming/deleting an index, adding a source manually) has no MCP tool and is still UI-only. See `tools-rag-workflow.md`.
273
273
  7. **Manual conversation capture**: Claude Desktop does not have automatic capture hooks. Create and save conversations explicitly when sessions are valuable.
274
274
  8. **Memory latencies are not cheap**: observed on prod 2026-05-07 — `memory_add` 12-21s/call (calls OpenAI), `memory_search` 2-6s/call. Budget accordingly. On the Free tier, `conversation_add_message` and `context_search` are each capped at 1,000 lifetime calls, and `memory_search` and `knowledgebase_search` at 1,000. Per-turn capture draws down the `conversation_add_message` cap, so on Free skip trivial turns. When a call returns `free_tier_limit_reached`, report it and stop calling that tool; it can arrive as HTTP 403 but isn't an authentication problem.
275
275
  9. **Known limitations**: see `tools-known-limitations.md` before attempting write operations on tools that appear in the catalog but aren't available on Cloud.
@@ -279,7 +279,7 @@ The Cloud UI's Learnings tab remains an alternative user-driven path.
279
279
 
280
280
  | File | What it covers |
281
281
  |------|---------------|
282
- | `tools-overview.md` | Complete catalog of all 25 tools available in production, with decision tree |
282
+ | `tools-overview.md` | Complete catalog of all 28 tools available in production, with decision tree |
283
283
  | `tools-cookbook.md` | Per-tool examples with correct parameters, responses, and error cases |
284
284
  | `tools-memory-vs-conversation.md` | When to use memory tools vs conversation tools |
285
285
  | `tools-rag-workflow.md` | End-to-end RAG pipeline flow |
@@ -1,6 +1,6 @@
1
1
  # Meko MCP Tools — Claude Desktop Setup
2
2
 
3
- Use the Meko MCP tools skill natively in Claude Desktop. Because Desktop has no lifecycle hooks, the skill teaches Claude to capture each substantive turn by posting it via `conversation_add_message` (the server extracts durable memories from those posts), to reserve explicit `memory_add` for the narrow cases (the user says "remember this", a fact lives only in the assistant's output or a tool result, or a corrected fact needs overwriting), to classify information, to use all <!--tool-count-->25<!--/tool-count--> Meko MCP tools correctly, and to handle errors gracefully.
3
+ Use the Meko MCP tools skill natively in Claude Desktop. Because Desktop has no lifecycle hooks, the skill teaches Claude to capture each substantive turn by posting it via `conversation_add_message` (the server extracts durable memories from those posts), to reserve explicit `memory_add` for the narrow cases (the user says "remember this", a fact lives only in the assistant's output or a tool result, or a corrected fact needs overwriting), to classify information, to use all <!--tool-count-->28<!--/tool-count--> Meko MCP tools correctly, and to handle errors gracefully.
4
4
 
5
5
  ## Setup
6
6
 
@@ -86,7 +86,7 @@ Start a new conversation and say:
86
86
 
87
87
  > What datapacks do I have?
88
88
 
89
- Claude should call `datapack_list` and return your accessible datapacks. If it works, the MCP server and skill are both connected.
89
+ Claude should call `datapack_search` (`datapack_list` on older servers) and return your accessible datapacks. If it works, the MCP server and skill are both connected.
90
90
 
91
91
  ### Step 4 (recommended): Make Desktop proactive
92
92
 
@@ -134,7 +134,7 @@ An explicit "remember this" is one of the narrow cases where the agent calls `me
134
134
  ### Save conversations (triggers conversation_create + conversation_add_message)
135
135
  > Save this conversation.
136
136
 
137
- ### Manage datapacks (triggers datapack_list / datapack_create)
137
+ ### Manage datapacks (triggers datapack_search / datapack_create)
138
138
  > List all datapacks.
139
139
 
140
140
  ## Differences from Claude Code
@@ -169,7 +169,7 @@ On Cloud Meko, `agent_id` is a row-level column value — any string works, it n
169
169
 
170
170
  ### "Conversation tools don't work"
171
171
 
172
- Conversation tools require Langfuse credentials (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`). The other 19 tools work without Langfuse. If you don't need conversation persistence, you can skip this.
172
+ Conversation tools require Langfuse credentials (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`). The other tools work without Langfuse. If you don't need conversation persistence, you can skip this.
173
173
 
174
174
  ### "Skill doesn't trigger"
175
175
 
@@ -6,7 +6,7 @@ description: Maps reference files to their topics for the meko-mcp-tools-desktop
6
6
  # Reference Sections
7
7
 
8
8
  ## Tool Selection & Catalog
9
- - [tools-overview.md](tools-overview.md) — Complete catalog of all 25 tools available in production, with a decision tree
9
+ - [tools-overview.md](tools-overview.md) — Complete catalog of all 28 tools available in production, with a decision tree
10
10
 
11
11
  ## Tool-Specific Guidance
12
12
  - [tools-agent-id-conventions.md](tools-agent-id-conventions.md) — Multi-agent model: the three buckets (project `<client>:<repo-basename>`, common `meko_agent`, loose client name), personal vs. team-shared read surfaces
@@ -68,7 +68,7 @@ memory_add(agent_id="claude_desktop",
68
68
 
69
69
  **What NOT to store via memory_add:**
70
70
  - Full conversations (use `conversation_create` + `conversation_add_message`)
71
- - Large documents (use the UI's Datapack → Actions → Add Knowledge upload flow)
71
+ - Large documents (use `knowledgebase_upload_document`, or the UI's Datapack → Actions → Add Knowledge upload flow)
72
72
 
73
73
  **Common errors:**
74
74
  - `syntax error at or near "-"` — legacy error from the pre-multi-tenancy schema when `agent_id` became part of a PostgreSQL identifier. No longer applies on Cloud (agent_id is a TEXT column value, any string is accepted). If you hit it on a deployment that still uses the old schema, use underscores instead of hyphens.
@@ -179,7 +179,7 @@ On 403, authentication, or permission failure, report the error and stop — do
179
179
  ```
180
180
  conversation_create(agent_id="claude_desktop",
181
181
  title="Debugging the auth middleware",
182
- datapack_id="<uuid from datapack_list>")
182
+ datapack_id="<uuid from datapack_search>")
183
183
  ```
184
184
 
185
185
  `datapack_id` is required whenever no server-side default resolves for the caller. Omitting it in that state returns `{"error": "datapack_id_required"}` and persists nothing; the same contract applies to `conversation_add_message`, `conversation_get`, `conversation_update`, and `conversation_delete`.
@@ -224,8 +224,8 @@ conversation_get(conversation_id="conv-uuid-123", agent_id="agent",
224
224
  ### conversation_list
225
225
 
226
226
  Target the datapack by `datapack_id` (UUID). It's optional — omit it to use the
227
- pinned/default datapack, or pass the pinned `datapack_id`. Use `datapack_list`
228
- to look up the id.
227
+ pinned/default datapack, or pass the pinned `datapack_id`. Use
228
+ `datapack_search(query="<part of the name>")` to look up the id.
229
229
 
230
230
  ```
231
231
  conversation_list(datapack_id="<datapack-uuid>", agent_id="agent", limit=20)
@@ -254,7 +254,7 @@ conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
254
254
 
255
255
  ## Knowledge Base Tools
256
256
 
257
- **KB ingestion is a UI-only activity.** Users upload files via the datapack's Actions → **Add Knowledge** dialog (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). MCP exposes two KB tools: `knowledgebase_search`, and `knowledgebase_delete_document` for removing a single uploaded file.
257
+ Agents upload files via `knowledgebase_upload_document` and poll `knowledgebase_document_status` for indexing progress; a human uploading through the Cloud UI still uses the datapack's Actions → **Add Knowledge** dialog (PDF/TXT/MD/JSON/CSV/XML/HTML, 5MB Free / 50MB Standard / 60MB Pro+ each, 10/batch) — both paths feed the same index. `knowledgebase_search` queries whatever the KB currently holds. MCP also exposes `knowledgebase_delete_document` for removing a single uploaded file.
258
258
 
259
259
  See `tools-rag-workflow.md` for the decision table.
260
260
 
@@ -293,6 +293,173 @@ knowledgebase_delete_document(document_id="<uuid from a search hit>",
293
293
 
294
294
  Returns `{"document_id", "chunks_deleted", "s3_deleted"}` — if `s3_deleted` is `false`, say so: the index entries are gone but the stored file may remain. Errors include a numeric `status`: `403` means the user is not the datapack owner, a maintainer, or the file's uploader — report it, don't retry; `409` (`DOCUMENT_PROCESSING`) means the file is still being indexed — wait for indexing to finish, then retry.
295
295
 
296
+ ### knowledgebase_upload_document
297
+
298
+ **When to use:** Get a file's bytes into the datapack's KB for later `knowledgebase_search` retrieval — a file already on disk, or one generated mid-conversation. This tool never touches the file's bytes itself; it only requests a presigned S3 URL. Meko registers the file once it lands, so there's no separate confirm call. **The caller POSTs the file to the returned `url` directly** — multipart/form-data, every key in `fields` as a form field (in order), then the file's bytes last as a field named `"file"`.
299
+
300
+ **Confirm first.** The file goes into the datapack's shared knowledge base, which every member can read. Before calling the tool, tell the user which file and datapack, say the team will see it, and wait for a yes.
301
+
302
+ **You need a shell that can make the POST** (Python, curl, or PowerShell, below). Without one, as in Claude Desktop by default, don't call the tool: point the user at Datapack → Actions → **Add Knowledge**. An issued URL holds its `size` against the storage quota for up to 15 minutes even if nothing is uploaded.
303
+
304
+ **After the user confirms and the tool returns, POST the file in the same turn.** The upload is only half-done once you have `url`/`fields`; nothing else completes it for you.
305
+
306
+ **`content_hash` and `content_head_base64` are both computed on the caller's own device, from the file's real bytes — this tool never computes either for you.** `content_head_base64` is compulsory: the tool refuses with `content_head_base64_required` if it's missing or blank, so there's no path that skips the sniff.
307
+
308
+ Linux:
309
+ ```bash
310
+ CONTENT_HASH=$(sha256sum report.pdf | cut -d' ' -f1)
311
+ CONTENT_HEAD_B64=$(head -c 3072 report.pdf | base64 -w0)
312
+ ```
313
+
314
+ macOS (no `sha256sum` by default — use `shasum`; BSD `base64` has no `-w0`, so strip newlines with `tr` instead):
315
+ ```bash
316
+ CONTENT_HASH=$(shasum -a 256 report.pdf | cut -d' ' -f1)
317
+ CONTENT_HEAD_B64=$(head -c 3072 report.pdf | base64 | tr -d '\n')
318
+ ```
319
+
320
+ Windows PowerShell:
321
+ ```powershell
322
+ $ContentHash = (Get-FileHash -Algorithm SHA256 -Path "report.pdf").Hash.ToLower()
323
+ $bytes = [System.IO.File]::ReadAllBytes("report.pdf")
324
+ $head = $bytes[0..([Math]::Min(3071, $bytes.Length - 1))]
325
+ $ContentHeadB64 = [Convert]::ToBase64String($head)
326
+ ```
327
+
328
+ Windows cmd.exe (`certutil` ships built in for the hash — prints it on its own line, strip the header/footer lines before use; cmd.exe has **no** built-in way to take just the first 3072 bytes *and* base64-encode them in one step, so use the PowerShell or Python snippet for `content_head_base64` even in a cmd.exe-driven workflow):
329
+ ```bat
330
+ certutil -hashfile report.pdf SHA256
331
+ ```
332
+
333
+ Python (cross-platform; streams the file so a large one isn't fully loaded into memory, and reuses the same read to build `content_head_base64` too):
334
+ ```python
335
+ import hashlib, base64
336
+
337
+ h = hashlib.sha256()
338
+ with open(LOCAL_PATH, "rb") as f:
339
+ head = f.read(3072) # also the content_head_base64 sample
340
+ h.update(head)
341
+ for chunk in iter(lambda: f.read(1 << 20), b""):
342
+ h.update(chunk)
343
+
344
+ content_hash = h.hexdigest()
345
+ content_head_base64 = base64.b64encode(head).decode()
346
+ ```
347
+
348
+ **Then, after the tool call returns `{url, fields}` — a portable snippet (identical on Linux/macOS/Windows, needs `python3` + `requests`), because it loops over whatever `fields` came back instead of hand-enumerating field names, so it can't drift out of sync with what the response actually contains:**
349
+
350
+ ```python
351
+ import json, requests
352
+ resp = json.loads(RESPONSE_JSON) # the tool's raw JSON string
353
+ if not resp.get("already_uploaded"):
354
+ with open(LOCAL_PATH, "rb") as f:
355
+ r = requests.post(resp["url"], data=resp["fields"], files={"file": (FILENAME, f)})
356
+ r.raise_for_status()
357
+ ```
358
+
359
+ **Linux/macOS, curl (needs `jq`; builds the `-F` flags dynamically from whatever `fields` actually contains — a signer using temporary credentials adds `x-amz-security-token`, and extra policy conditions add their own fields, so a hardcoded field list drops them and S3 answers 403 on a form missing a signed field):**
360
+
361
+ ```bash
362
+ if [ "$(echo "$RESPONSE_JSON" | jq -r '.already_uploaded')" != "true" ]; then
363
+ URL=$(echo "$RESPONSE_JSON" | jq -r '.url')
364
+ FIELDS=()
365
+ while IFS= read -r -d '' key && IFS= read -r -d '' value; do
366
+ FIELDS+=(-F "${key}=${value}")
367
+ done < <(echo "$RESPONSE_JSON" | jq -j '.fields | to_entries[] | (.key, "\u0000", .value, "\u0000")')
368
+ curl -sS --fail "${FIELDS[@]}" -F file=@/local/path/report.pdf "$URL"
369
+ fi
370
+ ```
371
+
372
+ **Windows PowerShell 7+ (`Invoke-RestMethod -Form` takes the whole `fields` object as a hashtable — no per-field enumeration needed at all; use `[ordered]@{}`, not a plain `@{}`, since S3 requires `file` to be the *last* form field and a plain hashtable has no guaranteed enumeration order):**
373
+
374
+ ```powershell
375
+ $resp = $json | ConvertFrom-Json
376
+ if (-not $resp.already_uploaded) {
377
+ $form = [ordered]@{}
378
+ $resp.fields.PSObject.Properties | ForEach-Object { $form[$_.Name] = $_.Value }
379
+ $form["file"] = Get-Item "C:\path\to\report.pdf"
380
+ Invoke-RestMethod -Uri $resp.url -Method Post -Form $form
381
+ }
382
+ ```
383
+
384
+ **Windows cmd.exe:** cmd.exe has no built-in JSON parsing, so there's no safe way to build the `-F` flags dynamically from whatever `fields` contains without an extra tool. Rather than hardcode a field list that silently drops fields (e.g. `x-amz-security-token` on temporary credentials, or extra policy conditions) and fail with a confusing S3 403, use the PowerShell or Python snippet above even from a cmd.exe-driven workflow.
385
+
386
+ `size` must be the file's exact length in bytes, and the URL only accepts a body of exactly that size and SHA-256, for 5 minutes. Accepted extensions: pdf, txt, text, md, json, csv, xml, html, htm. `content_head_base64` — the file's first 3072 bytes, or the whole file if shorter, base64-encoded — is **required**: the tool sniffs it against the extension before requesting the URL and rejects an obvious mismatch (e.g. a renamed file) at once as `VALIDATION_ERROR`; a missing or blank one is `content_head_base64_required`. Text files must be UTF-8, because indexing reads UTF-8 only: a Latin-1 or Excel "CSV (Windows)" file is refused with a message to save it as UTF-8 (Excel: "CSV UTF-8"). Samples up to 4096 bytes are accepted and trimmed, so older snippets that send 4096 still work. A mismatch the server catches later surfaces as `state: "abandoned"` from `knowledgebase_document_status`. Idempotent — uploading the same content twice (by SHA-256) returns `already_uploaded: true` with an empty `url` and no `fields`; if that file's indexing never started or failed, the repeat queues it again.
387
+
388
+ ```
389
+ knowledgebase_upload_document(
390
+ filename="report.pdf",
391
+ size=42000,
392
+ content_hash="<sha256 hex of the file's bytes>",
393
+ conversation_id="<uuid from conversation_create>",
394
+ content_head_base64="<base64 of the file's first 3072 bytes>",
395
+ agent_id="claude_desktop",
396
+ )
397
+ ```
398
+
399
+ **Response (fresh upload):**
400
+ ```json
401
+ {
402
+ "datapack_id": "...",
403
+ "url": "https://<bucket>.s3.amazonaws.com/",
404
+ "fields": {"key": "...", "policy": "...", "...": "..."},
405
+ "key": "user/datapack/hash/report.pdf",
406
+ "already_uploaded": false
407
+ }
408
+ ```
409
+
410
+ **Response (identical content already uploaded):**
411
+ ```json
412
+ {
413
+ "datapack_id": "...",
414
+ "url": "",
415
+ "key": "user/datapack/hash/report.pdf",
416
+ "already_uploaded": true,
417
+ "existing_filename": "report.pdf"
418
+ }
419
+ ```
420
+
421
+ After a fresh upload, POST the file to `url` yourself (see above), then save `key` (as `document_key`) and poll `knowledgebase_document_status` until `state` is terminal. S3 answers a successful POST with `204`. `400 EntityTooSmall` or `EntityTooLarge` means `size` wasn't the file's exact byte count: call the tool again with the right size and upload through the new URL. The earlier URL can never succeed (it only accepts the wrong size) and expires on its own within 5 minutes.
422
+
423
+ **Common errors:**
424
+ - `conversation_id_required` — `conversation_id` was missing or blank.
425
+ - `datapack_id_required` — no `datapack_id` was given and no tenant default could be resolved.
426
+ - `content_head_base64_required` — `content_head_base64` was missing or blank. Checked after the `filename`/`size`/`content_hash` `VALIDATION_ERROR` checks, but always before a URL is requested — there is no way to skip it.
427
+ - `VALIDATION_ERROR` — missing filename, unsupported extension, missing/malformed `content_hash`, size ≤ 0, invalid or oversized `content_head_base64`, a sample shorter than `min(size, 3072)` bytes or longer than `size` (so `size` is wrong), or the sampled content doesn't match its extension.
428
+ - `FREE_TIER_KB_STORAGE_LIMIT` / `STANDARD_TIER_KB_STORAGE_LIMIT` (`status` 402) — no room left in the storage quota. Tell the user to free space or upgrade instead of retrying: every issued URL holds its `size` against the quota until the file is registered, or for up to 15 minutes if it is never uploaded.
429
+
430
+ Every error from the server also carries `status`, its HTTP status code.
431
+ - `knowledgebase_upload_document_failed` — unexpected error (see `detail`).
432
+ - The actual S3 POST isn't made through this tool, so its own failures (e.g. the body exceeding the cap the URL was signed under) surface to whatever made that call directly, not from this tool.
433
+
434
+ ---
435
+
436
+ ### knowledgebase_document_status
437
+
438
+ **When to use:** Track a file uploaded via `knowledgebase_upload_document` from "waiting for bytes" through to indexed.
439
+
440
+ ```
441
+ knowledgebase_document_status(
442
+ document_key="user/datapack/hash/report.pdf",
443
+ conversation_id="<uuid from conversation_create>",
444
+ agent_id="claude_desktop"
445
+ )
446
+ ```
447
+
448
+ **Response (still indexing):**
449
+ ```json
450
+ {
451
+ "document_key": "user/datapack/hash/report.pdf",
452
+ "filename": "report.pdf",
453
+ "state": "indexing",
454
+ "message": "The file is registered and being indexed.",
455
+ "document": {"status": "PROCESSING", "chunks_processed": 3}
456
+ }
457
+ ```
458
+
459
+ Poll until `state` is `completed` or `failed` (or the pre-registration terminals `abandoned`/`oversized`). `NOT_FOUND` means `document_key` is unknown to this datapack — check it was copied verbatim from the upload response. `datapack_id_required` means no `datapack_id` was given and no tenant default could be resolved.
460
+
461
+ ---
462
+
296
463
  ## Artifact Tools
297
464
 
298
465
  ### artifact_put
@@ -372,14 +539,31 @@ For large files use `local_path` to read the file. S3 URLs are never exposed.
372
539
 
373
540
  ## Datapack Management Tools
374
541
 
375
- ### datapack_create / datapack_list / datapack_describe
542
+ ### datapack_create / datapack_search / datapack_list / datapack_describe
376
543
 
377
544
  ```
378
545
  datapack_create(name="analytics_prod", conversation_id="<conversation id>")
379
- datapack_list(conversation_id="<this conversation's id>") # returns datapack_id for each datapack
546
+ datapack_search(conversation_id="<this conversation's id>", query="analytics") # find an id by part of the name
547
+ datapack_search(conversation_id="<this conversation's id>", name="analytics_prod") # exact name
548
+ datapack_list(conversation_id="<this conversation's id>") # small accounts: every datapack in one array
380
549
  datapack_describe(datapack_id="<uuid>", include_status=True, conversation_id="<conversation id>")
381
550
  ```
382
551
 
552
+ Find a datapack id with `datapack_search(query=...)`. It returns one page:
553
+ `{"datapacks": [...], "has_more": true, "next_cursor": "<token>", "total": null}`.
554
+ To get the next page, call it again with the same filters and
555
+ `cursor="<next_cursor>"`. `next_cursor` is `""` on the last page, and also
556
+ when an older server has more matches than this page but cannot continue.
557
+ Do not send an empty cursor; ask for a narrower `query` instead. Treat the
558
+ cursor as opaque. Pass `include_total=True` only when you must show "N of M".
559
+
560
+ `datapack_list` still returns one array and is fine for an account with a
561
+ handful of datapacks. For an account that can see more than 1000 datapacks
562
+ (the server default limit) it returns `{"error": "too_many_datapacks", ...}`
563
+ instead; switch to `datapack_search`. If the server has no `datapack_search`
564
+ tool (an older server), use `datapack_list`.
565
+
566
+
383
567
  `datapack_describe` returns these counts:
384
568
 
385
569
  | Field | Meaning |
@@ -391,7 +575,7 @@ datapack_describe(datapack_id="<uuid>", include_status=True, conversation_id="<c
391
575
  | `knowledge_chunk_count` | KB chunks across all documents (for debugging retrieval) |
392
576
  | `shared_knowledge_count` | `collective_memory_count + knowledge_base_file_count`; `null` when the file count is `null` |
393
577
 
394
- `knowledge_count` is a deprecated alias of `knowledge_chunk_count`. `datapack_list` doesn't compute counts; call `datapack_describe` for them.
578
+ `knowledge_count` is a deprecated alias of `knowledge_chunk_count`. Neither `datapack_search` nor `datapack_list` computes counts; call `datapack_describe` for them.
395
579
 
396
580
  ### datapack_update / datapack_delete
397
581
 
@@ -412,4 +596,4 @@ Agent and KB lifecycle does not ship as MCP tools. If the user asks to create/li
412
596
  - REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (agents), `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases` (KB sources).
413
597
  - Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
414
598
 
415
- KB ingestion specifically lives in the UI today: Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5 MB each, 10/batch). Agents querying a populated index use `knowledgebase_search`, and can remove a single uploaded file with `knowledgebase_delete_document` — see `tools-rag-workflow.md`.
599
+ Uploading a *file* into an existing KB is not part of that lifecycle restriction — use `knowledgebase_upload_document` (see above) rather than the UI for anything driven from MCP. Agents querying a populated index use `knowledgebase_search`, and can remove a single uploaded file with `knowledgebase_delete_document` — see `tools-rag-workflow.md`.
@@ -14,9 +14,11 @@ The one exception is a single uploaded **file**: `knowledgebase_delete_document`
14
14
 
15
15
  **Workaround:** For stuck or failed indexes, create a new index with a different name. Stale indexes remain in the database until manually cleaned up by an admin.
16
16
 
17
- ## RAG ingestion is UI-only
17
+ ## KB index/source management is UI-only
18
18
 
19
- KB ingestion (creating an index, adding sources, polling build status) is not exposed via MCP. Documents go in through the Cloud UI's **Add Knowledge** flow (Datapack → Actions → Add Knowledge) — PDF/TXT/MD/JSON/MP4 up to 5 MB each, 10 per batch.
19
+ Manually creating a vector index, adding a source to an existing one, or polling raw build status is not exposed via MCP. Use the Cloud UI for those (Datapack → Actions → Add Knowledge).
20
+
21
+ **Adding a file** is a registered MCP tool: call `knowledgebase_upload_document` directly (accepted extensions PDF/TXT/MD/JSON/CSV/XML/HTML, up to 5 MB Free / 50 MB Standard / 60 MB Pro+ per file) to get a presigned URL, then POST the bytes to it yourself; Meko registers and indexes the file once it lands, so no separate index-management call is needed. Confirm with the user first, because every datapack member can read the knowledge base. The Cloud UI's **Add Knowledge** flow (10 files per batch) remains the human-facing path for the same upload.
20
22
 
21
23
  To **query** a built index, use `knowledgebase_search` — it returns both uploaded documents and memories the user promoted from the Learnings tab.
22
24
 
@@ -32,7 +34,7 @@ It works **poorly** for:
32
34
  - Data dictionaries — only partial information extracted
33
35
  - Structured schemas — relationships between fields lost
34
36
 
35
- **Structured data is not natively supported via MCP.** The options are:
37
+ **Don't store structured data as memories.** The options are:
36
38
 
37
39
  1. **Write a single narrative summary** as a memory — one call, not row-by-row:
38
40
  ```
@@ -41,8 +43,7 @@ It works **poorly** for:
41
43
  conversation_id="<session conversation_id>",
42
44
  text="Customer Complaints dataset has fields: Complaint ID (int PK), Date Submitted (date), Product (text, e.g. Mortgage/Credit Card), Sub-product (text), Issue (text), Company Response (text), State (text, 2-letter code), ZIP Code (text)")
43
45
  ```
44
- 2. **Upload the schema doc** through the Cloud UI's **Add Knowledge** flow (Datapack → Actions → Add Knowledge). Accepts PDF/TXT/MD/JSON — convert CSV to MD or JSON first. That makes it queryable via `knowledgebase_search`.
45
- 3. **Tell the user** that structured-data storage via MCP isn't supported and let them decide how to proceed.
46
+ 2. **Upload the file itself to the knowledge base** with `knowledgebase_upload_document` — `.csv`, `.json` and the other accepted types go in as they are — and query it with `knowledgebase_search`. (The Cloud UI's **Add Knowledge** flow does the same for a person.)
46
47
 
47
48
  Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
48
49
 
@@ -60,6 +61,10 @@ The skill description is tuned to its 1024-char ceiling; broadening it further d
60
61
 
61
62
  `memory_search` and `memory_get_all` return every agent's rows for the user. `memory_delete_all` deletes only rows in the `agent_id` you pass, and an omitted `agent_id` means the `meko_agent` bucket. A `memory_search(run_id=X)` preview can therefore list rows that `memory_delete_all(run_id=X)` leaves in place. To clear rows written by several agents, delete them by id with `memory_delete_by_id`, or call `memory_delete_all` once per `agent_id` shown in the preview.
62
63
 
64
+ ## Viewers can read but not write
65
+
66
+ On a datapack shared with you as a viewer, every conversation and memory write returns `read_only_access` and writes nothing: `conversation_create`, `conversation_add_message`, `conversation_update`, `memory_add`, `memory_update`, `memory_promote`, `artifact_put`, and `track_token_usage`. You can still delete your own memories with `memory_delete_by_id` and `memory_delete_all`, and delete a conversation you started. Searches work as for any other role. `context_search` covers every member's conversations, but for a viewer its conversation results and `conversation_get` return `user_id: null`, so they don't say who wrote a turn. On Claude Desktop there are no capture hooks: when your own `conversation_add_message` call returns `read_only_access`, stop recording turns for this datapack and tell the user.
67
+
63
68
  ## Promoted memories are read-only through MCP
64
69
 
65
70
  `memory_update` and `memory_delete_by_id` return `memory_is_promoted` for a memory that has been promoted to shared knowledge. Edit or remove promoted content in the Cloud UI Learnings tab.
@@ -27,11 +27,11 @@ Conversations are backed by Langfuse sessions and traces. They preserve full str
27
27
 
28
28
  ```
29
29
  conversation_create(agent_id="claude_desktop", title="Pricing discussion",
30
- datapack_id="<uuid from datapack_list>")
30
+ datapack_id="<uuid from datapack_search>")
31
31
  -- Returns: {"id": "conv-uuid-here"}
32
32
 
33
33
  conversation_add_message(conversation_id="conv-uuid-here", agent_id="claude_desktop",
34
- datapack_id="<uuid from datapack_list>",
34
+ datapack_id="<uuid from datapack_search>",
35
35
  input="What are your pricing tiers?",
36
36
  output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
37
37
  reasoning="Retrieved pricing page data. No special discounts apply.")
@@ -85,7 +85,7 @@ One `memory_search` already spans this user's memories across all agents; no per
85
85
  - **Personal memories** — written by `memory_add`. The `agent_id` records the writer but does not restrict reads; memories are scoped per-user, so any of that user's agents can read them and no other user can.
86
86
  - **Team-shared Shared Knowledge** — arrives two ways:
87
87
  1. An agent calls `memory_promote` for exact, user-confirmed memory UUIDs, or the user promotes them from the Cloud UI's Learnings tab. Promotion moves the memories into shared knowledge, strips `user_id`, preserves originating `agent_id` as provenance, and evicts the private mem0 records.
88
- 2. The user uploads a file via Datapack → Actions → **Add Knowledge** in the Cloud UI. PDF/TXT/MD/JSON/MP4 up to 5MB each.
88
+ 2. The user uploads a file via Datapack → Actions → **Add Knowledge** in the Cloud UI. PDF/TXT/MD/JSON/CSV/XML/HTML up to 5MB (Free) / 50MB (Standard) / 60MB (Pro+) each.
89
89
 
90
90
  Both show up in `knowledgebase_search`, tagged `metadata_filters.source: "memory"` vs other values so the agent can distinguish provenance in responses.
91
91
 
@@ -114,7 +114,7 @@ When you answer, be explicit about scope so the user knows why something is or i
114
114
  There is no MCP-side "just put it in a database table" option — raw SQL access isn't part of the MCP surface. Workarounds:
115
115
 
116
116
  1. **Write a single narrative summary** as a memory: `"The Customer Complaints dataset has fields: Complaint ID (int), Date Submitted (date), Product (text), Sub-product (text), Issue (text)..."` — one call, not row-by-row.
117
- 2. **Suggest the user upload the file** via the Cloud UI's Add Knowledge flow if it's a document (CSV files aren't in the supported list — PDF/TXT/MD/JSON/MP4 are; for CSV, convert to MD or JSON first).
117
+ 2. **Suggest the user upload the file** via the Cloud UI's Add Knowledge flow if it's a document (PDF/TXT/MD/JSON/CSV/XML/HTML are supported).
118
118
  3. **Never ingest CSV row-by-row** into memory — each row becomes a fragmented fact with lost context.
119
119
 
120
120
  ## Memory Storage: capture the turn, don't proactively memory_add
@@ -1,13 +1,13 @@
1
1
  # Complete Tool Catalog and Decision Tree
2
2
 
3
- **25 Meko data tools covered by this skill.** These are the tools available in production, grouped as: Retrieval (1), Memory (8), Conversation (6), Knowledge Base (2), Datapack (5), Artifacts (2), Observability (1). Combined Meko + AMP endpoints may expose additional infrastructure tools; those are outside this skill's scope.
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="claude_desktop", conversation_id="<id from conversation_create>")` — Confirms memory subsystem is up. May fail with "connection already closed" — see `tools-troubleshooting.md`.
10
- 2. `datapack_list(conversation_id="<this conversation's id>")` — Confirms Meko API connectivity. Returns the datapacks your token has access to.
10
+ 2. `datapack_search(conversation_id="<this conversation's 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="<this conversation's id>")` instead.
11
11
 
12
12
  ## Decision tree: which tool do I need?
13
13
 
@@ -16,7 +16,8 @@ User wants to...
16
16
  ├── Ask "what do you know about X?" --------> context_search (read; memory + KB + past conversations in one call)
17
17
  ├── Search personal context? ---------------> memory_search (read)
18
18
  ├── Search shared datapack knowledge? ------> knowledgebase_search (read)
19
- ├── Add documents to a knowledge base? -----> point user at Meko UI: Datapack → Actions → Add Knowledge
19
+ ├── Add a file to a knowledge base? --------> knowledgebase_upload_document (write)
20
+ │ └── Check its indexing progress? -------> knowledgebase_document_status (read)
20
21
  ├── Delete ONE knowledge-base file? --------> knowledgebase_delete_document (destructive — confirm with the user first)
21
22
  ├── Store or recall information?
22
23
  │ ├── Store a fact/preference/entity? -----------> memory_add (write)
@@ -28,10 +29,11 @@ User wants to...
28
29
  │ ├── Upload a generated file (report, CSV, PDF)? -> artifact_put (write)
29
30
  │ └── Retrieve a previously uploaded file? -------> artifact_get (read)
30
31
  └── Manage datapacks?
32
+ ├── Find a datapack id by name? -------> datapack_search(query=...) (read)
31
33
  └── CRUD datapack? --------------------> datapack_create/list/describe/update/delete
32
34
  ```
33
35
 
34
- Agent lifecycle and KB **ingestion / index lifecycle** (adding sources, uploads, re-indexing) are managed outside the MCP surface — typically in the Meko control-plane UI. Deleting a single KB file IS exposed here (`knowledgebase_delete_document`).
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`).
35
37
 
36
38
  ## Retrieval Tools (1)
37
39
 
@@ -39,12 +41,14 @@ Agent lifecycle and KB **ingestion / index lifecycle** (adding sources, uploads,
39
41
  |------|---------|
40
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. |
41
43
 
42
- ## Knowledge Base Tools (2)
44
+ ## Knowledge Base Tools (4)
43
45
 
44
46
  | Tool | Purpose |
45
47
  |------|---------|
46
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`). |
47
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). |
48
52
 
49
53
  ## Memory Tools (8)
50
54
 
@@ -66,21 +70,22 @@ Agent lifecycle and KB **ingestion / index lifecycle** (adding sources, uploads,
66
70
  | `conversation_create(agent_id=None, run_id=None, title=None, metadata=None, session_id="", datapack_id=None)` | Create conversation container (Langfuse session) |
67
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`). |
68
72
  | `conversation_get(conversation_id, agent_id=None, include_messages=False, limit=100, offset=0, datapack_id=None)` | Retrieve conversation, optionally with messages |
69
- | `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_list` to look it up. `conversation_id` optional (omit for browse). |
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). |
70
74
  | `conversation_update(conversation_id, agent_id=None, title=None, metadata=None, datapack_id=None)` | Update title or metadata |
71
75
  | `conversation_delete(conversation_id, agent_id=None, datapack_id=None)` | Delete entire conversation (destructive) |
72
76
 
73
- ## Datapack Management Tools (5)
77
+ ## Datapack Management Tools (6)
74
78
 
75
79
  | Tool | Purpose |
76
80
  |------|---------|
77
81
  | `datapack_create(name, conversation_id)` | Create new datapack |
78
- | `datapack_list(conversation_id, datapack_id=None)` | List all datapacks. `conversation_id` is required for trace nesting; omit `datapack_id` to use the endpoint default. |
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. |
79
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`. |
80
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. |
81
86
  | `datapack_delete(datapack_id, conversation_id)` | Delete datapack by UUID (irreversible) |
82
87
 
83
- All five datapack tools reject an empty `conversation_id` with `conversation_id_required`.
88
+ All six datapack tools reject an empty `conversation_id` with `conversation_id_required`.
84
89
 
85
90
  ## Artifact Tools (2)
86
91
 
@@ -108,9 +113,9 @@ Some things the Meko platform can do are not wired into the MCP tool surface tod
108
113
  | Langfuse project-key generation | `yugabyte/meko` API server | REST: `POST /datapacks/:datapack_id/langfuse/project-keys` |
109
114
  | Account / billing / tier management | Meko UI only | Not available via MCP or public REST |
110
115
 
111
- 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.
112
117
 
113
- For knowledge-base content on Cloud, the canonical path is **UI upload**: Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). `knowledgebase_search` queries the resulting index from MCP.
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.
114
119
 
115
120
  ## Common Parameter Patterns
116
121