@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
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
- A **preference**: "Customer budget is $50k"
|
|
9
9
|
- An **entity relationship**: "Alice works at Acme Corp"
|
|
10
10
|
|
|
11
|
-
Memory is backed by pgvector
|
|
11
|
+
Memory is backed by pgvector. Search is hybrid: semantic similarity, keyword matching, and a boost for memories that mention the entities named in your query (people, projects, tools). It retrieves relevant facts by meaning, not by conversation order.
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
memory_add(
|
|
15
|
-
text="Customer Alice (alice@acme.com) prefers email, has Pro plan."
|
|
14
|
+
memory_add(agent_id="support_bot",
|
|
15
|
+
text="Customer Alice (alice@acme.com) prefers email, has Pro plan.")
|
|
16
16
|
|
|
17
|
-
memory_search(
|
|
17
|
+
memory_search(query="What plan does Alice have?", agent_id="support_bot")
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## Use `conversation_create` + `conversation_add_message` when storing:
|
|
@@ -26,10 +26,10 @@ memory_search(scope="read", query="What plan does Alice have?", agent_id="suppor
|
|
|
26
26
|
Conversations are backed by Langfuse sessions and traces. They preserve full structure: who said what, in what order, with what reasoning.
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
conversation_create(
|
|
29
|
+
conversation_create(agent_id="support_bot", title="Pricing discussion")
|
|
30
30
|
-- Returns: {"id": "conv-uuid-here"}
|
|
31
31
|
|
|
32
|
-
conversation_add_message(
|
|
32
|
+
conversation_add_message(conversation_id="conv-uuid-here", agent_id="support_bot",
|
|
33
33
|
input="What are your pricing tiers?",
|
|
34
34
|
output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
|
|
35
35
|
reasoning="Retrieved pricing page data. No special discounts apply.")
|
|
@@ -65,47 +65,31 @@ All three fields — `input`, `output`, and `reasoning` — must contain the **e
|
|
|
65
65
|
|
|
66
66
|
The purpose of conversation storage is to create a faithful, replayable record. A rephrased summary loses the original wording, tone, and detail — making the stored conversation useless for review, debugging, or audit.
|
|
67
67
|
|
|
68
|
-
## Personal memory vs. team-shared knowledge — the
|
|
68
|
+
## Personal memory vs. team-shared knowledge — the two read paths
|
|
69
69
|
|
|
70
|
-
Agents on Cloud Meko have
|
|
70
|
+
Agents on Cloud Meko have two distinct read surfaces. Pick the right one for the question.
|
|
71
71
|
|
|
72
72
|
| Read path | What it returns | How to call |
|
|
73
73
|
|---|---|---|
|
|
74
|
-
| Your
|
|
75
|
-
| Cross-project common bucket | Memories any agent (including this one) wrote with `agent_id="meko_agent"` — the empty-default bucket for genuinely cross-project facts | `memory_search(agent_id="meko_agent", query="...", ...)` |
|
|
74
|
+
| Your personal memories | Everything you and any of your agents wrote for this user — filtered by `(datapack_id, user_id)`, **not** by `agent_id`; one call covers every bucket | `memory_search(agent_id="<your agent_id>", query="...", ...)` |
|
|
76
75
|
| Team's shared knowledge | Promoted memories + uploaded documents, visible to every member of the datapack | `knowledgebase_search(agent_id="<anything>", datapack_id="<datapack UUID>", query="...")` — `agent_id` is ignored |
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
`agent_id` does not filter memory reads, so a single `memory_search` already spans all of your agents; there is no per-agent fan-out to do.
|
|
79
78
|
|
|
80
79
|
### How content gets into each surface
|
|
81
80
|
|
|
82
|
-
- **Personal memories** — written by `memory_add`.
|
|
81
|
+
- **Personal memories** — written by `memory_add`. The `agent_id` records the writer but does not restrict reads; memories are scoped **per-user**, so any of that user's agents can read them via MCP, and no other user can.
|
|
83
82
|
- **Team-shared Shared Knowledge** — arrives two ways:
|
|
84
|
-
1.
|
|
83
|
+
1. An agent calls `memory_promote` for exact, user-confirmed memory UUIDs, or the user promotes them from the Cloud UI's Learnings tab. Promotion moves the memories 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
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
memory_search(agent_id="<your-agent-id>", query="X", conversation_id=..., ...)
|
|
97
|
-
memory_search(agent_id="meko_agent", query="X", conversation_id=..., ...) # cross-project common bucket
|
|
98
|
-
knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
When you answer, be explicit about scope so the user knows why something is or isn't there:
|
|
102
|
-
|
|
103
|
-
- "I found this in your own project memories…"
|
|
104
|
-
- "I found this in your common cross-project bucket (something you or another agent wrote under `meko_agent`)…"
|
|
105
|
-
- "I found this in your team's Shared Knowledge — someone (you or a teammate) promoted it earlier…"
|
|
106
|
-
- "I couldn't find anything in your personal memories. You might want to check the Cloud UI's Memory Summary tab for a cross-agent view."
|
|
107
|
-
|
|
108
|
-
For a true fan-out across other specific buckets (e.g. also see what was written from `claude_code:other-repo` or `cursor:foo`), call `memory_search` once per known agent_id — empty string just resolves to `meko_agent`, not a fan-out.
|
|
92
|
+
A full sweep is two calls: `memory_search` (all your personal memories, every agent — no per-agent fan-out) then `knowledgebase_search` (team-shared knowledge). When you answer, name which surface each finding came from, so the user knows why something is or isn't there.
|
|
109
93
|
|
|
110
94
|
## Memory limitations for structured data
|
|
111
95
|
|
|
@@ -119,72 +103,28 @@ There is no MCP-side "just put it in a database table" option — raw SQL access
|
|
|
119
103
|
|
|
120
104
|
## Memory Storage: automatic, not proactive
|
|
121
105
|
|
|
122
|
-
On Claude Code, do **not** proactively `memory_add` facts the user states
|
|
123
|
-
|
|
124
|
-
Explicit `memory_add` is reserved for the three cases automatic extraction cannot reach:
|
|
125
|
-
|
|
126
|
-
- **Explicit request** → the user says "remember this" / "save this."
|
|
127
|
-
- **Output-only / tool-derived fact** → a durable fact that lives only in your output or a tool result, never in a user turn. Extraction reads only the user turn, so it never sees these.
|
|
128
|
-
- **Overwriting correction** → a prior fact was negated and the stale memory must not survive. Extraction is additive (it adds the new fact but leaves the old one live), so `memory_search` for the stale memory and `memory_update` / `memory_delete_by_id` it.
|
|
129
|
-
|
|
130
|
-
Use `memory_search` at the start of sessions to recall what you already know before asking the user to repeat themselves.
|
|
131
|
-
|
|
132
|
-
## Using Both Together
|
|
133
|
-
|
|
134
|
-
Capture stores the full conversation (preserves structure) and extraction derives searchable memories from it — both happen automatically. Add an explicit `memory_add` only for the three cases above.
|
|
106
|
+
On Claude Code, do **not** proactively `memory_add` facts the user states — capture + server-side extraction stores them automatically. Explicit `memory_add` is reserved for the three cases extraction cannot reach (explicit "remember this"; output-only/tool-derived facts; overwriting a negated fact) — the canonical list and rules live in SKILL.md. Use `memory_search` at session start to recall what you already know.
|
|
135
107
|
|
|
136
108
|
## Key Retrieval Difference
|
|
137
109
|
|
|
138
|
-
- `memory_search`: **semantic similarity** across all memories
|
|
139
|
-
- `conversation_get`: **ordered
|
|
110
|
+
- `memory_search`: **semantic similarity** across all memories — relevant facts regardless of when stored.
|
|
111
|
+
- `conversation_get`: **ordered message turns** for one conversation. No semantic search; requires `conversation_id`.
|
|
140
112
|
|
|
141
113
|
## Automatic Conversation Capture
|
|
142
114
|
|
|
143
|
-
The
|
|
144
|
-
|
|
145
|
-
1. **Periodic checkpoint (~10 min)** — Agent-driven via CronCreate, uses `conversation_add_message` MCP tool directly
|
|
146
|
-
2. **PreCompact hook** — Shell script that fires before Claude Code's auto-compaction, captures via MCP JSON-RPC
|
|
147
|
-
3. **SessionEnd hook** — Shell script that fires at session termination, captures final exchanges
|
|
148
|
-
|
|
149
|
-
### What gets captured
|
|
150
|
-
|
|
151
|
-
The full transcript including:
|
|
152
|
-
- **User prompts** — verbatim text (the `input` field)
|
|
153
|
-
- **Assistant responses** — all text blocks (the `output` field)
|
|
154
|
-
- **Tool calls** — tool name + input parameters (the `reasoning` field)
|
|
155
|
-
- **Tool results** — output from tool executions (appended to `reasoning`)
|
|
156
|
-
|
|
157
|
-
This is more than just text — tool calls and results are critical context for session replay, cross-agent sharing, and compaction.
|
|
115
|
+
The plugin captures conversations via three mechanisms — a periodic checkpoint (~10 min), a PreCompact hook, and a SessionEnd hook — storing the full transcript verbatim (user prompts as `input`, assistant text as `output`, tool calls and results as `reasoning`).
|
|
158
116
|
|
|
159
|
-
|
|
117
|
+
Each message's seed is `<conversation_id>:<user_message_uuid>`; all three mechanisms derive the same deterministic trace ID from it, so overlapping captures are idempotent. A shared watermark file tracks what has been saved.
|
|
160
118
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
### When to manually store conversations
|
|
164
|
-
|
|
165
|
-
Automatic capture handles the raw exchange. You should still manually use `conversation_create` + `conversation_add_message` when:
|
|
166
|
-
- The user explicitly asks to "save this conversation"
|
|
167
|
-
- You want to add curated `reasoning` traces beyond raw tool calls
|
|
168
|
-
- You want to store a selected subset of the conversation with a descriptive title
|
|
169
|
-
|
|
170
|
-
### Watermark coordination
|
|
171
|
-
|
|
172
|
-
A shared watermark file at `~/.claude/meko-capture/<session-id>.watermark.json` tracks what has been saved. Both hooks and the agent's periodic checkpoint use this to avoid reprocessing already-captured exchanges.
|
|
119
|
+
Manually use `conversation_create` + `conversation_add_message` only when the user explicitly asks to save a conversation, or you want curated `reasoning` traces or a titled subset.
|
|
173
120
|
|
|
174
121
|
## Observability: conversation_id IS the Langfuse trace ID
|
|
175
122
|
|
|
176
|
-
This is the feature agents tend to miss.
|
|
123
|
+
This is the feature agents tend to miss.
|
|
177
124
|
|
|
178
|
-
- `conversation_create` returns a `conversation_id
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
- Child spans reveal internals. Observed structure:
|
|
182
|
-
- `memory_add`: `Memory Add (Meko MCP)` → `Create a new memory in Mem0` → `Bulk Payload Update (yugabytedb / vector)` → `Execute Query (yugabytedb / vector)`
|
|
183
|
-
- `memory_search`: `Memory Search (Meko MCP)` → `Search for memories based on a query in Mem0` (Retriever)
|
|
184
|
-
- `conversation_add_message`: `Conversation Add Message (Meko MCP)` → `Conversation Message Added` span → `Reasoning` generation (the `reasoning` field is stored as a Langfuse *generation*-typed span, not a plain text field)
|
|
185
|
-
- `knowledgebase_search`: `Knowledgebase Search (Meko MCP)` → multiple `Execute Query (yugabytedb)` child spans
|
|
186
|
-
- Trace tags include `agent:<agent_id>` and the Meko org UUID. Both are searchable/filterable in Langfuse.
|
|
187
|
-
- Each datapack has its own Langfuse project — traces for a tool call land in the project for whichever `datapack_id` was on the call (or the default datapack if omitted).
|
|
125
|
+
- `conversation_create` returns a `conversation_id`; that ID **is** the Langfuse trace_id — not a separate trace, the same identifier.
|
|
126
|
+
- Every MCP tool call made with that `conversation_id` becomes a span under the trace, named after the tool (e.g. `Memory Search (Meko MCP)`), with child spans exposing the storage steps.
|
|
127
|
+
- Trace tags include `agent:<agent_id>` and are filterable. Each datapack has its own Langfuse project — traces land in the project of whichever `datapack_id` was on the call.
|
|
188
128
|
|
|
189
129
|
### Finding a trace in the UI
|
|
190
130
|
|
|
@@ -195,14 +135,14 @@ Two navigation paths, both verified in the Meko UI:
|
|
|
195
135
|
|
|
196
136
|
The Conversations-tab row preview shows the first user turn verbatim, plus the agent_id tag, message count, and started-at timestamp. If you want a conversation to be recognizable in the UI, call `conversation_add_message` with a clean first-turn `input` early in the session.
|
|
197
137
|
|
|
198
|
-
###
|
|
138
|
+
### Typical latencies
|
|
199
139
|
|
|
200
140
|
From real traces, not the docstring happy path:
|
|
201
141
|
|
|
202
142
|
| Tool | Latency per call |
|
|
203
143
|
|---|---|
|
|
204
|
-
| `memory_add` |
|
|
205
|
-
| `memory_search` |
|
|
144
|
+
| `memory_add` | ~10-30 seconds (calls an LLM for extraction, then writes to the vector store; scales with payload size) |
|
|
145
|
+
| `memory_search` | ~2-6 seconds (small, focused memories; whole-document stores read ~4x slower — chunk on write) |
|
|
206
146
|
| `knowledgebase_search` | 0.6 seconds (empty index; will grow with index size) |
|
|
207
147
|
| `conversation_add_message` | 0.11 seconds (fire-and-forget; queued to Langfuse) |
|
|
208
148
|
|
|
@@ -210,9 +150,6 @@ From real traces, not the docstring happy path:
|
|
|
210
150
|
|
|
211
151
|
### Proactive diagnostic pattern
|
|
212
152
|
|
|
213
|
-
If a user reports "my memory_add didn't seem to save", open the Observe hub
|
|
214
|
-
|
|
215
|
-
- A `Memory Add (Meko MCP)` span with `Create a new memory in Mem0` child → the call reached Mem0. The fact extractor may have returned `"results": []` (common on short or non-fact-shaped text; not a bug, but lossy).
|
|
216
|
-
- No span at all → the call never reached the server. Likely a transport / auth / `conversation_id` mismatch issue.
|
|
153
|
+
If a user reports "my memory_add didn't seem to save", open the Observe hub, filter on their `conversation_id`, and check the span tree: a memory-add span present means the call arrived (the extractor may still have returned `"results": []` on non-fact-shaped text); no span means the call never reached the server (transport / auth / `conversation_id` mismatch).
|
|
217
154
|
|
|
218
|
-
The mem0 extractor is lossy — it extracts atomic facts and
|
|
155
|
+
The mem0 extractor is lossy — it extracts atomic facts and may drop prose that doesn't look fact-shaped to it; a `memory_add` can return `"results": []` on non-fact-shaped text. When preserving authoritative text matters, store it via `conversation_add_message` (verbatim in `input`/`output`/`reasoning`) — the conversation path preserves text without LLM re-extraction.
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
# Complete Tool Catalog and Decision Tree
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**23 Meko data tools covered by this skill.** These are the tools available in production, grouped as: Memory (8), Conversation (6), Knowledge Base (1), Datapack (5), Artifacts (2), Observability (1). Combined Meko + AMP endpoints may expose additional infrastructure tools; those are outside this skill's scope.
|
|
4
4
|
|
|
5
5
|
## Quick health check before using tools
|
|
6
6
|
|
|
7
7
|
Before starting a session, verify that the Meko MCP tools are working:
|
|
8
8
|
|
|
9
|
-
1. `memory_search(
|
|
10
|
-
2. `datapack_list(
|
|
9
|
+
1. `memory_search(query="test", agent_id="<your-session-agent-id>", conversation_id="<session-conversation-id>")` — Confirms memory subsystem is up. Use the `agent_id` and `conversation_id` from the SessionStart `additionalContext`. May fail with "connection already closed" — see `tools-troubleshooting.md`.
|
|
10
|
+
2. `datapack_list(conversation_id="<session-conversation-id>")` — Confirms Meko API connectivity. Returns the datapacks your token has access to.
|
|
11
11
|
|
|
12
12
|
## Decision tree: which tool do I need?
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
User wants to...
|
|
16
|
-
├── Search
|
|
16
|
+
├── Search personal context? ---------------> memory_search (read)
|
|
17
|
+
├── Search shared datapack knowledge? ------> knowledgebase_search (read)
|
|
17
18
|
├── Add documents to a knowledge base? -----> point user at Meko UI: Datapack → Actions → Add Knowledge
|
|
18
19
|
│ (no MCP tool — Cloud uses UI ingestion only)
|
|
19
20
|
├── Store or recall information?
|
|
20
21
|
│ ├── Store a fact/preference/entity? -----------> memory_add (write)
|
|
21
22
|
│ ├── Store a full conversation (multi-turn)? ---> conversation_create + conversation_add_message (write)
|
|
22
23
|
│ ├── Search past knowledge? --------------------> memory_search (read)
|
|
24
|
+
│ ├── Share private memories with the team? -----> memory_promote (write; owner/maintainer only)
|
|
23
25
|
│ └── Retrieve a past conversation? -------------> conversation_get (read)
|
|
24
26
|
├── Persist or retrieve a file?
|
|
25
27
|
│ ├── Upload a generated file (report, CSV, PDF)? -> artifact_put (write)
|
|
@@ -32,58 +34,58 @@ Agent / knowledge-base lifecycle is managed **outside** the MCP surface — typi
|
|
|
32
34
|
|
|
33
35
|
## Knowledge Base Tools (1)
|
|
34
36
|
|
|
35
|
-
| Tool |
|
|
36
|
-
|
|
37
|
-
| `knowledgebase_search(
|
|
37
|
+
| Tool | Purpose |
|
|
38
|
+
|------|---------|
|
|
39
|
+
| `knowledgebase_search(query, agent_id, conversation_id, datapack_id, limit=10)` | Semantic search across KB chunks. `datapack_id` is REQUIRED (no default). |
|
|
38
40
|
|
|
39
41
|
## Memory Tools (8)
|
|
40
42
|
|
|
41
|
-
| Tool |
|
|
42
|
-
|
|
43
|
-
| `memory_add(
|
|
44
|
-
| `memory_search(
|
|
45
|
-
| `memory_get_by_id(
|
|
46
|
-
| `memory_get_all(
|
|
47
|
-
| `memory_update(
|
|
48
|
-
| `memory_delete_by_id(
|
|
49
|
-
| `memory_delete_all(
|
|
50
|
-
| `
|
|
43
|
+
| Tool | Purpose |
|
|
44
|
+
|------|---------|
|
|
45
|
+
| `memory_add(text, agent_id, conversation_id, run_id=None, metadata=None, messages=None, datapack_id=None)` | Store fact/preference/entity as long-term memory |
|
|
46
|
+
| `memory_search(query, agent_id, conversation_id="", limit=10, datapack_id=None)` | Hybrid search across memories (semantic + keyword + entity boost). `conversation_id` optional (omit or pass `""` for cross-conversation discovery). |
|
|
47
|
+
| `memory_get_by_id(memory_id, agent_id, conversation_id, datapack_id=None)` | Direct pgvector row lookup by UUID. Preferred over `memory_search` for exact-id verification. |
|
|
48
|
+
| `memory_get_all(agent_id, conversation_id, run_id=None, datapack_id=None)` | List all of the user's memories (every agent — `agent_id` does not filter) |
|
|
49
|
+
| `memory_update(memory_id, text, agent_id, conversation_id, datapack_id=None)` | Overwrite memory text |
|
|
50
|
+
| `memory_delete_by_id(memory_id, agent_id, conversation_id, datapack_id=None)` | Delete a single memory |
|
|
51
|
+
| `memory_delete_all(agent_id, conversation_id, run_id=None, datapack_id=None)` | Delete all memories for agent (destructive) |
|
|
52
|
+
| `memory_promote(conversation_id, memory_ids, agent_id=None, datapack_id=None)` | Promote private memories into the datapack's shared knowledge base (moves them out of mem0, then evicts from mem0 — one-way). Owners/maintainers only; viewers/contributors get 403. |
|
|
51
53
|
|
|
52
54
|
## Conversation Tools (6)
|
|
53
55
|
|
|
54
|
-
| Tool |
|
|
55
|
-
|
|
56
|
-
| `conversation_create(
|
|
57
|
-
| `conversation_add_message(
|
|
58
|
-
| `conversation_get(
|
|
59
|
-
| `conversation_list(
|
|
60
|
-
| `conversation_update(
|
|
61
|
-
| `conversation_delete(
|
|
56
|
+
| Tool | Purpose |
|
|
57
|
+
|------|---------|
|
|
58
|
+
| `conversation_create(agent_id, run_id=None, title=None, metadata=None, session_id="")` | Create conversation container (Langfuse session) |
|
|
59
|
+
| `conversation_add_message(conversation_id, agent_id, input, output=None, reasoning=None, metadata=None, seed=None)` | Add a message turn (Langfuse trace) |
|
|
60
|
+
| `conversation_get(conversation_id, agent_id, include_messages=False, limit=100, offset=0)` | Retrieve conversation, optionally with messages |
|
|
61
|
+
| `conversation_list(agent_id=None, limit=20, offset=0, conversation_id="", datapack_id=None)` | List the user's conversations within a datapack (`agent_id` does not filter — trace attribution only). `datapack_id` (UUID) is optional — defaults to the pinned/tenant datapack; use `datapack_list` to look it up. `conversation_id` optional (omit for browse). |
|
|
62
|
+
| `conversation_update(conversation_id, agent_id, title=None, metadata=None)` | Update title or metadata |
|
|
63
|
+
| `conversation_delete(conversation_id, agent_id)` | Delete entire conversation (destructive) |
|
|
62
64
|
|
|
63
65
|
## Datapack Management Tools (5)
|
|
64
66
|
|
|
65
|
-
| Tool |
|
|
66
|
-
|
|
67
|
-
| `datapack_create(
|
|
68
|
-
| `datapack_list(
|
|
69
|
-
| `datapack_describe(
|
|
70
|
-
| `datapack_update(
|
|
71
|
-
| `datapack_delete(
|
|
67
|
+
| Tool | Purpose |
|
|
68
|
+
|------|---------|
|
|
69
|
+
| `datapack_create(name)` | Create new datapack |
|
|
70
|
+
| `datapack_list(conversation_id, datapack_id=None)` | List all datapacks. `conversation_id` is required for trace nesting; omit `datapack_id` to use the endpoint default. |
|
|
71
|
+
| `datapack_describe(datapack_id, include_status=False)` | Describe datapack by UUID |
|
|
72
|
+
| `datapack_update(datapack_id, name=None, description=None, conversation_search_opt_out=None)` | Rename a datapack, update its description, and/or opt out of (or back into) conversation-search caching. Pass at least one field. Opt-out is owner/maintainer only. |
|
|
73
|
+
| `datapack_delete(datapack_id)` | Delete datapack by UUID (irreversible) |
|
|
72
74
|
|
|
73
75
|
## Artifact Tools (2)
|
|
74
76
|
|
|
75
77
|
Content-addressed blob store scoped to a datapack. Files < 1 MB go inline in the DB; files ≥ 1 MB go to S3. Identity is SHA-256 — uploading the same bytes twice returns the same `content_hash`. Free-tier artifacts expire after 30 days of inactivity; pro-tier artifacts have no TTL.
|
|
76
78
|
|
|
77
|
-
| Tool |
|
|
78
|
-
|
|
79
|
-
| `artifact_put(
|
|
80
|
-
| `artifact_get(
|
|
79
|
+
| Tool | Purpose |
|
|
80
|
+
|------|---------|
|
|
81
|
+
| `artifact_put(filename, content_base64, content_type, conversation_id, datapack_id=None, agent_id=None)` | Upload a file to the datapack. Returns `{artifact_id, content_hash, filename, size_bytes, stored_in}`. Max 5 MiB (configurable via `MEKO_MAX_ARTIFACT_UPLOAD_BYTES`). |
|
|
82
|
+
| `artifact_get(content_hash, conversation_id, datapack_id=None, agent_id=None)` | Retrieve a file by SHA-256 hash. Small files return `content_base64` inline; large files (S3) are written to `~/.meko/artifacts/<hash>/<filename>` and `local_path` is returned. |
|
|
81
83
|
|
|
82
84
|
## Observability Tools (1)
|
|
83
85
|
|
|
84
|
-
| Tool |
|
|
85
|
-
|
|
86
|
-
| `track_token_usage(
|
|
86
|
+
| Tool | Purpose |
|
|
87
|
+
|------|---------|
|
|
88
|
+
| `track_token_usage(conversation_id, name, input_tokens=0, output_tokens=0, total_tokens=None, model=None, message_id=None, datapack_id=None)` | Record an LLM-cost GENERATION observation on the conversation's trace. Primarily called by first-party Meko services (e.g. inference_gateway) that know their LLM's exact token counts. Most end-agents (Cursor, Claude Desktop) don't have those counts at the MCP call layer, so this tool is rarely useful for third-party agents. |
|
|
87
89
|
|
|
88
90
|
## Platform capabilities NOT exposed via MCP
|
|
89
91
|
|
|
@@ -102,4 +104,4 @@ For knowledge-base content on Cloud, the canonical path is **UI upload**: Datapa
|
|
|
102
104
|
|
|
103
105
|
## Common Parameter Patterns
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
Memory and KB tools accept optional `datapack_id` to target a specific datapack. `agent_id` attributes writes and is enforced only on `conversation_get` (agent-owned — a wrong value returns `agent_id_mismatch`); it does **not** filter memory reads (`memory_search`/`memory_get_all`) or `conversation_list`, which return all your agents' rows for the user. See `tools-agent-id-conventions.md`.
|
|
@@ -16,7 +16,6 @@ creation and ingestion happen out of band — through the **Meko UI**
|
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
knowledgebase_search(
|
|
19
|
-
scope="read",
|
|
20
19
|
query="natural-language question",
|
|
21
20
|
agent_id="<your agent_id>",
|
|
22
21
|
conversation_id="<uuid from conversation_create>",
|
|
@@ -24,7 +23,7 @@ knowledgebase_search(
|
|
|
24
23
|
limit=10)
|
|
25
24
|
```
|
|
26
25
|
|
|
27
|
-
Required: `
|
|
26
|
+
Required: `query`, `agent_id`, `conversation_id`, `datapack_id`.
|
|
28
27
|
Unlike the memory tools, `datapack_id` has no default here — you must
|
|
29
28
|
pass it explicitly. `agent_id` is **ignored for filtering** on this
|
|
30
29
|
tool (KB results are team-shared on the datapack), but you still pass
|
|
@@ -7,7 +7,7 @@ These patterns are extracted from real agent sessions. Follow them to avoid wast
|
|
|
7
7
|
1. **Never retry the identical failed call more than once.** If it fails twice with the same error, it's not transient — diagnose the cause.
|
|
8
8
|
2. **Distinguish transient vs persistent failures.** "Connection already closed" is transient (retry once). "Permission denied" is persistent (stop, don't retry).
|
|
9
9
|
3. **Don't guess parameters sequentially.** If a tool fails with one parameter format, don't try 4 variations. Check this skill's docs for the correct format first.
|
|
10
|
-
4. **Use your session's `agent_id` consistently
|
|
10
|
+
4. **Use your session's `agent_id` consistently on writes** (the SessionStart-injected value), and on `conversation_get` — conversations are owned by the creating `agent_id`; a wrong value returns `agent_id_mismatch`. Memory reads and `conversation_list` are unaffected by `agent_id`. Don't switch write forms mid-session.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -26,17 +26,24 @@ These patterns are extracted from real agent sessions. Follow them to avoid wast
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## An error payload is a FAILED search, never an empty one
|
|
30
30
|
|
|
31
|
-
**
|
|
31
|
+
Quota errors, rate-limit errors, and tool refusals come back as an error object with **no `results` key** — reading `response.get("results", [])` first silently converts "you were refused" into "the store is empty." Follow SKILL.md operating contract 1: report it as "search failed: `<error code>` — findings unknown," never as "no results."
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Rate limiting: `PAT_RATE_LIMITED`
|
|
36
|
+
|
|
37
|
+
Bursts of requests on one token return:
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
```json
|
|
40
|
+
{"error": "PAT_RATE_LIMITED", "detail": "too many requests for this token; retry after 60s"}
|
|
41
|
+
```
|
|
38
42
|
|
|
39
|
-
**
|
|
43
|
+
- Throttling is **endpoint-specific**: `artifact_put` bursts and high-concurrency `memory_get_all` trigger it readily; `memory_search` tolerates far more. Do not assume one safe concurrency level for every tool.
|
|
44
|
+
- A rate-limited `artifact_put` returns this error **instead of** a `content_hash` — checking only for the hash misreads throttling as silent write loss.
|
|
45
|
+
- Honor the retry-after (~60s) or back off exponentially; pace sustained work. Retry only idempotent operations or hash-protected writes.
|
|
46
|
+
- Distinct from the lifetime quota error (`free_tier_limit_reached`) — waiting never recovers that one.
|
|
40
47
|
|
|
41
48
|
---
|
|
42
49
|
|
|
@@ -52,9 +59,9 @@ If you call `memory_add` with empty / None / whitespace `agent_id`, the server d
|
|
|
52
59
|
|
|
53
60
|
Fix: always pass a concrete non-empty `agent_id`. Fetch the value the SessionStart hook injected into `additionalContext` and pass it verbatim. Use `agent_id="meko_agent"` only when you genuinely want a fact in the cross-project pool (user identity, global preferences).
|
|
54
61
|
|
|
55
|
-
### "My reads return fewer results than I expected"
|
|
62
|
+
### "My memory reads return fewer results than I expected"
|
|
56
63
|
|
|
57
|
-
`memory_search` and `memory_get_all`
|
|
64
|
+
`memory_search` and `memory_get_all` do **not** filter by `agent_id` — a single call returns all of your memories for this user across every agent, so a mismatched `agent_id` is not the cause. If results seem thin, check that you're on the right datapack (`datapack_id`), that the write actually landed (mem0 extraction is lossy — see `tools-memory-vs-conversation.md`), and that the query is semantically close to the stored text. `conversation_get`, by contrast, *is* agent-owned: pass the exact `agent_id` the conversation was created under, or you'll get `agent_id_mismatch`. `conversation_list` is not agent-filtered — it returns the datapack's conversations for your user regardless of the `agent_id` passed.
|
|
58
65
|
|
|
59
66
|
### "I'm seeing rows tagged with legacy agent_id values"
|
|
60
67
|
|
|
@@ -66,7 +73,7 @@ Pre-existing data may be tagged `"agent"`, `"claude_code"`, `"cursor:<slug>"`, o
|
|
|
66
73
|
|
|
67
74
|
| Tool | Safe to retry? | Why |
|
|
68
75
|
|------|---------------|-----|
|
|
69
|
-
| All
|
|
76
|
+
| All read-only tools | Yes | Reads are idempotent |
|
|
70
77
|
| `memory_add` | Yes (once) | Mem0 has dedup logic |
|
|
71
78
|
| `memory_update` | Yes (once) | Overwrites same ID |
|
|
72
79
|
| `memory_delete_by_id` | Yes | Deleting already-deleted is a no-op |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# user_id — identity scoping on Cloud Meko
|
|
2
2
|
|
|
3
|
-
On Cloud Meko, every write and every personal read carries a `user_id` that identifies **who** (the cognito account) is calling. The filter
|
|
3
|
+
On Cloud Meko, every write and every personal read carries a `user_id` that identifies **who** (the cognito account) is calling. The read filter for personal **memories** is `(datapack_id, user_id)` — you see all your own memories for this user regardless of which agent wrote them (`agent_id` labels the writer but does not filter memory reads). Personal **conversation fetches** (`conversation_get`) additionally enforce `agent_id` — conversations are owned by the agent that created them; `conversation_list` does not filter by it. Either way you only ever see content your own user_id wrote (or content other team members have explicitly promoted to Shared Knowledge, which is separate — see `tools-agent-id-conventions.md`).
|
|
4
4
|
|
|
5
5
|
## The default behavior: automatic user_id from cognito
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ On Cloud, the server resolves your `user_id` automatically from the cognito acco
|
|
|
9
9
|
This is the common case for Claude Code / Claude Desktop / Cursor:
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
memory_add(
|
|
12
|
+
memory_add(
|
|
13
13
|
text="User prefers concise responses, no emojis.",
|
|
14
14
|
agent_id="claude_code:meko-mcp-server",
|
|
15
15
|
conversation_id="<session conversation_id>")
|
|
@@ -24,21 +24,21 @@ Explicit `user_id` is an **optional sub-scope** for agents that serve multiple e
|
|
|
24
24
|
|
|
25
25
|
```
|
|
26
26
|
# Serving Alice
|
|
27
|
-
memory_add(
|
|
27
|
+
memory_add(
|
|
28
28
|
text="Alice prefers email communication. Has Pro plan.",
|
|
29
29
|
agent_id="support-bot",
|
|
30
30
|
user_id="alice_123",
|
|
31
31
|
conversation_id="<conv>")
|
|
32
32
|
|
|
33
33
|
# Serving Bob — completely separate partition, same cognito account
|
|
34
|
-
memory_add(
|
|
34
|
+
memory_add(
|
|
35
35
|
text="Bob prefers Slack. On Enterprise plan.",
|
|
36
36
|
agent_id="support-bot",
|
|
37
37
|
user_id="bob_456",
|
|
38
38
|
conversation_id="<conv>")
|
|
39
39
|
|
|
40
40
|
# Search only returns Alice's memories
|
|
41
|
-
memory_search(
|
|
41
|
+
memory_search(
|
|
42
42
|
query="communication preference",
|
|
43
43
|
agent_id="support-bot",
|
|
44
44
|
user_id="alice_123",
|
|
@@ -60,11 +60,12 @@ Mixing creates invisible data.
|
|
|
60
60
|
|
|
61
61
|
| Layer | Filter | Role of user_id |
|
|
62
62
|
|---|---|---|
|
|
63
|
-
| Personal memories (`memory_add`, `memory_search`, `memory_get_all`) | `(datapack_id, user_id
|
|
64
|
-
|
|
|
63
|
+
| Personal memories (`memory_add`, `memory_search`, `memory_get_all`) | `(datapack_id, user_id)` | Enforced on every read. `agent_id` is not applied — one user sees all their own memories across every agent, but cannot see another user's un-promoted memories. |
|
|
64
|
+
| Conversation listing (`conversation_list`) | `(datapack_id, user_id)` | Enforced. `agent_id` is not applied — you see all your own conversations across every agent. |
|
|
65
|
+
| Conversation fetch (`conversation_get`) | `(datapack_id, user_id, agent_id)` | Enforced. Agent-owned: pass the creating `agent_id` or you get `agent_id_mismatch`. Cross-user reads require promotion. |
|
|
65
66
|
| Team Shared Knowledge (`knowledgebase_search`) | `(datapack_id)` only | **Not used** — `user_id` is stripped when a memory is promoted to Knowledge. All team members on the datapack see the same Shared Knowledge. |
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
Personal content crosses the `user_id` boundary through `memory_promote` or the Cloud UI's "Promote to Knowledge" action. The MCP path requires exact memory UUIDs, explicit user confirmation, and an owner/maintainer role; it moves the records into team-visible Shared Knowledge and evicts the private copies.
|
|
68
69
|
|
|
69
70
|
## Parameter summary
|
|
70
71
|
|
|
@@ -74,6 +75,6 @@ The "Promote to Knowledge" action in the Cloud UI is the one way personal conten
|
|
|
74
75
|
| `user_id` | The cognito account or end-user (for multi-user agents) | auto from cognito for single-human clients; explicit string for multi-user agents | Optional (server auto-fills from cognito context) |
|
|
75
76
|
| `agent_id` | Which agent wrote / is reading | `"claude_code:<repo>"`, `"claude_desktop"`, `"cursor:<repo>"`, `"meko_agent"` (common bucket) | Optional (empty/missing → `meko_agent` server-side); pass the per-session value verbatim for project-scoped reads/writes. Ignored on `knowledgebase_search`. |
|
|
76
77
|
| `app_id` | Optional application/product sub-scope | `"second_brain"`, `"helpdesk"` | Optional |
|
|
77
|
-
| `run_id` |
|
|
78
|
+
| `run_id` | A conversation id, used as a read/delete filter against the row's `meko_conversation_id` | `"374c70f3b95745ac92724d98475cc2d6"` | Optional. On `memory_add` it is trace metadata only and does not scope the write — see `tools-agent-id-conventions.md`. |
|
|
78
79
|
|
|
79
80
|
See `tools-agent-id-conventions.md` for the full `agent_id` model.
|