@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
@@ -1,113 +1,22 @@
1
1
  # Tool Cookbook — Complete Usage Examples
2
2
 
3
- Every tool example below shows the correct parameters, expected response, and common errors. Use `scope="read"` for reads and `scope="write"` for writes — never `"all"` or any other value.
3
+ Every tool example below shows the correct parameters, expected response, and common errors.
4
4
 
5
- > **Note on `agent_id` in the examples below.** The string `"agent"` appears in these examples as a placeholder shorthand; it is NOT a required constant. Substitute **your** client's bucket: for Claude Desktop, the bare client name `claude_desktop`; for Claude Code/Cursor, `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`). For genuinely cross-project facts (user identity, global preferences) write/read with `agent_id="meko_agent"` — the common bucket the server stores empty/missing values into. See `tools-agent-id-conventions.md`.
6
- >
7
- > **Note on availability on Cloud.** The `db_*` tools and the three KB ingestion tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) return `{"error": "not_available"}` on Cloud Meko today. This cookbook keeps their examples for reference but you can't call them from a Cloud client.
8
-
9
- ---
10
-
11
- ## Database Tools
12
-
13
- ### db_summarize_database
14
-
15
- **When to use:** First thing in a session to understand what's in the database. Prefer this over writing your own `information_schema` query.
16
-
17
- ```
18
- db_summarize_database(scope="read", schema="public")
19
- ```
20
-
21
- **Response:**
22
- ```json
23
- [
24
- {
25
- "table_name": "customers",
26
- "schema": [
27
- {"column_name": "id", "data_type": "uuid"},
28
- {"column_name": "name", "data_type": "text"}
29
- ],
30
- "row_count": 1523
31
- }
32
- ]
33
- ```
34
-
35
- **With datapack:**
36
- ```
37
- db_summarize_database(scope="read", schema="public", datapack_id="dp-uuid-123")
38
- ```
39
-
40
- **Common errors:**
41
- - `Insufficient scope: 'all'` — Use `scope="read"`, not `"all"`
42
- - Empty result — The schema may not exist, try `schema="public"`
43
-
44
- ---
45
-
46
- ### db_run_read_only_query
47
-
48
- **When to use:** Any SELECT query. Always add `LIMIT` on exploratory queries.
49
-
50
- ```
51
- db_run_read_only_query(scope="read", query="SELECT id, name FROM customers LIMIT 10")
52
- ```
53
-
54
- **Response:** JSON array of row objects.
55
- ```json
56
- [{"id": "abc-123", "name": "Alice"}, {"id": "def-456", "name": "Bob"}]
57
- ```
58
-
59
- **Best practices:**
60
- - Always use `LIMIT` on unfamiliar tables to avoid flooding context
61
- - Select specific columns rather than `SELECT *` to keep responses small
62
- - For non-public schemas: `SELECT * FROM analytics."monthly_revenue" LIMIT 5`
63
- - Escape single quotes in values: `WHERE name = 'O''Brien'`
64
-
65
- **Common errors:**
66
- - `cannot execute INSERT in a read-only transaction` — Use `db_run_write_query` for writes
67
- - `permission denied for table X` — MCP user lacks access to this table (server-side config issue, not fixable via MCP)
68
- - `connection already closed` — Retry once. If persistent, the DB pool is unhealthy.
69
-
70
- ---
71
-
72
- ### db_run_write_query
73
-
74
- **When to use:** INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX.
75
-
76
- ```
77
- db_run_write_query(scope="write", query="INSERT INTO customers (id, name) VALUES ('abc-123', 'Alice')")
78
- ```
79
-
80
- **Response:**
81
- ```json
82
- {"rows_affected": 1}
83
- ```
84
-
85
- **One statement per call.** This is wrong:
86
- ```
87
- db_run_write_query(scope="write", query="CREATE TABLE a (id INT); CREATE TABLE b (id INT);")
88
- ```
89
- Split into two separate calls.
90
-
91
- **Bulk inserts:** Maximum 1000 rows per INSERT VALUES. For more, use `INSERT ... SELECT` or batch into multiple calls.
92
-
93
- **Common errors:**
94
- - `Multi-statement queries not allowed` — Send one statement per call
95
- - `DROP SCHEMA is not allowed` — See `tools-write-guardrails.md` for blocked operations
96
- - `'dict' object has no attribute 'guardrail_config'` — Known server bug in some deployments. Write operations may be unavailable.
5
+ > **Note on `agent_id` in the examples below.** The string `"agent"` appears in these examples as a placeholder shorthand; it is NOT a required constant. Substitute **your** client's value: for Claude Desktop, use `claude_desktop`; for Claude Code/Cursor, use `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`). Write genuinely cross-project facts with `agent_id="meko_agent"`. On memory reads, `agent_id` attributes the trace but does not filter results. See `tools-agent-id-conventions.md`.
97
6
 
