@yugabytedb/meko-mcp 1.0.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +242 -44
- package/assets/hooks-handlers/before-submit-prompt.sh +44 -0
- package/assets/hooks-handlers/cursor-session-start.sh +42 -0
- package/assets/hooks-handlers/lib/capture.js +457 -107
- package/assets/hooks-handlers/lib/package.json +1 -0
- package/assets/hooks-handlers/test_single_conversation.sh +1 -1
- package/assets/scripts/package-desktop-skill.sh +36 -0
- package/assets/skills/meko-mcp-tools/SKILL.md +167 -53
- package/assets/skills/meko-mcp-tools/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +84 -22
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +89 -56
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +15 -7
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +17 -9
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +94 -5
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +52 -37
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +108 -37
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +6 -10
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +30 -18
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +55 -69
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +251 -0
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +150 -0
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +24 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +99 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +406 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +69 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +217 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +112 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +134 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +75 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +155 -0
- package/bin/create-meko-setup.mjs +151 -22
- package/lib/clients/claude-code.mjs +378 -68
- package/lib/clients/claude-desktop.mjs +45 -8
- package/lib/clients/codex.mjs +1209 -0
- package/lib/clients/common.mjs +223 -1
- package/lib/clients/cursor.mjs +118 -13
- package/lib/clients/index.mjs +2 -0
- package/lib/config.mjs +56 -0
- package/lib/detect.mjs +52 -44
- package/lib/installer.mjs +11 -4
- package/lib/mcp-transport.mjs +61 -2
- package/lib/migrate/adapters/memory-md.mjs +13 -6
- package/lib/migrate/datapack.mjs +167 -0
- package/lib/migrate/id.mjs +127 -9
- package/lib/migrate/orchestrator.mjs +68 -10
- package/lib/migrate.mjs +346 -3
- package/lib/prompt.mjs +22 -4
- package/lib/validate.mjs +313 -9
- package/lib/version-check.mjs +178 -0
- package/package.json +2 -1
- package/scripts/bundle-assets.mjs +8 -0
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
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.
|
|
4
4
|
|
|
5
|
-
> **Note on `agent_id` in the examples below.**
|
|
5
|
+
> **Note on `agent_id` in the examples below.** Where you see `agent_id="agent"` in an example, substitute **your** session's `agent_id` — the value the SessionStart hook injected into `additionalContext`. For Claude Code that's `claude_code:<repo-basename>` (e.g. `claude_code:meko-mcp-server`); for Cursor, `cursor:<repo-basename>`; for Claude Desktop, the bare client name `claude_desktop`. 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.
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
@@ -97,14 +99,14 @@ Split into two separate calls.
|
|
|
97
99
|
|
|
98
100
|
## Memory Tools
|
|
99
101
|
|
|
100
|
-
**Critical:** `agent_id`
|
|
102
|
+
**Critical:** Pass your session's `agent_id` on every memory call (the value from the SessionStart `additionalContext`, e.g. `claude_code:meko-mcp-server`). 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. For genuinely cross-project facts, write with `agent_id="meko_agent"` so any agent can pick them up.
|
|
101
103
|
|
|
102
104
|
### memory_add
|
|
103
105
|
|
|
104
106
|
**When to use:** Store facts, preferences, user profile info, org conventions, corrections, learnings. Use proactively — don't wait for the user to ask.
|
|
105
107
|
|
|
106
108
|
```
|
|
107
|
-
memory_add(scope="write", agent_id="
|
|
109
|
+
memory_add(scope="write", agent_id="agent",
|
|
108
110
|
text="User Amiram is VP of Product at YugabyteDB. Prefers concise responses.")
|
|
109
111
|
```
|
|
110
112
|
|
|
@@ -115,7 +117,7 @@ memory_add(scope="write", agent_id="claude_code",
|
|
|
115
117
|
|
|
116
118
|
**With user scoping:**
|
|
117
119
|
```
|
|
118
|
-
memory_add(scope="write", agent_id="
|
|
120
|
+
memory_add(scope="write", agent_id="agent", user_id="amiram",
|
|
119
121
|
text="Prefers Python for backend, Go for infrastructure.")
|
|
120
122
|
```
|
|
121
123
|
|
|
@@ -125,7 +127,7 @@ memory_add(scope="write", agent_id="claude_code", user_id="amiram",
|
|
|
125
127
|
- Large documents (use knowledge base ingestion)
|
|
126
128
|
|
|
127
129
|
**Common errors:**
|
|
128
|
-
- `syntax error at or near "-"` —
|
|
130
|
+
- `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.
|
|
129
131
|
- `connection already closed` — Retry once. If it fails again, the memory subsystem is down.
|
|
130
132
|
|
|
131
133
|
---
|
|
@@ -135,7 +137,7 @@ memory_add(scope="write", agent_id="claude_code", user_id="amiram",
|
|
|
135
137
|
**When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
|
|
136
138
|
|
|
137
139
|
```
|
|
138
|
-
memory_search(scope="read", query="What programming language does the team use?", agent_id="
|
|
140
|
+
memory_search(scope="read", query="What programming language does the team use?", agent_id="agent")
|
|
139
141
|
```
|
|
140
142
|
|
|
141
143
|
**Response:**
|
|
@@ -145,7 +147,7 @@ memory_search(scope="read", query="What programming language does the team use?"
|
|
|
145
147
|
|
|
146
148
|
**With limit:**
|
|
147
149
|
```
|
|
148
|
-
memory_search(scope="read", query="user preferences", agent_id="
|
|
150
|
+
memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
|
|
149
151
|
```
|
|
150
152
|
|
|
151
153
|
---
|
|
@@ -155,12 +157,12 @@ memory_search(scope="read", query="user preferences", agent_id="claude_code", li
|
|
|
155
157
|
**When to use:** List everything stored for an agent. Useful at session start to load context.
|
|
156
158
|
|
|
157
159
|
```
|
|
158
|
-
memory_get_all(scope="read", agent_id="
|
|
160
|
+
memory_get_all(scope="read", agent_id="agent")
|
|
159
161
|
```
|
|
160
162
|
|
|
161
163
|
**With user scoping:**
|
|
162
164
|
```
|
|
163
|
-
memory_get_all(scope="read", agent_id="
|
|
165
|
+
memory_get_all(scope="read", agent_id="agent", user_id="amiram")
|
|
164
166
|
```
|
|
165
167
|
|
|
166
168
|
---
|
|
@@ -168,7 +170,7 @@ memory_get_all(scope="read", agent_id="claude_code", user_id="amiram")
|
|
|
168
170
|
### memory_get_by_id
|
|
169
171
|
|
|
170
172
|
```
|
|
171
|
-
memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="
|
|
173
|
+
memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
|
|
172
174
|
```
|
|
173
175
|
|
|
174
176
|
---
|
|
@@ -178,7 +180,7 @@ memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="claude_code")
|
|
|
178
180
|
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
179
181
|
|
|
180
182
|
```
|
|
181
|
-
memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="
|
|
183
|
+
memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
|
|
182
184
|
```
|
|
183
185
|
|
|
184
186
|
---
|
|
@@ -186,7 +188,7 @@ memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses
|
|
|
186
188
|
### memory_delete_by_id
|
|
187
189
|
|
|
188
190
|
```
|
|
189
|
-
memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="
|
|
191
|
+
memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="agent")
|
|
190
192
|
```
|
|
191
193
|
|
|
192
194
|
---
|
|
@@ -196,7 +198,7 @@ memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="claude_co
|
|
|
196
198
|
**Destructive. Requires admin scope.** Deletes all memories for the agent.
|
|
197
199
|
|
|
198
200
|
```
|
|
199
|
-
memory_delete_all(scope="admin", agent_id="
|
|
201
|
+
memory_delete_all(scope="admin", agent_id="agent")
|
|
200
202
|
```
|
|
201
203
|
|
|
202
204
|
---
|
|
@@ -208,7 +210,7 @@ memory_delete_all(scope="admin", agent_id="claude_code")
|
|
|
208
210
|
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
209
211
|
|
|
210
212
|
```
|
|
211
|
-
conversation_create(scope="write", agent_id="
|
|
213
|
+
conversation_create(scope="write", agent_id="agent", user_id="amiram",
|
|
212
214
|
title="Debugging the auth middleware")
|
|
213
215
|
```
|
|
214
216
|
|
|
@@ -224,7 +226,7 @@ conversation_create(scope="write", agent_id="claude_code", user_id="amiram",
|
|
|
224
226
|
**When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
|
|
225
227
|
|
|
226
228
|
```
|
|
227
|
-
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="
|
|
229
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
228
230
|
input="Why is the auth middleware returning 401?",
|
|
229
231
|
output="The token validation is checking the wrong issuer claim...",
|
|
230
232
|
reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
|
|
@@ -232,10 +234,10 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
|
|
|
232
234
|
|
|
233
235
|
**With dedup seed (use when client hooks also write to Langfuse):**
|
|
234
236
|
```
|
|
235
|
-
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="
|
|
237
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
236
238
|
input="Why is the auth middleware returning 401?",
|
|
237
239
|
output="The token validation is checking the wrong issuer claim...",
|
|
238
|
-
seed="conv-uuid-123:
|
|
240
|
+
seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
|
|
239
241
|
```
|
|
240
242
|
|
|
241
243
|
---
|
|
@@ -243,7 +245,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
|
|
|
243
245
|
### conversation_get
|
|
244
246
|
|
|
245
247
|
```
|
|
246
|
-
conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="
|
|
248
|
+
conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent",
|
|
247
249
|
include_messages=True, limit=50)
|
|
248
250
|
```
|
|
249
251
|
|
|
@@ -252,7 +254,7 @@ conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="claude
|
|
|
252
254
|
### conversation_list
|
|
253
255
|
|
|
254
256
|
```
|
|
255
|
-
conversation_list(scope="read", agent_id="
|
|
257
|
+
conversation_list(scope="read", agent_id="agent", limit=20)
|
|
256
258
|
```
|
|
257
259
|
|
|
258
260
|
---
|
|
@@ -260,48 +262,65 @@ conversation_list(scope="read", agent_id="claude_code", limit=20)
|
|
|
260
262
|
### conversation_update
|
|
261
263
|
|
|
262
264
|
```
|
|
263
|
-
conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="
|
|
265
|
+
conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
264
266
|
title="Resolved: Auth middleware issuer mismatch")
|
|
265
267
|
```
|
|
266
268
|
|
|
267
269
|
---
|
|
268
270
|
|
|
269
|
-
###
|
|
271
|
+
### conversation_delete
|
|
272
|
+
|
|
273
|
+
**Destructive. Requires admin scope.**
|
|
270
274
|
|
|
271
275
|
```
|
|
272
|
-
|
|
273
|
-
agent_id="claude_code", trace_id="trace-uuid-456")
|
|
276
|
+
conversation_delete(scope="admin", conversation_id="conv-uuid-123", agent_id="agent")
|
|
274
277
|
```
|
|
275
278
|
|
|
276
279
|
---
|
|
277
280
|
|
|
278
|
-
|
|
281
|
+
## RAG / Knowledge Base Tools
|
|
279
282
|
|
|
280
|
-
**
|
|
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.
|
|
284
|
+
|
|
285
|
+
See `tools-rag-workflow.md` for the decision table and why.
|
|
286
|
+
|
|
287
|
+
### knowledgebase_search
|
|
288
|
+
|
|
289
|
+
**When to use:** Retrieve chunks from a populated KB. Works on cloud today.
|
|
281
290
|
|
|
282
291
|
```
|
|
283
|
-
|
|
292
|
+
knowledgebase_search(
|
|
293
|
+
scope="read",
|
|
294
|
+
query="natural-language question",
|
|
295
|
+
agent_id="agent",
|
|
296
|
+
conversation_id="<uuid from conversation_create>",
|
|
297
|
+
datapack_id="<datapack UUID — REQUIRED here, no default>",
|
|
298
|
+
limit=10)
|
|
284
299
|
```
|
|
285
300
|
|
|
286
|
-
|
|
301
|
+
Unlike memory tools, `datapack_id` has no default — you must pass it explicitly.
|
|
287
302
|
|
|
288
|
-
|
|
303
|
+
**Response (empty KB, verified 2026-05-07):**
|
|
304
|
+
```json
|
|
305
|
+
{"results": [], "count": 0}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Populated KBs return results with chunk content and similarity scores. An empty/nonexistent KB is not an error — just `count: 0`.
|
|
309
|
+
|
|
310
|
+
---
|
|
289
311
|
|
|
290
312
|
### knowledgebase_trigger_index_creation
|
|
291
313
|
|
|
292
|
-
**When to use:**
|
|
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."}`).
|
|
293
315
|
|
|
294
316
|
```
|
|
295
|
-
knowledgebase_trigger_index_creation(
|
|
317
|
+
knowledgebase_trigger_index_creation(
|
|
318
|
+
scope="write",
|
|
319
|
+
conversation_id="<uuid from conversation_create>",
|
|
296
320
|
source_uris="s3://my-bucket/docs/,s3://my-bucket/reports/",
|
|
297
321
|
index_name="company_docs")
|
|
298
322
|
```
|
|
299
323
|
|
|
300
|
-
**Response:**
|
|
301
|
-
```json
|
|
302
|
-
{"source_ids": ["src-uuid-1", "src-uuid-2"], "index_name": "company_docs", "status": "build_triggered"}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
324
|
**Optional parameters:**
|
|
306
325
|
- `ai_provider="OPENAI"` (default)
|
|
307
326
|
- `embedding_model="text-embedding-3-large"` (default)
|
|
@@ -310,31 +329,54 @@ knowledgebase_trigger_index_creation(scope="write",
|
|
|
310
329
|
- `chunk_overlap=256` (default)
|
|
311
330
|
- `datapack_id=None`
|
|
312
331
|
|
|
313
|
-
**
|
|
332
|
+
**Success response:**
|
|
333
|
+
```json
|
|
334
|
+
{"source_ids": ["<uuid>", ...], "index_id": "<uuid>", "index_name": "company_docs",
|
|
335
|
+
"status": "build_triggered", "message": "... registered, index '...' initialised, and build triggered."}
|
|
336
|
+
```
|
|
337
|
+
|
|
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.
|
|
314
343
|
|
|
315
344
|
---
|
|
316
345
|
|
|
317
346
|
### knowledgebase_check_index_status
|
|
318
347
|
|
|
319
|
-
**When to use:** Poll
|
|
348
|
+
**When to use:** Poll a self-hosted build for completion. **Not available on cloud Free Tier** (returns `{"error": "not_available"}`).
|
|
320
349
|
|
|
321
350
|
```
|
|
322
|
-
knowledgebase_check_index_status(
|
|
351
|
+
knowledgebase_check_index_status(
|
|
352
|
+
scope="read",
|
|
353
|
+
conversation_id="<uuid from conversation_create>",
|
|
354
|
+
index_name="company_docs",
|
|
355
|
+
datapack_id=None)
|
|
323
356
|
```
|
|
324
357
|
|
|
325
|
-
|
|
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.
|
|
326
359
|
|
|
327
360
|
---
|
|
328
361
|
|
|
329
362
|
### knowledgebase_add_source_to_index
|
|
330
363
|
|
|
331
|
-
**
|
|
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`).
|
|
332
365
|
|
|
333
366
|
```
|
|
334
|
-
knowledgebase_add_source_to_index(
|
|
335
|
-
|
|
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/")
|
|
336
372
|
```
|
|
337
373
|
|
|
374
|
+
Param is **`source_uri`** (URI string), not `source_id` — older docs had this wrong.
|
|
375
|
+
|
|
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 '...'"}`.
|
|
377
|
+
|
|
378
|
+
Same S3-only / worker-credentials caveats as `trigger_index_creation` apply.
|
|
379
|
+
|
|
338
380
|
---
|
|
339
381
|
|
|
340
382
|
## Datapack Management Tools
|
|
@@ -354,20 +396,11 @@ datapack_update(scope="write", name="analytics_prod", connection_string="postgre
|
|
|
354
396
|
datapack_delete(scope="admin", name="analytics_prod") # Irreversible!
|
|
355
397
|
```
|
|
356
398
|
|
|
357
|
-
### Agent management
|
|
399
|
+
### Agent and knowledge-base management (NOT MCP — control-plane only)
|
|
358
400
|
|
|
359
|
-
|
|
360
|
-
datapack_create_agent(scope="write", datapack_name="analytics_prod", agent_name="analytics_bot")
|
|
361
|
-
datapack_list_agents(scope="read", datapack_name="analytics_prod")
|
|
362
|
-
datapack_delete_agent(scope="admin", datapack_name="analytics_prod", agent_name="analytics_bot")
|
|
363
|
-
```
|
|
401
|
+
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:
|
|
364
402
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
```
|
|
368
|
-
datapack_add_knowledge_base(scope="write", datapack_name="analytics_prod", url="s3://data/reports/")
|
|
369
|
-
datapack_list_knowledge_bases(scope="read", datapack_name="analytics_prod")
|
|
370
|
-
datapack_delete_knowledge_base(scope="admin", datapack_name="analytics_prod", url="s3://data/reports/")
|
|
371
|
-
```
|
|
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.
|
|
372
405
|
|
|
373
|
-
|
|
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.
|
|
@@ -32,23 +32,31 @@ All **Database**, **RAG**, and **Memory** tools accept `datapack_id`.
|
|
|
32
32
|
|
|
33
33
|
## Datapack lifecycle
|
|
34
34
|
|
|
35
|
-
### Creation and setup
|
|
35
|
+
### Creation and setup (MCP)
|
|
36
36
|
|
|
37
37
|
```
|
|
38
38
|
datapack_create(scope="write", name="sales_analytics")
|
|
39
|
-
datapack_create_agent(scope="write", datapack_name="sales_analytics", agent_name="sales_agent")
|
|
40
|
-
datapack_add_knowledge_base(scope="write", datapack_name="sales_analytics", url="s3://company-docs/sales/")
|
|
41
39
|
db_run_write_query(scope="write", query="CREATE TABLE leads (...)", datapack_id="dp-uuid-from-step-1")
|
|
42
40
|
```
|
|
43
41
|
|
|
42
|
+
Provisioning agents and knowledge-base sources on the datapack is **not** MCP-exposed — do that in the Meko control plane (UI at `app.mekodev.com` → Datapacks, or directly via the REST API:
|
|
43
|
+
`POST /datapacks/:name/agents`, `POST /datapacks/:name/knowledge-bases`). If the user asks the agent to set those up mid-session, tell them where to go rather than inventing an MCP call that will fail.
|
|
44
|
+
|
|
45
|
+
For RAG indexes inside the datapack's database, use the MCP-exposed RAG tools:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
knowledgebase_trigger_index_creation(scope="write", source_uris=[...], index_name="leads_docs", datapack_id="dp-uuid-from-step-1")
|
|
49
|
+
knowledgebase_check_index_status(scope="read", index_name="leads_docs", datapack_id="dp-uuid-from-step-1")
|
|
50
|
+
```
|
|
51
|
+
|
|
44
52
|
### Teardown (requires admin scope)
|
|
45
53
|
|
|
46
|
-
Delete child resources
|
|
54
|
+
Delete child resources first (agents and KB sources via the control plane), then the datapack:
|
|
47
55
|
|
|
48
56
|
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
datapack_delete(scope="admin", name="sales_analytics")
|
|
57
|
+
# Control-plane (REST or UI): DELETE /datapacks/sales_analytics/knowledge-bases
|
|
58
|
+
# Control-plane (REST or UI): DELETE /datapacks/sales_analytics/agents/sales_agent
|
|
59
|
+
datapack_delete(scope="admin", name="sales_analytics") # MCP-exposed, destructive
|
|
52
60
|
```
|
|
53
61
|
|
|
54
62
|
## Common mistake: mixing default and datapack databases
|
|
@@ -10,7 +10,7 @@ There are no MCP tools to:
|
|
|
10
10
|
- Clear stuck work queue entries
|
|
11
11
|
- Reset a failed pipeline
|
|
12
12
|
|
|
13
|
-
|
|
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.
|
|
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
|
|
|
@@ -18,7 +18,7 @@ The `datapack_delete_knowledge_base` tool only removes the KB source **registrat
|
|
|
18
18
|
|
|
19
19
|
The RAG tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) handle index **creation and monitoring** only.
|
|
20
20
|
|
|
21
|
-
To actually **query** a built index, use `
|
|
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.
|
|
22
22
|
|
|
23
23
|
## Memory tools unreliable for structured/tabular data
|
|
24
24
|
|
|
@@ -32,13 +32,19 @@ It works **poorly** for:
|
|
|
32
32
|
- Data dictionaries — only partial information extracted
|
|
33
33
|
- Structured schemas — relationships between fields lost
|
|
34
34
|
|
|
35
|
-
**
|
|
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:
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
memory_add(scope="write",
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
1. **Write a single narrative summary** as a memory — one call, not row-by-row:
|
|
38
|
+
```
|
|
39
|
+
memory_add(scope="write",
|
|
40
|
+
agent_id="<your session agent_id>",
|
|
41
|
+
conversation_id="<session conversation_id>",
|
|
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
|
+
```
|
|
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.
|
|
46
|
+
|
|
47
|
+
Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
|
|
42
48
|
|
|
43
49
|
## MCP user permission gaps
|
|
44
50
|
|
|
@@ -52,7 +58,9 @@ If `db_run_read_only_query` returns "permission denied", this is a server-side c
|
|
|
52
58
|
|
|
53
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.
|
|
54
60
|
|
|
55
|
-
|
|
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.)
|
|
56
64
|
|
|
57
65
|
## No conversation search
|
|
58
66
|
|
|
@@ -65,14 +65,57 @@ 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
|
-
##
|
|
68
|
+
## Personal memory vs. team-shared knowledge — the three read paths
|
|
69
|
+
|
|
70
|
+
Agents on Cloud Meko have three distinct read surfaces. Pick the right one for the question.
|
|
71
|
+
|
|
72
|
+
| Read path | What it returns | How to call |
|
|
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="...", ...)` |
|
|
76
|
+
| 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
|
+
|
|
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.
|
|
79
|
+
|
|
80
|
+
### How content gets into each surface
|
|
81
|
+
|
|
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.
|
|
83
|
+
- **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.
|
|
85
|
+
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
|
+
|
|
87
|
+
Both show up in `knowledgebase_search`, tagged `metadata_filters.source: "memory"` vs other values so the agent can distinguish provenance in responses.
|
|
88
|
+
|
|
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.
|
|
90
|
+
|
|
91
|
+
### When the user asks "what do you know about X?"
|
|
92
|
+
|
|
93
|
+
A full sweep is three calls (budget for it — each is 2-6 seconds):
|
|
94
|
+
|
|
95
|
+
```
|
|
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
|
|
98
|
+
knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
When you answer, be explicit about scope so the user knows why something is or isn't there:
|
|
102
|
+
|
|
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`)…"
|
|
105
|
+
- "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.
|
|
109
|
+
|
|
110
|
+
## Memory limitations for structured data
|
|
69
111
|
|
|
70
112
|
**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.
|
|
71
113
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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:
|
|
115
|
+
|
|
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).
|
|
118
|
+
3. **Never ingest CSV row-by-row** into memory — each row becomes a fragmented fact with lost context.
|
|
76
119
|
|
|
77
120
|
## Proactive Memory Storage
|
|
78
121
|
|
|
@@ -126,3 +169,49 @@ Automatic capture handles the raw exchange. You should still manually use `conve
|
|
|
126
169
|
### Watermark coordination
|
|
127
170
|
|
|
128
171
|
A shared watermark file at `~/.claude/meko-capture/<session-id>.watermark.json` tracks what has been saved. Both hooks and the agent's periodic checkpoint use this to avoid reprocessing already-captured exchanges.
|
|
172
|
+
|
|
173
|
+
## Observability: conversation_id IS the Langfuse trace ID
|
|
174
|
+
|
|
175
|
+
This is the feature agents tend to miss. Verified live 2026-05-07 in the Meko UI's Observe hub.
|
|
176
|
+
|
|
177
|
+
- `conversation_create` returns a `conversation_id` (e.g. `d71fc8b61a7f45d585eea9a6436e0c3f`).
|
|
178
|
+
- That ID is also the **Langfuse trace_id** for the conversation. Not a separate trace — literally the same identifier.
|
|
179
|
+
- Every subsequent MCP tool call made while passing that `conversation_id` becomes a **span under that trace**, named after the tool: `Memory Add (Meko MCP)`, `Memory Search (Meko MCP)`, `Knowledgebase Search (Meko MCP)`, `Conversation Add Message (Meko MCP)`, etc.
|
|
180
|
+
- Child spans reveal internals. Observed structure:
|
|
181
|
+
- `memory_add`: `Memory Add (Meko MCP)` → `Create a new memory in Mem0` → `Bulk Payload Update (yugabytedb / vector)` → `Execute Query (yugabytedb / vector)`
|
|
182
|
+
- `memory_search`: `Memory Search (Meko MCP)` → `Search for memories based on a query in Mem0` (Retriever)
|
|
183
|
+
- `conversation_add_message`: `Conversation Add Message (Meko MCP)` → `Conversation Message Added` span → `Reasoning` generation (the `reasoning` field is stored as a Langfuse *generation*-typed span, not a plain text field)
|
|
184
|
+
- `knowledgebase_search`: `Knowledgebase Search (Meko MCP)` → multiple `Execute Query (yugabytedb)` child spans
|
|
185
|
+
- Trace tags include `agent:<agent_id>` and the Meko org UUID. Both are searchable/filterable in Langfuse.
|
|
186
|
+
- Each datapack has its own Langfuse project — traces for a tool call land in the project for whichever `datapack_id` was on the call (or the default datapack if omitted).
|
|
187
|
+
|
|
188
|
+
### Finding a trace in the UI
|
|
189
|
+
|
|
190
|
+
Two navigation paths, both verified in the Meko UI:
|
|
191
|
+
|
|
192
|
+
1. **Datapack → Conversations tab** — every row has an **Open in Observe** button that deep-links to the trace with `session=<conversation_id>` pre-filled. Fastest when you know which conversation to inspect.
|
|
193
|
+
2. **Observe hub** — browse all traces across a datapack. URL shape: `/observe-hub?project=<langfuse_project_id>&session=<conversation_id>`.
|
|
194
|
+
|
|
195
|
+
The Conversations-tab row preview shows the first user turn verbatim, plus the agent_id tag, message count, and started-at timestamp. If you want a conversation to be recognizable in the UI, call `conversation_add_message` with a clean first-turn `input` early in the session.
|
|
196
|
+
|
|
197
|
+
### Observed latencies on prod (2026-05-07)
|
|
198
|
+
|
|
199
|
+
From real traces, not the docstring happy path:
|
|
200
|
+
|
|
201
|
+
| Tool | Latency per call |
|
|
202
|
+
|---|---|
|
|
203
|
+
| `memory_add` | 12-21 seconds (calls OpenAI for extraction, then writes to vector + graph) |
|
|
204
|
+
| `memory_search` | 1.8-5.9 seconds |
|
|
205
|
+
| `knowledgebase_search` | 0.6 seconds (empty index; will grow with index size) |
|
|
206
|
+
| `conversation_add_message` | 0.11 seconds (fire-and-forget; queued to Langfuse) |
|
|
207
|
+
|
|
208
|
+
`memory_add` is the expensive one. If you're capturing a long conversation, batch through `conversation_add_message` (cheap, queued) and let the server-side Mem0 extractor handle the heavy lifting on its own schedule, rather than firing `memory_add(messages=...)` per turn.
|
|
209
|
+
|
|
210
|
+
### Proactive diagnostic pattern
|
|
211
|
+
|
|
212
|
+
If a user reports "my memory_add didn't seem to save", open the Observe hub for their datapack, filter on their `conversation_id`, and look at the span tree. You will see either:
|
|
213
|
+
|
|
214
|
+
- A `Memory Add (Meko MCP)` span with `Create a new memory in Mem0` child → the call reached Mem0. The fact extractor may have returned `"results": []` (common on short or non-fact-shaped text; not a bug, but lossy).
|
|
215
|
+
- No span at all → the call never reached the server. Likely a transport / auth / `conversation_id` mismatch issue.
|
|
216
|
+
|
|
217
|
+
The mem0 extractor is lossy — it extracts atomic facts and graph triples, and may drop prose that doesn't look fact-shaped to it. Observed 2026-05-07: 2 of 5 `memory_add` calls returned `"results": []` and only the graph side landed. When preserving authoritative text matters, store it via `conversation_add_message` (verbatim in `input`/`output`/`reasoning`) — the conversation path preserves text without LLM re-extraction.
|