@yugabytedb/meko-mcp 2.0.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 (48) hide show
  1. package/README.md +31 -6
  2. package/assets/hooks-handlers/codex-session-end.sh +78 -0
  3. package/assets/hooks-handlers/lib/capture.js +163 -14
  4. package/assets/hooks-handlers/lib/checkpoint-timer.js +44 -2
  5. package/assets/hooks-handlers/session-end.sh +10 -0
  6. package/assets/hooks-handlers/session-start.sh +8 -1
  7. package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
  8. package/assets/scripts/package-desktop-skill.sh +32 -1
  9. package/assets/skills/meko-mcp-tools/SKILL.md +47 -41
  10. package/assets/skills/meko-mcp-tools/references/_sections.md +2 -4
  11. package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +29 -25
  12. package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +5 -7
  13. package/assets/skills/meko-mcp-tools/references/tools-conversation-reasoning.md +50 -0
  14. package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +63 -46
  15. package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +6 -6
  16. package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +4 -4
  17. package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +17 -22
  18. package/assets/skills/meko-mcp-tools/references/tools-overview.md +40 -39
  19. package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +1 -2
  20. package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +4 -18
  21. package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +9 -8
  22. package/assets/skills/meko-mcp-tools-desktop/SKILL.md +49 -42
  23. package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +6 -6
  24. package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +2 -2
  25. package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +28 -24
  26. package/assets/skills/meko-mcp-tools-desktop/references/tools-conversation-reasoning.md +50 -0
  27. package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +61 -36
  28. package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +4 -4
  29. package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +16 -19
  30. package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +40 -39
  31. package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +1 -2
  32. package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +3 -17
  33. package/assets/skills/meko-select-datapack-desktop/SKILL.md +31 -21
  34. package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +8 -8
  35. package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +41 -0
  36. package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +1 -1
  37. package/bin/create-meko-setup.mjs +45 -6
  38. package/lib/clients/claude-code.mjs +8 -4
  39. package/lib/clients/claude-desktop.mjs +14 -0
  40. package/lib/clients/codex.mjs +23 -8
  41. package/lib/clients/common.mjs +2 -0
  42. package/lib/clients/cursor.mjs +7 -2
  43. package/lib/detect.mjs +7 -2
  44. package/lib/prompt.mjs +1 -1
  45. package/lib/url-selection.mjs +55 -0
  46. package/package.json +1 -1
  47. package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +0 -71
  48. package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +0 -71
@@ -4,13 +4,13 @@
4
4
 
5
5
  When MCP clients have built-in Langfuse hooks (Cursor, Claude Code), both the client hook and the MCP server may write a trace for the same message → duplicate traces, doubled message counts, corrupted conversation retrieval.
6
6
 
7
- **WRONG:** Neither `seed` nor `trace_id` provided → both sides generate random IDs → two traces per message.
7
+ **WRONG:** No `seed` provided → both sides generate random trace IDs → two traces per message.
8
8
 
9
9
  ## Solution: Use seed for deterministic trace IDs
10
10
 