98
7
  ---
99
8
 
100
9
  ## Memory Tools
101
10
 
102
- **Critical:** Pass your session's `agent_id` on every memory call. For Claude Desktop that's `claude_desktop` for client-personal context, or `meko_agent` for genuinely cross-project facts (user identity, global preferences). Personal writes are scoped strictly by `agent_id` — other agents won't see your writes on personal reads unless they pass the same exact value.
11
+ **Critical:** Pass your session's `agent_id` on every memory call. For Claude Desktop that's `claude_desktop` for normal attribution, or `meko_agent` when writing genuinely cross-project facts. Writes retain that attribution, while personal memory reads span all of this user's agents.
103
12
 
104
13
  ### memory_add
105
14
 
106
- **When to use:** Store facts, preferences, user profile info, org conventions, corrections, learnings. Use proactively — don't wait for the user to ask.
15
+ **When to use:** NOT for facts the user states — those are captured when you post the turn with `conversation_add_message` and the server extracts them. Reserve `memory_add` for the three cases per-turn capture can't reach: (1) the user explicitly says "remember this"; (2) a durable fact only in your output or a tool result, never in a user turn; (3) overwriting a negated/corrected fact (pair with `memory_delete_by_id`, since extraction is additive).
107
16
 
108
17
  ```
109
- memory_add(scope="write", agent_id="agent",
110
- text="User Amiram is VP of Product at YugabyteDB. Prefers concise responses.")
18
+ memory_add(agent_id="claude_desktop",
19
+ text="Remember: deploy scripts must be run from the repo root, never a subdir.")
111
20
  ```
112
21
 
113
22
  **Response:**
