@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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# agent_id — multi-agent identity on Cloud Meko
|
|
2
2
|
|
|
3
|
-
`agent_id` identifies **which agent wrote a memory or created a conversation**. It is not a constant. Pick a value that represents the
|
|
3
|
+
`agent_id` identifies **which agent wrote a memory or created a conversation**. It is not a constant. Pick a value that represents the client you're acting for and use it consistently for writes and trace attribution within this session.
|
|
4
4
|
|
|
5
|
-
The Cloud UI (`cloud.mekodata.ai`) renders `agent_id` as a badge on every memory and conversation row — so the value you pick is user-visible. Multiple different agents
|
|
5
|
+
The Cloud UI (`cloud.mekodata.ai`) renders `agent_id` as a badge on every memory and conversation row — so the value you pick is user-visible. Multiple different agents can write into the same datapack, and both the UI and one `memory_search` show the user's full cross-agent picture.
|
|
6
6
|
|
|
7
7
|
## The three buckets
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Each memory is tagged with the writing `agent_id`. Pick the right value up front so attribution remains meaningful:
|
|
10
10
|
|
|
11
11
|
| Pattern | When to use | Example |
|
|
12
12
|
|---|---|---|
|
|
@@ -14,13 +14,15 @@ Memories segregate strictly by `agent_id`. Pick the right bucket up front:
|
|
|
14
14
|
| `<client>:<repo-basename>` | Coding agents (Claude Code, Cursor) writing project-scoped facts. **Not used by Claude Desktop**, but you'll see these values on rows written by other clients in the same datapack. | `claude_code:meko-mcp-server` |
|
|
15
15
|
| `meko_agent` | Cross-project common bucket — facts any agent should see regardless of project (user identity, global preferences). The server stores empty/missing `agent_id` here automatically. | `meko_agent` |
|
|
16
16
|
|
|
17
|
-
**For Claude Desktop, the practical default is `claude_desktop
|
|
17
|
+
**For Claude Desktop, the practical default is `claude_desktop`; use `meko_agent` for genuinely cross-client facts.** This controls attribution, not read visibility: the user's other agents can read either value.
|
|
18
|
+
|
|
19
|
+
**Don't write with another client's shape.** A Claude Desktop session that writes with `agent_id="claude_code"` (or `claude_code:something`) creates rows the UI will incorrectly attribute to Claude Code. Use `claude_desktop` when Desktop is running.
|
|
18
20
|
|
|
19
21
|
## Valid characters
|
|
20
22
|
|
|
21
23
|
The server stores `agent_id` as a row-level column value — it never becomes a PostgreSQL identifier on Cloud. Any printable string works: colons, hyphens, dots, underscores, spaces. Stay within what's readable in the UI badge.
|
|
22
24
|
|
|
23
|
-
Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`, `claude-code`, `claude_code`, `cursor:<slug>`, `claude-code:-Users-...`, `claude-desktop` (hyphenated). None of them cause errors
|
|
25
|
+
Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`, `claude-code`, `claude_code`, `cursor:<slug>`, `claude-code:-Users-...`, `claude-desktop` (hyphenated). None of them cause errors or prevent memory recall. New writes should follow the table above.
|
|
24
26
|
|
|
25
27
|
## How agent_id filters reads and writes
|
|
26
28
|
|
|
@@ -29,15 +31,19 @@ Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`,
|
|
|
29
31
|
- The row stores `(meko_datapack_id, meko_user_id, meko_agent_id)` — the user_id comes from your cognito account; the datapack_id defaults or is explicit; the agent_id is what you pass.
|
|
30
32
|
- If you pass an empty or whitespace-only `agent_id`, the server stores `meko_agent`. That's the common bucket — fine for cross-client facts; not what you want for desktop-personal writes.
|
|
31
33
|
|
|
32
|
-
### Personal reads — `memory_search`, `memory_get_all
|
|
34
|
+
### Personal memory reads — `memory_search`, `memory_get_all`
|
|
35
|
+
|
|
36
|
+
Filter tuple: `(datapack_id, user_id)`. `agent_id` is not applied on memory reads.
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
- `user_id` is **always enforced**: one user cannot read another team member's un-promoted memories directly from MCP.
|
|
39
|
+
- `agent_id` does **not** filter results. One search returns this user's memories across every agent, including `claude_desktop`, project agents, legacy values, and the `meko_agent` common bucket.
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
- `agent_id` is **strictly matched**: a search with `agent_id="claude_desktop"` returns only rows whose stored value is exactly that. Memories written from `agent_id="claude_code:foo"` are invisible to it.
|
|
38
|
-
- An empty `agent_id` is rewritten to `meko_agent` server-side, so a "broad" read with empty string returns only common-bucket rows — **not** a cross-client fan-out. To search across multiple agent_ids, call once per known value.
|
|
41
|
+
Empirically verified 2026-07-23 on Cloud prod: memories written under two distinct `agent_id` values were both returned by a search using a third value.
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
### Personal conversation reads — `conversation_get`, `conversation_list`
|
|
44
|
+
|
|
45
|
+
- `conversation_get` is agent-owned: pass the exact `agent_id` that created the conversation.
|
|
46
|
+
- `conversation_list` is not agent-filtered and returns the datapack's conversations for this user across agents.
|
|
41
47
|
|
|
42
48
|
### Team-shared reads — `knowledgebase_search`
|
|
43
49
|
|
|
@@ -57,7 +63,8 @@ memory_add(agent_id=X, text=...)
|
|
|
57
63
|
▼
|
|
58
64
|
mem0_collection ── personal memories, scoped (datapack, user, agent)
|
|
59
65
|
│
|
|
60
|
-
│
|
|
66
|
+
│ memory_promote (exact UUIDs + explicit confirmation)
|
|
67
|
+
│ or UI "Promote to Knowledge" (Learnings tab)
|
|
61
68
|
│ ─────────────────────────────────────────
|
|
62
69
|
│ Strips user_id, keeps agent_id as metadata,
|
|
63
70
|
│ copies into team-shared table
|
|
@@ -70,23 +77,20 @@ knowledgebase_search(agent_id=anything, query=...)
|
|
|
70
77
|
|
|
71
78
|
- **Personal memories** are what you get from `memory_search` / `memory_get_all`. Private to you.
|
|
72
79
|
- **Shared Knowledge** is what you get from `knowledgebase_search`. Visible to every user and every agent on the datapack.
|
|
73
|
-
- **Promotion
|
|
80
|
+
- **Promotion has MCP and UI paths.** `memory_promote` moves exact, user-confirmed memories into Shared Knowledge and evicts the private records; the Learnings tab is the user-driven alternative. Only datapack owners and maintainers may use the MCP path.
|
|
74
81
|
|
|
75
82
|
## When to use what — broad-query guidance
|
|
76
83
|
|
|
77
|
-
If the user asks "what do you know about X?"
|
|
78
|
-
|
|
79
|
-
1. **First call**: `memory_search(agent_id="claude_desktop", query="X")` — returns your desktop-personal memories.
|
|
80
|
-
2. **Second call**: `memory_search(agent_id="meko_agent", query="X")` — returns the common cross-project bucket: anything written with `agent_id="meko_agent"` from any client, plus rows the server stored under that name when called with empty `agent_id`.
|
|
81
|
-
3. **Third call**: `knowledgebase_search(agent_id="<anything>", datapack_id="<datapack>", query="X")` — returns team-shared knowledge. Useful when the answer may have been promoted by the user or a teammate.
|
|
84
|
+
If the user asks "what do you know about X?":
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
1. **`memory_search(agent_id="claude_desktop", query="X")`** — returns all of this user's personal memories across every agent. `agent_id` attributes the trace.
|
|
87
|
+
2. **`knowledgebase_search(agent_id="<anything>", datapack_id="<datapack>", query="X")`** — returns team-shared knowledge. Useful when the answer may have been promoted by the user or a teammate.
|
|
84
88
|
|
|
85
|
-
Always tell the user
|
|
89
|
+
Always tell the user which surface you searched: personal memory or team-shared knowledge.
|
|
86
90
|
|
|
87
|
-
##
|
|
91
|
+
## Optional sub-scoping
|
|
88
92
|
|
|
89
|
-
Optional parameters narrow
|
|
93
|
+
Optional parameters can narrow a call further:
|
|
90
94
|
- `user_id` — explicitly scope writes/reads to a specific end-user if your agent serves multiple (rare in Claude Desktop; more common in API products)
|
|
91
95
|
- `run_id` — per-execution run
|
|
92
96
|
|
|
@@ -94,6 +98,6 @@ Available on `memory_add`, `memory_search`, `memory_get_all`, `memory_delete_all
|
|
|
94
98
|
|
|
95
99
|
## Things I checked and found in-data on real Cloud datapacks
|
|
96
100
|
|
|
97
|
-
- `agent_id="agent"` appears on many legacy rows — it was the previous canonical constant. New writes should use the schema in the table above;
|
|
98
|
-
- Memory Summary UI (`/datapacks/<name>/memory-summary`)
|
|
101
|
+
- `agent_id="agent"` appears on many legacy rows — it was the previous canonical constant. New writes should use the schema in the table above; memory reads still return the legacy rows.
|
|
102
|
+
- Memory Summary UI (`/datapacks/<name>/memory-summary`) shows every row for the user and renders the stored `agent_id` as a badge, consistent with cross-agent MCP memory reads.
|
|
99
103
|
- Subagents spawned via the `Agent` tool in Claude Code do not automatically inherit the parent's `agent_id`. The parent must inject it into the spawn prompt. See the SKILL.md "When spawning subagents" section in the coding-agent skill.
|
|
@@ -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,21 @@
|
|
|
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.** The string `"agent"` appears in these examples as a placeholder shorthand; it is NOT a required constant. Substitute **your** client's
|
|
5
|
+
> **Note on `agent_id` in the examples below.** The string `"agent"` appears in these examples as a placeholder shorthand; it is NOT a required constant. Substitute **your** client's value: for Claude Desktop, use `claude_desktop`; for Claude Code/Cursor, use `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`). Write genuinely cross-project facts with `agent_id="meko_agent"`. On memory reads, `agent_id` attributes the trace but does not filter results. 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. For Claude Desktop that's `claude_desktop` for
|
|
11
|
+
**Critical:** Pass your session's `agent_id` on every memory call. For Claude Desktop that's `claude_desktop` for normal attribution, or `meko_agent` when writing genuinely cross-project facts. Writes retain that attribution, while personal memory reads span all of this user's agents.
|
|
12
12
|
|
|
13
13
|
### memory_add
|
|
14
14
|
|
|
15
15
|
**When to use:** NOT for facts the user states — those are captured when you post the turn with `conversation_add_message` and the server extracts them. Reserve `memory_add` for the three cases per-turn capture can't reach: (1) the user explicitly says "remember this"; (2) a durable fact 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="claude_desktop",
|
|
19
19
|
text="Remember: deploy scripts must be run from the repo root, never a subdir.")
|
|
20
20
|
```
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ memory_add(scope="write", agent_id="claude_desktop",
|
|
|
26
26
|
|
|
27
27
|
**With user scoping:**
|
|
28
28
|
```
|
|
29
|
-
memory_add(
|
|
29
|
+
memory_add(agent_id="agent", user_id="amiram",
|
|
30
30
|
text="Prefers Python for backend, Go for infrastructure.")
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -44,8 +44,10 @@ memory_add(scope="write", agent_id="agent", user_id="amiram",
|
|
|
44
44
|
|
|
45
45
|
**When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
|
|
46
46
|
|
|
47
|
+
**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.
|
|
48
|
+
|
|
47
49
|
```
|
|
48
|
-
memory_search(
|
|
50
|
+
memory_search(query="What programming language does the team use?", agent_id="agent")
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
**Response:**
|
|
@@ -55,7 +57,7 @@ memory_search(scope="read", query="What programming language does the team use?"
|
|
|
55
57
|
|
|
56
58
|
**With limit:**
|
|
57
59
|
```
|
|
58
|
-
memory_search(
|
|
60
|
+
memory_search(query="user preferences", agent_id="agent", limit=5)
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
---
|
|
@@ -65,12 +67,12 @@ memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
|
|
|
65
67
|
**When to use:** List everything stored for an agent. Useful at session start to load context.
|
|
66
68
|
|
|
67
69
|
```
|
|
68
|
-
memory_get_all(
|
|
70
|
+
memory_get_all(agent_id="agent")
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
**With user scoping:**
|
|
72
74
|
```
|
|
73
|
-
memory_get_all(
|
|
75
|
+
memory_get_all(agent_id="agent", user_id="amiram")
|
|
74
76
|
```
|
|
75
77
|
|
|
76
78
|
---
|
|
@@ -78,7 +80,7 @@ memory_get_all(scope="read", agent_id="agent", user_id="amiram")
|
|
|
78
80
|
### memory_get_by_id
|
|
79
81
|
|
|
80
82
|
```
|
|
81
|
-
memory_get_by_id(
|
|
83
|
+
memory_get_by_id(memory_id="mem-uuid-123", agent_id="agent")
|
|
82
84
|
```
|
|
83
85
|
|
|
84
86
|
---
|
|
@@ -88,7 +90,7 @@ memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
|
|
|
88
90
|
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
89
91
|
|
|
90
92
|
```
|
|
91
|
-
memory_update(
|
|
93
|
+
memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
---
|
|
@@ -96,19 +98,39 @@ memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses
|
|
|
96
98
|
### memory_delete_by_id
|
|
97
99
|
|
|
98
100
|
```
|
|
99
|
-
memory_delete_by_id(
|
|
101
|
+
memory_delete_by_id(memory_id="mem-uuid-123", agent_id="agent")
|
|
100
102
|
```
|
|
101
103
|
|
|
102
104
|
---
|
|
103
105
|
|
|
104
106
|
### memory_delete_all
|
|
105
107
|
|
|
106
|
-
**Destructive
|
|
108
|
+
**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.
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
memory_delete_all(agent_id="agent")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### memory_promote
|
|
117
|
+
|
|
118
|
+
**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.
|
|
107
119
|
|
|
108
120
|
```
|
|
109
|
-
|
|
121
|
+
memory_promote(memory_ids=["mem-uuid-123", "mem-uuid-456"],
|
|
122
|
+
agent_id="claude_desktop", conversation_id="<uuid from conversation_create>")
|
|
110
123
|
```
|
|
111
124
|
|
|
125
|
+
**Response:**
|
|
126
|
+
```json
|
|
127
|
+
{"inserted_ids": ["mem-uuid-123"], "updated_ids": ["mem-uuid-456"], "not_found_ids": []}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
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`.
|
|
131
|
+
|
|
132
|
+
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.
|
|
133
|
+
|
|
112
134
|
---
|
|
113
135
|
|
|
114
136
|
## Conversation Tools
|
|
@@ -118,7 +140,7 @@ memory_delete_all(scope="admin", agent_id="agent")
|
|
|
118
140
|
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
119
141
|
|
|
120
142
|
```
|
|
121
|
-
conversation_create(
|
|
143
|
+
conversation_create(agent_id="agent", user_id="amiram",
|
|
122
144
|
title="Debugging the auth middleware")
|
|
123
145
|
```
|
|
124
146
|
|
|
@@ -133,23 +155,21 @@ conversation_create(scope="write", agent_id="agent", user_id="amiram",
|
|
|
133
155
|
|
|
134
156
|
**When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
|
|
135
157
|
|
|
136
|
-
|
|
158
|
+
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
159
|
|
|
138
160
|
```
|
|
139
|
-
conversation_add_message(
|
|
161
|
+
conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
|
|
140
162
|
input="Why is the auth middleware returning 401?",
|
|
141
163
|
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)
|
|
164
|
+
reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
|
|
144
165
|
```
|
|
145
166
|
|
|
146
167
|
**With dedup seed (use when client hooks also write to Langfuse):**
|
|
147
168
|
```
|
|
148
|
-
conversation_add_message(
|
|
169
|
+
conversation_add_message(conversation_id="conv-uuid-123", agent_id="agent",
|
|
149
170
|
input="Why is the auth middleware returning 401?",
|
|
150
171
|
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)
|
|
172
|
+
seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
|
|
153
173
|
```
|
|
154
174
|
|
|
155
175
|
---
|
|
@@ -157,7 +177,7 @@ conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_i
|
|
|
157
177
|
### conversation_get
|
|
158
178
|
|
|
159
179
|
```
|
|
160
|
-
conversation_get(
|
|
180
|
+
conversation_get(conversation_id="conv-uuid-123", agent_id="agent",
|
|
161
181
|
include_messages=True, limit=50)
|
|
162
182
|
```
|
|
163
183
|
|
|
@@ -165,8 +185,12 @@ conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent"
|
|
|
165
185
|
|
|
166
186
|
### conversation_list
|
|
167
187
|
|
|
188
|
+
Target the datapack by `datapack_id` (UUID). It's optional — omit it to use the
|
|
189
|
+
pinned/default datapack, or pass the pinned `datapack_id`. Use `datapack_list`
|
|
190
|
+
to look up the id.
|
|
191
|
+
|
|
168
192
|
```
|
|
169
|
-
conversation_list(
|
|
193
|
+
conversation_list(datapack_id="<datapack-uuid>", agent_id="agent", limit=20)
|
|
170
194
|
```
|
|
171
195
|
|
|
172
196
|
---
|
|
@@ -174,7 +198,7 @@ conversation_list(scope="read", agent_id="agent", limit=20)
|
|
|
174
198
|
### conversation_update
|
|
175
199
|
|
|
176
200
|
```
|
|
177
|
-
conversation_update(
|
|
201
|
+
conversation_update(conversation_id="conv-uuid-123", agent_id="agent",
|
|
178
202
|
title="Resolved: Auth middleware issuer mismatch")
|
|
179
203
|
```
|
|
180
204
|
|
|
@@ -182,10 +206,10 @@ conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="ag
|
|
|
182
206
|
|
|
183
207
|
### conversation_delete
|
|
184
208
|
|
|
185
|
-
**Destructive
|
|
209
|
+
**Destructive.**
|
|
186
210
|
|
|
187
211
|
```
|
|
188
|
-
conversation_delete(
|
|
212
|
+
conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
|
|
189
213
|
```
|
|
190
214
|
|
|
191
215
|
---
|
|
@@ -202,7 +226,6 @@ See `tools-rag-workflow.md` for the decision table.
|
|
|
202
226
|
|
|
203
227
|
```
|
|
204
228
|
knowledgebase_search(
|
|
205
|
-
scope="read",
|
|
206
229
|
query="natural-language question",
|
|
207
230
|
agent_id="agent",
|
|
208
231
|
conversation_id="<uuid from conversation_create>",
|
|
@@ -229,7 +252,6 @@ Populated KBs return results with chunk content and similarity scores. An empty/
|
|
|
229
252
|
|
|
230
253
|
```
|
|
231
254
|
artifact_put(
|
|
232
|
-
scope="write",
|
|
233
255
|
filename="analysis_report.csv",
|
|
234
256
|
content_type="text/csv",
|
|
235
257
|
content_base64="<base64-encoded bytes>",
|
|
@@ -265,7 +287,6 @@ Save the `content_hash` — it's the retrieval key for `artifact_get`.
|
|
|
265
287
|
**Small files (< 1 MB) — content returned inline:**
|
|
266
288
|
```
|
|
267
289
|
artifact_get(
|
|
268
|
-
scope="read",
|
|
269
290
|
content_hash="a665a45920422f9d417e4867efdc4fb8a5f1f89ea5b8440b1ad4c4c6b8a7e4d3",
|
|
270
291
|
conversation_id="<uuid from conversation_create>",
|
|
271
292
|
agent_id="claude_desktop"
|
|
@@ -305,16 +326,20 @@ For large files use `local_path` to read the file. S3 URLs are never exposed.
|
|
|
305
326
|
### datapack_create / datapack_list / datapack_describe
|
|
306
327
|
|
|
307
328
|
```
|
|
308
|
-
datapack_create(
|
|
309
|
-
datapack_list(
|
|
310
|
-
datapack_describe(
|
|
329
|
+
datapack_create(name="analytics_prod")
|
|
330
|
+
datapack_list() # returns datapack_id for each datapack
|
|
331
|
+
datapack_describe(datapack_id="<uuid>", include_status=True)
|
|
311
332
|
```
|
|
312
333
|
|
|
313
334
|
### datapack_update / datapack_delete
|
|
314
335
|
|
|
336
|
+
`datapack_update` renames or edits a datapack's description. At least one of `name` / `description` must be provided (or the tool returns `nothing_to_update`). The server refuses to rename `meko_default_datapack` — the error is `"meko_default_datapack cannot be renamed"`. Passing `description=""` does NOT clear an existing description.
|
|
337
|
+
|
|
315
338
|
```
|
|
316
|
-
datapack_update(
|
|
317
|
-
|
|
339
|
+
datapack_update(datapack_id="<uuid>", name="renamed-datapack")
|
|
340
|
+
datapack_update(datapack_id="<uuid>", description="new description")
|
|
341
|
+
datapack_update(datapack_id="<uuid>", name="x", description="y")
|
|
342
|
+
datapack_delete(datapack_id="<uuid>") # Irreversible!
|
|
318
343
|
```
|
|
319
344
|
|
|
320
345
|
### Agent and knowledge-base management (NOT MCP — control-plane only)
|
|
@@ -322,6 +347,6 @@ datapack_delete(scope="admin", datapack_id="<uuid>") # Irreversible!
|
|
|
322
347
|
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:
|
|
323
348
|
|
|
324
349
|
- REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (agents), `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases` (KB sources).
|
|
325
|
-
- Or the Meko UI at `
|
|
350
|
+
- Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
|
|
326
351
|
|
|
327
352
|
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`.
|
|
@@ -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)")
|
|
@@ -56,8 +56,8 @@ The skill description is tuned to its 1024-char ceiling; broadening it further d
|
|
|
56
56
|
2. **Server-side guidance** — the `agent_id` tool docstrings and the server's connect-time instructions name `claude_desktop` as this client's bucket, so even a skill-less tool-search call avoids the wrong-bucket (`claude_code`) write.
|
|
57
57
|
3. Nothing is lost when the *user* explicitly recalls or saves — only passive capture of in-passing facts is best-effort.
|
|
58
58
|
|
|
59
|
-
## No conversation
|
|
59
|
+
## No semantic search over conversation content
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
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`.
|
|
62
62
|
|
|
63
|
-
For finding past knowledge by meaning,
|
|
63
|
+
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(
|
|
14
|
+
memory_add(agent_id="support_bot",
|
|
15
15
|
text="Customer Alice (alice@acme.com) prefers email, has Pro plan.", user_id="alice_123")
|
|
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", user_id="alice_123", 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,44 @@ 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)` and not by `agent_id` | `memory_search(agent_id="claude_desktop", query="...", ...)` — `agent_id` attributes the trace |
|
|
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
|
+
One `memory_search` already spans this user's memories across all agents; no per-agent fan-out is needed.
|
|
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 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 2-6 seconds):
|
|
94
93
|
|
|
95
94
|
```
|
|
96
95
|
memory_search(agent_id="claude_desktop", query="X", conversation_id=..., ...)
|
|
97
|
-
memory_search(agent_id="meko_agent", query="X", conversation_id=..., ...) # cross-project common bucket
|
|
98
96
|
knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
|
|
99
97
|
```
|
|
100
98
|
|
|
99
|
+
The single `memory_search` includes everything this user and their other agents wrote in the datapack.
|
|
100
|
+
|
|
101
101
|
When you answer, be explicit about scope so the user knows why something is or isn't there:
|
|
102
102
|
|
|
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`)…"
|
|
103
|
+
- "I found this in your personal memories (something you or another of your agents saved earlier)…"
|
|
105
104
|
- "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 clients' buckets (e.g. also see what was written from `claude_code:some-repo` or `cursor:foo`), call `memory_search` once per known agent_id — empty string just resolves to `meko_agent`, not a fan-out.
|
|
105
|
+
- "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab."
|
|
109
106
|
|
|
110
107
|
## Memory limitations for structured data
|
|
111
108
|
|