@yugabytedb/meko-mcp 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +59 -25
  2. package/assets/hooks-handlers/before-submit-prompt.sh +2 -2
  3. package/assets/hooks-handlers/codex-session-end.sh +78 -0
  4. package/assets/hooks-handlers/lib/capture.js +366 -152
  5. package/assets/hooks-handlers/lib/checkpoint-timer.js +67 -13
  6. package/assets/hooks-handlers/session-end.sh +10 -0
  7. package/assets/hooks-handlers/session-start.sh +14 -3
  8. package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
  9. package/assets/scripts/meko-statusline.sh +119 -0
  10. package/assets/scripts/package-desktop-skill.sh +64 -30
  11. package/assets/skills/meko-mcp-tools/SKILL.md +84 -86
  12. package/assets/skills/meko-mcp-tools/references/_sections.md +2 -4
  13. package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +29 -25
  14. package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +5 -7
  15. package/assets/skills/meko-mcp-tools/references/tools-conversation-reasoning.md +50 -0
  16. package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +126 -184
  17. package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +31 -37
  18. package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +10 -26
  19. package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +26 -30
  20. package/assets/skills/meko-mcp-tools/references/tools-overview.md +60 -66
  21. package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +28 -93
  22. package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +5 -99
  23. package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +9 -8
  24. package/assets/skills/meko-mcp-tools-desktop/SKILL.md +138 -138
  25. package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +46 -16
  26. package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +2 -2
  27. package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +28 -24
  28. package/assets/skills/meko-mcp-tools-desktop/references/tools-conversation-reasoning.md +50 -0
  29. package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +120 -174
  30. package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +16 -22
  31. package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +28 -34
  32. package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +60 -66
  33. package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +28 -93
  34. package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +4 -98
  35. package/assets/skills/meko-select-datapack-desktop/SKILL.md +208 -0
  36. package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +121 -0
  37. package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +41 -0
  38. package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +66 -0
  39. package/bin/create-meko-setup.mjs +74 -6
  40. package/lib/clients/claude-code.mjs +137 -6
  41. package/lib/clients/claude-desktop.mjs +51 -12
  42. package/lib/clients/codex.mjs +329 -13
  43. package/lib/clients/common.mjs +43 -1
  44. package/lib/clients/cursor.mjs +82 -21
  45. package/lib/config.mjs +26 -0
  46. package/lib/detect.mjs +7 -2
  47. package/lib/installer.mjs +24 -0
  48. package/lib/mcp-transport.mjs +5 -0
  49. package/lib/prompt.mjs +1 -1
  50. package/lib/url-selection.mjs +55 -0
  51. package/lib/validate.mjs +0 -1
  52. package/package.json +1 -1
  53. package/scripts/bundle-assets.mjs +8 -0
  54. package/assets/skills/meko-mcp-tools/references/tools-db-query-patterns.md +0 -38
  55. package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +0 -75
  56. package/assets/skills/meko-mcp-tools/references/tools-write-guardrails.md +0 -30
  57. package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +0 -75
@@ -10,15 +10,15 @@ There are no MCP tools to:
10
10
  - Clear stuck work queue entries
11
11
  - Reset a failed pipeline
12
12
 
13
- KB-source deletion happens via the Meko control plane (REST: `DELETE /datapacks/:name/knowledge-bases`, or the UI), which removes the registration from the Meko API — but does **not** touch the actual `dist_rag` index, source records, or vector data in the datapack's database.
13
+ KB-source deletion happens via the Meko control plane (REST: `DELETE /datapacks/:datapack_id/knowledge-bases`, or the UI), which removes the registration from the Meko API — but does **not** touch the actual `dist_rag` index, source records, or vector data in the datapack's database.
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
- ## No MCP tool to query a built RAG index
17
+ ## RAG ingestion is UI-only
18
18
 
19
- The RAG tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) handle index **creation and monitoring** only.
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.
20
20
 
21
- To actually **query** a built index on Cloud, use `knowledgebase_search` — it returns both uploaded documents (UI "Add Knowledge" flow) and memories the user promoted from the Learnings tab. The `db_run_read_only_query` direct-DB path is Free-Tier-gated on Cloud.
21
+ To **query** a built index, use `knowledgebase_search` — it returns both uploaded documents and memories the user promoted from the Learnings tab.
22
22
 
23
23
  ## Memory tools unreliable for structured/tabular data
24
24
 
@@ -32,38 +32,22 @@ It works **poorly** for:
32
32
  - Data dictionaries — only partial information extracted
33
33
  - Structured schemas — relationships between fields lost
34
34
 
35
- **On Cloud, structured data is not MCP-supported today.** `db_run_write_query` / `db_run_read_only_query` / `db_summarize_database` all return `{"error": "not_available", "detail": "Free Tier: DB Tools access is not enabled. coming soon."}`. The options are:
35
+ **Structured data is not natively supported via MCP.** The options are:
36
36
 
37
37
  1. **Write a single narrative summary** as a memory — one call, not row-by-row:
38
38
  ```
39
- memory_add(scope="write",
39
+ memory_add(
40
40
  agent_id="<your session agent_id>",
41
41
  conversation_id="<session conversation_id>",
42
42
  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
43
  ```
44
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 a Cloud feature today and let them decide how to proceed.
45
+ 3. **Tell the user** that structured-data storage via MCP isn't supported and let them decide how to proceed.
46
46
 
47
47
  Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
48
48
 
49
- ## MCP user permission gaps
49
+ ## No semantic search over conversation content
50
50
 