@@ -117,14 +26,13 @@ memory_add(scope="write", agent_id="agent",
117
26
 
118
27
  **With user scoping:**
119
28
  ```
120
- memory_add(scope="write", agent_id="agent", user_id="amiram",
29
+ memory_add(agent_id="agent", user_id="amiram",
121
30
  text="Prefers Python for backend, Go for infrastructure.")
122
31
  ```
123
32
 
124
33
  **What NOT to store via memory_add:**
125
- - CSV rows or tabular data (use `db_run_write_query` instead)
126
34
  - Full conversations (use `conversation_create` + `conversation_add_message`)
127
- - Large documents (use knowledge base ingestion)
35
+ - Large documents (use the UI's Datapack → Actions → Add Knowledge upload flow)
128
36
 
129
37
  **Common errors:**
130
38
  - `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.
@@ -136,8 +44,10 @@ memory_add(scope="write", agent_id="agent", user_id="amiram",
136
44
 
137
45
  **When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
138
46
 
47
+ **Cross-conversation discovery.** `memory_search` returns hits across every stored conversation for the `(datapack_id, user_id)` pair, across all agents (the tool intentionally passes `meko_agent_id=None` to mem0, so the `agent_id` argument scopes the trace but does not filter results). When a hit references an interesting conversation, follow up with `conversation_list` to browse the associated threads and `conversation_get` to read a specific one — the memory hit's `meko_conversation_id` field is the id to fetch. Pass `run_id` on the search itself to narrow to a single conversation up front.
48
+
139
49
  ```
140
- memory_search(scope="read", query="What programming language does the team use?", agent_id="agent")
50
+ memory_search(query="What programming language does the team use?", agent_id="agent")
141
51
  ```
142
52
 
143
53
  **Response:**
@@ -147,7 +57,7 @@ memory_search(scope="read", query="What programming language does the team use?"
147
57
 
148
58
  **With limit:**
149
59
  ```
150
- memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
60
+ memory_search(query="user preferences", agent_id="agent", limit=5)
151
61
  ```
152
62
 
153
63
  ---
@@ -157,12 +67,12 @@ memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
157
67
  **When to use:** List everything stored for an agent. Useful at session start to load context.
158
68
 
159
69
  ```
160
- memory_get_all(scope="read", agent_id="agent")
70
+ memory_get_all(agent_id="agent")
161
71
  ```
162
72
 
163
73
  **With user scoping:**
164
74
  ```
165
- memory_get_all(scope="read", agent_id="agent", user_id="amiram")
75
+ memory_get_all(agent_id="agent", user_id="amiram")
166
76
  ```
167
77
 
168
78
  ---
@@ -170,7 +80,7 @@ memory_get_all(scope="read", agent_id="agent", user_id="amiram")
170
80
  ### memory_get_by_id
171
81
 
172
82
  ```
173
- memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
83
+ memory_get_by_id(memory_id="mem-uuid-123", agent_id="agent")
174
84
  ```
175
85
 
176
86
  ---
@@ -180,7 +90,7 @@ memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
180
90
  **When to use:** Overwrite a specific memory's text. Requires the memory UUID.
181
91
 
182
92
  ```
183
- memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
93
+ memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
184
94
  ```
185
95
 
186
96
  ---
@@ -188,19 +98,39 @@ memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses
188
98
  ### memory_delete_by_id
189
99
 
190
100
  ```
191
- memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="agent")
101
+ memory_delete_by_id(memory_id="mem-uuid-123", agent_id="agent")
192
102
  ```
193
103
 
194
104
  ---
195
105
 
196
106
  ### memory_delete_all
197
107
 
198
- **Destructive. Requires admin scope.** Deletes all memories for the agent.
108
+ **Destructive.** Deletes all memories for the agent. For removing a single memory, prefer `memory_delete_by_id` — `memory_delete_all` wipes the entire agent scope in the datapack.
109
+
110
+ ```
111
+ memory_delete_all(agent_id="agent")
112
+ ```
113
+
114
+ ---
115
+
116
+ ### memory_promote
117
+
118
+ **When to use:** The user asks to share or promote specific memories to the team's knowledge base — the MCP counterpart of the Cloud UI's "Promote to Knowledge" flow. One-way: promoted memories become team-visible via `knowledgebase_search` and are evicted from the private memory store. Requires the caller to be a datapack **owner or maintainer**; viewers and contributors get a 403 permission error.
199
119
 
200
120
  ```
201
- memory_delete_all(scope="admin", agent_id="agent")
121
+ memory_promote(memory_ids=["mem-uuid-123", "mem-uuid-456"],
122
+ agent_id="claude_desktop", conversation_id="<uuid from conversation_create>")
202
123
  ```
203
124
 
125
+ **Response:**
126
+ ```json
127
+ {"inserted_ids": ["mem-uuid-123"], "updated_ids": ["mem-uuid-456"], "not_found_ids": []}
128
+ ```
129
+
130
+ Get exact UUIDs from the `id` field of `memory_search` / `memory_get_all` results; never use graph relation IDs. Before the call, show the user each exact memory and UUID, explain that promotion is team-visible, one-way, and evicts the private records, then obtain explicit confirmation for those candidates. Pass the active `conversation_id` and intended `agent_id` / `datapack_id`; on legacy schemas that expose `scope`, use `write`, not `admin`.
131
+
132
+ On 403, authentication, or permission failure, report the error and stop — do not escalate scope, change datapacks, or alter identity. After a successful call, `knowledgebase_search` may verify shared visibility, but it is not a rollback mechanism.
133
+
204
134
  ---
205
135
 
206
136
  ## Conversation Tools
@@ -210,7 +140,7 @@ memory_delete_all(scope="admin", agent_id="agent")
210
140
  **When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
211
141
 
212
142
  ```
213
- conversation_create(scope="write", agent_id="agent", user_id="amiram",
143
+ conversation_create(agent_id="agent", user_id="amiram",
214
144
  title="Debugging the auth middleware")
215
145
  ```
216
146
 
@@ -225,8 +155,10 @@ conversation_create(scope="write", agent_id="agent", user_id="amiram",
225
155
 
226
156
  **When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
227
157
 
158
+ Leave `index_for_search` at its default (`False`). Conversation-cache embedding is currently a WorkbenchLM-only feature — the inference gateway opts in on its own turns; agent-harness conversations should not opt in.
159
+
228
160
  ```
229
- conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
161
+ conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
230
162
  input="Why is the auth middleware returning 401?",
231
163
  output="The token validation is checking the wrong issuer claim...",
232
164
  reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
@@ -234,7 +166,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
234
166
 
235
167
  **With dedup seed (use when client hooks also write to Langfuse):**
236
168
  ```
237
- conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
169
+ conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
238
170
  input="Why is the auth middleware returning 401?",
239
171
  output="The token validation is checking the wrong issuer claim...",
240
172
  seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
@@ -245,7 +177,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
245
177
  ### conversation_get
246
178
 
247
179
  ```
248
- conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent",
180
+ conversation_get(conversation_id="conv-uuid-123", agent_id="agent",
249
181
  include_messages=True, limit=50)
250
182
  ```
251
183
 
@@ -253,8 +185,12 @@ conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent"
253
185
 
254
186
  ### conversation_list
255
187
 
188
+ Target the datapack by `datapack_id` (UUID). It's optional — omit it to use the
189
+ pinned/default datapack, or pass the pinned `datapack_id`. Use `datapack_list`
190
+ to look up the id.
191
+
256
192
  ```
257
- conversation_list(scope="read", agent_id="agent", limit=20)
193
+ conversation_list(datapack_id="<datapack-uuid>", agent_id="agent", limit=20)
258
194
  ```
259
195
 
260
196
  ---
@@ -262,7 +198,7 @@ conversation_list(scope="read", agent_id="agent", limit=20)
262
198
  ### conversation_update
263
199
 
264
200
  ```
265
- conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
201
+ conversation_update(conversation_id="conv-uuid-123", agent_id="agent",
266
202
  title="Resolved: Auth middleware issuer mismatch")
267
203
  ```
268
204
 
@@ -270,19 +206,19 @@ conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="ag
270
206
 
271
207
  ### conversation_delete
272
208
 
273
- **Destructive. Requires admin scope.**
209
+ **Destructive.**
274
210
 
275
211
  ```
276
- conversation_delete(scope="admin", conversation_id="conv-uuid-123", agent_id="agent")
212
+ conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
277
213
  ```
278
214
 
279
215
  ---
280
216
 
281
- ## RAG / Knowledge Base Tools
217
+ ## Knowledge Base Tools
282
218
 
283
- **On cloud Meko today, 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). The three ingestion-side MCP tools below are Free-Tier-gated on cloud and brittle even when ungated. `knowledgebase_search` is the one KB tool to reach for.
219
+ **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). `knowledgebase_search` is the one KB tool exposed via MCP.
284
220
 
285
- See `tools-rag-workflow.md` for the decision table and why.
221
+ See `tools-rag-workflow.md` for the decision table.
286
222
 
287
223
  ### knowledgebase_search
288
224
 
@@ -290,7 +226,6 @@ See `tools-rag-workflow.md` for the decision table and why.
290
226
 
291
227
  ```
292
228
  knowledgebase_search(
293
- scope="read",
294
229
  query="natural-language question",
295
230
  agent_id="agent",
296
231
  conversation_id="<uuid from conversation_create>",
@@ -309,73 +244,80 @@ Populated KBs return results with chunk content and similarity scores. An empty/
309
244
 
310
245
  ---
311
246
 
312
- ### knowledgebase_trigger_index_creation
247
+ ## Artifact Tools
313
248
 
314
- **When to use:** Self-hosted deployments where the ingestion worker has IAM access to the target S3 bucket. **Not available on cloud Free Tier** (returns `{"error": "not_available", "detail": "Vector index creation is not available on the free tier."}`).
249
+ ### artifact_put
250
+
251
+ **When to use:** An agent has generated a file (report, CSV, PDF, code output, image) and wants to persist it in Meko for later retrieval or cross-agent sharing. Files < 1 MB are stored inline in the DB; files ≥ 1 MB go to the datapack's S3 bucket. Idempotent — uploading the same bytes twice returns the same `content_hash`.
315
252
 
316
253
  ```
317
- knowledgebase_trigger_index_creation(
318
- scope="write",
254
+ artifact_put(
255
+ filename="analysis_report.csv",
256
+ content_type="text/csv",
257
+ content_base64="<base64-encoded bytes>",
319
258
  conversation_id="<uuid from conversation_create>",
320
- source_uris="s3://my-bucket/docs/,s3://my-bucket/reports/",
321
- index_name="company_docs")
259
+ agent_id="claude_desktop"
260
+ )
322
261
  ```
323
262
 
324
- **Optional parameters:**
325
- - `ai_provider="OPENAI"` (default)
326
- - `embedding_model="text-embedding-3-large"` (default)
327
- - `embedding_dimensions=1536` (default)
328
- - `chunk_size=1024` (default)
329
- - `chunk_overlap=256` (default)
330
- - `datapack_id=None`
331
-
332
- **Success response:**
263
+ **Response:**
333
264
  ```json
334
- {"source_ids": ["<uuid>", ...], "index_id": "<uuid>", "index_name": "company_docs",
335
- "status": "build_triggered", "message": "... registered, index '...' initialised, and build triggered."}
265
+ {
266
+ "artifact_id": "550e8400-e29b-41d4-a716-446655440000",
267
+ "content_hash": "a665a45920422f9d417e4867efdc4fb8a5f1f89ea5b8440b1ad4c4c6b8a7e4d3",
268
+ "filename": "analysis_report.csv",
269
+ "content_type": "text/csv",
270
+ "size_bytes": 4096,
271
+ "stored_in": "db"
272
+ }
336
273
  ```
337
274
 
338
- **Critical caveats:**
339
- - URIs must start with `s3://`. The worker (`aws_source_processor.py:86-117`) rejects any other scheme with `ValueError("Invalid source URI")` — async, not surfaced through the MCP response.
340
- - The worker uses the boto3 default credential chain (env vars, IAM role, `~/.aws/credentials` on the worker host). There is no way for the user to pass AWS credentials through the MCP tool. If the worker's identity can't read the bucket, the build stalls at INIT.
341
- - Each call creates a new index. Do NOT retry on failure — you'll get duplicate indexes.
342
- - Tracked as a gap: [yugabyte/meko-mcp-server#89](https://github.com/yugabyte/meko-mcp-server/issues/89) / MEKO-96.
275
+ Save the `content_hash` — it's the retrieval key for `artifact_get`.
276
+
277
+ **Common errors:**
278
+ - `invalid_base64` — `content_base64` is not valid base64.
279
+ - `artifact_too_large` — file exceeds 5 MiB (default). Set `MEKO_MAX_ARTIFACT_UPLOAD_BYTES` to raise the limit.
343
280
 
344
281
  ---
345
282
 
346
- ### knowledgebase_check_index_status
283
+ ### artifact_get
347
284
 
348
- **When to use:** Poll a self-hosted build for completion. **Not available on cloud Free Tier** (returns `{"error": "not_available"}`).
285
+ **When to use:** Retrieve a file previously uploaded with `artifact_put`.
349
286
 
287
+ **Small files (< 1 MB) — content returned inline:**
350
288
  ```
351
- knowledgebase_check_index_status(
352
- scope="read",
289
+ artifact_get(
290
+ content_hash="a665a45920422f9d417e4867efdc4fb8a5f1f89ea5b8440b1ad4c4c6b8a7e4d3",
353
291
  conversation_id="<uuid from conversation_create>",
354
- index_name="company_docs",
355
- datapack_id=None)
292
+ agent_id="claude_desktop"
293
+ )
356
294
  ```
357
295
 
358
- Check `completion_rate_percent` in `pipeline_stats` and `document_status` in `pipeline_details`. If documents stay at `INIT` for >5 minutes, the worker probably can't reach the bucket. Stop polling after 3 consecutive no-progress checks.
359
-
360
- ---
361
-
362
- ### knowledgebase_add_source_to_index
363
-
364
- **When to use:** Grow an existing index with a new source URI (self-hosted / paid). **Not available on cloud Free Tier** (same "Vector index creation is not available" gate as `trigger_index_creation`).
365
-
366
- ```
367
- knowledgebase_add_source_to_index(
368
- scope="write",
369
- conversation_id="<uuid from conversation_create>",
370
- index_name="company_docs",
371
- source_uri="s3://my-bucket/new-docs/")
296
+ **Response (inline):**
297
+ ```json
298
+ {
299
+ "content_hash": "a665a45920422f9d417e4867efdc4fb8...",
300
+ "filename": "analysis_report.csv",
301
+ "stored_in": "db",
302
+ "content_base64": "<base64-encoded bytes>"
303
+ }
372
304
  ```
373
305
 
374
- Param is **`source_uri`** (URI string), not `source_id` — older docs had this wrong.
306
+ **Large files (≥ 1 MB) — written to local disk:**
307
+ ```json
308
+ {
309
+ "content_hash": "a665a45920422f9d417e4867efdc4fb8...",
310
+ "filename": "dataset.parquet",
311
+ "stored_in": "s3",
312
+ "local_path": "/Users/you/.meko/artifacts/a665a4.../dataset.parquet"
313
+ }
314
+ ```
375
315
 
376
- The historical `r_index_name` vs `r_index_id` parameter-mismatch bug (reported in 2026-03) is **fixed** on main. The tool now resolves `index_name → index_id` internally via `SELECT id FROM dist_rag.vector_indexes WHERE index_name = %s` before calling the dist_rag function. If the name doesn't exist you get `{"error": "index_not_found", "detail": "No vector index found with name '...'"}`.
316
+ For large files use `local_path` to read the file. S3 URLs are never exposed.
377
317
 
378
- Same S3-only / worker-credentials caveats as `trigger_index_creation` apply.
318
+ **Common errors:**
319
+ - `ARTIFACT_NOT_FOUND` — no artifact with that hash in this datapack.
320
+ - `ARTIFACT_EXPIRED` — free-tier TTL has elapsed (30 days of no access).
379
321
 
380
322
  ---
381
323
 
@@ -384,23 +326,27 @@ Same S3-only / worker-credentials caveats as `trigger_index_creation` apply.
384
326
  ### datapack_create / datapack_list / datapack_describe
385
327
 
386
328
  ```
387
- datapack_create(scope="write", name="analytics_prod")
388
- datapack_list(scope="read")
389
- datapack_describe(scope="read", name="analytics_prod", include_status=True)
329
+ datapack_create(name="analytics_prod")
330
+ datapack_list() # returns datapack_id for each datapack
331
+ datapack_describe(datapack_id="<uuid>", include_status=True)
390
332
  ```
391
333
 
392
334
  ### datapack_update / datapack_delete
393
335
 
336
+ `datapack_update` renames or edits a datapack's description. At least one of `name` / `description` must be provided (or the tool returns `nothing_to_update`). The server refuses to rename `meko_default_datapack` — the error is `"meko_default_datapack cannot be renamed"`. Passing `description=""` does NOT clear an existing description.
337
+
394
338
  ```
395
- datapack_update(scope="write", name="analytics_prod", connection_string="postgresql://...")
396
- datapack_delete(scope="admin", name="analytics_prod") # Irreversible!
339
+ datapack_update(datapack_id="<uuid>", name="renamed-datapack")
340
+ datapack_update(datapack_id="<uuid>", description="new description")
341
+ datapack_update(datapack_id="<uuid>", name="x", description="y")
342
+ datapack_delete(datapack_id="<uuid>") # Irreversible!
397
343
  ```
398
344
 
399
345
  ### Agent and knowledge-base management (NOT MCP — control-plane only)
400
346
 
401
347
  Agent and KB lifecycle does not ship as MCP tools. If the user asks to create/list/delete agents or KB sources, don't invent a tool call — point them at the control plane:
402
348
 
403
- - REST: `POST/GET/DELETE /datapacks/:name/agents` (agents), `POST/GET/DELETE /datapacks/:name/knowledge-bases` (KB sources).
404
- - Or the Meko UI at `app.mekodev.com` → Datapacks → agents / knowledge-bases.
349
+ - REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (agents), `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases` (KB sources).
350
+ - Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
405
351
 
406
- To build a RAG index from inside a session (which IS MCP-exposed), use `knowledgebase_trigger_index_creation` / `knowledgebase_add_source_to_index` / `knowledgebase_check_index_status` — those operate on `dist_rag` tables inside the datapack's database.
352
+ 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` — see `tools-rag-workflow.md`.
@@ -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,32 @@ 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
+ ## Activation is model-judged on Desktop (no hooks)
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
+ Claude Desktop has no lifecycle hooks, so this skill activates only when the model judges it relevant from the skill's `description`. Reliable triggers: recall questions ("what do you know about me"), explicit save requests ("remember this"), and mentions of memory/Meko/datapacks. **Best-effort** triggers: task-shaped prompts where a durable fact appears only in passing ("I'm evaluating pnpm; I already use Turborepo") — the skill may not fire and the turn goes uncaptured. Also, when the model resolves a tool directly via tool search it may call `memory_add`/`memory_search` without reading this skill at all.
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.
53
+ The skill description is tuned to its 1024-char ceiling; broadening it further does not close the task-shaped-prompt gap (empirically confirmed in Phase-9 testing). Mitigations, in order of leverage:
56
54
 
57
- ## Currently broken tools
55
+ 1. **Personal-preferences snippet** (always-on) — paste the snippet from the Desktop setup README's "Make Desktop proactive" step into Claude's profile preferences; it is injected into every conversation regardless of prompt shape. This is the only true fix for task-shaped misses.
56
+ 2. **Server-side guidance** — the `agent_id` tool docstrings and the server's connect-time instructions name `claude_desktop` as this client's bucket, so even a skill-less tool-search call avoids the wrong-bucket (`claude_code`) write.
57
+ 3. Nothing is lost when the *user* explicitly recalls or saves — only passive capture of in-passing facts is best-effort.
58
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.
59
+ ## No semantic search over conversation content
60
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.
61
+ 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`.
62
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.
63
+ 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.