@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.
- package/README.md +31 -6
- package/assets/hooks-handlers/codex-session-end.sh +78 -0
- package/assets/hooks-handlers/lib/capture.js +163 -14
- package/assets/hooks-handlers/lib/checkpoint-timer.js +44 -2
- package/assets/hooks-handlers/session-end.sh +10 -0
- package/assets/hooks-handlers/session-start.sh +8 -1
- package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
- package/assets/scripts/package-desktop-skill.sh +32 -1
- package/assets/skills/meko-mcp-tools/SKILL.md +47 -41
- package/assets/skills/meko-mcp-tools/references/_sections.md +2 -4
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +29 -25
- package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +5 -7
- package/assets/skills/meko-mcp-tools/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +63 -46
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +6 -6
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +4 -4
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +17 -22
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +40 -39
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +1 -2
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +4 -18
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +9 -8
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +49 -42
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +6 -6
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +28 -24
- package/assets/skills/meko-mcp-tools-desktop/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +61 -36
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +4 -4
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +16 -19
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +40 -39
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +1 -2
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +3 -17
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +31 -21
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +8 -8
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +41 -0
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +1 -1
- package/bin/create-meko-setup.mjs +45 -6
- package/lib/clients/claude-code.mjs +8 -4
- package/lib/clients/claude-desktop.mjs +14 -0
- package/lib/clients/codex.mjs +23 -8
- package/lib/clients/common.mjs +2 -0
- package/lib/clients/cursor.mjs +7 -2
- package/lib/detect.mjs +7 -2
- package/lib/prompt.mjs +1 -1
- package/lib/url-selection.mjs +55 -0
- package/package.json +1 -1
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +0 -71
- 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:**
|
|
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
|
-
|
|
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
|
-
##
|
|
22
|
+
## Trace ID Rules
|
|
23
23
|
|
|
24
|
-
1. **`
|
|
25
|
-
2.
|
|
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.
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
199
|
+
**Destructive.**
|
|
186
200
|
|
|
187
201
|
```
|
|
188
|
-
conversation_delete(
|
|
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(
|
|
313
|
-
datapack_list(
|
|
314
|
-
datapack_describe(
|
|
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(
|
|
321
|
-
|
|
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 `
|
|
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(
|
|
26
|
-
conversation_id="<uuid>"
|
|
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(
|
|
40
|
+
memory_search(agent_id="<your-agent-id>",
|
|
41
41
|
conversation_id="<uuid>", query="...", datapack_id="dp-uuid-123")
|
|
42
|
-
knowledgebase_search(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
49
|
+
## No semantic search over conversation content
|
|
50
50
|
|
|
51
|
-
|
|
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,
|
|
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(
|
|
15
|
-
text="Customer Alice (alice@acme.com) prefers email, has Pro plan."
|
|
14
|
+
memory_add(agent_id="support_bot",
|
|
15
|
+
text="Customer Alice (alice@acme.com) prefers email, has Pro plan.")
|
|
16
16
|
|
|
17
|
-
memory_search(
|
|
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(
|
|
29
|
+
conversation_create(agent_id="support_bot", title="Pricing discussion")
|
|
30
30
|
-- Returns: {"id": "conv-uuid-here"}
|
|
31
31
|
|
|
32
|
-
conversation_add_message(
|
|
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
|
|
68
|
+
## Personal memory vs. team-shared knowledge — the two read paths
|
|
69
69
|
|
|
70
|
-
Agents on Cloud Meko have
|
|
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
|
|
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
|
-
|
|
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`.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|