51
- The MCP database user may not have read access to all tables within a datapack, particularly:
52
- - Data tables created by the provisioning system
53
- - Tables in non-public schemas
51
+ Semantic (meaning-based) search across stored conversation content is not part of the public tool surface today. To find a past conversation, browse with `conversation_list` (by datapack) and inspect candidates with `conversation_get`.
54
52
 
55
- If `db_run_read_only_query` returns "permission denied", this is a server-side configuration issue. Use `db_summarize_database` to see which tables are accessible.
56
-
57
- ## Currently broken tools
58
-
59
- **`db_run_write_query`** — May fail with `'dict' object has no attribute 'guardrail_config'` in some deployments. When this happens, all write operations are blocked for the session.
60
-
61
- **Knowledge-base ingestion tools on cloud Meko** (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) return `{"error": "not_available"}` on Free Tier. Even when ungated, the async worker only reads `s3://` URIs and uses its own boto3 credential chain — it cannot read buckets the user provides credentials for. Tracked: [yugabyte/meko-mcp-server#89](https://github.com/yugabyte/meko-mcp-server/issues/89) / MEKO-96. Use the Meko UI's **Add Knowledge** file-upload dialog for ingestion on cloud. `knowledgebase_search` works on cloud today.
62
-
63
- (Historical note: `knowledgebase_add_source_to_index` used to have a `r_index_name` vs `r_index_id` SQL-signature bug. That specific bug was fixed on main in commit `3ae724a` — the tool now resolves `index_name → index_id` internally.)
64
-
65
- ## No conversation search
66
-
67
- `conversation_list` returns conversations by agent, but there is no semantic search across conversation content. To find a specific past exchange, you need to list conversations and inspect them individually with `conversation_get`.
68
-
69
- For finding past knowledge by meaning, use `memory_search` instead — which is why storing key facts via `memory_add` alongside conversations is important.
53
+ For finding past knowledge by meaning, `memory_search` remains the most reliable path — which is why storing key facts via `memory_add` alongside conversations is important.
@@ -11,10 +11,10 @@
11
11
  Memory is backed by pgvector (semantic search) and Apache AGE (entity-relationship graph). It retrieves relevant facts by meaning, not by conversation order.
12
12
 
13
13
  ```
14
- memory_add(scope="write", agent_id="support_bot",
15
- text="Customer Alice (alice@acme.com) prefers email, has Pro plan.", user_id="alice_123")
14
+ memory_add(agent_id="support_bot",
15
+ text="Customer Alice (alice@acme.com) prefers email, has Pro plan.")
16
16
 
17
- memory_search(scope="read", query="What plan does Alice have?", agent_id="support_bot")
17
+ memory_search(query="What plan does Alice have?", agent_id="support_bot")
18
18
  ```
19
19
 
20
20
  ## Use `conversation_create` + `conversation_add_message` when storing:
@@ -26,10 +26,10 @@ memory_search(scope="read", query="What plan does Alice have?", agent_id="suppor
26
26
  Conversations are backed by Langfuse sessions and traces. They preserve full structure: who said what, in what order, with what reasoning.
27
27
 
28
28
  ```
29
- conversation_create(scope="write", agent_id="support_bot", user_id="alice_123", title="Pricing discussion")
29
+ conversation_create(agent_id="support_bot", title="Pricing discussion")
30
30
  -- Returns: {"id": "conv-uuid-here"}
31
31
 
32
- conversation_add_message(scope="write", conversation_id="conv-uuid-here", agent_id="support_bot",
32
+ conversation_add_message(conversation_id="conv-uuid-here", agent_id="support_bot",
33
33
  input="What are your pricing tiers?",
34
34
  output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
35
35
  reasoning="Retrieved pricing page data. No special discounts apply.")
@@ -65,72 +65,68 @@ All three fields — `input`, `output`, and `reasoning` — must contain the **e
65
65
 
66
66
  The purpose of conversation storage is to create a faithful, replayable record. A rephrased summary loses the original wording, tone, and detail — making the stored conversation useless for review, debugging, or audit.
67
67
 
68
- ## Personal memory vs. team-shared knowledge — the three read paths
68
+ ## Personal memory vs. team-shared knowledge — the two read paths
69
69
 
70
- Agents on Cloud Meko have three distinct read surfaces. Pick the right one for the question.
70
+ Agents on Cloud Meko have two distinct read surfaces. Pick the right one for the question.
71
71
 
72
72
  | Read path | What it returns | How to call |
73
73
  |---|---|---|
74
- | Your own project memories | Memories you wrote under this `agent_id`, filtered by `(datapack_id, user_id, agent_id)` | `memory_search(agent_id="<your agent_id>", query="...", ...)` |
75
- | Cross-project common bucket | Memories any agent (including this one) wrote with `agent_id="meko_agent"` — the empty-default bucket for genuinely cross-project facts | `memory_search(agent_id="meko_agent", query="...", ...)` |
74
+ | Your personal memories | Everything you and any of your agents wrote for this user — filtered by `(datapack_id, user_id)`, **not** by `agent_id`. One call covers your project bucket, the `meko_agent` common bucket, and every other project's rows. | `memory_search(agent_id="<your agent_id>", query="...", ...)` — `agent_id` scopes the Langfuse trace, not the results |
76
75
  | Team's shared knowledge | Promoted memories + uploaded documents, visible to every member of the datapack | `knowledgebase_search(agent_id="<anything>", datapack_id="<datapack UUID>", query="...")` — `agent_id` is ignored |
77
76
 
78
- For a true fan-out across multiple specific agent_ids (e.g. also see what was written from `claude_code:other-repo` or `cursor:foo`), call `memory_search` once per agent_id — there's no single-call shortcut. Empty string is rewritten to `meko_agent` server-side; it does not drop the filter.
77
+ `agent_id` does not filter memory reads, so a single `memory_search` already spans all of your agents; there is no per-agent fan-out to do.
79
78
 
80
79
  ### How content gets into each surface
81
80
 
82
- - **Personal memories** — written by `memory_add`. Scoped per-user and per-agent from the moment of write. Only the writer sees them via MCP reads.
81
+ - **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 via MCP, and no other user can.
83
82
  - **Team-shared Shared Knowledge** — arrives two ways:
84
- 1. The **user** (never the agent) promotes a personal memory to Knowledge via the Cloud UI's Learnings tab. That copies the row into the shared `knowledge_base` table with the `user_id` stripped, making it team-wide. Originating `agent_id` is preserved in metadata for provenance.
83
+ 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 and graph context into shared knowledge, strips `user_id`, preserves originating `agent_id` as provenance, and evicts the private mem0 records.
85
84
  2. The user uploads a file via Datapack → Actions → **Add Knowledge** in the Cloud UI. PDF/TXT/MD/JSON/MP4 up to 5MB each.
86
85
 
87
86
  Both show up in `knowledgebase_search`, tagged `metadata_filters.source: "memory"` vs other values so the agent can distinguish provenance in responses.
88
87
 
89
- **No MCP tool promotes to Shared Knowledge.** The agent can flag memories it thinks are worth promoting and suggest the user do it from the UI — but the action is user-initiated.
88
+ `memory_promote` is a one-way, destructive MCP path. Before calling it, retrieve exact UUIDs with `memory_search` or `memory_get_all`, show the exact candidates, explain team visibility and private-record eviction, and obtain explicit user confirmation. Only owners and maintainers may promote; report 403/auth failures without escalating scope or switching datapacks. The Cloud UI remains an alternative.
90
89
 
91
90
  ### When the user asks "what do you know about X?"
92
91
 
93
- A full sweep is three calls (budget for it — each is 2-6 seconds):
92
+ A full sweep is two calls (budget for it — each is 0.6-6 seconds):
94
93
 
95
94
  ```
96
- memory_search(agent_id="<your-agent-id>", query="X", conversation_id=..., ...)
97
- memory_search(agent_id="meko_agent", query="X", conversation_id=..., ...) # cross-project common bucket
95
+ memory_search(agent_id="<your-agent-id>", query="X", conversation_id=..., ...) # all your personal memories, every agent
98
96
  knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
99
97
  ```
100
98
 
101
- When you answer, be explicit about scope so the user knows why something is or isn't there:
99
+ The single `memory_search` already returns everything you and any other agent wrote for this user (`agent_id` doesn't filter memory reads) — no per-agent fan-out. When you answer, be explicit about scope so the user knows why something is or isn't there:
102
100
 
103
- - "I found this in your own project memories…"
104
- - "I found this in your common cross-project bucket (something you or another agent wrote under `meko_agent`)…"
101
+ - "I found this in your personal memories (something you or another of your agents saved earlier)…"
105
102
  - "I found this in your team's Shared Knowledge — someone (you or a teammate) promoted it earlier…"
106
- - "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab for a cross-agent view."
107
-
108
- For a true fan-out across other specific buckets (e.g. also see what was written from `claude_code:other-repo` or `cursor:foo`), call `memory_search` once per known agent_id — empty string just resolves to `meko_agent`, not a fan-out.
103
+ - "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab."
109
104
 
110
105
  ## Memory limitations for structured data
111
106
 
112
107
  **WRONG:** Using `memory_add` to ingest CSV rows, data dictionaries, or tabular schemas — Mem0 extracts individual facts and may drop columns, rows, or structural relationships.
113
108
 
114
- On Cloud Meko today the `db_run_write_query` path isn't available (returns `{"error": "not_available"}`), so there's no MCP-side "just put it in a database table" option. Workarounds:
109
+ 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
110
 
116
111
  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
112
  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).
118
113
  3. **Never ingest CSV row-by-row** into memory — each row becomes a fragmented fact with lost context.
119
114
 
120
- ## Proactive Memory Storage
115
+ ## Memory Storage: automatic, not proactive
116
+
117
+ On Claude Code, do **not** proactively `memory_add` facts the user states. Conversation capture is automatic (see below) and the server extracts durable memories from the captured turns on its own — personal info, team conventions, domain knowledge the user states, and corrections are all saved without a tool call. Re-storing them with `memory_add` just duplicates what extraction already holds.
121
118
 
122
- Don't wait for the user to say "remember this." Store context proactively when you detect:
119
+ Explicit `memory_add` is reserved for the three cases automatic extraction cannot reach:
123
120
 
124
- - **Personal info** → `memory_add`: "User is VP of Product, prefers concise responses"
125
- - **Team conventions** → `memory_add`: "Team uses Python for backend, Go for infrastructure"
126
- - **Domain knowledge** → `memory_add`: "Meko traces are decision traces that capture how and why decisions were made"
127
- - **Corrections** → `memory_add`: "User corrected: always use 'resilience' instead of 'high availability'"
121
+ - **Explicit request** → the user says "remember this" / "save this."
122
+ - **Output-only / tool-derived fact** → a durable fact that lives only in your output or a tool result, never in a user turn. Extraction reads only the user turn, so it never sees these.
123
+ - **Overwriting correction** → a prior fact was negated and the stale memory must not survive. Extraction is additive (it adds the new fact but leaves the old one live), so `memory_search` for the stale memory and `memory_update` / `memory_delete_by_id` it.
128
124
 
129
125
  Use `memory_search` at the start of sessions to recall what you already know before asking the user to repeat themselves.
130
126
 
131
127
  ## Using Both Together
132
128
 
133
- A common pattern: store the full conversation (preserves structure) AND extract key facts with `memory_add` (enables semantic search later).
129
+ Capture stores the full conversation (preserves structure) and extraction derives searchable memories from it — both happen automatically. Add an explicit `memory_add` only for the three cases above.
134
130
 
135
131
  ## Key Retrieval Difference
136
132
 
@@ -1,96 +1,90 @@
1
1
  # Complete Tool Catalog and Decision Tree
2
2
 
3
- **26 tools on cloud Meko** (verified against `https://mcp.mekodata.ai/mcp` on 2026-05-07). Earlier counts of 25 or 31 in other docs are stale. Grouped: Memory (8), Conversation (6), Knowledge Base (4), Datapack (5), Database (3).
4
-
5
- ## Cloud Free-Tier gating at a glance
6
-
7
- Some tools return `{"error": "not_available", "detail": "..."}` on cloud Free Tier. This is a server-side tier block — don't retry.
8
-
9
- - **Gated on Free Tier**: `db_summarize_database`, `db_run_read_only_query`, `db_run_write_query`, `knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`
10
- - **Works on Free Tier**: all memory tools, all conversation tools, `knowledgebase_search`, all datapack tools, `flush_pending_memory_candidates`
3
+ **23 tools on Cloud Meko** (verified against `https://mcp.mekodata.ai/mcp`). Grouped: Memory (8), Conversation (6), Knowledge Base (1), Datapack (5), Artifacts (2), Observability (1).
11
4
 
12
5
  ## Quick health check before using tools
13
6
 
14
7
  Before starting a session, verify that the Meko MCP tools are working:
15
8
 
16
- 1. `memory_search(scope="read", 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`.
17
- 2. `datapack_list(scope="read")` — Confirms Meko API connectivity
18
- 3. `db_summarize_database(scope="read")` — *Optional, paid-tier only.* On free-tier datapacks this returns `{"error": "not_available"}`. The old "use this for `agent_id` discovery" protocol is retired — use the session-injected `agent_id` for project-scoped calls, or `meko_agent` for the common bucket.
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. `datapack_list()` — Confirms Meko API connectivity. Returns the datapacks your token has access to.
19
11
 
20
12
  ## Decision tree: which tool do I need?
21
13
 
22
14
  ```
23
15
  User wants to...
24
- ├── Query or explore the database?
25
- │ ├── See what tables exist? ---------> db_summarize_database (read)
26
- │ ├── Run a SELECT / read query? -----> db_run_read_only_query (read)
27
- │ └── INSERT / UPDATE / DELETE? -------> db_run_write_query (write)
28
- ├── Query or build a knowledge base (RAG)?
29
- │ ├── Search chunks in an existing KB? -> knowledgebase_search (read) — WORKS on cloud today
30
- │ ├── Create a new index from sources? -> knowledgebase_trigger_index_creation (write) — Free-Tier gated, self-hosted only
31
- │ ├── Add source to existing index? ---> knowledgebase_add_source_to_index (write) — Free-Tier gated
32
- │ └── Check build progress? -----------> knowledgebase_check_index_status (read) — Free-Tier gated
16
+ ├── Search a knowledge base? ---------------> knowledgebase_search (read)
17
+ ├── Add documents to a knowledge base? -----> point user at Meko UI: Datapack → Actions → Add Knowledge
18
+ │ (no MCP tool — Cloud uses UI ingestion only)
33
19
  ├── Store or recall information?
34
20
  │ ├── Store a fact/preference/entity? -----------> memory_add (write)
35
21
  │ ├── Store a full conversation (multi-turn)? ---> conversation_create + conversation_add_message (write)
36
22
  │ ├── Search past knowledge? --------------------> memory_search (read)
23
+ │ ├── Share private memories with the team? -----> memory_promote (write; owner/maintainer only)
37
24
  │ └── Retrieve a past conversation? -------------> conversation_get (read)
25
+ ├── Persist or retrieve a file?
26
+ │ ├── Upload a generated file (report, CSV, PDF)? -> artifact_put (write)
27
+ │ └── Retrieve a previously uploaded file? -------> artifact_get (read)
38
28
  └── Manage datapacks?
39
- └── CRUD datapack? -> datapack_create/list/describe/update/delete
29
+ └── CRUD datapack? --------------------> datapack_create/list/describe/update/delete
40
30
  ```
41
31
 
42
32
  Agent / knowledge-base lifecycle is managed **outside** the MCP surface — typically in the Meko control-plane UI — and is not exposed as tools here.
43
33
 
44
- ## Database Tools (3)
45
-
46
- | Tool | Scope | Purpose |
47
- |------|-------|---------|
48
- | `db_summarize_database(scope, schema="public", datapack_id=None)` | read | List tables with column schemas and row counts |
49
- | `db_run_read_only_query(scope, query, datapack_id=None)` | read | Run SELECT, returns JSON. Uses `BEGIN READ ONLY` + `ROLLBACK` |
50
- | `db_run_write_query(scope, query, datapack_id=None)` | write | Execute INSERT/UPDATE/DELETE/CREATE TABLE. Guardrail-validated. Auto-committed |
51
-
52
- ## RAG / Knowledge Base Tools (4)
34
+ ## Knowledge Base Tools (1)
53
35
 
54
- | Tool | Scope | Purpose |
55
- |------|-------|---------|
56
- | `knowledgebase_search(scope, query, agent_id, conversation_id, datapack_id, limit=10)` | read | Semantic search across KB chunks. `datapack_id` is REQUIRED (no default). Works on cloud today. |
57
- | `knowledgebase_trigger_index_creation(scope, conversation_id, source_uris, index_name, ai_provider="OPENAI", embedding_model="text-embedding-3-large", embedding_dimensions=1536, chunk_size=1024, chunk_overlap=256, datapack_id=None)` | write | Register sources + init vector index + trigger build. **S3-only worker + no user creds; Free-Tier gated on cloud.** See `tools-rag-workflow.md`. |
58
- | `knowledgebase_add_source_to_index(scope, conversation_id, index_name, source_uri, chunk_size=1024, chunk_overlap=256, datapack_id=None)` | write | Add a new source (URI, not id) to an existing index. Free-Tier gated on cloud. |
59
- | `knowledgebase_check_index_status(scope, conversation_id, index_name, datapack_id=None)` | read | Check build progress via `dist_rag.vector_index_pipeline_details`. Free-Tier gated on cloud. |
36
+ | Tool | Purpose |
37
+ |------|---------|
38
+ | `knowledgebase_search(query, agent_id, conversation_id, datapack_id, limit=10)` | Semantic search across KB chunks. `datapack_id` is REQUIRED (no default). |
60
39
 
61
40
  ## Memory Tools (8)
62
41
 
63
- | Tool | Scope | Purpose |
64
- |------|-------|---------|
65
- | `memory_add(scope, text, agent_id, conversation_id, user_id=None, app_id=None, run_id=None, metadata=None, messages=None, datapack_id=None)` | write | Store fact/preference/entity as long-term memory |
66
- | `memory_search(scope, query, agent_id, conversation_id="", user_id=None, limit=10, datapack_id=None)` | read | Semantic search across memories + graph relations. `conversation_id` optional (omit or pass `""` for cross-conversation discovery). |
67
- | `memory_get_by_id(scope, memory_id, agent_id, conversation_id, datapack_id=None)` | read | Direct pgvector row lookup by UUID. Preferred over `memory_search` for exact-id verification. |
68
- | `memory_get_all(scope, agent_id, conversation_id, user_id=None, app_id=None, run_id=None, datapack_id=None)` | read | List all memories for agent |
69
- | `memory_update(scope, memory_id, text, agent_id, conversation_id, datapack_id=None)` | write | Overwrite memory text |
70
- | `memory_delete_by_id(scope, memory_id, agent_id, conversation_id, datapack_id=None)` | write | Delete a single memory |
71
- | `memory_delete_all(scope, agent_id, conversation_id, user_id=None, app_id=None, run_id=None, datapack_id=None)` | admin | Delete all memories for agent (destructive) |
72
- | `flush_pending_memory_candidates(scope, agent_id)` | read | Desktop-skill helper: returns an instruction payload telling the agent to scan recent user turns and `memory_add` unsaved facts. No server-side DB write. |
42
+ | Tool | Purpose |
43
+ |------|---------|
44
+ | `memory_add(text, agent_id, conversation_id, run_id=None, metadata=None, messages=None, datapack_id=None)` | Store fact/preference/entity as long-term memory |
45
+ | `memory_search(query, agent_id, conversation_id="", limit=10, datapack_id=None)` | Semantic search across memories + graph relations. `conversation_id` optional (omit or pass `""` for cross-conversation discovery). |
46
+ | `memory_get_by_id(memory_id, agent_id, conversation_id, datapack_id=None)` | Direct pgvector row lookup by UUID. Preferred over `memory_search` for exact-id verification. |
47
+ | `memory_get_all(agent_id, conversation_id, run_id=None, datapack_id=None)` | List all of the user's memories (every agent — `agent_id` does not filter) |
48
+ | `memory_update(memory_id, text, agent_id, conversation_id, datapack_id=None)` | Overwrite memory text |
49
+ | `memory_delete_by_id(memory_id, agent_id, conversation_id, datapack_id=None)` | Delete a single memory |
50
+ | `memory_delete_all(agent_id, conversation_id, run_id=None, datapack_id=None)` | Delete all memories for agent (destructive) |
51
+ | `memory_promote(conversation_id, memory_ids, agent_id=None, datapack_id=None)` | Promote private memories into the datapack's shared knowledge base (moves them + graph context out of mem0, then evicts from mem0 — one-way). Owners/maintainers only; viewers/contributors get 403. |
73
52
 
74
53
  ## Conversation Tools (6)
75
54
 
76
- | Tool | Scope | Purpose |
77
- |------|-------|---------|
78
- | `conversation_create(scope, agent_id, user_id=None, app_id=None, run_id=None, title=None, metadata=None, session_id="")` | write | Create conversation container (Langfuse session) |
79
- | `conversation_add_message(scope, conversation_id, agent_id, input, output=None, reasoning=None, metadata=None, seed=None, trace_id="")` | write | Add a message turn (Langfuse trace) |
80
- | `conversation_get(scope, conversation_id, agent_id, include_messages=False, limit=100, offset=0)` | read | Retrieve conversation, optionally with messages |
81
- | `conversation_list(scope, agent_id, conversation_id="", user_id=None, limit=20, offset=0)` | read | List conversations for agent. `conversation_id` optional (omit for browse). |
82
- | `conversation_update(scope, conversation_id, agent_id, title=None, metadata=None)` | write | Update title or metadata |
83
- | `conversation_delete(scope, conversation_id, agent_id)` | admin | Delete entire conversation (destructive) |
55
+ | Tool | Purpose |
56
+ |------|---------|
57
+ | `conversation_create(agent_id, run_id=None, title=None, metadata=None, session_id="")` | Create conversation container (Langfuse session) |
58
+ | `conversation_add_message(conversation_id, agent_id, input, output=None, reasoning=None, metadata=None, seed=None)` | Add a message turn (Langfuse trace) |
59
+ | `conversation_get(conversation_id, agent_id, include_messages=False, limit=100, offset=0)` | Retrieve conversation, optionally with messages |
60
+ | `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). |
61
+ | `conversation_update(conversation_id, agent_id, title=None, metadata=None)` | Update title or metadata |
62
+ | `conversation_delete(conversation_id, agent_id)` | Delete entire conversation (destructive) |
84
63
 
85
64
  ## Datapack Management Tools (5)
86
65
 
87
- | Tool | Scope | Purpose |
88
- |------|-------|---------|
89
- | `datapack_create(scope, name)` | write | Create new datapack |
90
- | `datapack_list(scope)` | read | List all datapacks |
91
- | `datapack_describe(scope, name, include_status=False)` | read | Describe datapack |
92
- | `datapack_update(scope, name, connection_string)` | write | Update connection string |
93
- | `datapack_delete(scope, name)` | admin | Delete datapack (irreversible) |
66
+ | Tool | Purpose |
67
+ |------|---------|
68
+ | `datapack_create(name)` | Create new datapack |
69
+ | `datapack_list()` | List all datapacks |
70
+ | `datapack_describe(datapack_id, include_status=False)` | Describe datapack by UUID |
71
+ | `datapack_update(datapack_id, name=None, description=None)` | Rename a datapack and/or update its description. Pass at least one of `name` / `description`. |
72
+ | `datapack_delete(datapack_id)` | Delete datapack by UUID (irreversible) |
73
+
74
+ ## Artifact Tools (2)
75
+
76
+ Content-addressed blob store scoped to a datapack. Files < 1 MB go inline in the DB; files ≥ 1 MB go to S3. Identity is SHA-256 — uploading the same bytes twice returns the same `content_hash`. Free-tier artifacts expire after 30 days of inactivity; pro-tier artifacts have no TTL.
77
+
78
+ | Tool | Purpose |
79
+ |------|---------|
80
+ | `artifact_put(filename, content_base64, content_type, conversation_id, datapack_id=None, agent_id=None)` | Upload a file to the datapack. Returns `{artifact_id, content_hash, filename, size_bytes, stored_in}`. Max 5 MiB (configurable via `MEKO_MAX_ARTIFACT_UPLOAD_BYTES`). |
81
+ | `artifact_get(content_hash, conversation_id, datapack_id=None, agent_id=None)` | Retrieve a file by SHA-256 hash. Small files return `content_base64` inline; large files (S3) are written to `~/.meko/artifacts/<hash>/<filename>` and `local_path` is returned. |
82
+
83
+ ## Observability Tools (1)
84
+
85
+ | Tool | Purpose |
86
+ |------|---------|
87
+ | `track_token_usage(conversation_id, name, input_tokens=0, output_tokens=0, total_tokens=None, model=None, message_id=None, datapack_id=None)` | Record an LLM-cost GENERATION observation on the conversation's trace. Primarily called by first-party Meko services (e.g. inference_gateway) that know their LLM's exact token counts. Most end-agents (Cursor, Claude Desktop) don't have those counts at the MCP call layer, so this tool is rarely useful for third-party agents. |
94
88
 
95
89
  ## Platform capabilities NOT exposed via MCP
96
90
 
@@ -98,15 +92,15 @@ Some things the Meko platform can do are not wired into the MCP tool surface tod
98
92
 
99
93
  | Capability | Where it lives | How to reach it |
100
94
  |---|---|---|
101
- | Create / list / delete **agents** within a datapack | `yugabyte/meko` API server | REST: `POST/GET/DELETE /datapacks/:name/agents` (`POST/GET/DELETE /agents/:agent` for targeted deletes), or the Meko control-plane UI |
102
- | Add / list / delete **knowledge-base sources** on a datapack | `yugabyte/meko` API server | REST: `POST/GET/DELETE /datapacks/:name/knowledge-bases`, plus `upload-url`, `upload-complete`, `create`, `status` subroutes. Also available in the Meko UI. |
103
- | Langfuse project-key generation | `yugabyte/meko` API server | REST: `POST /datapacks/:name/langfuse/project-keys` |
95
+ | Create / list / delete **agents** within a datapack | `yugabyte/meko` API server | REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (`POST/GET/DELETE /agents/:agent` for targeted deletes), or the Meko control-plane UI |
96
+ | Add / list / delete **knowledge-base sources** on a datapack | `yugabyte/meko` API server | REST: `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases`, plus `upload-url`, `upload-complete`, `create`, `status` subroutes. Also available in the Meko UI. |
97
+ | Langfuse project-key generation | `yugabyte/meko` API server | REST: `POST /datapacks/:datapack_id/langfuse/project-keys` |
104
98
  | Account / billing / tier management | Meko UI only | Not available via MCP or public REST |
105
99
 
106
100
  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.
107
101
 
108
- For knowledge-base content on cloud today, 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. The MCP ingestion tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) exist but are Free-Tier gated and rely on an S3-only worker with no user-supplied credentials — see `tools-rag-workflow.md` for the full picture. Tracked upstream as [#89](https://github.com/yugabyte/meko-mcp-server/issues/89) / MEKO-96.
102
+ 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.
109
103
 
110
104
  ## Common Parameter Patterns
111
105
 
112
- Every tool accepts `scope` as the first parameter. All DB, RAG, and memory tools accept optional `datapack_id` to target a specific datapack's database. Memory and conversation tools require `agent_id` for namespace isolation (see `tools-agent-id-conventions.md`).
106
+ Memory and KB tools accept optional `datapack_id` to target a specific datapack. `agent_id` attributes writes and is enforced only on `conversation_get` (agent-owned — a wrong value returns `agent_id_mismatch`); it does **not** filter memory reads (`memory_search`/`memory_get_all`) or `conversation_list`, which return all your agents' rows for the user. See `tools-agent-id-conventions.md`.
@@ -1,25 +1,21 @@
1
1
  # Knowledge Base / RAG workflow
2
2
 
3
- As of 2026-05-07, **knowledge-base ingestion on cloud Meko is a UI-only activity**. The MCP ingestion tools exist but are gated off on cloud and rely on an S3-only worker that has no mechanism to read user-supplied buckets. `knowledgebase_search` is the only KB tool agents can rely on today.
4
-
5
- This page tells you which tool to reach for, what's usable where, and where the current gaps are tracked.
3
+ `knowledgebase_search` is the only KB tool exposed via MCP. Index
4
+ creation and ingestion happen out of band — through the **Meko UI**
5
+ (`cloud.mekodata.ai`).
6
6
 
7
7
  ## Decision table
8
8
 
9
9
  | Situation | Use this | Why |
10
10
  |---|---|---|
11
- | Search an existing KB | `knowledgebase_search` | The one KB tool that works on cloud Free Tier and prod today |
12
- | Add documents to a KB on cloud | **Meko UI** — Datapack → Actions menu → **Add Knowledge** | File-upload dialog (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). The MCP ingestion path is not usable on cloud |
13
- | Create a new vector index (self-hosted / paid) | `knowledgebase_trigger_index_creation` | Only works when the ingestion worker has IAM access to the S3 bucket you pass |
14
- | Add a source to an existing index (self-hosted / paid) | `knowledgebase_add_source_to_index` | Same caveat as above |
15
- | Poll a build (self-hosted / paid) | `knowledgebase_check_index_status` | Gated on cloud Free Tier |
16
- | Anything that needs KB lifecycle management (list, delete, rename) | **UI** | No MCP tools for KB lifecycle |
11
+ | Search an existing KB | `knowledgebase_search` | The one KB tool exposed via MCP |
12
+ | Add documents to a KB | **Meko UI** — Datapack → Actions → **Add Knowledge** | File-upload dialog (PDF/TXT/MD/JSON/MP4, 5 MB each, 10/batch). No MCP equivalent |
13
+ | Anything else (list / delete / rename / re-index) | **UI** | No MCP tools for KB lifecycle |
17
14
 
18
15
  ## knowledgebase_search — the one you'll actually call
19
16
 
20
17
  ```
21
18
  knowledgebase_search(
22
- scope="read",
23
19
  query="natural-language question",
24
20
  agent_id="<your agent_id>",
25
21
  conversation_id="<uuid from conversation_create>",
@@ -27,60 +23,16 @@ knowledgebase_search(
27
23
  limit=10)
28
24
  ```
29
25
 
30
- Required: `scope`, `query`, `agent_id`, `conversation_id`, `datapack_id`. Unlike the memory tools, `datapack_id` has no default here — you must pass it explicitly. `agent_id` is **ignored for filtering** on this tool (KB results are team-shared on the datapack), but you still pass it — your session's value is fine.
31
-
32
- Response shape (verified 2026-05-07 against prod):
33
- ```
34
- {"results": [], "count": 0}
35
- ```
36
-
37
- On a populated KB each result carries chunk content and similarity scores. On an empty or nonexistent KB you get an empty array and `count: 0` — not an error.
38
-
39
- ## MCP ingestion tools — what actually happens when you call them
40
-
41
- This applies to `knowledgebase_trigger_index_creation` and `knowledgebase_add_source_to_index`. Understanding the two-layer architecture is the only way to predict whether a call will succeed.
42
-
43
- **MCP layer (`src/tools.py`):** takes `source_uris`, splits on `,`, passes each string to `dist_rag.create_source(<uri>)` with **zero validation**. No scheme check, no reachability probe. Returns `"build_triggered"` immediately.
44
-
45
- **Worker layer (`yugabyte-db/python/ai/rag_agent/rag_pipeline/aws_source_processor.py`):** only handles `s3://` URIs. Any other scheme raises `ValueError("Invalid source URI")` inside the worker — **async, never surfaced to the MCP caller**. The S3 crawler is instantiated with no credentials; it relies on boto3's default chain (env vars, IAM role, `~/.aws/credentials` on the worker host). So the worker can only read buckets its own AWS identity has access to.
46
-
47
- **Implication:** pointing the MCP tool at a user-owned S3 bucket from cloud will return `"build_triggered"` and silently stall at INIT forever. There is no way for the user to supply AWS credentials through the MCP tool.
48
-
49
- ## Free-Tier cloud gating (verified 2026-05-07 against `https://mcp.mekodata.ai/mcp`)
50
-
51
- | Tool | Verbatim response |
52
- |---|---|
53
- | `knowledgebase_trigger_index_creation` | `{"error": "not_available", "detail": "Vector index creation is not available on the free tier."}` |
54
- | `knowledgebase_add_source_to_index` | Same as above |
55
- | `knowledgebase_check_index_status` | `{"error": "not_available", "detail": "Index status check is not available on the free tier."}` |
56
- | `knowledgebase_search` | Works: `{"results": [], "count": 0}` |
57
-
58
- `{"error": "not_available"}` is a server-side tier block. Don't retry.
59
-
60
- ## UI ingestion (cloud Meko) — what the user sees
61
-
62
- From `cloud.mekodata.ai`:
63
-
64
- 1. Open a datapack (`/datapacks/<name>`).
65
- 2. Click **Actions** → **Add Knowledge**.
66
- 3. Drag-and-drop or browse for files. Supported: PDF, TXT, MD, JSON, MP4. Per-file limit 5 MB. Up to 10 files per batch.
67
- 4. The UI handles upload, storage, and index build. The user does not pick a bucket or provide credentials.
68
- 5. Search results from `knowledgebase_search` become available once indexing completes.
69
-
70
- If a user asks you "how do I add a document to my knowledge base?", point them at this flow. Do not suggest `knowledgebase_trigger_index_creation` with an S3 URI — on cloud that path does not work.
26
+ Required: `query`, `agent_id`, `conversation_id`, `datapack_id`.
27
+ Unlike the memory tools, `datapack_id` has no default here — you must
28
+ pass it explicitly. `agent_id` is **ignored for filtering** on this
29
+ tool (KB results are team-shared on the datapack), but you still pass
30
+ it — your session's value is fine.
71
31
 
72
- ## Tracked gaps
73
-
74
- - **Upstream GitHub**: [yugabyte/meko-mcp-server#89](https://github.com/yugabyte/meko-mcp-server/issues/89) — disable or gate KB ingestion tools on cloud until the S3 path works end-to-end; return a clearer error than "not_available"; validate schemes at MCP-call time.
75
- - **Upstream Jira**: MEKO-96 (same issue, cross-linked).
76
-
77
- When either lands, the free-tier-gate responses above will change and this page should be revisited.
78
-
79
- ## Response-shape reference (for agents that need to parse)
80
-
81
- ### knowledgebase_search
32
+ ## Response shape
82
33
 
83
34
  Populated KB:
35
+
84
36
  ```
85
37
  {
86
38
  "results": [
@@ -97,38 +49,21 @@ Populated KB:
97
49
  }
98
50
  ```
99
51
 
100
- Empty or nonexistent KB: `{"results": [], "count": 0}` (no error).
101
-
102
- ### knowledgebase_trigger_index_creation (when not gated)
103
-
104
- Success shape:
105
- ```
106
- {
107
- "source_ids": ["<uuid>", ...],
108
- "index_id": "<uuid>",
109
- "index_name": "<name>",
110
- "status": "build_triggered",
111
- "message": "N source(s) registered, index '...' initialised, and build triggered."
112
- }
113
- ```
114
-
115
- Do NOT retry this on failure. Each call creates a new index.
116
-
117
- ### knowledgebase_add_source_to_index (when not gated)
118
-
119
- The historical `r_index_name` vs `r_index_id` parameter-mismatch bug is fixed on main (`src/tools.py` resolves `index_name → index_id` via `SELECT id FROM dist_rag.vector_indexes WHERE index_name = %s` before calling the dist_rag function). If `index_name` doesn't exist you get `{"error": "index_not_found", "detail": "No vector index found with name '...'"}`.
120
-
121
- Param is `source_uri` (URI string like `s3://bucket/path/`), **not** `source_id` as older docs may claim.
52
+ Empty or nonexistent KB: `{"results": [], "count": 0}` (no error,
53
+ just an empty array).
122
54
 
123
- ### knowledgebase_check_index_status (when not gated)
55
+ ## UI ingestion — what the user sees
124
56
 
125
- Returns `pipeline_details` (per-document status) and `pipeline_stats` (aggregated). Check `completion_rate_percent` in `pipeline_stats` and `document_status` in `pipeline_details`.
126
-
127
- Stuck at INIT for >5 minutes under self-hosted usually means the worker couldn't reach the bucket — check AWS credentials on the worker host, not the MCP server.
128
-
129
- ## Prerequisites (self-hosted)
57
+ From `cloud.mekodata.ai`:
130
58
 
131
- - `dist_rag` PostgreSQL extension enabled on the target YugabyteDB database
132
- - Ingestion workers running (`yugabyte-db/python/ai/rag_agent/`)
133
- - AWS credentials on the worker host for any S3 bucket you intend to ingest from
134
- - `datapack_id` passed on every call when targeting a non-default datapack
59
+ 1. Open a datapack (`/datapacks/<name>`).
60
+ 2. Click **Actions** → **Add Knowledge**.
61
+ 3. Drag-and-drop or browse for files. Supported: PDF, TXT, MD, JSON,
62
+ MP4. Per-file limit 5 MB. Up to 10 files per batch.
63
+ 4. The UI handles upload, storage, and index build. The user does not
64
+ pick a bucket or provide credentials.
65
+ 5. Search results from `knowledgebase_search` become available once
66
+ indexing completes.
67
+
68
+ If a user asks you "how do I add a document to my knowledge base?",
69
+ point them at this flow.