@yugabytedb/meko-mcp 1.0.3
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 +505 -0
- package/assets/hooks-handlers/lib/capture.js +863 -0
- package/assets/hooks-handlers/lib/checkpoint-timer.js +72 -0
- package/assets/hooks-handlers/pre-compact.sh +3 -0
- package/assets/hooks-handlers/session-end.sh +27 -0
- package/assets/hooks-handlers/session-start.sh +24 -0
- package/assets/hooks-handlers/test_single_conversation.sh +169 -0
- package/assets/skills/meko-mcp-tools/SKILL.md +192 -0
- package/assets/skills/meko-mcp-tools/references/_sections.md +31 -0
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +39 -0
- package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +49 -0
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +373 -0
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +56 -0
- package/assets/skills/meko-mcp-tools/references/tools-db-query-patterns.md +38 -0
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +61 -0
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +128 -0
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +97 -0
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +63 -0
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +79 -0
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +143 -0
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +93 -0
- package/assets/skills/meko-mcp-tools/references/tools-write-guardrails.md +30 -0
- package/bin/create-meko-setup.mjs +499 -0
- package/lib/claude-code.mjs +14 -0
- package/lib/clients/claude-code.mjs +265 -0
- package/lib/clients/claude-desktop.mjs +256 -0
- package/lib/clients/common.mjs +107 -0
- package/lib/clients/cursor.mjs +332 -0
- package/lib/clients/index.mjs +14 -0
- package/lib/config.mjs +369 -0
- package/lib/detect.mjs +125 -0
- package/lib/installer.mjs +255 -0
- package/lib/logger.mjs +97 -0
- package/lib/mcp-transport.mjs +204 -0
- package/lib/migrate/adapters/claude-code.mjs +165 -0
- package/lib/migrate/adapters/cursor.mjs +221 -0
- package/lib/migrate/adapters/memory-md.mjs +230 -0
- package/lib/migrate/claude-parser.mjs +306 -0
- package/lib/migrate/daemon.mjs +67 -0
- package/lib/migrate/id.mjs +83 -0
- package/lib/migrate/lockfile.mjs +121 -0
- package/lib/migrate/logger.mjs +79 -0
- package/lib/migrate/mcp-client.mjs +224 -0
- package/lib/migrate/orchestrator.mjs +443 -0
- package/lib/migrate/progress.mjs +76 -0
- package/lib/migrate/state.mjs +177 -0
- package/lib/migrate.mjs +328 -0
- package/lib/prompt.mjs +212 -0
- package/lib/validate.mjs +259 -0
- package/package.json +49 -0
- package/scripts/bundle-assets.mjs +49 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# Tool Cookbook — Complete Usage Examples
|
|
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.
|
|
4
|
+
|
|
5
|
+
> **Note on `agent_id` in the examples below.** The examples use `agent_id="claude_code"` for readability, but `agent_id` is a **per-user namespace**, not a per-tool label. At runtime, use the value you discovered via `db_summarize_database` at session start (see the main SKILL.md). Substitute it anywhere you see `claude_code` in the examples. Issue [#10](https://github.com/amiramm/meko-mcp-server/issues/10) tracks the eventual schema fix.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Database Tools
|
|
10
|
+
|
|
11
|
+
### db_summarize_database
|
|
12
|
+
|
|
13
|
+
**When to use:** First thing in a session to understand what's in the database. Prefer this over writing your own `information_schema` query.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
db_summarize_database(scope="read", schema="public")
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Response:**
|
|
20
|
+
```json
|
|
21
|
+
[
|
|
22
|
+
{
|
|
23
|
+
"table_name": "customers",
|
|
24
|
+
"schema": [
|
|
25
|
+
{"column_name": "id", "data_type": "uuid"},
|
|
26
|
+
{"column_name": "name", "data_type": "text"}
|
|
27
|
+
],
|
|
28
|
+
"row_count": 1523
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**With datapack:**
|
|
34
|
+
```
|
|
35
|
+
db_summarize_database(scope="read", schema="public", datapack_id="dp-uuid-123")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Common errors:**
|
|
39
|
+
- `Insufficient scope: 'all'` — Use `scope="read"`, not `"all"`
|
|
40
|
+
- Empty result — The schema may not exist, try `schema="public"`
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### db_run_read_only_query
|
|
45
|
+
|
|
46
|
+
**When to use:** Any SELECT query. Always add `LIMIT` on exploratory queries.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
db_run_read_only_query(scope="read", query="SELECT id, name FROM customers LIMIT 10")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Response:** JSON array of row objects.
|
|
53
|
+
```json
|
|
54
|
+
[{"id": "abc-123", "name": "Alice"}, {"id": "def-456", "name": "Bob"}]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Best practices:**
|
|
58
|
+
- Always use `LIMIT` on unfamiliar tables to avoid flooding context
|
|
59
|
+
- Select specific columns rather than `SELECT *` to keep responses small
|
|
60
|
+
- For non-public schemas: `SELECT * FROM analytics."monthly_revenue" LIMIT 5`
|
|
61
|
+
- Escape single quotes in values: `WHERE name = 'O''Brien'`
|
|
62
|
+
|
|
63
|
+
**Common errors:**
|
|
64
|
+
- `cannot execute INSERT in a read-only transaction` — Use `db_run_write_query` for writes
|
|
65
|
+
- `permission denied for table X` — MCP user lacks access to this table (server-side config issue, not fixable via MCP)
|
|
66
|
+
- `connection already closed` — Retry once. If persistent, the DB pool is unhealthy.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### db_run_write_query
|
|
71
|
+
|
|
72
|
+
**When to use:** INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
db_run_write_query(scope="write", query="INSERT INTO customers (id, name) VALUES ('abc-123', 'Alice')")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Response:**
|
|
79
|
+
```json
|
|
80
|
+
{"rows_affected": 1}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**One statement per call.** This is wrong:
|
|
84
|
+
```
|
|
85
|
+
db_run_write_query(scope="write", query="CREATE TABLE a (id INT); CREATE TABLE b (id INT);")
|
|
86
|
+
```
|
|
87
|
+
Split into two separate calls.
|
|
88
|
+
|
|
89
|
+
**Bulk inserts:** Maximum 1000 rows per INSERT VALUES. For more, use `INSERT ... SELECT` or batch into multiple calls.
|
|
90
|
+
|
|
91
|
+
**Common errors:**
|
|
92
|
+
- `Multi-statement queries not allowed` — Send one statement per call
|
|
93
|
+
- `DROP SCHEMA is not allowed` — See `tools-write-guardrails.md` for blocked operations
|
|
94
|
+
- `'dict' object has no attribute 'guardrail_config'` — Known server bug in some deployments. Write operations may be unavailable.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Memory Tools
|
|
99
|
+
|
|
100
|
+
**Critical:** `agent_id` must not contain hyphens. Use `"claude_code"`, not `"claude-code"`.
|
|
101
|
+
|
|
102
|
+
### memory_add
|
|
103
|
+
|
|
104
|
+
**When to use:** Store facts, preferences, user profile info, org conventions, corrections, learnings. Use proactively — don't wait for the user to ask.
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
memory_add(scope="write", agent_id="claude_code",
|
|
108
|
+
text="User Amiram is VP of Product at YugabyteDB. Prefers concise responses.")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Response:**
|
|
112
|
+
```json
|
|
113
|
+
{"results": [{"id": "mem-uuid-123", "memory": "User Amiram is VP of Product at YugabyteDB. Prefers concise responses."}]}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**With user scoping:**
|
|
117
|
+
```
|
|
118
|
+
memory_add(scope="write", agent_id="claude_code", user_id="amiram",
|
|
119
|
+
text="Prefers Python for backend, Go for infrastructure.")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**What NOT to store via memory_add:**
|
|
123
|
+
- CSV rows or tabular data (use `db_run_write_query` instead)
|
|
124
|
+
- Full conversations (use `conversation_create` + `conversation_add_message`)
|
|
125
|
+
- Large documents (use knowledge base ingestion)
|
|
126
|
+
|
|
127
|
+
**Common errors:**
|
|
128
|
+
- `syntax error at or near "-"` — Your `agent_id` contains a hyphen. Use underscores.
|
|
129
|
+
- `connection already closed` — Retry once. If it fails again, the memory subsystem is down.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### memory_search
|
|
134
|
+
|
|
135
|
+
**When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
memory_search(scope="read", query="What programming language does the team use?", agent_id="claude_code")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Response:**
|
|
142
|
+
```json
|
|
143
|
+
{"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89}]}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**With limit:**
|
|
147
|
+
```
|
|
148
|
+
memory_search(scope="read", query="user preferences", agent_id="claude_code", limit=5)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### memory_get_all
|
|
154
|
+
|
|
155
|
+
**When to use:** List everything stored for an agent. Useful at session start to load context.
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
memory_get_all(scope="read", agent_id="claude_code")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**With user scoping:**
|
|
162
|
+
```
|
|
163
|
+
memory_get_all(scope="read", agent_id="claude_code", user_id="amiram")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### memory_get_by_id
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="claude_code")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### memory_update
|
|
177
|
+
|
|
178
|
+
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="claude_code")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### memory_delete_by_id
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="claude_code")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### memory_delete_all
|
|
195
|
+
|
|
196
|
+
**Destructive. Requires admin scope.** Deletes all memories for the agent.
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
memory_delete_all(scope="admin", agent_id="claude_code")
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Conversation Tools
|
|
205
|
+
|
|
206
|
+
### conversation_create
|
|
207
|
+
|
|
208
|
+
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
conversation_create(scope="write", agent_id="claude_code", user_id="amiram",
|
|
212
|
+
title="Debugging the auth middleware")
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Response:**
|
|
216
|
+
```json
|
|
217
|
+
{"id": "conv-uuid-123", "title": "Debugging the auth middleware"}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### conversation_add_message
|
|
223
|
+
|
|
224
|
+
**When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="claude_code",
|
|
228
|
+
input="Why is the auth middleware returning 401?",
|
|
229
|
+
output="The token validation is checking the wrong issuer claim...",
|
|
230
|
+
reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**With dedup seed (use when client hooks also write to Langfuse):**
|
|
234
|
+
```
|
|
235
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="claude_code",
|
|
236
|
+
input="Why is the auth middleware returning 401?",
|
|
237
|
+
output="The token validation is checking the wrong issuer claim...",
|
|
238
|
+
seed="conv-uuid-123:claude_code:Why is the auth middleware returning 401?")
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### conversation_get
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="claude_code",
|
|
247
|
+
include_messages=True, limit=50)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### conversation_list
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
conversation_list(scope="read", agent_id="claude_code", limit=20)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
### conversation_update
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="claude_code",
|
|
264
|
+
title="Resolved: Auth middleware issuer mismatch")
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### conversation_delete_message
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
conversation_delete_message(scope="write", conversation_id="conv-uuid-123",
|
|
273
|
+
agent_id="claude_code", trace_id="trace-uuid-456")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### conversation_delete
|
|
279
|
+
|
|
280
|
+
**Destructive. Requires admin scope.**
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
conversation_delete(scope="admin", conversation_id="conv-uuid-123", agent_id="claude_code")
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## RAG / Knowledge Base Tools
|
|
289
|
+
|
|
290
|
+
### knowledgebase_trigger_index_creation
|
|
291
|
+
|
|
292
|
+
**When to use:** Create a new vector index from source URIs. This is the only way to start a RAG pipeline.
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
knowledgebase_trigger_index_creation(scope="write",
|
|
296
|
+
source_uris="s3://my-bucket/docs/,s3://my-bucket/reports/",
|
|
297
|
+
index_name="company_docs")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Response:**
|
|
301
|
+
```json
|
|
302
|
+
{"source_ids": ["src-uuid-1", "src-uuid-2"], "index_name": "company_docs", "status": "build_triggered"}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Optional parameters:**
|
|
306
|
+
- `ai_provider="OPENAI"` (default)
|
|
307
|
+
- `embedding_model="text-embedding-3-large"` (default)
|
|
308
|
+
- `embedding_dimensions=1536` (default)
|
|
309
|
+
- `chunk_size=1024` (default)
|
|
310
|
+
- `chunk_overlap=256` (default)
|
|
311
|
+
- `datapack_id=None`
|
|
312
|
+
|
|
313
|
+
**Warning:** Each call creates a new index. Do NOT retry on failure — you'll get duplicate indexes (e.g., `docs_v1`, `docs_v2`, `docs_v3`).
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
### knowledgebase_check_index_status
|
|
318
|
+
|
|
319
|
+
**When to use:** Poll for build completion after triggering creation.
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
knowledgebase_check_index_status(scope="read", index_name="company_docs")
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Polling strategy:** Check every 1-2 minutes. If `pipeline_details` is empty or documents remain at `INIT` for more than 5 minutes, the pipeline is likely stuck. Stop polling after 3 consecutive no-progress checks — see `tools-troubleshooting.md`.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
### knowledgebase_add_source_to_index
|
|
330
|
+
|
|
331
|
+
**Known bug:** This tool has a parameter mismatch (`r_index_name` vs `r_index_id`) and may fail. Prefer `knowledgebase_trigger_index_creation` with all sources at once instead.
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
knowledgebase_add_source_to_index(scope="write", index_name="company_docs",
|
|
335
|
+
source_id="src-uuid-new")
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Datapack Management Tools
|
|
341
|
+
|
|
342
|
+
### datapack_create / datapack_list / datapack_describe
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
datapack_create(scope="write", name="analytics_prod")
|
|
346
|
+
datapack_list(scope="read")
|
|
347
|
+
datapack_describe(scope="read", name="analytics_prod", include_status=True)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### datapack_update / datapack_delete
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
datapack_update(scope="write", name="analytics_prod", connection_string="postgresql://...")
|
|
354
|
+
datapack_delete(scope="admin", name="analytics_prod") # Irreversible!
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Agent management within datapacks
|
|
358
|
+
|
|
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
|
+
```
|
|
364
|
+
|
|
365
|
+
### Knowledge base source management within datapacks
|
|
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
|
+
```
|
|
372
|
+
|
|
373
|
+
**Note:** `datapack_delete_knowledge_base` removes the source registration from the Meko API. It does NOT delete the actual vector index, source records, or vector data from the database.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Datapack Lifecycle and datapack_id Routing
|
|
2
|
+
|
|
3
|
+
**WRONG:** Creating a datapack then calling `db_summarize_database(scope="read")` without `datapack_id` — this queries the DEFAULT database, not the datapack.
|
|
4
|
+
|
|
5
|
+
## Always pass datapack_id for datapack-scoped operations
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
datapack_create(scope="write", name="analytics_prod")
|
|
9
|
+
-- Returns: {"id": "dp-uuid-123", ...}
|
|
10
|
+
|
|
11
|
+
db_summarize_database(scope="read", schema="public", datapack_id="dp-uuid-123")
|
|
12
|
+
db_run_read_only_query(scope="read", query="SELECT * FROM customers LIMIT 10", datapack_id="dp-uuid-123")
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## How datapack_id routing works
|
|
16
|
+
|
|
17
|
+
1. When `datapack_id` is **omitted**: uses the default pool from `YUGABYTEDB_URL`
|
|
18
|
+
2. When `datapack_id` is **provided**: resolves connection string via Meko API, creates/reuses a cached pool for that datapack
|
|
19
|
+
|
|
20
|
+
## Which tools accept datapack_id?
|
|
21
|
+
|
|
22
|
+
All **Database**, **RAG**, and **Memory** tools accept `datapack_id`.
|
|
23
|
+
|
|
24
|
+
**Conversation** tools do NOT — they always use Langfuse.
|
|
25
|
+
**Datapack management** tools do NOT — they operate on the Meko API itself.
|
|
26
|
+
|
|
27
|
+
## How to obtain a datapack_id
|
|
28
|
+
|
|
29
|
+
- From `datapack_create` response (`"id"` field)
|
|
30
|
+
- From `datapack_list` (each entry has `"id"`)
|
|
31
|
+
- From `datapack_describe` response
|
|
32
|
+
|
|
33
|
+
## Datapack lifecycle
|
|
34
|
+
|
|
35
|
+
### Creation and setup
|
|
36
|
+
|
|
37
|
+
```
|
|
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
|
+
db_run_write_query(scope="write", query="CREATE TABLE leads (...)", datapack_id="dp-uuid-from-step-1")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Teardown (requires admin scope)
|
|
45
|
+
|
|
46
|
+
Delete child resources before the datapack:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
datapack_delete_knowledge_base(scope="admin", datapack_name="sales_analytics", url="s3://company-docs/sales/")
|
|
50
|
+
datapack_delete_agent(scope="admin", datapack_name="sales_analytics", agent_name="sales_agent")
|
|
51
|
+
datapack_delete(scope="admin", name="sales_analytics")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Common mistake: mixing default and datapack databases
|
|
55
|
+
|
|
56
|
+
If you created a table with a `datapack_id`, always query it with the same `datapack_id`. Creating in default DB and querying in a datapack (or vice versa) will fail with "table not found".
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Read-Only vs Write Query Execution Patterns
|
|
2
|
+
|
|
3
|
+
**WRONG:** `db_run_write_query(scope="write", query="SELECT * FROM users")` — requires write scope unnecessarily, triggers guardrail validation, returns `{"rows_affected": -1}` instead of data.
|
|
4
|
+
**WRONG:** `db_run_read_only_query(scope="read", query="INSERT INTO ...")` — fails: "cannot execute INSERT in a read-only transaction."
|
|
5
|
+
|
|
6
|
+
## How Each Tool Works
|
|
7
|
+
|
|
8
|
+
**`db_run_read_only_query`:** `BEGIN READ ONLY` → execute → `ROLLBACK`. Returns JSON array of row objects.
|
|
9
|
+
|
|
10
|
+
**`db_run_write_query`:** Guardrail validation → execute → `COMMIT`. Returns `{"rows_affected": N}`.
|
|
11
|
+
|
|
12
|
+
## When to Use db_summarize_database
|
|
13
|
+
|
|
14
|
+
Use instead of writing your own `information_schema` query when you need a table overview:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
db_summarize_database(scope="read", schema="public")
|
|
18
|
+
-- Returns table names, column schemas, AND row counts in one call
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## SQL Best Practices
|
|
22
|
+
|
|
23
|
+
**Schema qualification:** For non-public schemas, use `analytics."monthly_revenue"` and pass `schema="analytics"` to `db_summarize_database`.
|
|
24
|
+
|
|
25
|
+
**String escaping:** Queries are passed directly to `cur.execute()` — no parameter placeholders. Escape values in SQL: `WHERE name = 'O''Brien'`.
|
|
26
|
+
|
|
27
|
+
**LIMIT on exploratory queries:**
|
|
28
|
+
```
|
|
29
|
+
db_run_read_only_query(scope="read", query="SELECT * FROM large_table LIMIT 25")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Batch large writes:** Due to the 1000-row INSERT cap, split large inserts. Or use `INSERT ... SELECT` for unlimited rows from an existing table.
|
|
33
|
+
|
|
34
|
+
**One statement per call:**
|
|
35
|
+
```
|
|
36
|
+
WRONG: "CREATE TABLE a (id INT); CREATE TABLE b (id INT);"
|
|
37
|
+
RIGHT: Two separate db_run_write_query calls
|
|
38
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Known Limitations
|
|
2
|
+
|
|
3
|
+
These are current limitations of the Meko MCP tools. Know them upfront to avoid wasted tool calls.
|
|
4
|
+
|
|
5
|
+
## No delete tools for RAG artifacts
|
|
6
|
+
|
|
7
|
+
There are no MCP tools to:
|
|
8
|
+
- Delete a vector index
|
|
9
|
+
- Remove a source from an index
|
|
10
|
+
- Clear stuck work queue entries
|
|
11
|
+
- Reset a failed pipeline
|
|
12
|
+
|
|
13
|
+
The `datapack_delete_knowledge_base` tool only removes the KB source **registration** from the Meko API. It does NOT touch the actual `dist_rag` index, source records, or vector data in the database.
|
|
14
|
+
|
|
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
|
+
|
|
17
|
+
## No MCP tool to query a built RAG index
|
|
18
|
+
|
|
19
|
+
The RAG tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) handle index **creation and monitoring** only.
|
|
20
|
+
|
|
21
|
+
To actually **query** a built index, use `db_run_read_only_query` with `dist_rag` SQL functions directly. The specific query syntax depends on the `dist_rag` extension API.
|
|
22
|
+
|
|
23
|
+
## Memory tools unreliable for structured/tabular data
|
|
24
|
+
|
|
25
|
+
`memory_add` passes text through Mem0's fact extraction pipeline. This works well for:
|
|
26
|
+
- Facts: "Alice works at Acme Corp"
|
|
27
|
+
- Preferences: "User prefers dark mode"
|
|
28
|
+
- Entity relationships: "Amiram reports to Karthik"
|
|
29
|
+
|
|
30
|
+
It works **poorly** for:
|
|
31
|
+
- CSV rows or tabular data — columns and rows get dropped
|
|
32
|
+
- Data dictionaries — only partial information extracted
|
|
33
|
+
- Structured schemas — relationships between fields lost
|
|
34
|
+
|
|
35
|
+
**Use instead:** `db_run_write_query` to CREATE TABLE and INSERT the data as proper database rows. Then query it with `db_run_read_only_query`.
|
|
36
|
+
|
|
37
|
+
If you must store a schema overview in memory, write a single narrative summary:
|
|
38
|
+
```
|
|
39
|
+
memory_add(scope="write", agent_id="claude_code",
|
|
40
|
+
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)")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## MCP user permission gaps
|
|
44
|
+
|
|
45
|
+
The MCP database user may not have read access to all tables within a datapack, particularly:
|
|
46
|
+
- Data tables created by the provisioning system
|
|
47
|
+
- Tables in non-public schemas
|
|
48
|
+
|
|
49
|
+
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.
|
|
50
|
+
|
|
51
|
+
## Currently broken tools
|
|
52
|
+
|
|
53
|
+
**`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
|
+
|
|
55
|
+
**`knowledgebase_add_source_to_index`** — SQL parameter mismatch: tool passes `r_index_name` (string) but the DB function expects `r_index_id` (UUID). Workaround: use `knowledgebase_trigger_index_creation` with all sources at once.
|
|
56
|
+
|
|
57
|
+
## No conversation search
|
|
58
|
+
|
|
59
|
+
`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`.
|
|
60
|
+
|
|
61
|
+
For finding past knowledge by meaning, use `memory_search` instead — which is why storing key facts via `memory_add` alongside conversations is important.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# When to Use Memory Tools vs Conversation Tools
|
|
2
|
+
|
|
3
|
+
**WRONG:** `memory_add(text="User asked about pricing. I explained tiers. User chose Pro.")` — mem0 extracts facts, discarding conversational structure, turn ordering, and reasoning traces.
|
|
4
|
+
|
|
5
|
+
## Use `memory_add` when storing:
|
|
6
|
+
|
|
7
|
+
- A **fact**: "User prefers dark mode"
|
|
8
|
+
- A **preference**: "Customer budget is $50k"
|
|
9
|
+
- An **entity relationship**: "Alice works at Acme Corp"
|
|
10
|
+
|
|
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
|
+
|
|
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")
|
|
16
|
+
|
|
17
|
+
memory_search(scope="read", query="What plan does Alice have?", agent_id="support_bot")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Use `conversation_create` + `conversation_add_message` when storing:
|
|
21
|
+
|
|
22
|
+
- A **full dialog exchange** with input/output pairs
|
|
23
|
+
- A **chain-of-thought** reasoning trace alongside the response
|
|
24
|
+
- A **multi-turn chat** where turn order matters
|
|
25
|
+
|
|
26
|
+
Conversations are backed by Langfuse sessions and traces. They preserve full structure: who said what, in what order, with what reasoning.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
conversation_create(scope="write", agent_id="support_bot", user_id="alice_123", title="Pricing discussion")
|
|
30
|
+
-- Returns: {"id": "conv-uuid-here"}
|
|
31
|
+
|
|
32
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-here", agent_id="support_bot",
|
|
33
|
+
input="What are your pricing tiers?",
|
|
34
|
+
output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
|
|
35
|
+
reasoning="Retrieved pricing page data. No special discounts apply.")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Decision Matrix
|
|
39
|
+
|
|
40
|
+
| Signal | Tool |
|
|
41
|
+
|--------|------|
|
|
42
|
+
| "remember that...", "note that...", "keep in mind..." | `memory_add` |
|
|
43
|
+
| "store this conversation", "save this chat" | `conversation_create` + `conversation_add_message` |
|
|
44
|
+
| "what do you know about X?", "recall..." | `memory_search` |
|
|
45
|
+
| "show me our past conversation about..." | `conversation_list` + `conversation_get` |
|
|
46
|
+
| "the user prefers...", "their budget is..." | `memory_add` |
|
|
47
|
+
| "save my query and your response" | `conversation_add_message` |
|
|
48
|
+
|
|
49
|
+
## Verbatim Content Rules for conversation_add_message
|
|
50
|
+
|
|
51
|
+
**WRONG:** Summarizing or rephrasing content before storing:
|
|
52
|
+
```
|
|
53
|
+
conversation_add_message(...,
|
|
54
|
+
input="User inquired about database performance", -- rephrased
|
|
55
|
+
output="I provided optimization suggestions", -- summarized
|
|
56
|
+
reasoning="Analyzed the query and suggested improvements" -- condensed
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
All three fields — `input`, `output`, and `reasoning` — must contain the **exact, verbatim text**. Never summarize, rephrase, editorialize, or condense any field:
|
|
61
|
+
|
|
62
|
+
- **`input`**: The user's exact prompt, word for word
|
|
63
|
+
- **`output`**: The assistant's complete response, word for word — including code blocks, formatting, and all detail
|
|
64
|
+
- **`reasoning`**: The full chain-of-thought or internal reasoning trace, unedited
|
|
65
|
+
|
|
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
|
+
|
|
68
|
+
## Memory Limitations for Structured Data
|
|
69
|
+
|
|
70
|
+
**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
|
+
|
|
72
|
+
For tabular data, prefer:
|
|
73
|
+
1. **Create a table** via `db_run_write_query` and insert the data as rows — preserves all structure
|
|
74
|
+
2. **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
|
|
75
|
+
3. **Never ingest CSV row-by-row** into memory — each row becomes a fragmented fact with lost context
|
|
76
|
+
|
|
77
|
+
## Proactive Memory Storage
|
|
78
|
+
|
|
79
|
+
Don't wait for the user to say "remember this." Store context proactively when you detect:
|
|
80
|
+
|
|
81
|
+
- **Personal info** → `memory_add`: "User is VP of Product, prefers concise responses"
|
|
82
|
+
- **Team conventions** → `memory_add`: "Team uses Python for backend, Go for infrastructure"
|
|
83
|
+
- **Domain knowledge** → `memory_add`: "Meko traces are decision traces that capture how and why decisions were made"
|
|
84
|
+
- **Corrections** → `memory_add`: "User corrected: always use 'resilience' instead of 'high availability'"
|
|
85
|
+
|
|
86
|
+
Use `memory_search` at the start of sessions to recall what you already know before asking the user to repeat themselves.
|
|
87
|
+
|
|
88
|
+
## Using Both Together
|
|
89
|
+
|
|
90
|
+
A common pattern: store the full conversation (preserves structure) AND extract key facts with `memory_add` (enables semantic search later).
|
|
91
|
+
|
|
92
|
+
## Key Retrieval Difference
|
|
93
|
+
|
|
94
|
+
- `memory_search`: **semantic similarity** across all memories via pgvector. Returns relevant facts regardless of when stored.
|
|
95
|
+
- `conversation_get`: **ordered list of message turns** for a specific conversation. No semantic search. Requires `conversation_id`.
|
|
96
|
+
|
|
97
|
+
## Automatic Conversation Capture
|
|
98
|
+
|
|
99
|
+
The Meko plugin captures conversations automatically via three mechanisms:
|
|
100
|
+
|
|
101
|
+
1. **Periodic checkpoint (~10 min)** — Agent-driven via CronCreate, uses `conversation_add_message` MCP tool directly
|
|
102
|
+
2. **PreCompact hook** — Shell script that fires before Claude Code's auto-compaction, captures via MCP JSON-RPC
|
|
103
|
+
3. **SessionEnd hook** — Shell script that fires at session termination, captures final exchanges
|
|
104
|
+
|
|
105
|
+
### What gets captured
|
|
106
|
+
|
|
107
|
+
The full transcript including:
|
|
108
|
+
- **User prompts** — verbatim text (the `input` field)
|
|
109
|
+
- **Assistant responses** — all text blocks (the `output` field)
|
|
110
|
+
- **Tool calls** — tool name + input parameters (the `reasoning` field)
|
|
111
|
+
- **Tool results** — output from tool executions (appended to `reasoning`)
|
|
112
|
+
|
|
113
|
+
This is more than just text — tool calls and results are critical context for session replay, cross-agent sharing, and compaction.
|
|
114
|
+
|
|
115
|
+
### Seed-based deduplication
|
|
116
|
+
|
|
117
|
+
Each message's seed is `<conversation_id>:<user_message_uuid>`. All three capture mechanisms generate the same seed for the same exchange, producing the same deterministic trace ID via `sha256(seed)[:16].hex()`. This means duplicate writes from overlapping captures are idempotent.
|
|
118
|
+
|
|
119
|
+
### When to manually store conversations
|
|
120
|
+
|
|
121
|
+
Automatic capture handles the raw exchange. You should still manually use `conversation_create` + `conversation_add_message` when:
|
|
122
|
+
- The user explicitly asks to "save this conversation"
|
|
123
|
+
- You want to add curated `reasoning` traces beyond raw tool calls
|
|
124
|
+
- You want to store a selected subset of the conversation with a descriptive title
|
|
125
|
+
|
|
126
|
+
### Watermark coordination
|
|
127
|
+
|
|
128
|
+
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.
|