11
11
  ```
12
12
  conversation_add_message(
13
- scope="write", conversation_id="conv-uuid", agent_id="my_agent",
13
+ conversation_id="conv-uuid", agent_id="my_agent",
14
14
  input="What is our Q3 revenue?",
15
15
  output="Q3 revenue was $4.2M, up 15% from Q2.",
16
16
  seed="conv-uuid:my_agent:What is our Q3 revenue?"
@@ -19,11 +19,10 @@ conversation_add_message(
19
19
 
20
20
  Both sides hash the same seed string to produce the same trace ID. Langfuse treats the second write as an upsert → exactly one trace.
21
21
 
22
- ## Priority Rules
22
+ ## Trace ID Rules
23
23
 
24
- 1. **`trace_id`** — if provided, used directly (highest precedence)
25
- 2. **`seed`** — if provided, hashed to produce deterministic trace ID
26
- 3. **Neither** — random trace ID generated
24
+ 1. **`seed`** — if provided, hashed to produce a deterministic trace ID
25
+ 2. **Not provided** — a random trace ID is generated
27
26
 
28
27
  ## Choosing a Good Seed
29
28
 
@@ -41,7 +40,6 @@ seed = f"{conversation_id}:{agent_id}:{message_index}"
41
40
  |----------|-----|
42
41
  | Client hook + MCP server both write to Langfuse | `seed` |
43
42
  | Only the MCP server writes (no client hook) | Neither (random is fine) |
44
- | Migrating from another system with existing IDs | `trace_id` |
45
43
  | Replaying messages idempotently | `seed` |
46
44
 
47
45
  ## session_id on conversation_create
@@ -0,0 +1,50 @@
1
+ # Authoring `reasoning` and `plan` on `conversation_add_message`
2
+
3
+ `conversation_add_message` accepts two optional fields — `reasoning` and `plan` — that capture *why* the assistant replied the way it did and *what* concrete steps it took. They are stored side-by-side on the per-turn `Reasoning` observation in Langfuse, independently, so consumers can read or render either one on its own.
4
+
5
+ Provide them on the large majority of substantive turns. Skip both only for genuinely trivial acknowledgements (a one-word reply, a pure restatement). Do not fabricate deliberation — but in practice, almost every substantive reply has at least a one-line *why* and a one-step plan.
6
+
7
+ ## `reasoning`
8
+
9
+ A short paragraph (1–3 sentences) of the **why**. Plain English. Explain which trade-off you weighed, which user fact tipped the decision, why this answer beat the alternatives. Inline markdown (`**bold**`, `*italics*`, `` `code` ``) is fine.
10
+
11
+ Do NOT include a `**Plan:**` heading inside `reasoning` — put steps in the `plan` field instead.
12
+
13
+ ## `plan`
14
+
15
+ A list of 2 to 4 concrete actions taken for this turn. Each entry is a single imperative sentence, like a checklist item. Pass a list of strings.
16
+
17
+ Do NOT pre-number entries. Do NOT include a `**Plan:**` heading inside the strings — `plan` is stored as a structured array on the observation's `metadata.plan`, independent of `reasoning`.
18
+
19
+ ## Two examples
20
+
21
+ ### Example A — database recommendation
22
+
23
+ ```
24
+ reasoning:
25
+ "The user cares about low latency and predictable cost.
26
+ Option A wins on latency but costs more per month; option
27
+ B is cheaper but adds 30 ms p99. Latency was their top
28
+ priority, so I picked Option A."
29
+
30
+ plan: [
31
+ "Recommend Option A and call out the latency advantage.",
32
+ "Show the monthly cost delta in clear numbers.",
33
+ "Flag the cost difference so the user can decide if it fits."
34
+ ]
35
+ ```
36
+
37
+ ### Example B — book pick for a long flight
38
+
39
+ ```
40
+ reasoning:
41
+ "The user wants a non-fiction book for a six-hour flight
42
+ and does not enjoy business memoirs. *Sapiens* fits the
43
+ time slot, is non-fiction, and is not a memoir."
44
+
45
+ plan: [
46
+ "Recommend *Sapiens* as the main pick.",
47
+ "Offer *Bad Blood* as a non-memoir backup.",
48
+ "Skip founder memoirs per the user's stated dislike."
49
+ ]
50
+ ```
@@ -1,21 +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.** 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`.
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 with `agent_id="meko_agent"` — the common bucket the server stores empty/missing values into. See `tools-agent-id-conventions.md`.
6
6
 
7
7
  ---
8
8
 
9
9
  ## Memory Tools
10
10
 
11
- **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.
11
+ **Critical:** Pass your session's `agent_id` on every memory *write* (the value from the SessionStart `additionalContext`, e.g. `claude_code:meko-mcp-server`) — it is stored on the row and rendered as the UI badge. Note that `agent_id` labels writes but does **not** filter personal reads: a single `memory_search` / `memory_get_all` returns all of your memories for this user across every `agent_id` (see the `memory_search` note below). For genuinely cross-project facts, write with `agent_id="meko_agent"` so the row lands in the common bucket.
12
12
 
13
13
  ### memory_add
14
14
 
15
15
  **When to use:** NOT for facts the user states in conversation — those are saved automatically by conversation capture + server-side extraction. Reserve `memory_add` for the three cases extraction can't reach: (1) the user explicitly says "remember this"; (2) a durable fact that lives 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).
16
16
 
