@yugabytedb/meko-mcp 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -33
- package/assets/hooks-handlers/codex-session-end.sh +13 -0
- package/assets/hooks-handlers/cursor-session-start.sh +19 -1
- package/assets/hooks-handlers/lib/capture-notices.js +321 -0
- package/assets/hooks-handlers/lib/capture-state.js +2079 -0
- package/assets/hooks-handlers/lib/capture-status-cli.js +82 -0
- package/assets/hooks-handlers/lib/capture.js +1653 -225
- package/assets/hooks-handlers/lib/checkpoint-timer.js +455 -50
- package/assets/hooks-handlers/lib/kiro-handler.js +738 -0
- package/assets/hooks-handlers/lib/terminal-handoff.js +418 -0
- package/assets/hooks-handlers/session-end.sh +3 -24
- package/assets/hooks-handlers/session-start.sh +8 -1
- package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
- package/assets/scripts/meko-statusline.sh +41 -1
- package/assets/scripts/package-desktop-skill.sh +32 -1
- package/assets/skills/meko-mcp-tools/SKILL.md +90 -137
- package/assets/skills/meko-mcp-tools/references/_sections.md +3 -5
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +31 -28
- 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 +69 -49
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +6 -6
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +29 -5
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +29 -92
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +42 -40
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +1 -2
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +18 -11
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +10 -9
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +51 -44
- 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 +34 -25
- 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 +63 -37
- 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 +19 -22
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +42 -40
- 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 +93 -16
- package/lib/capture-status.mjs +67 -0
- package/lib/clients/aliases.mjs +5 -0
- package/lib/clients/claude-code.mjs +8 -4
- package/lib/clients/claude-desktop.mjs +133 -4
- package/lib/clients/codex.mjs +29 -11
- package/lib/clients/common.mjs +2 -0
- package/lib/clients/cursor.mjs +7 -2
- package/lib/clients/index.mjs +2 -0
- package/lib/clients/kiro.mjs +705 -0
- package/lib/config.mjs +90 -0
- package/lib/detect.mjs +7 -2
- package/lib/installer.mjs +1 -0
- package/lib/migrate/adapters/codex.mjs +490 -0
- package/lib/migrate/id.mjs +28 -3
- package/lib/migrate/orchestrator.mjs +34 -7
- package/lib/migrate.mjs +4 -2
- package/lib/prompt.mjs +17 -2
- package/lib/url-selection.mjs +55 -0
- package/package.json +4 -4
- 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,38 +1,34 @@
|
|
|
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* (from the SessionStart `additionalContext`) — it is stored on the row as attribution. It does **not** filter reads: one `memory_search` / `memory_get_all` returns all of your memories across every `agent_id`. For cross-project facts, write with `agent_id="meko_agent"`.
|
|
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
|
|
|
22
23
|
**Response:**
|
|
23
24
|
```json
|
|
24
|
-
{"results": [{"id": "mem-uuid-123", "memory": "
|
|
25
|
-
```
|
|
26
|
-
|
|
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.")
|
|
25
|
+
{"results": [{"id": "mem-uuid-123", "memory": "Deploy scripts must be run from the repo root, never a subdir."}]}
|
|
31
26
|
```
|
|
32
27
|
|
|
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)
|
|
31
|
+
- Multi-topic dumps (transcripts, mixed logs + decisions) — store **one coherent fact per memory**, with the identifiers a later search will use
|
|
36
32
|
|
|
37
33
|
**Common errors:**
|
|
38
34
|
- `syntax error at or near "-"` — legacy error from the pre-multi-tenancy schema when `agent_id` became part of a PostgreSQL identifier. No longer applies on Cloud (agent_id is a TEXT column value, any string is accepted). If you hit it on a deployment that still uses the old schema, use underscores instead of hyphens.
|
|
@@ -45,9 +41,13 @@ memory_add(scope="write", agent_id="agent", user_id="amiram",
|
|
|
45
41
|
**When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
|
|
46
42
|
|
|
47
43
|
```
|
|
48
|
-
memory_search(
|
|
44
|
+
memory_search(query="What programming language does the team use?", agent_id="agent", conversation_id="<uuid>")
|
|
49
45
|
```
|
|
50
46
|
|
|
47
|
+
**Cross-conversation discovery.** `memory_search` returns hits across every stored conversation for the `(datapack_id, user_id)` pair, across all agents (`agent_id` scopes the call's trace, not the 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. For a deliberately cross-conversation search leave `run_id` off; to scope a search to a single conversation instead, pass `run_id=<conversation_id>` (it filters on `meko_conversation_id` — see `tools-known-limitations.md`).
|
|
48
|
+
|
|
49
|
+
**Relevance floor.** Vector-matched `results` below `MEMORY_SEARCH_MIN_SCORE` (mem0's cosine-similarity score, default `0.5`) are dropped as weak matches rather than returned. A query can come back with fewer results than `limit`, or an empty list, when nothing clears the bar; that means no sufficiently relevant memory, not a broken call.
|
|
50
|
+
|
|
51
51
|
**Response:**
|
|
52
52
|
```json
|
|
53
53
|
{"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89}]}
|
|
@@ -55,22 +55,19 @@ memory_search(scope="read", query="What programming language does the team use?"
|
|
|
55
55
|
|
|
56
56
|
**With limit:**
|
|
57
57
|
```
|
|
58
|
-
memory_search(
|
|
58
|
+
memory_search(query="user preferences", agent_id="agent", conversation_id="<uuid>", limit=5)
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
**Evidence cap (SKILL.md operating contract 3): reason over at most ~10 results, no matter how many were retrieved or requested.** If asked to "use everything," still select the ~10 most relevant and say that you did.
|
|
62
|
+
|
|
61
63
|
---
|
|
62
64
|
|
|
63
65
|
### memory_get_all
|
|
64
66
|
|
|
65
|
-
**When to use:** List
|
|
67
|
+
**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.
|
|
66
68
|
|
|
67
69
|
```
|
|
68
|
-
memory_get_all(
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**With user scoping:**
|
|
72
|
-
```
|
|
73
|
-
memory_get_all(scope="read", agent_id="agent", user_id="amiram")
|
|
70
|
+
memory_get_all(agent_id="agent", conversation_id="<uuid>")
|
|
74
71
|
```
|
|
75
72
|
|
|
76
73
|
---
|
|
@@ -78,7 +75,7 @@ memory_get_all(scope="read", agent_id="agent", user_id="amiram")
|
|
|
78
75
|
### memory_get_by_id
|
|
79
76
|
|
|
80
77
|
```
|
|
81
|
-
memory_get_by_id(
|
|
78
|
+
memory_get_by_id(memory_id="mem-uuid-123", agent_id="agent", conversation_id="<uuid>")
|
|
82
79
|
```
|
|
83
80
|
|
|
84
81
|
---
|
|
@@ -88,7 +85,7 @@ memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
|
|
|
88
85
|
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
89
86
|
|
|
90
87
|
```
|
|
91
|
-
memory_update(
|
|
88
|
+
memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent", conversation_id="<uuid>")
|
|
92
89
|
```
|
|
93
90
|
|
|
94
91
|
---
|
|
@@ -96,21 +93,39 @@ memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses
|
|
|
96
93
|
### memory_delete_by_id
|
|
97
94
|
|
|
98
95
|
```
|
|
99
|
-
memory_delete_by_id(
|
|
96
|
+
memory_delete_by_id(memory_id="mem-uuid-123", agent_id="agent", conversation_id="<uuid>")
|
|
100
97
|
```
|
|
101
98
|
|
|
102
99
|
---
|
|
103
100
|
|
|
104
101
|
### memory_delete_all
|
|
105
102
|
|
|
106
|
-
**Destructive
|
|
103
|
+
**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
104
|
|
|
108
105
|
```
|
|
109
|
-
memory_delete_all(
|
|
106
|
+
memory_delete_all(agent_id="agent", conversation_id="<uuid>")
|
|
110
107
|
```
|
|
111
108
|
|
|
112
109
|
---
|
|
113
110
|
|
|
111
|
+
### memory_promote
|
|
112
|
+
|
|
113
|
+
**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.
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
memory_promote(memory_ids=["mem-uuid-123", "mem-uuid-456"],
|
|
117
|
+
agent_id="agent", conversation_id="<uuid from conversation_create>")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Response:**
|
|
121
|
+
```json
|
|
122
|
+
{"inserted_ids": ["mem-uuid-123"], "updated_ids": ["mem-uuid-456"], "not_found_ids": []}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Get exact UUIDs from the `id` field of `memory_search` / `memory_get_all` results (never any other identifier), and follow the confirmation checklist in SKILL.md before calling. On 403 or any auth failure, report and stop — never escalate scope, change datapacks, or alter identity.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
114
129
|
## Conversation Tools
|
|
115
130
|
|
|
116
131
|
### conversation_create
|
|
@@ -118,7 +133,7 @@ memory_delete_all(scope="admin", agent_id="agent")
|
|
|
118
133
|
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
119
134
|
|
|
120
135
|
```
|
|
121
|
-
conversation_create(
|
|
136
|
+
conversation_create(agent_id="agent",
|
|
122
137
|
title="Debugging the auth middleware")
|
|
123
138
|
```
|
|
124
139
|
|
|
@@ -133,23 +148,19 @@ conversation_create(scope="write", agent_id="agent", user_id="amiram",
|
|
|
133
148
|
|
|
134
149
|
**When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
|
|
135
150
|
|
|
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.
|
|
137
|
-
|
|
138
151
|
```
|
|
139
|
-
conversation_add_message(
|
|
152
|
+
conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
|
|
140
153
|
input="Why is the auth middleware returning 401?",
|
|
141
154
|
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)
|
|
155
|
+
reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
|
|
144
156
|
```
|
|
145
157
|
|
|
146
158
|
**With dedup seed (use when client hooks also write to Langfuse):**
|
|
147
159
|
```
|
|
148
|
-
conversation_add_message(
|
|
160
|
+
conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
|
|
149
161
|
input="Why is the auth middleware returning 401?",
|
|
150
162
|
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)
|
|
163
|
+
seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
|
|
153
164
|
```
|
|
154
165
|
|
|
155
166
|
---
|
|
@@ -157,7 +168,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
|
|
|
157
168
|
### conversation_get
|
|
158
169
|
|
|
159
170
|
```
|
|
160
|
-
conversation_get(
|
|
171
|
+
conversation_get(conversation_id="conv-uuid-123", agent_id="agent",
|
|
161
172
|
include_messages=True, limit=50)
|
|
162
173
|
```
|
|
163
174
|
|
|
@@ -165,8 +176,12 @@ conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent"
|
|
|
165
176
|
|
|
166
177
|
### conversation_list
|
|
167
178
|
|
|
179
|
+
Target the datapack by `datapack_id` (UUID). It's optional — omit it to use the
|
|
180
|
+
pinned/default datapack, or pass the pinned `datapack_id`. Use `datapack_list`
|
|
181
|
+
to look up the id.
|
|
182
|
+
|
|
168
183
|
```
|
|
169
|
-
conversation_list(
|
|
184
|
+
conversation_list(datapack_id="<datapack-uuid>", agent_id="agent", limit=20)
|
|
170
185
|
```
|
|
171
186
|
|
|
172
187
|
---
|
|
@@ -174,7 +189,7 @@ conversation_list(scope="read", agent_id="agent", limit=20)
|
|
|
174
189
|
### conversation_update
|
|
175
190
|
|
|
176
191
|
```
|
|
177
|
-
conversation_update(
|
|
192
|
+
conversation_update(conversation_id="conv-uuid-123", agent_id="agent",
|
|
178
193
|
title="Resolved: Auth middleware issuer mismatch")
|
|
179
194
|
```
|
|
180
195
|
|
|
@@ -182,10 +197,10 @@ conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="ag
|
|
|
182
197
|
|
|
183
198
|
### conversation_delete
|
|
184
199
|
|
|
185
|
-
**Destructive
|
|
200
|
+
**Destructive.**
|
|
186
201
|
|
|
187
202
|
```
|
|
188
|
-
conversation_delete(
|
|
203
|
+
conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
|
|
189
204
|
```
|
|
190
205
|
|
|
191
206
|
---
|
|
@@ -202,7 +217,6 @@ See `tools-rag-workflow.md` for the decision table.
|
|
|
202
217
|
|
|
203
218
|
```
|
|
204
219
|
knowledgebase_search(
|
|
205
|
-
scope="read",
|
|
206
220
|
query="natural-language question",
|
|
207
221
|
agent_id="agent",
|
|
208
222
|
conversation_id="<uuid from conversation_create>",
|
|
@@ -212,7 +226,7 @@ knowledgebase_search(
|
|
|
212
226
|
|
|
213
227
|
Unlike memory tools, `datapack_id` has no default — you must pass it explicitly.
|
|
214
228
|
|
|
215
|
-
**Response (empty KB
|
|
229
|
+
**Response (empty KB):**
|
|
216
230
|
```json
|
|
217
231
|
{"results": [], "count": 0}
|
|
218
232
|
```
|
|
@@ -229,7 +243,6 @@ Populated KBs return results with chunk content and similarity scores. An empty/
|
|
|
229
243
|
|
|
230
244
|
```
|
|
231
245
|
artifact_put(
|
|
232
|
-
scope="write",
|
|
233
246
|
filename="analysis_report.csv",
|
|
234
247
|
content_type="text/csv",
|
|
235
248
|
content_base64="<base64-encoded bytes>",
|
|
@@ -255,6 +268,7 @@ Save the `content_hash` — it's the retrieval key for `artifact_get`.
|
|
|
255
268
|
**Common errors:**
|
|
256
269
|
- `invalid_base64` — `content_base64` is not valid base64; decode the file before passing it.
|
|
257
270
|
- `artifact_too_large` — file exceeds 5 MiB (default). Set `MEKO_MAX_ARTIFACT_UPLOAD_BYTES` to raise the limit.
|
|
271
|
+
- `PAT_RATE_LIMITED` — burst uploads throttle; the error carries **no `content_hash`**, which mimics silent write loss. Pace bulk uploads, back off ~60s. The `content_hash` is the plain SHA-256 of the bytes — compute it locally and verify important artifacts with an `artifact_get` read-back.
|
|
258
272
|
|
|
259
273
|
---
|
|
260
274
|
|
|
@@ -265,7 +279,6 @@ Save the `content_hash` — it's the retrieval key for `artifact_get`.
|
|
|
265
279
|
**Small files (< 1 MB) — content returned inline:**
|
|
266
280
|
```
|
|
267
281
|
artifact_get(
|
|
268
|
-
scope="read",
|
|
269
282
|
content_hash="a665a45920422f9d417e4867efdc4fb8a5f1f89ea5b8440b1ad4c4c6b8a7e4d3",
|
|
270
283
|
conversation_id="<uuid from conversation_create>",
|
|
271
284
|
agent_id="agent"
|
|
@@ -309,16 +322,23 @@ For large files use the `local_path` value to read the file with normal file too
|
|
|
309
322
|
### datapack_create / datapack_list / datapack_describe
|
|
310
323
|
|
|
311
324
|
```
|
|
312
|
-
datapack_create(
|
|
313
|
-
datapack_list(
|
|
314
|
-
datapack_describe(
|
|
325
|
+
datapack_create(name="analytics_prod")
|
|
326
|
+
datapack_list(conversation_id="<session conversation id>") # returns datapack_id for each datapack
|
|
327
|
+
datapack_describe(datapack_id="<uuid>", include_status=True)
|
|
315
328
|
```
|
|
316
329
|
|
|
317
330
|
### datapack_update / datapack_delete
|
|
318
331
|
|
|
332
|
+
`datapack_update` renames a datapack, edits its description, and/or opts it in/out of conversation-search embedding. `name`, `description`, and `conversation_search_opt_out` are all optional; pass at least one. If none are provided the tool returns `nothing_to_update` without hitting the API.
|
|
333
|
+
|
|
334
|
+
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. Conversation-search embedding is on by default; `conversation_search_opt_out=True` stops future turns from being indexed (already-cached turns are unaffected) and is restricted to the datapack's owner or a maintainer. This is best-effort, not a hard guarantee — a transient database error on the live embed path's opt-out check fails open, so a turn can occasionally still get embedded for an opted-out datapack.
|
|
335
|
+
|
|
319
336
|
```
|
|
320
|
-
datapack_update(
|
|
321
|
-
|
|
337
|
+
datapack_update(datapack_id="<uuid>", name="renamed-datapack")
|
|
338
|
+
datapack_update(datapack_id="<uuid>", description="new description")
|
|
339
|
+
datapack_update(datapack_id="<uuid>", name="x", description="y")
|
|
340
|
+
datapack_update(datapack_id="<uuid>", conversation_search_opt_out=True)
|
|
341
|
+
datapack_delete(datapack_id="<uuid>") # Irreversible!
|
|
322
342
|
```
|
|
323
343
|
|
|
324
344
|
### Agent and knowledge-base management (NOT MCP — control-plane only)
|
|
@@ -326,6 +346,6 @@ datapack_delete(scope="admin", datapack_id="<uuid>") # Irreversible!
|
|
|
326
346
|
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
347
|
|
|
328
348
|
- 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 `
|
|
349
|
+
- Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
|
|
330
350
|
|
|
331
351
|
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
|
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
These are current limitations of the Meko MCP tools. Know them upfront to avoid wasted tool calls.
|
|
4
4
|
|
|
5
|
+
## Lifetime request quotas by tier
|
|
6
|
+
|
|
7
|
+
`memory_search`, `knowledgebase_search`, and `memory_add` are quota-gated **per user, lifetime** — not per minute or per day. Default caps by plan:
|
|
8
|
+
|
|
9
|
+
| Tier | memory_search | knowledgebase_search | memory_add |
|
|
10
|
+
|---|---:|---:|---:|
|
|
11
|
+
| Free | 1,000 | 1,000 | 10,000 |
|
|
12
|
+
| Standard | 5,000 | 5,000 | 30,000 |
|
|
13
|
+
| Pro / Enterprise | uncapped | uncapped | uncapped |
|
|
14
|
+
|
|
15
|
+
When the cap is reached the tool returns an error object with code `free_tier_limit_reached` (on every tier; the `tier` field names the capped tier) and **no `results` key**.
|
|
16
|
+
|
|
17
|
+
- **Do not retry** — the cap is lifetime.
|
|
18
|
+
- **Budget searches**: polling, verify read-backs, and per-item sweeps all draw from one pool.
|
|
19
|
+
- **Never report this error as "no results"** — it is a failed search; see `tools-troubleshooting.md`.
|
|
20
|
+
|
|
21
|
+
## memory_get_all returns a fixed recent window — it has NO pagination
|
|
22
|
+
|
|
23
|
+
One call returns roughly the **20 most recent rows**; the response's `total` reports the true count. Scoping arguments do not narrow the window, and paging parameters are rejected — there is no way to reach older rows through this tool. A second call with `promoted=true` returns the recent window of promoted rows, not the remaining personal rows; neither call alone nor the two together is a complete listing. Follow SKILL.md operating contract 2: state the gap when `total` exceeds rows returned, never claim a complete enumeration, and use `memory_search` or `memory_get_by_id` for anything specific.
|
|
24
|
+
|
|
25
|
+
## run_id is a read/delete filter on the conversation id, not a write key
|
|
26
|
+
|
|
27
|
+
`memory_search(run_id=<conversation_id>)` and the memory delete tools filter on the row's `meko_conversation_id`, so passing a conversation id there correctly scopes the call to that one conversation — a supported, reliable way to read a single conversation's memories (read/write/delete scoping was made consistent in MEKO-473/MEKO-474, #271). The one gotcha is on the write side: `memory_add`'s own `run_id` is Langfuse trace metadata only and is **not** persisted as the row's conversation id, so a row written with `memory_add(run_id=X)` is not findable via `memory_search(run_id=X)`. Scope writes with `conversation_id`, then filter the matching read by that same id.
|
|
28
|
+
|
|
5
29
|
## No delete tools for RAG artifacts
|
|
6
30
|
|
|
7
31
|
There are no MCP tools to:
|
|
@@ -25,7 +49,7 @@ To **query** a built index, use `knowledgebase_search` — it returns both uploa
|
|
|
25
49
|
`memory_add` passes text through Mem0's fact extraction pipeline. This works well for:
|
|
26
50
|
- Facts: "Alice works at Acme Corp"
|
|
27
51
|
- Preferences: "User prefers dark mode"
|
|
28
|
-
- Entity relationships: "
|
|
52
|
+
- Entity relationships: "Alice reports to Bob"
|
|
29
53
|
|
|
30
54
|
It works **poorly** for:
|
|
31
55
|
- CSV rows or tabular data — columns and rows get dropped
|
|
@@ -36,7 +60,7 @@ It works **poorly** for:
|
|
|
36
60
|
|
|
37
61
|
1. **Write a single narrative summary** as a memory — one call, not row-by-row:
|
|
38
62
|
```
|
|
39
|
-
memory_add(
|
|
63
|
+
memory_add(
|
|
40
64
|
agent_id="<your session agent_id>",
|
|
41
65
|
conversation_id="<session conversation_id>",
|
|
42
66
|
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 +70,8 @@ It works **poorly** for:
|
|
|
46
70
|
|
|
47
71
|
Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
|
|
48
72
|
|
|
49
|
-
## No conversation
|
|
73
|
+
## No semantic search over conversation content
|
|
50
74
|
|
|
51
|
-
|
|
75
|
+
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
76
|
|
|
53
|
-
For finding past knowledge by meaning,
|
|
77
|
+
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.
|