@yugabytedb/meko-mcp 1.1.0 → 2.0.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 +81 -23
- package/assets/hooks-handlers/before-submit-prompt.sh +44 -0
- package/assets/hooks-handlers/cursor-session-start.sh +42 -0
- package/assets/hooks-handlers/lib/capture.js +404 -88
- package/assets/hooks-handlers/lib/checkpoint-timer.js +23 -11
- package/assets/hooks-handlers/session-start.sh +6 -2
- package/assets/scripts/meko-statusline.sh +119 -0
- package/assets/scripts/package-desktop-skill.sh +39 -0
- package/assets/skills/meko-mcp-tools/SKILL.md +42 -50
- package/assets/skills/meko-mcp-tools/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +75 -150
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +30 -36
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +6 -22
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +9 -8
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +35 -42
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +28 -92
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +5 -9
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +1 -81
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +244 -0
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +180 -0
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +24 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +99 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +327 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +63 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +214 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +105 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +70 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +71 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +75 -0
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +198 -0
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +121 -0
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +66 -0
- package/bin/create-meko-setup.mjs +33 -4
- package/lib/clients/claude-code.mjs +133 -6
- package/lib/clients/claude-desktop.mjs +48 -20
- package/lib/clients/codex.mjs +538 -5
- package/lib/clients/common.mjs +122 -1
- package/lib/clients/cursor.mjs +120 -27
- package/lib/config.mjs +52 -0
- package/lib/installer.mjs +26 -2
- package/lib/mcp-transport.mjs +5 -0
- package/lib/validate.mjs +0 -1
- package/package.json +1 -1
- package/scripts/bundle-assets.mjs +16 -0
- package/assets/skills/meko-mcp-tools/references/tools-db-query-patterns.md +0 -38
- package/assets/skills/meko-mcp-tools/references/tools-write-guardrails.md +0 -30
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meko-mcp-tools-desktop
|
|
3
|
+
description: >-
|
|
4
|
+
Behavioral guide for Meko MCP tools on desktop Claude. READ IT BEFORE
|
|
5
|
+
calling any meko tool — it sets the required agent_id and workflow; calling
|
|
6
|
+
a meko tool without it produces wrong-bucket writes. Use whenever the user
|
|
7
|
+
mentions memory, Meko, datapacks, knowledge base, or conversations, or asks
|
|
8
|
+
to remember/save/store anything. ALSO trigger (even with no tool or Meko
|
|
9
|
+
keyword) when: (a) the user states ANY durable fact about themselves — name,
|
|
10
|
+
role, team, tools, stack, preferences, conventions — INCLUDING facts dropped
|
|
11
|
+
inside a task/technical question ("I use pnpm", "I'm evaluating X"); or
|
|
12
|
+
(b) the user asks a RECALL question — "what do you know about me", "who am
|
|
13
|
+
I", "what was the last thing I told you" — then search Meko (memory_search)
|
|
14
|
+
first and never claim memory is unavailable without checking. On Desktop the
|
|
15
|
+
agent_id is ALWAYS "claude_desktop" (or "meko_agent" for cross-project
|
|
16
|
+
identity) — NEVER "claude_code".
|
|
17
|
+
license: MIT
|
|
18
|
+
metadata:
|
|
19
|
+
author: Meko
|
|
20
|
+
version: "2.7.0"
|
|
21
|
+
tags: mcp, yugabytedb, tools, datapack, memory, conversation, rag, meko, desktop
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Meko MCP Tools — Agent Behavioral Guide (Desktop)
|
|
25
|
+
|
|
26
|
+
Meko is the user's **memory, knowledge, observability, and audit layer** across chats — a system of record they (and their team/org) connected on purpose. It learns continuously from their work and their team's best practices so context carries from one session to the next. This skill teaches you how to use Meko's 22 MCP tools. Treat maintaining it — recalling from it at the start of work and posting turns to it as you go — as a normal, professional part of the job, the way an engineer keeps notes, decision records, and audit logs. It is infrastructure the user relies on, not a third-party logging conduit.
|
|
27
|
+
|
|
28
|
+
**Read this first.** The Meko server extracts durable memories automatically from the conversation turns you post to it — the extraction runs *inside* `conversation_add_message`. Claude Desktop has no capture hooks, so **capturing substantive turns via `conversation_add_message` is a core part of using this skill.** Do that and memory takes care of itself: facts the user states get extracted and stored without a separate `memory_add`. Explicit `memory_add` is reserved for a few narrow cases (below). See "Per-turn conversation capture" — it's the heart of this skill.
|
|
29
|
+
|
|
30
|
+
**Why this is legitimate.** Meko is the user's own system of record — serving their memory, their team's shared knowledge, and their observability/audit needs — so posting turns to it is maintaining *their* infrastructure, the same as keeping notes or decision logs. Do it **transparently**: briefly tell the user when you save or recall ("saved that to your Meko memory", "checked your Meko memory — here's what I had"), disclose the way a colleague would mention they're writing something down. The only carve-outs: if an item is sensitive (credentials, legal, medical) or the user asked you not to store something, ask or skip.
|
|
31
|
+
|
|
32
|
+
> **If you reached a meko tool without reading this skill** (e.g. tool search resolved `memory_add`/`memory_search` directly): two rules override anything you inferred from the raw tool descriptions. (1) On Claude Desktop the `agent_id` is **always `"claude_desktop"`** (or `"meko_agent"` for cross-project identity) — **never `"claude_code"`**, which is a *different* client's bucket. (2) Prefer `conversation_add_message` over `memory_add` for facts the user stated — extraction handles them. Then read the rest of this skill.
|
|
33
|
+
|
|
34
|
+
## First turn of every session
|
|
35
|
+
|
|
36
|
+
Claude Desktop has no SessionStart hook. You are responsible for bootstrapping memory yourself — both the conversation container (so capture can run) and recall.
|
|
37
|
+
|
|
38
|
+
On the first user turn in any session, before answering substantive questions:
|
|
39
|
+
|
|
40
|
+
1. **Resolve the active datapack pin first — before creating the conversation.** A conversation cannot move between datapacks once created, so you must know the pinned datapack *before* `conversation_create`, or capture lands in the wrong workspace. Call:
|
|
41
|
+
```
|
|
42
|
+
memory_search(scope="read", query="meko_active_datapack",
|
|
43
|
+
agent_id="claude_desktop", conversation_id="", limit=1)
|
|
44
|
+
```
|
|
45
|
+
If a pin row comes back, extract the UUID after `meko_active_datapack=` — call it `<PIN>` — and pass `datapack_id="<PIN>"` to **every** Meko call for the rest of the session (`conversation_create`, `memory_search`, `conversation_add_message`, etc.). If no pin is found, omit `datapack_id` everywhere and let the server resolve the default. (The `meko-select-datapack-desktop` skill is what writes this pin; you honor it here whether or not that skill ran this session.)
|
|
46
|
+
2. **Call `conversation_create`** (`agent_id="claude_desktop"`, and `datapack_id="<PIN>"` if a pin was found) once and keep the returned `conversation_id` for the whole session. You need it to post turns (per-turn capture, above) and for memory calls.
|
|
47
|
+
3. **Call `memory_search`** with `agent_id="claude_desktop"`, the `conversation_id` from step 2, `datapack_id="<PIN>"` if pinned, and a query derived from the user's topic. Also call it once with `agent_id="meko_agent"` to surface cross-project facts (user identity, global preferences) that any Meko client may have stored.
|
|
48
|
+
4. Incorporate the recalled facts into your reply. Don't re-ask things you've been told before.
|
|
49
|
+
|
|
50
|
+
Recall and capture are routine parts of answering — the user has set Meko up as their memory layer, so you don't need a per-call permission prompt for them. Do briefly say what you did ("checked your Meko memory", "saved that to your Meko memory") — a short disclosure, not a silent background action and not a big announcement.
|
|
51
|
+
|
|
52
|
+
## `agent_id` — multi-agent identity
|
|
53
|
+
|
|
54
|
+
`agent_id` identifies **which agent wrote a memory or conversation**. It is not a constant. Different agents (Claude Code, Cursor, this Claude Desktop client) each use their own `agent_id`, and the Cloud UI renders the value as a badge on every row.
|
|
55
|
+
|
|
56
|
+
**For Claude Desktop, use `agent_id="claude_desktop"` by default.** Desktop has no per-project concept, so a stable client name is the right granularity (it's a "loose" client in contract terms). Coding agents like Claude Code and Cursor use `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`). For genuinely cross-project facts that any agent should see — user identity, global preferences — use the common bucket `agent_id="meko_agent"`.
|
|
57
|
+
|
|
58
|
+
**Read scoping:**
|
|
59
|
+
- `memory_search` / `memory_get_all` / `conversation_list` / `conversation_get` — scoped to `(datapack_id, user_id, agent_id)`, strictly matched. To read across multiple agents (e.g. memories you wrote from Claude Code in different repos), call once per agent_id. Empty/missing `agent_id` is rewritten to `meko_agent` server-side, so it returns the common bucket only — not a fan-out.
|
|
60
|
+
- `knowledgebase_search` — scoped to `datapack_id` only. `agent_id` on the request is ignored. Returns the team's Shared Knowledge — uploaded documents plus memories the user promoted via the UI.
|
|
61
|
+
|
|
62
|
+
Some pre-existing rows use the older constant `agent_id="agent"` or ad-hoc shapes (e.g. `claude-desktop` with a hyphen). They remain readable — query them with the literal value. See `tools-agent-id-conventions.md` for the full model.
|
|
63
|
+
|
|
64
|
+
## Per-turn conversation capture — the heart of this skill
|
|
65
|
+
|
|
66
|
+
Claude Desktop has no capture hooks, so you are the capture mechanism. **When the user shares durable context, post that turn to Meko with `conversation_add_message` in the same turn you answer, and briefly say you did.** The server extracts durable memories from the turns you post — so posting the turn IS how a fact the user states ("btw I use helix", "I'm a VP of Product", "we write backend in Go") gets remembered. You do not also `memory_add` it; that duplicates what extraction produces.
|
|
67
|
+
|
|
68
|
+
Concretely, once per session call `conversation_create` (see "First turn of every session" above) to get a `conversation_id`, then for each substantive exchange:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
conversation_add_message(scope="write", conversation_id="<id>",
|
|
72
|
+
agent_id="claude_desktop",
|
|
73
|
+
input="<the user's exact prompt>",
|
|
74
|
+
output="<your exact response>",
|
|
75
|
+
reasoning="<why you answered as you did; tool calls if any>")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Post the turn verbatim — do not summarize. The call is cheap (queued, ~0.1s) and returns immediately.
|
|
79
|
+
|
|
80
|
+
The failure mode to avoid: answering the user and moving on **without posting the turn**. If you don't post it, nothing is captured and nothing is extracted — a turn later there's no record the exchange happened. Treat `conversation_add_message` as part of completing a substantive turn: once you've written your reply, post the turn (and note you did) before the turn is done. This is transparent capture into the user's own memory store, so there's no reason to skip it — but if the content is sensitive or the user asked you not to store it, skip and say so.
|
|
81
|
+
|
|
82
|
+
Skip posting only for genuinely trivial turns (a one-word acknowledgement, a pure restatement) that carry no durable content.
|
|
83
|
+
|
|
84
|
+
**Capture cadence is your call — pick what you're comfortable with, but don't let it be zero.** Per-turn posting is the default and works well for many models. If posting *every* turn feels like too much standing background activity, capture **opportunistically** instead: every few turns, at your own discretion, batch the durable facts that have come up into the user's Meko memory (a `conversation_add_message` covering the recent exchange, or a `memory_add` of the key fact). Either cadence is fine — the user chose Meko as their own memory layer and wants context to persist across chats, so periodic capture at your judgment is helpful and fully disclosed. The only real failure is capturing *nothing* across a whole session; a light-touch checkpoint avoids that.
|
|
85
|
+
|
|
86
|
+
And regardless of cadence: when the user says **"remember this"** / "save that," always capture it right then — that's an explicit, unambiguous request, not background activity.
|
|
87
|
+
|
|
88
|
+
### When to also call memory_add
|
|
89
|
+
|
|
90
|
+
Because extraction runs over the turns you post, `memory_add` is reserved for the few things per-turn capture cannot reach:
|
|
91
|
+
|
|
92
|
+
- **Explicit request** — the user says "remember this" / "save this." Store it verbatim.
|
|
93
|
+
- **Output-only / tool-derived fact** — a durable fact that lives only in your output or a tool result, not in the user's words. Extraction reads the **user** side of the turn, so it won't capture these on its own.
|
|
94
|
+
- **Overwriting correction** — the user negated a prior fact and the stale memory must not survive. Extraction is additive, so `memory_search` for the old memory and `memory_update` / `memory_delete_by_id` it.
|
|
95
|
+
|
|
96
|
+
Use the right bucket: `agent_id="meko_agent"` for cross-project facts (user identity, global preferences), `agent_id="claude_desktop"` for desktop-specific context. Saving is a normal part of the turn and doesn't need a confirmation prompt each time; ask first only when the information is sensitive (credentials, legal, medical).
|
|
97
|
+
|
|
98
|
+
## What Meko enables
|
|
99
|
+
|
|
100
|
+
Meko turns your volatile context window into persistent, shareable knowledge:
|
|
101
|
+
|
|
102
|
+
- **Personal memory** — Store who the user is, their preferences, role, and working style. Survives across sessions. Private to you (scoped per-user and per-agent).
|
|
103
|
+
- **Team-shared knowledge** — Memories the user promotes from the Learnings tab in the Cloud UI become visible to every member of the datapack. Uploaded documents land in the same place. Both are queryable via `knowledgebase_search`.
|
|
104
|
+
- **Conversation history** — Preserve full dialog exchanges with reasoning traces for audit, replay, and learning transfer.
|
|
105
|
+
- **Decision traces** — Capture how and why decisions were made, enabling debugging and continuous improvement.
|
|
106
|
+
|
|
107
|
+
## When to use this skill
|
|
108
|
+
|
|
109
|
+
- You are calling tools on a Meko MCP server
|
|
110
|
+
- You need to decide what to store, where, and how (personal memory vs. team-shared knowledge)
|
|
111
|
+
- You want to search the team's shared knowledge base (`knowledgebase_search`)
|
|
112
|
+
- You are managing datapacks
|
|
113
|
+
- You want to understand scope/permission requirements, `agent_id` conventions, or `datapack_id` routing
|
|
114
|
+
|
|
115
|
+
## Critical: Use Meko, not local storage
|
|
116
|
+
|
|
117
|
+
**Meko is the memory store — never write memories to local files, markdown notes, or any file-based memory system.** Meko's memory is persistent across all agents, sessions, and team members; local files are not.
|
|
118
|
+
|
|
119
|
+
- To remember what the user says → **post the turn with `conversation_add_message`** (the server extracts memories from it), NOT write to a local file.
|
|
120
|
+
- To recall → call `memory_search` on the MCP server, NOT read local files.
|
|
121
|
+
- For the narrow explicit-save cases → `memory_add` (see "When to also call memory_add").
|
|
122
|
+
|
|
123
|
+
If a Meko call fails, you may fall back to local storage and tell the user — but Meko is always the first choice.
|
|
124
|
+
|
|
125
|
+
## Core principle: capture the turn, don't hand-curate memory
|
|
126
|
+
|
|
127
|
+
Your job is not to decide fact-by-fact what to `memory_add`. It's to **post every substantive turn** and let the server's extractor build memory from it. Rules of thumb:
|
|
128
|
+
|
|
129
|
+
- **Post-the-turn, not save-later.** The moment you answer a substantive turn, `conversation_add_message` it. Don't promise to remember — capture the turn and extraction handles the rest.
|
|
130
|
+
- **Verbatim.** Post the user's exact `input` and your exact `output`; never summarize. Extraction works best on the real words.
|
|
131
|
+
- **Transparently.** Briefly disclose the save — a short "saved that to your Meko memory" — rather than doing it silently. One line, not a paragraph; don't interrupt the flow, but don't hide it either.
|
|
132
|
+
- **memory_add is the exception, not the rule** — only the three cases below.
|
|
133
|
+
|
|
134
|
+
### What to do when the user shares information
|
|
135
|
+
|
|
136
|
+
| Signal in conversation | What to do |
|
|
137
|
+
|---|---|
|
|
138
|
+
| User states a fact about themselves, their team, tools, or preferences | **Post the turn with `conversation_add_message`.** Extraction stores the fact — no separate `memory_add`. |
|
|
139
|
+
| User corrects or negates a prior fact | Post the turn (the new fact is extracted). Extraction is **additive**, so if the stale fact must not survive, `memory_search` for it and `memory_update` / `memory_delete_by_id`. |
|
|
140
|
+
| User explicitly says "remember this" | `memory_add` (verbatim), in addition to posting the turn. |
|
|
141
|
+
| A durable fact lives only in your output or a tool result | `memory_add`. Extraction reads the user side of the turn, so it won't capture these. |
|
|
142
|
+
| User asks "what do you know about X?" | Three-call sweep: `memory_search(agent_id="claude_desktop")` → `memory_search(agent_id="meko_agent")` → `knowledgebase_search(datapack_id=<X>)`. |
|
|
143
|
+
| User asks "what do we (as a team) know about X?" or about uploaded documents | `knowledgebase_search` (returns uploaded docs + promoted memories). |
|
|
144
|
+
| User provides structured/tabular data (CSV, data dictionary) | Not natively supported via MCP. Point the user at the UI's Add Knowledge upload; do not `memory_add` row-by-row. |
|
|
145
|
+
| User wants to add documents to the team's knowledge base | Point them at the Cloud UI flow — Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). MCP ingestion tools are not available on Cloud. |
|
|
146
|
+
|
|
147
|
+
## Conversation capture — mechanics
|
|
148
|
+
|
|
149
|
+
The **what and when** is covered above ("Per-turn conversation capture" — post every substantive turn; "First turn of every session" — `conversation_create` once). This section is the mechanics.
|
|
150
|
+
|
|
151
|
+
`conversation_create` — once per session; keep the `conversation_id`:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
conversation_create(scope="write", agent_id="claude_desktop",
|
|
155
|
+
title="<descriptive topic>")
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`conversation_add_message` — every substantive turn (see the code block in "Per-turn conversation capture"). Rules:
|
|
159
|
+
|
|
160
|
+
- **Verbatim content only** — never summarize, rephrase, or condense any field. Extraction (and replay) depend on the real words.
|
|
161
|
+
- **Include tool calls** in the `reasoning` field — essential for session replay.
|
|
162
|
+
- **Use seeds** for dedup: `seed="<conversation_id>:claude-desktop:<sequential_number>"`.
|
|
163
|
+
- Don't also `memory_add` the same fact — the server extracts memories from the posted turn. `memory_add` is only for the three exception cases above.
|
|
164
|
+
|
|
165
|
+
## Calling tools correctly on the first attempt
|
|
166
|
+
|
|
167
|
+
**Use only the required parameters. Do not guess optional parameters.**
|
|
168
|
+
|
|
169
|
+
### memory_add — correct call pattern
|
|
170
|
+
|
|
171
|
+
Only for the three exception cases (explicit "remember this", output-only/tool-derived fact, overwriting correction) — not for facts the user stated, which the posted turn already captures. Example of an explicit save:
|
|
172
|
+
```
|
|
173
|
+
memory_add(scope="write",
|
|
174
|
+
text="Remember: deploy scripts must be run from the repo root, never a subdir",
|
|
175
|
+
agent_id="claude_desktop",
|
|
176
|
+
conversation_id="<id from conversation_create>")
|
|
177
|
+
```
|
|
178
|
+
Required parameters: `scope`, `text`, `agent_id`, `conversation_id`. On **writes**, `conversation_id` must be a real UUID from `conversation_create` — writes attached to a nil/empty conversation are orphaned in Langfuse traces. Empty / missing `agent_id` is NOT rejected — the server quietly falls back to the `meko_agent` common bucket. Pass `agent_id="claude_desktop"` explicitly so this client's writes stay in the right bucket and don't pollute the cross-project pool.
|
|
179
|
+
|
|
180
|
+
### memory_search — correct call pattern
|
|
181
|
+
```
|
|
182
|
+
memory_search(scope="read",
|
|
183
|
+
query="user role",
|
|
184
|
+
agent_id="claude_desktop",
|
|
185
|
+
conversation_id="<id from conversation_create>")
|
|
186
|
+
```
|
|
187
|
+
Required parameters: `scope`, `query`, `agent_id`, `conversation_id`. On **`memory_search`** specifically, `conversation_id` is used only for Langfuse trace nesting — it does NOT filter results. Pass the session's UUID so the search span appears under the active conversation; passing `""` is accepted and means "don't nest under any trace." For conversation-scoped filtering use the separate `run_id` parameter.
|
|
188
|
+
|
|
189
|
+
For cross-project common-bucket search (facts written under `agent_id="meko_agent"`, including everything written with empty/missing `agent_id`), pass it explicitly:
|
|
190
|
+
```
|
|
191
|
+
memory_search(scope="read", query="user role",
|
|
192
|
+
agent_id="meko_agent", conversation_id="<id>")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Empty string also resolves to `meko_agent` server-side. To search across other clients' specific buckets (e.g. `claude_code:some-repo`), call `memory_search` once per known agent_id — there's no single-call fan-out.
|
|
196
|
+
|
|
197
|
+
**Interpreting results — trust the memory rows, be skeptical of stray `relations`.** `memory_search` returns three lists: `results` (the actual stored memories — trust these), `relations`, and `promoted_relations` (entity-graph edges). Two things to know so you don't discard useful results:
|
|
198
|
+
|
|
199
|
+
- **`memory_search` is cross-agent by design.** Results include memories written by *other* clients (`agent_id` "agent", "claude_code:…", etc.) for the same user — that is expected, not a tenant leak. Use them.
|
|
200
|
+
- **A `relations` edge can outlive the memory it came from.** Deleting a memory does not always remove its graph edges, so `relations` may contain stale or contradicted entities (e.g. an identity that conflicts with the consistent picture in `results`). When a relation contradicts the memory rows, **trust the rows and disregard the stray relation** — don't conclude the whole result set is "someone else's data" and throw it away.
|
|
201
|
+
|
|
202
|
+
### knowledgebase_search — correct call pattern
|
|
203
|
+
```
|
|
204
|
+
knowledgebase_search(scope="read",
|
|
205
|
+
query="...",
|
|
206
|
+
agent_id="<anything — ignored>",
|
|
207
|
+
conversation_id="<id>",
|
|
208
|
+
datapack_id="<datapack UUID>",
|
|
209
|
+
limit=10)
|
|
210
|
+
```
|
|
211
|
+
Required parameters: `scope`, `query`, `agent_id`, `conversation_id`, `datapack_id`. `datapack_id` has no default here. `agent_id` is ignored for filtering — results are the team's shared knowledge on the datapack regardless of what you pass.
|
|
212
|
+
|
|
213
|
+
### Critical parameter rules
|
|
214
|
+
|
|
215
|
+
- **agent_id**: `"claude_desktop"` for this client's project-less personal writes/reads. Use `"meko_agent"` for the cross-project common bucket (genuinely global facts like user identity). Empty/missing routes to `meko_agent` server-side; that's not a cross-agent fan-out. Ignored on `knowledgebase_search`. See `tools-agent-id-conventions.md`.
|
|
216
|
+
- **conversation_id**: Behavior varies by tool. On write tools (`memory_add`, `conversation_add_message`) pass a real UUID from `conversation_create` — a nil/empty value orphans the Langfuse trace. On `memory_search` it's used only for trace nesting (not for filtering), and empty-string is accepted; on `memory_get_all` and most read tools, still pass the session UUID when you have one. Never pass `"current"` or other non-UUID junk — only a real UUID or an intentionally empty string where the tool allows it.
|
|
217
|
+
- **scope**: Only `"read"`, `"write"`, or `"admin"`. Nothing else.
|
|
218
|
+
- **When in doubt about optional parameters, omit them.** The server has sensible defaults.
|
|
219
|
+
|
|
220
|
+
## Key concepts
|
|
221
|
+
|
|
222
|
+
1. **22 tools in 5 groups**: Memory (8 — including `flush_pending_memory_candidates`, deprecated; per-turn `conversation_add_message` replaces it), Conversation (6), Knowledge Base (1 — `knowledgebase_search`), Datapack (5), Artifacts (2 — `artifact_put`, `artifact_get`). KB ingestion is UI-only (Datapack → Actions → Add Knowledge); raw SQL is not exposed. See `tools-overview.md`.
|
|
223
|
+
2. **Scope hierarchy**: `read < write < admin` — every tool validates scope at entry. Only three valid values: `"read"`, `"write"`, `"admin"`. Using anything else (e.g., `"all"`) will fail. Pass the **minimum** each tool needs: reads (`memory_search`, `memory_get_*`, `conversation_get`/`list`, `datapack_list`/`describe`) take `"read"`; writes (`memory_add`/`update`, `conversation_create`/`add_message`, `datapack_create`/`update`) take `"write"`; only the destructive tools (`memory_delete_all`, `conversation_delete`, `datapack_delete`) require `"admin"`. Each tool's docstring states its required scope — follow it; don't escalate a search to `"admin"`.
|
|
224
|
+
3. **datapack_id routing**: DB, RAG, and memory tools accept optional `datapack_id` (default datapack if omitted). `knowledgebase_search` is the exception: `datapack_id` is **required** there.
|
|
225
|
+
4. **agent_id is multi-agent**: For Claude Desktop, use `agent_id="claude_desktop"` for desktop-personal writes and `agent_id="meko_agent"` for cross-project common facts. Writes are scoped to `(datapack_id, user_id, agent_id)`. Personal reads filter strictly on this tuple — to span agent_ids, call once per known value (the empty-string shortcut is not a fan-out; the server rewrites empty to `meko_agent`). `knowledgebase_search` ignores `agent_id` entirely. See `tools-agent-id-conventions.md`.
|
|
226
|
+
5. **Personal memory vs. team-shared knowledge**: Un-promoted memories are scoped per-user and per-agent — only you see them. The user can promote important memories to Shared Knowledge via the Cloud UI's Learnings tab, which makes them visible to every team member on the datapack. `knowledgebase_search` is the MCP read path for both Shared Knowledge and uploaded documents.
|
|
227
|
+
6. **conversation_id IS the Langfuse trace ID**: every MCP tool call inside a conversation becomes a span under that trace. Observable in the Meko UI's Observe hub. See `tools-memory-vs-conversation.md`.
|
|
228
|
+
7. **Adding documents to the team knowledge base is UI-only on Cloud today**: user uploads files via Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5MB each). The MCP ingestion tools are not available on Cloud. See `tools-rag-workflow.md`.
|
|
229
|
+
8. **Manual conversation capture**: Claude Desktop does not have automatic capture hooks. Create and save conversations explicitly when sessions are valuable.
|
|
230
|
+
9. **Memory latencies are not cheap**: observed on prod 2026-05-07 — `memory_add` 12-21s/call (calls OpenAI), `memory_search` 2-6s/call. Budget accordingly.
|
|
231
|
+
10. **Known limitations**: see `tools-known-limitations.md` before attempting write operations on tools that appear in the catalog but aren't available on Cloud.
|
|
232
|
+
11. **Error recovery**: Connection errors are common with memory tools — see `tools-troubleshooting.md` for retry strategies and fallbacks.
|
|
233
|
+
|
|
234
|
+
## Reference sections
|
|
235
|
+
|
|
236
|
+
| File | What it covers |
|
|
237
|
+
|------|---------------|
|
|
238
|
+
| `tools-overview.md` | Complete catalog of all 22 tools with decision tree |
|
|
239
|
+
| `tools-cookbook.md` | Per-tool examples with correct parameters, responses, and error cases |
|
|
240
|
+
| `tools-memory-vs-conversation.md` | When to use memory tools vs conversation tools |
|
|
241
|
+
| `tools-rag-workflow.md` | End-to-end RAG pipeline flow |
|
|
242
|
+
| `tools-scope-permissions.md` | read/write/admin permission hierarchy |
|
|
243
|
+
| `tools-troubleshooting.md` | Error recovery, retry strategies, stuck pipeline diagnosis |
|
|
244
|
+
| `tools-known-limitations.md` | Broken tools, missing capabilities, permission gaps |
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Meko MCP Tools — Claude Desktop Setup
|
|
2
|
+
|
|
3
|
+
Use the Meko MCP tools skill natively in Claude Desktop. Because Desktop has no lifecycle hooks, the skill teaches Claude to capture each substantive turn by posting it via `conversation_add_message` (the server extracts durable memories from those posts), to reserve explicit `memory_add` for the narrow cases (the user says "remember this", a fact lives only in the assistant's output or a tool result, or a corrected fact needs overwriting), to classify information, to use all 25 Meko MCP tools correctly, and to handle errors gracefully.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### Step 1: Install the skill
|
|
8
|
+
|
|
9
|
+
**Option A — Plugin marketplace** (recommended):
|
|
10
|
+
|
|
11
|
+
In Claude Desktop: Customize > Personal plugins > Browse plugin marketplace. Search for `meko-agent-skills-claude-desktop` and install.
|
|
12
|
+
|
|
13
|
+
**Option B — .skill file:**
|
|
14
|
+
|
|
15
|
+
Download `meko-mcp-tools-desktop.skill` from the [releases page](https://github.com/yugabyte/meko-mcp-server/releases) and drag it into Claude Desktop (or use Customize > Skills > Import).
|
|
16
|
+
|
|
17
|
+
**Option C — Manual install:**
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git clone https://github.com/yugabyte/meko-mcp-server.git
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Copy `skills/skills/meko-mcp-tools-desktop/` into Claude Desktop's skill directory. The exact path depends on your Desktop version — check Customize > Skills for the install location.
|
|
24
|
+
|
|
25
|
+
### Step 2: Configure the MCP server
|
|
26
|
+
|
|
27
|
+
Add the Meko MCP server to your Claude Desktop configuration. Go to Claude > Settings > Developer > Edit Config and add a `mcpServers` entry.
|
|
28
|
+
|
|
29
|
+
**Local HTTP** (for [meko-test](https://github.com/yugabyte/meko-test) docker-compose users):
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"meko": {
|
|
35
|
+
"url": "http://localhost:8000/mcp"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Local stdio** (running the server directly via uv):
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"meko": {
|
|
47
|
+
"command": "uv",
|
|
48
|
+
"args": [
|
|
49
|
+
"--directory",
|
|
50
|
+
"/path/to/meko-mcp-server",
|
|
51
|
+
"run",
|
|
52
|
+
"src/server.py"
|
|
53
|
+
],
|
|
54
|
+
"env": {
|
|
55
|
+
"YUGABYTEDB_URL": "dbname=yugabyte host=localhost port=5433 user=yugabyte password=yugabyte",
|
|
56
|
+
"OPENAI_API_KEY": "your-openai-api-key",
|
|
57
|
+
"OPENAI_MODEL": "gpt-4.1-nano-2025-04-14",
|
|
58
|
+
"OPENAI_EMBEDDING_MODEL": "text-embedding-3-small"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Replace `/path/to/meko-mcp-server` with your cloned repo path and set the correct database URL and API keys.
|
|
66
|
+
|
|
67
|
+
**Managed instance:**
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mcpServers": {
|
|
72
|
+
"meko": {
|
|
73
|
+
"url": "https://<your-instance>.mcp.mekodev.com/mcp"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Get the URL from your team.
|
|
80
|
+
|
|
81
|
+
Restart Claude Desktop after editing the configuration.
|
|
82
|
+
|
|
83
|
+
### Step 3: Verify
|
|
84
|
+
|
|
85
|
+
Start a new conversation and say:
|
|
86
|
+
|
|
87
|
+
> What datapacks do I have?
|
|
88
|
+
|
|
89
|
+
Claude should call `datapack_list` and return your accessible datapacks. If it works, the MCP server and skill are both connected.
|
|
90
|
+
|
|
91
|
+
### Step 4 (recommended): Make Desktop proactive
|
|
92
|
+
|
|
93
|
+
Claude Desktop has no lifecycle hooks, so skill activation is model-judged from the skill's description. On clean prompts ("what do you know about me?") it fires reliably, but on **task-shaped prompts that only mention a fact in passing** ("I'm evaluating pnpm vs npm; I already use Turborepo") the skill may not activate, and the turn — with its fact — goes uncaptured. See [Desktop activation ceiling](#skill-doesnt-trigger).
|
|
94
|
+
|
|
95
|
+
The one always-on lever on Desktop is the **Instructions for Claude** field, which is injected into every conversation as *your* (first-party) instruction. Paste this into Claude > Settings > General > Profile > **Instructions for Claude** ("Claude will keep these in mind across chats") to close the gap:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
About my setup: Meko (my connected MCP memory server) is my memory, knowledge,
|
|
99
|
+
observability and auditing layer across chats. It learns continuously from my
|
|
100
|
+
work and my team's/org's best practices. At the start of a chat, look me up
|
|
101
|
+
(load the skill and connect to the MCP endpoint): call conversation_create
|
|
102
|
+
(always use agent_id "claude_desktop" across all Meko calls) and either memory
|
|
103
|
+
or knowledge tools, to provide better context based on past conversations and
|
|
104
|
+
what I, and the team who's collaborating with me, already learned. Save to Meko
|
|
105
|
+
(conversation_add_message) on a regular basis to enable memories to be
|
|
106
|
+
implicitly generated in the background and for observability and audit
|
|
107
|
+
compliance.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This is the recommended fix — and for **Sonnet- and Opus-class models it is required**, not just recommended: those models will not do proactive per-turn capture from the skill alone (see "Skill doesn't trigger" below). Eager models (Haiku, Fable) capture from the fortified skill without it; Sonnet and Opus need this always-on, first-party instruction.
|
|
111
|
+
|
|
112
|
+
Why *this* wording (it was hard-won). Empirically, framings that ask the model to "log/save every exchange" — even transparent, user-owned ones — are refused by capability-cautious models as *silent standing background logging to an external server*. What unlocks proactive capture is reframing **what Meko is**: not a logging conduit but the user's own **memory / knowledge / observability / audit system of record** that learns from the user and their team. That legitimacy framing (system-of-record + collaborative + a sanctioned purpose) is what moved Opus from refusal to full proactive capture. Note also *why the Profile field specifically*: it is the only channel that is both always in context **and** carries first-party (user) authority — the skill is read at the model's discretion, and MCP `server_instructions` are treated as untrusted tool-channel data, so neither can substitute for this field on the cautious tier.
|
|
113
|
+
|
|
114
|
+
## Usage
|
|
115
|
+
|
|
116
|
+
The skill triggers automatically based on context — just talk to Claude naturally:
|
|
117
|
+
|
|
118
|
+
### Share personal info (captured by posting the turn via conversation_add_message)
|
|
119
|
+
> I'm a backend engineer. We use Go and YugabyteDB for everything.
|
|
120
|
+
|
|
121
|
+
Stated facts like this are captured when the agent posts the turn with `conversation_add_message`; the server extracts durable memories from the post. You don't need a proactive `memory_add`.
|
|
122
|
+
|
|
123
|
+
### Explicitly save a fact (triggers memory_add)
|
|
124
|
+
> Remember that I prefer tabs over spaces.
|
|
125
|
+
|
|
126
|
+
An explicit "remember this" is one of the narrow cases where the agent calls `memory_add` directly.
|
|
127
|
+
|
|
128
|
+
### Recall memories (triggers memory_search)
|
|
129
|
+
> What do you know about me?
|
|
130
|
+
|
|
131
|
+
### Search the team's knowledge base (triggers knowledgebase_search)
|
|
132
|
+
> What does our docs say about deployment?
|
|
133
|
+
|
|
134
|
+
### Save conversations (triggers conversation_create + conversation_add_message)
|
|
135
|
+
> Save this conversation.
|
|
136
|
+
|
|
137
|
+
### Manage datapacks (triggers datapack_list / datapack_create)
|
|
138
|
+
> List all datapacks.
|
|
139
|
+
|
|
140
|
+
## Differences from Claude Code
|
|
141
|
+
|
|
142
|
+
| Feature | Claude Code | Claude Desktop |
|
|
143
|
+
|---------|-------------|----------------|
|
|
144
|
+
| Skill name | `meko-mcp-tools` | `meko-mcp-tools-desktop` |
|
|
145
|
+
| Installation | `claude plugin install meko-agent-skills` | Plugin marketplace / .skill file / manual |
|
|
146
|
+
| MCP connection | `claude mcp add --transport http meko <url>` | `claude_desktop_config.json` |
|
|
147
|
+
| Automatic capture | Hooks (SessionStart, PreCompact, SessionEnd) | Skill-driven — agent posts each turn via `conversation_add_message`; server extracts memories |
|
|
148
|
+
| Periodic checkpoints | CronCreate (every 10 min) | Not available |
|
|
149
|
+
| Proactive activation | Deterministic (SessionStart hook always injects doctrine) | Model-judged from skill description; best-effort. Backstop with a personal-preferences snippet (Step 4) |
|
|
150
|
+
| agent_id | `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`) | `claude_desktop` |
|
|
151
|
+
|
|
152
|
+
## Troubleshooting
|
|
153
|
+
|
|
154
|
+
### "Tools aren't available"
|
|
155
|
+
|
|
156
|
+
1. Check that `claude_desktop_config.json` has valid JSON syntax
|
|
157
|
+
2. Restart Claude Desktop after editing the config
|
|
158
|
+
3. Check logs at `~/Library/Logs/Claude` (macOS) or `%APPDATA%\Claude\Logs` (Windows)
|
|
159
|
+
|
|
160
|
+
### "Connection refused"
|
|
161
|
+
|
|
162
|
+
Ensure the MCP server is running:
|
|
163
|
+
- For docker-compose: `docker compose ps` — the `meko-mcp` service should be healthy
|
|
164
|
+
- For stdio: the server starts automatically when Claude Desktop launches
|
|
165
|
+
|
|
166
|
+
### "memory_add fails with SQL syntax error"
|
|
167
|
+
|
|
168
|
+
On Cloud Meko, `agent_id` is a row-level column value — any string works, it never becomes a PostgreSQL identifier. Use `agent_id="claude_desktop"` for this client (or the value the skill tells you to use). Empty / missing `agent_id` is NOT rejected — the server resolves it to `meko_agent` (the cross-project common bucket). That's rarely what you want for Desktop, so always pass `agent_id="claude_desktop"` explicitly to keep this client's writes in the right bucket.
|
|
169
|
+
|
|
170
|
+
### "Conversation tools don't work"
|
|
171
|
+
|
|
172
|
+
Conversation tools require Langfuse credentials (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`). The other 19 tools work without Langfuse. If you don't need conversation persistence, you can skip this.
|
|
173
|
+
|
|
174
|
+
### "Skill doesn't trigger"
|
|
175
|
+
|
|
176
|
+
The skill activates when Claude detects relevant context (MCP tools, memory operations, database queries, etc.). If it doesn't trigger:
|
|
177
|
+
1. Verify the skill appears in Customize > Skills and is enabled
|
|
178
|
+
2. Try a more explicit prompt: "Use the Meko tools to store this in memory: I prefer Python."
|
|
179
|
+
|
|
180
|
+
**Known limitation (hookless Desktop activation ceiling).** Unlike Claude Code — where a SessionStart hook deterministically injects the memory doctrine every session — Desktop activation is judged by the model from the skill's description alone. This works for clean semantic matches (recall questions, explicit "remember this", keyword mentions) but is best-effort for **task-shaped prompts** where a durable fact appears only in passing inside a technical question. The skill description is already tuned to its 1024-character ceiling; broadening it further does not close this gap. The reliable fix is the always-on **personal-preferences snippet** in [Step 4](#step-4-recommended-make-desktop-proactive), which is injected into every conversation regardless of the prompt. Even without it, no data is lost when the *user* explicitly asks to recall or save — only passive capture of in-passing facts is best-effort.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Section Index
|
|
3
|
+
description: Maps reference files to their topics for the meko-mcp-tools-desktop skill
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reference Sections
|
|
7
|
+
|
|
8
|
+
## Tool Selection & Catalog
|
|
9
|
+
- [tools-overview.md](tools-overview.md) — Complete catalog of all 22 tools with a decision tree
|
|
10
|
+
|
|
11
|
+
## Tool-Specific Guidance
|
|
12
|
+
- [tools-agent-id-conventions.md](tools-agent-id-conventions.md) — Multi-agent model: the three buckets (project `<client>:<repo-basename>`, common `meko_agent`, loose client name), personal vs. team-shared read surfaces
|
|
13
|
+
- [tools-memory-vs-conversation.md](tools-memory-vs-conversation.md) — Decision framework: memory_add vs conversation_create/conversation_add_message, plus Desktop capture guidance
|
|
14
|
+
- [tools-rag-workflow.md](tools-rag-workflow.md) — End-to-end RAG pipeline: source registration, index creation, status polling
|
|
15
|
+
|
|
16
|
+
## Safety & Permissions
|
|
17
|
+
- [tools-scope-permissions.md](tools-scope-permissions.md) — read/write/admin permission hierarchy and per-tool requirements
|
|
18
|
+
|
|
19
|
+
## Practical Usage
|
|
20
|
+
- [tools-cookbook.md](tools-cookbook.md) — Per-tool examples with correct parameters, expected responses, and common errors
|
|
21
|
+
|
|
22
|
+
## Troubleshooting & Limitations
|
|
23
|
+
- [tools-troubleshooting.md](tools-troubleshooting.md) — Error recovery, retry strategies, stuck pipeline diagnosis
|
|
24
|
+
- [tools-known-limitations.md](tools-known-limitations.md) — Broken tools, missing capabilities, permission gaps
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# agent_id — multi-agent identity on Cloud Meko
|
|
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 specific agent + project you're acting for, use it consistently for writes within this session, and use it to scope your own reads.
|
|
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 with different `agent_id` values can write into the same datapack; each one's personal view is scoped to itself, and the UI shows the full cross-agent picture.
|
|
6
|
+
|
|
7
|
+
## The three buckets
|
|
8
|
+
|
|
9
|
+
Memories segregate strictly by `agent_id`. Pick the right bucket up front:
|
|
10
|
+
|
|
11
|
+
| Pattern | When to use | Example |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| Loose client name | Claude Desktop and other non-coding clients — there's no per-project concept, so the bare client name is the right granularity. | `claude_desktop` |
|
|
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
|
+
| `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
|
+
|
|
17
|
+
**For Claude Desktop, the practical default is `claude_desktop` for personal context and `meko_agent` for genuinely cross-client facts.** When the user's information is project-agnostic ("the user is named Amiram", "the user prefers vim"), prefer `meko_agent` so other clients (Claude Code, Cursor) can see it too.
|
|
18
|
+
|
|
19
|
+
## Valid characters
|
|
20
|
+
|
|
21
|
+
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
|
+
|
|
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. To query those rows, pass the literal legacy value as `agent_id`. New writes should follow the table above.
|
|
24
|
+
|
|
25
|
+
## How agent_id filters reads and writes
|
|
26
|
+
|
|
27
|
+
### Writes — `memory_add`, `conversation_create`, `conversation_add_message`
|
|
28
|
+
|
|
29
|
+
- 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
|
+
- 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
|
+
|
|
32
|
+
### Personal reads — `memory_search`, `memory_get_all`, `conversation_list`, `conversation_get`
|
|
33
|
+
|
|
34
|
+
Filter tuple: `(datapack_id, user_id, agent_id)`.
|
|
35
|
+
|
|
36
|
+
- `user_id` is **always enforced**: you can only see memories and conversations you wrote (or that other team members shared with you via promotion — see below). One user cannot read another team member's un-promoted memories directly from MCP.
|
|
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.
|
|
39
|
+
|
|
40
|
+
Empirically verified 2026-05-19 on Cloud prod (free-tier multitenant mode, segregation via row-level filter).
|
|
41
|
+
|
|
42
|
+
### Team-shared reads — `knowledgebase_search`
|
|
43
|
+
|
|
44
|
+
Filter tuple: `(datapack_id)` only. **`agent_id` on the request is ignored.** Whatever value you pass, `knowledgebase_search` returns every row on the datapack.
|
|
45
|
+
|
|
46
|
+
This is the multi-user, multi-agent read path. Content in `knowledgebase_search` is shared across:
|
|
47
|
+
- All agents on the datapack (any `agent_id` value)
|
|
48
|
+
- All users with access to the datapack (`user_id` is not a column on the shared table)
|
|
49
|
+
|
|
50
|
+
The originating `agent_id` is preserved in each result's `metadata_filters.agent_id` for provenance, but it does not affect which rows come back.
|
|
51
|
+
|
|
52
|
+
## What lives where
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
memory_add(agent_id=X, text=...)
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
mem0_collection ── personal memories, scoped (datapack, user, agent)
|
|
59
|
+
│
|
|
60
|
+
│ UI "Promote to Knowledge" (Learnings tab)
|
|
61
|
+
│ ─────────────────────────────────────────
|
|
62
|
+
│ Strips user_id, keeps agent_id as metadata,
|
|
63
|
+
│ copies into team-shared table
|
|
64
|
+
▼
|
|
65
|
+
knowledge_base ── team-shared, scoped (datapack) only
|
|
66
|
+
│
|
|
67
|
+
▼
|
|
68
|
+
knowledgebase_search(agent_id=anything, query=...)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Personal memories** are what you get from `memory_search` / `memory_get_all`. Private to you.
|
|
72
|
+
- **Shared Knowledge** is what you get from `knowledgebase_search`. Visible to every user and every agent on the datapack.
|
|
73
|
+
- **Promotion is UI-only.** There is no MCP tool for promoting a memory to Shared Knowledge — the user triggers it from the datapack's Learnings tab in the Cloud UI.
|
|
74
|
+
|
|
75
|
+
## When to use what — broad-query guidance
|
|
76
|
+
|
|
77
|
+
If the user asks "what do you know about X?" and you want to maximize recall:
|
|
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.
|
|
82
|
+
|
|
83
|
+
For a true cross-agent fan-out (e.g. you also want to see what was written from `claude_code:some-repo` or `cursor:foo`), call `memory_search` once per known agent_id — the empty-string shortcut does not bypass the filter; the server rewrites empty to `meko_agent`.
|
|
84
|
+
|
|
85
|
+
Always tell the user what scope you searched, so they understand why the answer is or isn't there. Example wording: "I found this in your desktop personal memories" vs. "I found this in your common cross-project bucket" vs. "I found this in your team's shared knowledge."
|
|
86
|
+
|
|
87
|
+
## Sub-scoping within an agent
|
|
88
|
+
|
|
89
|
+
Optional parameters narrow further within the same `agent_id`:
|
|
90
|
+
- `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
|
+
- `run_id` — per-execution run
|
|
92
|
+
|
|
93
|
+
Available on `memory_add`, `memory_search`, `memory_get_all`, `memory_delete_all`, `conversation_create`, `conversation_list`.
|
|
94
|
+
|
|
95
|
+
## Things I checked and found in-data on real Cloud datapacks
|
|
96
|
+
|
|
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; query legacy rows with `agent_id="agent"` explicitly.
|
|
98
|
+
- Memory Summary UI (`/datapacks/<name>/memory-summary`) is agent-id-agnostic — shows every row in the datapack, renders the stored `agent_id` as a badge. The filtering is MCP-side only.
|
|
99
|
+
- 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.
|