17
17
  ```
18
- memory_add(scope="write", agent_id="<your-agent-id>",
18
+ memory_add(agent_id="<your-agent-id>",
19
+ conversation_id="<uuid from conversation_create or the SessionStart hook>",
19
20
  text="Remember: deploy scripts must be run from the repo root, never a subdir.")
20
21
  ```
21
22
 
@@ -24,12 +25,6 @@ memory_add(scope="write", agent_id="<your-agent-id>",
24
25
  {"results": [{"id": "mem-uuid-123", "memory": "User Amiram is VP of Product at YugabyteDB. Prefers concise responses."}]}
25
26
  ```
26
27
 
27
- **With user scoping:**
28
- ```
29
- memory_add(scope="write", agent_id="agent", user_id="amiram",
30
- text="Prefers Python for backend, Go for infrastructure.")
31
- ```
32
-
33
28
  **What NOT to store via memory_add:**
34
29
  - Full conversations (use `conversation_create` + `conversation_add_message`)
35
30
  - Large documents (use the UI's Datapack → Actions → Add Knowledge upload flow)
@@ -45,9 +40,11 @@ memory_add(scope="write", agent_id="agent", user_id="amiram",
45
40
  **When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
46
41
 
47
42
  ```
48
- memory_search(scope="read", query="What programming language does the team use?", agent_id="agent")
43
+ memory_search(query="What programming language does the team use?", agent_id="agent", conversation_id="<uuid>")
49
44
  ```
50
45
 
46
+ **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.
47
+
51
48
  **Response:**
52
49
  ```json
53
50
  {"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89}]}
@@ -55,22 +52,17 @@ memory_search(scope="read", query="What programming language does the team use?"
55
52
 
56
53
  **With limit:**
57
54
  ```
58
- memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
55
+ memory_search(query="user preferences", agent_id="agent", conversation_id="<uuid>", limit=5)
59
56
  ```
60
57
 
61
58
  ---
62
59
 
63
60
  ### memory_get_all
64
61
 
65
- **When to use:** List everything stored for an agent. Useful at session start to load context.
66
-
67
- ```
68
- memory_get_all(scope="read", agent_id="agent")
69
- ```
62
+ **When to use:** List all of your memories for this user — across every `agent_id` (`agent_id` does not filter the result). Useful at session start to load context.
70
63
 
71
- **With user scoping:**
72
64
  ```
73
- memory_get_all(scope="read", agent_id="agent", user_id="amiram")
65
+ memory_get_all(agent_id="agent", conversation_id="<uuid>")
74
66
  ```
75
67
 
76
68
  ---
@@ -78,7 +70,7 @@ memory_get_all(scope="read", agent_id="agent", user_id="amiram")
78
70
  ### memory_get_by_id
79
71
 
80
72
  ```
81
- memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
73
+ memory_get_by_id(memory_id="mem-uuid-123", agent_id="agent", conversation_id="<uuid>")
82
74
  ```
83
75
 
84
76
  ---
@@ -88,7 +80,7 @@ memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
88
80
  **When to use:** Overwrite a specific memory's text. Requires the memory UUID.
89
81
 
90
82
  ```
91
- memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
83
+ memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent", conversation_id="<uuid>")
92
84
  ```
93
85
 
94
86
  ---
@@ -96,21 +88,41 @@ memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses
96
88
  ### memory_delete_by_id
97
89
 
98
90
  ```
99
- memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="agent")
91
+ memory_delete_by_id(memory_id="mem-uuid-123", agent_id="agent", conversation_id="<uuid>")
100
92
  ```
101
93
 
102
94
  ---
103
95
 
104
96
  ### memory_delete_all
105
97
 
106
- **Destructive. Requires admin scope.** Deletes all memories for the agent.
98
+ **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.
107
99
 
108
100
  ```
109
- memory_delete_all(scope="admin", agent_id="agent")
101
+ memory_delete_all(agent_id="agent", conversation_id="<uuid>")
110
102
  ```
111
103
 
112
104
  ---
113
105
 
106
+ ### memory_promote
107
+
108
+ **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.
109
+
110
+ ```
111
+ memory_promote(memory_ids=["mem-uuid-123", "mem-uuid-456"],
112
+ agent_id="agent", conversation_id="<uuid from conversation_create>")
113
+ ```
114
+
115
+ **Response:**
116
+ ```json
117
+ {"inserted_ids": ["mem-uuid-123"], "updated_ids": ["mem-uuid-456"], "not_found_ids": []}
118
+ ```
119
+
120
+ 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`.
121
+
122
+ 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.
123
+
124
+ ---
125
+
114
126
  ## Conversation Tools
115
127
 
116
128
  ### conversation_create
@@ -118,7 +130,7 @@ memory_delete_all(scope="admin", agent_id="agent")
118
130
  **When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
119
131
 
120
132
  ```
121
- conversation_create(scope="write", agent_id="agent", user_id="amiram",
133
+ conversation_create(agent_id="agent",
122
134
  title="Debugging the auth middleware")
123
135
  ```
124
136
 
@@ -133,23 +145,21 @@ conversation_create(scope="write", agent_id="agent", user_id="amiram",
133
145
 
134
146
  **When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
135
147
 
136
- Pass `index_for_search=True` on substantive turns so this conversation is embedded into the shared conversation-history cache (searchable later via `conversation_search` / `contextual_prominence_search`). This isn't limited to WorkbenchLM — pass it for agent-harness conversations too.
148
+ 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.
137
149
 
138
150
  ```
139
- conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
151
+ conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
140
152
  input="Why is the auth middleware returning 401?",
141
153
  output="The token validation is checking the wrong issuer claim...",
142
- reasoning="Checked the middleware source, found issuer mismatch between config and JWT...",
143
- index_for_search=True)
154
+ reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
144
155
  ```
145
156
 
146
157
  **With dedup seed (use when client hooks also write to Langfuse):**
147
158
  ```
148
- conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
159
+ conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
149
160
  input="Why is the auth middleware returning 401?",
150
161
  output="The token validation is checking the wrong issuer claim...",
151
- seed="conv-uuid-123:agent:Why is the auth middleware returning 401?",
152
- index_for_search=True)
162
+ seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
153
163
  ```
154
164
 
155
165
  ---
@@ -157,7 +167,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
157
167
  ### conversation_get
158
168
 
159
169
  ```
160
- conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent",
170
+ conversation_get(conversation_id="conv-uuid-123", agent_id="agent",
161
171
  include_messages=True, limit=50)
162
172
  ```
163
173
 
@@ -165,8 +175,12 @@ conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent"
165
175
 
166
176
  ### conversation_list
167
177
 
178
+ Target the datapack by `datapack_id` (UUID). It's optional — omit it to use the
179
+ pinned/default datapack, or pass the pinned `datapack_id`. Use `datapack_list`
180
+ to look up the id.
181
+
168
182
  ```
169
- conversation_list(scope="read", agent_id="agent", limit=20)
183
+ conversation_list(datapack_id="<datapack-uuid>", agent_id="agent", limit=20)
170
184
  ```
171
185
 
172
186
  ---
@@ -174,7 +188,7 @@ conversation_list(scope="read", agent_id="agent", limit=20)
174
188
  ### conversation_update
175
189
 
176
190
  ```
177
- conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
191
+ conversation_update(conversation_id="conv-uuid-123", agent_id="agent",
178
192
  title="Resolved: Auth middleware issuer mismatch")
179
193
  ```
180
194
 
@@ -182,10 +196,10 @@ conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="ag
182
196
 
183
197
  ### conversation_delete
184
198
 
185
- **Destructive. Requires admin scope.**
199
+ **Destructive.**
186
200
 
187
201
  ```
188
- conversation_delete(scope="admin", conversation_id="conv-uuid-123", agent_id="agent")
202
+ conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
189
203
  ```
190
204
 
191
205
  ---
@@ -202,7 +216,6 @@ See `tools-rag-workflow.md` for the decision table.
202
216
 
203
217
  ```
204
218
  knowledgebase_search(
205
- scope="read",
206
219
  query="natural-language question",
207
220
  agent_id="agent",
208
221
  conversation_id="<uuid from conversation_create>",
@@ -229,7 +242,6 @@ Populated KBs return results with chunk content and similarity scores. An empty/
229
242
 
230
243
  ```
231
244
  artifact_put(
232
- scope="write",
233
245
  filename="analysis_report.csv",
234
246
  content_type="text/csv",
235
247
  content_base64="<base64-encoded bytes>",
@@ -265,7 +277,6 @@ Save the `content_hash` — it's the retrieval key for `artifact_get`.
265
277
  **Small files (< 1 MB) — content returned inline:**
266
278
  ```
267
279
  artifact_get(
268
- scope="read",
269
280
  content_hash="a665a45920422f9d417e4867efdc4fb8a5f1f89ea5b8440b1ad4c4c6b8a7e4d3",
270
281
  conversation_id="<uuid from conversation_create>",
271
282
  agent_id="agent"
@@ -309,16 +320,22 @@ For large files use the `local_path` value to read the file with normal file too
309
320
  ### datapack_create / datapack_list / datapack_describe
310
321
 
311
322
  ```
312
- datapack_create(scope="write", name="analytics_prod")
313
- datapack_list(scope="read") # returns datapack_id for each datapack
314
- datapack_describe(scope="read", datapack_id="<uuid>", include_status=True)
323
+ datapack_create(name="analytics_prod")
324
+ datapack_list() # returns datapack_id for each datapack
325
+ datapack_describe(datapack_id="<uuid>", include_status=True)
315
326
  ```
316
327
 
317
328
  ### datapack_update / datapack_delete
318
329
 
330
+ `datapack_update` renames or edits the description of a datapack. Both `name` and `description` are optional; pass at least one. If both are omitted the tool returns `nothing_to_update` without hitting the API.
331
+
332
+ The server refuses to rename the caller's `meko_default_datapack` — a rename call against that datapack returns `"meko_default_datapack cannot be renamed"`. Description edits on the default datapack are still allowed. Passing `description=""` does NOT clear an existing description; clearing is not supported via MCP.
333
+
319
334
  ```
320
- datapack_update(scope="write", datapack_id="<uuid>", connection_string="postgresql://...")
321
- datapack_delete(scope="admin", datapack_id="<uuid>") # Irreversible!
335
+ datapack_update(datapack_id="<uuid>", name="renamed-datapack")
336
+ datapack_update(datapack_id="<uuid>", description="new description")
337
+ datapack_update(datapack_id="<uuid>", name="x", description="y")
338
+ datapack_delete(datapack_id="<uuid>") # Irreversible!
322
339
  ```
323
340
 
324
341
  ### Agent and knowledge-base management (NOT MCP — control-plane only)
@@ -326,6 +343,6 @@ datapack_delete(scope="admin", datapack_id="<uuid>") # Irreversible!
326
343
  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:
327
344
 
328
345
  - REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (agents), `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases` (KB sources).
329
- - Or the Meko UI at `app.mekodev.com` → Datapacks → agents / knowledge-bases.
346
+ - Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
330
347
 
331
348
  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`.
@@ -22,8 +22,8 @@ Datapacks are isolated workspaces — each has its own memory store and knowledg
22
22
  ### Creation
23
23
 
24
24
  ```
25
- datapack_create(scope="write", agent_id="<your agent_id>",
26
- conversation_id="<uuid>", name="sales_analytics")
25
+ datapack_create(name="sales_analytics",
26
+ conversation_id="<uuid>")
27
27
  -- Returns: {"datapack_id": "dp-uuid-123", "datapack_name": "sales_analytics", ...}
28
28
  ```
29
29
 
@@ -37,20 +37,20 @@ If the user asks to set those up mid-session, point them at the control plane ra
37
37
  ### Targeting a specific datapack on subsequent calls
38
38
 
39
39
  ```
40
- memory_search(scope="read", agent_id="<your-agent-id>",
40
+ memory_search(agent_id="<your-agent-id>",
41
41
  conversation_id="<uuid>", query="...", datapack_id="dp-uuid-123")
42
- knowledgebase_search(scope="read", agent_id="<your-agent-id>",
42
+ knowledgebase_search(agent_id="<your-agent-id>",
43
43
  conversation_id="<uuid>", datapack_id="dp-uuid-123", query="...")
44
44
  ```
45
45
 
46
- ### Teardown (requires admin scope)
46
+ ### Teardown
47
47
 
48
48
  Delete child resources first (agents and KB sources via the control plane), then the datapack:
49
49
 
50
50
  ```
51
51
  # Control-plane (REST or UI): DELETE /datapacks/:datapack_id/knowledge-bases
52
52
  # Control-plane (REST or UI): DELETE /datapacks/:datapack_id/agents/sales_agent
53
- datapack_delete(scope="admin", datapack_id="dp-uuid-123") # MCP-exposed, destructive, irreversible
53
+ datapack_delete(datapack_id="dp-uuid-123") # MCP-exposed, destructive, irreversible
54
54
  ```
55
55
 
56
56
  ## Common mistake: forgetting datapack_id on memory tools
@@ -36,7 +36,7 @@ It works **poorly** for:
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)")
@@ -46,8 +46,8 @@ It works **poorly** for:
46
46
 
47
47
  Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
48
48
 
49
- ## No conversation search
49
+ ## No semantic search over conversation content
50
50
 
51
- `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`.
51
+ Semantic (meaning-based) search across stored conversation content is not part of the public tool surface today. To find a past conversation, browse with `conversation_list` (by datapack) and inspect candidates with `conversation_get`.
52
52
 
53
- For finding past knowledge by meaning, use `memory_search` instead — which is why storing key facts via `memory_add` alongside conversations is important.
53
+ For finding past knowledge by meaning, `memory_search` remains the most reliable path — which is why storing key facts via `memory_add` alongside conversations is important.
@@ -11,10 +11,10 @@
11
11
  Memory is backed by pgvector (semantic search) and Apache AGE (entity-relationship graph). It retrieves relevant facts by meaning, not by conversation order.
12
12
 
13
13
  ```
14
- memory_add(scope="write", agent_id="support_bot",
15
- text="Customer Alice (alice@acme.com) prefers email, has Pro plan.", user_id="alice_123")
14
+ memory_add(agent_id="support_bot",
15
+ text="Customer Alice (alice@acme.com) prefers email, has Pro plan.")
16
16
 
17
- memory_search(scope="read", query="What plan does Alice have?", agent_id="support_bot")
17
+ memory_search(query="What plan does Alice have?", agent_id="support_bot")
18
18
  ```
19
19
 
20
20
  ## Use `conversation_create` + `conversation_add_message` when storing:
@@ -26,10 +26,10 @@ memory_search(scope="read", query="What plan does Alice have?", agent_id="suppor
26
26
  Conversations are backed by Langfuse sessions and traces. They preserve full structure: who said what, in what order, with what reasoning.
27
27
 
28
28
  ```
29
- conversation_create(scope="write", agent_id="support_bot", user_id="alice_123", title="Pricing discussion")
29
+ conversation_create(agent_id="support_bot", title="Pricing discussion")
30
30
  -- Returns: {"id": "conv-uuid-here"}
31
31
 
32
- conversation_add_message(scope="write", conversation_id="conv-uuid-here", agent_id="support_bot",
32
+ conversation_add_message(conversation_id="conv-uuid-here", agent_id="support_bot",
33
33
  input="What are your pricing tiers?",
34
34
  output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
35
35
  reasoning="Retrieved pricing page data. No special discounts apply.")
@@ -65,47 +65,42 @@ All three fields — `input`, `output`, and `reasoning` — must contain the **e
65
65
 
66
66
  The purpose of conversation storage is to create a faithful, replayable record. A rephrased summary loses the original wording, tone, and detail — making the stored conversation useless for review, debugging, or audit.
67
67
 
68
- ## Personal memory vs. team-shared knowledge — the three read paths
68
+ ## Personal memory vs. team-shared knowledge — the two read paths
69
69
 
70
- Agents on Cloud Meko have three distinct read surfaces. Pick the right one for the question.
70
+ Agents on Cloud Meko have two distinct read surfaces. Pick the right one for the question.
71
71
 
72
72
  | Read path | What it returns | How to call |
73
73
  |---|---|---|
74
- | Your own project memories | Memories you wrote under this `agent_id`, filtered by `(datapack_id, user_id, agent_id)` | `memory_search(agent_id="<your agent_id>", query="...", ...)` |
75
- | Cross-project common bucket | Memories any agent (including this one) wrote with `agent_id="meko_agent"` — the empty-default bucket for genuinely cross-project facts | `memory_search(agent_id="meko_agent", query="...", ...)` |
74
+ | Your personal memories | Everything you and any of your agents wrote for this user — filtered by `(datapack_id, user_id)`, **not** by `agent_id`. One call covers your project bucket, the `meko_agent` common bucket, and every other project's rows. | `memory_search(agent_id="<your agent_id>", query="...", ...)` — `agent_id` scopes the Langfuse trace, not the results |
76
75
  | Team's shared knowledge | Promoted memories + uploaded documents, visible to every member of the datapack | `knowledgebase_search(agent_id="<anything>", datapack_id="<datapack UUID>", query="...")` — `agent_id` is ignored |
77
76
 
78
- For a true fan-out across multiple specific agent_ids (e.g. also see what was written from `claude_code:other-repo` or `cursor:foo`), call `memory_search` once per agent_id — there's no single-call shortcut. Empty string is rewritten to `meko_agent` server-side; it does not drop the filter.
77
+ `agent_id` does not filter memory reads, so a single `memory_search` already spans all of your agents; there is no per-agent fan-out to do.
79
78
 
80
79
  ### How content gets into each surface
81
80
 
82
- - **Personal memories** — written by `memory_add`. Scoped per-user and per-agent from the moment of write. Only the writer sees them via MCP reads.
81
+ - **Personal memories** — written by `memory_add`. The `agent_id` records the writer but does not restrict reads; memories are scoped **per-user**, so any of that user's agents can read them via MCP, and no other user can.
83
82
  - **Team-shared Shared Knowledge** — arrives two ways:
84
- 1. The **user** (never the agent) promotes a personal memory to Knowledge via the Cloud UI's Learnings tab. That copies the row into the shared `knowledge_base` table with the `user_id` stripped, making it team-wide. Originating `agent_id` is preserved in metadata for provenance.
83
+ 1. An agent calls `memory_promote` for exact, user-confirmed memory UUIDs, or the user promotes them from the Cloud UI's Learnings tab. Promotion moves the memories and graph context into shared knowledge, strips `user_id`, preserves originating `agent_id` as provenance, and evicts the private mem0 records.
85
84
  2. The user uploads a file via Datapack → Actions → **Add Knowledge** in the Cloud UI. PDF/TXT/MD/JSON/MP4 up to 5MB each.
86
85
 
87
86
  Both show up in `knowledgebase_search`, tagged `metadata_filters.source: "memory"` vs other values so the agent can distinguish provenance in responses.
88
87
 
89
- **No MCP tool promotes to Shared Knowledge.** The agent can flag memories it thinks are worth promoting and suggest the user do it from the UI — but the action is user-initiated.
88
+ `memory_promote` is a one-way, destructive MCP path. Before calling it, retrieve exact UUIDs with `memory_search` or `memory_get_all`, show the exact candidates, explain team visibility and private-record eviction, and obtain explicit user confirmation. Only owners and maintainers may promote; report 403/auth failures without escalating scope or switching datapacks. The Cloud UI remains an alternative.
90
89
 
91
90
  ### When the user asks "what do you know about X?"
92
91
 
93
- A full sweep is three calls (budget for it — each is 2-6 seconds):
92
+ A full sweep is two calls (budget for it — each is 0.6-6 seconds):
94
93
 
95
94
  ```
96
- memory_search(agent_id="<your-agent-id>", query="X", conversation_id=..., ...)
97
- memory_search(agent_id="meko_agent", query="X", conversation_id=..., ...) # cross-project common bucket
95
+ memory_search(agent_id="<your-agent-id>", query="X", conversation_id=..., ...) # all your personal memories, every agent
98
96
  knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
99
97
  ```
100
98
 
101
- When you answer, be explicit about scope so the user knows why something is or isn't there:
99
+ The single `memory_search` already returns everything you and any other agent wrote for this user (`agent_id` doesn't filter memory reads) — no per-agent fan-out. When you answer, be explicit about scope so the user knows why something is or isn't there:
102
100
 
103
- - "I found this in your own project memories…"
104
- - "I found this in your common cross-project bucket (something you or another agent wrote under `meko_agent`)…"
101
+ - "I found this in your personal memories (something you or another of your agents saved earlier)…"
105
102
  - "I found this in your team's Shared Knowledge — someone (you or a teammate) promoted it earlier…"
106
- - "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab for a cross-agent view."
107
-
108
- For a true fan-out across other specific buckets (e.g. also see what was written from `claude_code:other-repo` or `cursor:foo`), call `memory_search` once per known agent_id — empty string just resolves to `meko_agent`, not a fan-out.
103
+ - "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab."
109
104
 
110
105
  ## Memory limitations for structured data
111
106