@yugabytedb/meko-mcp 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -25
- package/assets/hooks-handlers/before-submit-prompt.sh +2 -2
- package/assets/hooks-handlers/codex-session-end.sh +78 -0
- package/assets/hooks-handlers/lib/capture.js +366 -152
- package/assets/hooks-handlers/lib/checkpoint-timer.js +67 -13
- package/assets/hooks-handlers/session-end.sh +10 -0
- package/assets/hooks-handlers/session-start.sh +14 -3
- package/assets/hooks-handlers/test_checkpoint_timer.sh +162 -0
- package/assets/scripts/meko-statusline.sh +119 -0
- package/assets/scripts/package-desktop-skill.sh +64 -30
- package/assets/skills/meko-mcp-tools/SKILL.md +84 -86
- package/assets/skills/meko-mcp-tools/references/_sections.md +2 -4
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +29 -25
- package/assets/skills/meko-mcp-tools/references/tools-conversation-dedup.md +5 -7
- package/assets/skills/meko-mcp-tools/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +126 -184
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +31 -37
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +10 -26
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +26 -30
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +60 -66
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +28 -93
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +5 -99
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +9 -8
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +138 -138
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +46 -16
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +28 -24
- package/assets/skills/meko-mcp-tools-desktop/references/tools-conversation-reasoning.md +50 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +120 -174
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +16 -22
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +28 -34
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +60 -66
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +28 -93
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +4 -98
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +208 -0
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +121 -0
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +41 -0
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +66 -0
- package/bin/create-meko-setup.mjs +74 -6
- package/lib/clients/claude-code.mjs +137 -6
- package/lib/clients/claude-desktop.mjs +51 -12
- package/lib/clients/codex.mjs +329 -13
- package/lib/clients/common.mjs +43 -1
- package/lib/clients/cursor.mjs +82 -21
- package/lib/config.mjs +26 -0
- package/lib/detect.mjs +7 -2
- package/lib/installer.mjs +24 -0
- package/lib/mcp-transport.mjs +5 -0
- package/lib/prompt.mjs +1 -1
- package/lib/url-selection.mjs +55 -0
- package/lib/validate.mjs +0 -1
- package/package.json +1 -1
- package/scripts/bundle-assets.mjs +8 -0
- package/assets/skills/meko-mcp-tools/references/tools-db-query-patterns.md +0 -38
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +0 -75
- package/assets/skills/meko-mcp-tools/references/tools-write-guardrails.md +0 -30
- package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +0 -75
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: meko-mcp-tools
|
|
3
|
-
description: Behavioral guide for AI agents using Meko MCP tools. Triggers when calling MCP tools, storing memories, persisting knowledge, managing datapacks, or
|
|
3
|
+
description: Behavioral guide for AI agents using Meko MCP tools. Triggers when calling MCP tools, storing memories, persisting knowledge, managing datapacks, or searching shared knowledge bases through Meko.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: Meko
|
|
7
|
-
version: "
|
|
8
|
-
tags: mcp,
|
|
7
|
+
version: "3.0.2"
|
|
8
|
+
tags: mcp, tools, datapack, memory, conversation, rag, meko
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Meko MCP Tools — Agent Behavioral Guide
|
|
12
12
|
|
|
13
|
-
Meko is agent-native data infrastructure that enables continuous learning from context windows through collective memory and shared knowledge. This skill teaches you how to use Meko's
|
|
13
|
+
Meko is agent-native data infrastructure that enables continuous learning from context windows through collective memory and shared knowledge. This skill teaches you how to use Meko's 23 MCP tools.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
**Read this first.** On Claude Code, conversation capture is automatic (SessionStart / PreCompact / SessionEnd hooks) and the Meko server extracts durable memories from the captured turns on its own. Facts the user states in conversation are saved for you — you do **not** proactively call `memory_add` for them. Your active jobs are: **recall** what's already known (`memory_search`, `knowledgebase_search`), and the **few** save cases automatic extraction cannot reach. Details below.
|
|
14
17
|
|
|
15
18
|
## What Meko enables
|
|
16
19
|
|
|
17
20
|
Meko turns your volatile context window into persistent, shareable knowledge:
|
|
18
21
|
|
|
19
|
-
- **Personal memory** — Store who the user is, their preferences, role, and working style. Private to you (scoped per-user
|
|
20
|
-
- **Team-shared knowledge** —
|
|
22
|
+
- **Personal memory** — Store who the user is, their preferences, role, and working style. Private to you (scoped per-user; readable across all of your agents). Survives across sessions.
|
|
23
|
+
- **Team-shared knowledge** — Important memories can be promoted with `memory_promote` (after explicit confirmation) or from the Cloud UI's Learnings tab. Uploaded documents arrive through **Add Knowledge**. The resulting content is visible to every datapack member and queryable via `knowledgebase_search`.
|
|
21
24
|
- **Conversation history** — Preserve full dialog exchanges with reasoning traces for audit, replay, and learning transfer.
|
|
22
25
|
- **Decision traces** — Capture how and why decisions were made, enabling debugging and continuous improvement.
|
|
23
26
|
|
|
@@ -27,7 +30,7 @@ Meko turns your volatile context window into persistent, shareable knowledge:
|
|
|
27
30
|
- You need to decide what to store, where, and how (personal memory vs. team-shared knowledge)
|
|
28
31
|
- You want to search the team's shared knowledge base (`knowledgebase_search`)
|
|
29
32
|
- You are managing datapacks
|
|
30
|
-
- You want to understand
|
|
33
|
+
- You want to understand `agent_id` conventions, or `datapack_id` routing
|
|
31
34
|
|
|
32
35
|
## `agent_id` — multi-agent identity
|
|
33
36
|
|
|
@@ -44,25 +47,26 @@ agent_id = "claude_code:meko-mcp-server" # this session's project bucket
|
|
|
44
47
|
agent_id = "meko_agent" # cross-project facts
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
The SessionStart hook injects the project-bucket value into the first-turn `additionalContext`. Use that value verbatim for project-scoped Meko MCP calls in this session; do not re-derive it. Use `meko_agent` explicitly when you want a write
|
|
50
|
+
The SessionStart hook injects the project-bucket value into the first-turn `additionalContext`. Use that value verbatim for project-scoped Meko MCP calls in this session; do not re-derive it. Use `meko_agent` explicitly when you want a write to land in the cross-project bucket.
|
|
48
51
|
|
|
49
52
|
**Read scoping varies by tool:**
|
|
50
|
-
- `memory_search` / `memory_get_all`
|
|
53
|
+
- `memory_search` / `memory_get_all` — scoped to `(datapack_id, user_id)`. **`agent_id` does not filter memory reads:** one call returns all of your memories for this user across every `agent_id` (the tool passes `meko_agent_id=None` to mem0, so `agent_id` scopes the Langfuse trace, not the result set). No need to fan out per agent_id or read the `meko_agent` bucket separately — a single search already includes it.
|
|
54
|
+
- `conversation_get` — agent-owned: pass the exact `agent_id` that created the conversation; any other value returns `agent_id_mismatch`.
|
|
55
|
+
- `conversation_list` — returns the datapack's conversations for your user regardless of `agent_id` (the argument is trace-attribution only, like memory reads).
|
|
51
56
|
- `knowledgebase_search` — scoped to `(datapack_id)` only. `agent_id` on the request is **ignored**; you see the team's shared knowledge regardless of what you pass. Includes uploaded documents and memories that the user promoted via the UI's "Promote to Knowledge" flow.
|
|
52
57
|
|
|
53
58
|
See `tools-agent-id-conventions.md` for the full model, including how promotion works and how to phrase broad-query responses to the user.
|
|
54
59
|
|
|
55
60
|
Some pre-existing rows in real datapacks use the older `agent_id="agent"` constant or other ad-hoc shapes (`claude_code`, `cursor:<slug>`). They remain readable — query them with `agent_id="agent"` explicitly. New writes should follow the schema above.
|
|
56
61
|
|
|
57
|
-
## Critical: Use Meko
|
|
62
|
+
## Critical: Use Meko, not local storage
|
|
58
63
|
|
|
59
|
-
**
|
|
64
|
+
**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. On Claude Code, memory reaches Meko two ways, and neither is a local file:
|
|
60
65
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- Conversation worth preserving → call `conversation_create`, NOT save to a local log
|
|
66
|
+
- **Automatic capture + extraction** (the dominant path) — the hooks capture this session's turns and the server extracts memories from them. Facts the user states are stored without any tool call from you.
|
|
67
|
+
- **Explicit `memory_add`** (the narrow path) — only for the cases extraction can't reach (see "When to call memory_add" below).
|
|
64
68
|
|
|
65
|
-
If a Meko
|
|
69
|
+
To recall, call `memory_search` on the MCP server, NOT read local files. If a Meko read/write call fails, you may fall back to local storage and tell the user — but Meko is always the first choice.
|
|
66
70
|
|
|
67
71
|
## When spawning subagents
|
|
68
72
|
|
|
@@ -112,49 +116,39 @@ If the inherited block is **absent**, the subagent MUST NOT guess — see the se
|
|
|
112
116
|
|
|
113
117
|
Subagents cannot auto-discover the parent's watermark today: Claude Code does not expose a `CLAUDE_PARENT_SESSION_ID` env var or any equivalent marker file to subagent processes (see the spike note in `skills/hooks-handlers/lib/capture.js`). Prompt injection is the only enforcement mechanism.
|
|
114
118
|
|
|
115
|
-
## Core principle:
|
|
119
|
+
## Core principle: capture is automatic — recall, don't re-store
|
|
116
120
|
|
|
117
|
-
**
|
|
121
|
+
Meko is your long-term memory, but on Claude Code you do **not** build it by hand. The hooks capture every turn of this session and the server extracts durable memories from them automatically. **A fact the user states in conversation — name, role, preferences, org conventions, corrections, casual asides — is already saved. Calling `memory_add` for it just duplicates what extraction stored.** (Verified empirically: the server extracts conversationally-stated facts verbatim, including multi-fact turns and precise multi-clause facts.)
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
So your Meko reflexes are:
|
|
120
124
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
| User states a preference ("I prefer dark mode", "always use Python") | Store as personal preference | `memory_add` |
|
|
125
|
-
| User shares org convention ("we write in Go", "our standard is X") | Store as organizational memory | `memory_add` |
|
|
126
|
-
| User teaches domain knowledge ("Meko traces are decision traces") | Store as memory; consider suggesting they promote it to Shared Knowledge from the Learnings tab | `memory_add` |
|
|
127
|
-
| User corrects your behavior ("don't do X, do Y instead") | Store the correction as a learning | `memory_add` |
|
|
128
|
-
| User asks "what do you know about X?" | Three-call sweep: your project's memories, then the cross-project common bucket, then team-shared knowledge | `memory_search(agent_id=<yours>)` → `memory_search(agent_id="meko_agent")` → `knowledgebase_search` |
|
|
129
|
-
| User asks "what do we (as a team) know about X?" or about uploaded documents | Query the team's Shared Knowledge directly | `knowledgebase_search` (returns uploaded docs + promoted memories) |
|
|
130
|
-
| Session produced a valuable multi-turn exchange | Preserve the full conversation | `conversation_create` + `conversation_add_message` |
|
|
131
|
-
| Significant learnings accumulated during session | Offer to persist key takeaways; remind the user they can promote important ones to Shared Knowledge from the Cloud UI | Summarize and propose `memory_add` calls |
|
|
132
|
-
| User provides structured/tabular data (CSV, data dictionary) | Not natively supported via MCP on Cloud today — `db_run_write_query` returns `{"error": "not_available"}`. Store the key facts as memories or point the user at the UI's knowledge-base upload for file form | `memory_add` for facts, UI "Add Knowledge" for files |
|
|
133
|
-
| 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). The MCP ingestion tools are not available on Cloud. | UI only |
|
|
125
|
+
1. **Recall first.** When the user asks what's known, or before you act on something they may have an opinion about, search — don't assume.
|
|
126
|
+
2. **Save only what capture can't reach** (the three narrow cases below).
|
|
127
|
+
3. **Never** re-store a fact the user just said. **Never** write memories to local files.
|
|
134
128
|
|
|
135
|
-
###
|
|
129
|
+
### When the user shares information
|
|
136
130
|
|
|
137
|
-
|
|
131
|
+
| Signal in conversation | What to do |
|
|
132
|
+
|---|---|
|
|
133
|
+
| User states a fact about themselves, their team, tools, or preferences | **Nothing — automatic capture + extraction stores it.** Just answer. |
|
|
134
|
+
| User corrects your behavior or negates a prior fact ("actually, we use Nomad now") | The new fact is captured automatically, but extraction is **additive** — it does not remove the old one. If a stale, contradicted memory must not survive, `memory_search` for it and `memory_update` / `memory_delete_by_id`. |
|
|
135
|
+
| User explicitly says "remember this" / "save this to memory" | `memory_add` (verbatim). This is the clearest explicit-save case. |
|
|
136
|
+
| A durable fact appears only in YOUR output or a tool result, never in the user's words | `memory_add`. Extraction reads only the **user** turn, so facts you derive or a tool surfaces are never captured otherwise. |
|
|
137
|
+
| User asks "what do you know about X?" | Two surfaces: `memory_search` (one call — all your personal memories for this user, every agent) then `knowledgebase_search` (team-shared knowledge). |
|
|
138
|
+
| User asks "what do we (as a team) know about X?" or about uploaded documents | `knowledgebase_search` (returns uploaded docs + promoted memories). |
|
|
139
|
+
| User asks to share specific private memories with the team | Follow the `memory_promote` confirmation workflow below. Never promote based on a fuzzy search result or implied consent. |
|
|
140
|
+
| 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. |
|
|
141
|
+
| 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. |
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
│ files via the UI's Datapack → Actions → Add Knowledge flow
|
|
149
|
-
├── A correction or learning ("don't do X", "always do Y")
|
|
150
|
-
│ → memory_add — behavioral feedback
|
|
151
|
-
├── Full conversation worth preserving (multi-turn, reasoning traces)
|
|
152
|
-
│ → conversation_create + conversation_add_message — verbatim
|
|
153
|
-
└── Structured/tabular data (CSV rows, schemas, data dictionaries)
|
|
154
|
-
→ Not MCP-supported on Cloud today (db_run_write_query returns
|
|
155
|
-
{"error": "not_available"}). Extract key facts to memory_add
|
|
156
|
-
or tell the user this isn't a Cloud feature yet.
|
|
157
|
-
```
|
|
143
|
+
### When to call memory_add (the whole list)
|
|
144
|
+
|
|
145
|
+
Automatic capture handles the rest, so explicit `memory_add` is reserved for exactly three cases:
|
|
146
|
+
|
|
147
|
+
1. **Explicit request** — the user says "remember this" / "save this."
|
|
148
|
+
2. **Output-only / tool-derived fact** — a durable fact that lives only in the assistant's output or a tool result, never in a user turn (extraction only sees the user turn).
|
|
149
|
+
3. **Overwriting correction** — a prior fact was negated and the stale memory must not survive (extraction is additive; pair `memory_add`/`memory_update` with a `memory_delete_by_id` of the old one).
|
|
150
|
+
|
|
151
|
+
When you do call it, store the fact verbatim in the user's own words; do not summarize.
|
|
158
152
|
|
|
159
153
|
## Automatic conversation capture
|
|
160
154
|
|
|
@@ -171,7 +165,7 @@ All three are handled automatically. **Do NOT set up CronCreate for conversation
|
|
|
171
165
|
The SessionStart hook has already done the setup for you:
|
|
172
166
|
|
|
173
167
|
1. **Created a Meko conversation** — `conversation_id` is injected into `additionalContext` on the first turn. Use that value for all subsequent MCP tool calls that accept `conversation_id`.
|
|
174
|
-
2. **Echoed the session's `agent_id`** — also injected into `additionalContext`. Use the injected value verbatim for project-scoped Meko tool calls. It's a per-session value derived from the cwd (shape: `claude_code:<repo-basename>`), not a constant. For genuinely cross-project facts, write
|
|
168
|
+
2. **Echoed the session's `agent_id`** — also injected into `additionalContext`. Use the injected value verbatim for project-scoped Meko tool calls. It's a per-session value derived from the cwd (shape: `claude_code:<repo-basename>`), not a constant. For genuinely cross-project facts, write with `agent_id="meko_agent"` (the common bucket) instead.
|
|
175
169
|
3. **Preloaded recent memories** — `additionalContext` may include a `### Memories from prior sessions` block. Inspect it before acting so you don't re-ask questions the user has already answered.
|
|
176
170
|
|
|
177
171
|
If `additionalContext` is absent or empty (hook failed, MCP unavailable), ask the user for their `agent_id` — do not invent one. See `tools-agent-id-conventions.md`.
|
|
@@ -181,11 +175,11 @@ If `additionalContext` is absent or empty (hook failed, MCP unavailable), ask th
|
|
|
181
175
|
Before any action that deletes, overwrites, or restructures user content — `Write` overwriting an existing file, large `Edit` deletions, `rm` / `rm -rf`, `git reset --hard`, destructive SQL (`DROP`, `TRUNCATE`, `DELETE` without `WHERE`) — run a `memory_search` for relevant feedback:
|
|
182
176
|
|
|
183
177
|
```
|
|
184
|
-
memory_search(
|
|
178
|
+
memory_search(query="destructive <action type> preferences feedback",
|
|
185
179
|
agent_id=<your agent_id>, conversation_id=<session_conversation_id>)
|
|
186
180
|
```
|
|
187
181
|
|
|
188
|
-
|
|
182
|
+
A single `memory_search` already covers everything you and other agents wrote for this user — `agent_id` doesn't filter memory reads. Also consider a `knowledgebase_search` for team-wide guidance if the action is one the team has promoted policy on.
|
|
189
183
|
|
|
190
184
|
If a relevant feedback memory exists (e.g., "always ask before deleting content"), confirm with the user before proceeding. If the search is empty, proceed, but treat the action as irreversible and prefer a dry-run / preview when one is available.
|
|
191
185
|
|
|
@@ -203,47 +197,56 @@ If a relevant feedback memory exists (e.g., "always ask before deleting content"
|
|
|
203
197
|
In the examples below, `<your-agent-id>` means the value the SessionStart hook injected into `additionalContext` — for Claude Code, something like `claude_code:meko-mcp-server`. Not the literal string `"<your-agent-id>"`.
|
|
204
198
|
|
|
205
199
|
### memory_add — correct call pattern
|
|
200
|
+
|
|
201
|
+
Only for the three narrow cases in "When to call memory_add" above — not for facts the user stated in conversation (those are captured automatically). The example below is an explicit "remember this" save:
|
|
206
202
|
```
|
|
207
|
-
memory_add(
|
|
208
|
-
text="
|
|
203
|
+
memory_add(
|
|
204
|
+
text="Remember: deploy scripts must be run from the repo root, never a subdir",
|
|
209
205
|
agent_id="<your-agent-id>",
|
|
210
206
|
conversation_id="<session_conversation_id>")
|
|
211
207
|
```
|
|
212
|
-
Required parameters: `
|
|
208
|
+
Required parameters: `text`, `conversation_id`. On **writes**, `conversation_id` must be a real UUID (from `conversation_create` or the SessionStart hook) — writes attached to a nil/empty conversation are orphaned in Langfuse traces. NEVER pass `"current"` or other non-UUID values. `agent_id` is technically optional — empty/missing routes the write into the `meko_agent` common bucket — but for project-scoped facts pass the SessionStart-injected value verbatim.
|
|
213
209
|
|
|
214
210
|
### memory_search — correct call pattern
|
|
215
211
|
```
|
|
216
|
-
memory_search(
|
|
212
|
+
memory_search(
|
|
217
213
|
query="user role",
|
|
218
214
|
agent_id="<your-agent-id>",
|
|
219
215
|
conversation_id="<session_conversation_id>")
|
|
220
216
|
```
|
|
221
|
-
Required parameters: `
|
|
217
|
+
Required parameters: `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 in Observe; passing `""` is accepted and means "don't nest under any trace." For conversation-scoped filtering use the separate `run_id` parameter.
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
```
|
|
225
|
-
memory_search(scope="read", query="user role",
|
|
226
|
-
agent_id="meko_agent", conversation_id="<session_conversation_id>")
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Empty string also resolves to `meko_agent` server-side, but be explicit so it's obvious from the call you mean the common bucket. To search results across multiple specific projects (e.g. also see what was written from `claude_code:other-repo`), call `memory_search` once per agent_id — there's no single-call fan-out.
|
|
219
|
+
`agent_id` does not filter what `memory_search` returns — a single call already surfaces everything you and every other agent wrote for this user in the datapack, including the `meko_agent` common bucket and any other project's rows. There's no need to repeat the search per agent_id. Use `run_id` if you want to narrow to a single conversation/run.
|
|
230
220
|
|
|
231
221
|
### knowledgebase_search — correct call pattern
|
|
232
222
|
```
|
|
233
|
-
knowledgebase_search(
|
|
223
|
+
knowledgebase_search(
|
|
234
224
|
query="...",
|
|
235
225
|
agent_id="<anything — ignored>",
|
|
236
226
|
conversation_id="<session_conversation_id>",
|
|
237
227
|
datapack_id="<datapack UUID>",
|
|
238
228
|
limit=10)
|
|
239
229
|
```
|
|
240
|
-
Required parameters: `
|
|
230
|
+
Required parameters: `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.
|
|
231
|
+
|
|
232
|
+
### memory_promote — explicit confirmation required
|
|
233
|
+
|
|
234
|
+
`memory_promote` is destructive and non-idempotent: it makes selected content visible to the datapack, moves the memories and graph context into shared knowledge, and evicts the private mem0 records. There is no MCP rollback.
|
|
235
|
+
|
|
236
|
+
1. Use `memory_search` or `memory_get_all` to obtain exact memory UUIDs. Never pass relation or graph-edge IDs.
|
|
237
|
+
2. Present each exact candidate memory and its UUID to the user.
|
|
238
|
+
3. State that promotion is one-way, team-visible, and removes the private records.
|
|
239
|
+
4. Obtain explicit confirmation for those exact candidates before calling `memory_promote`.
|
|
240
|
+
5. Call it with the active `conversation_id`, exact `memory_ids`, intended `agent_id`, and intended `datapack_id`. If a legacy deployment exposes `scope`, use the minimum `write` scope; do not escalate to `admin`.
|
|
241
|
+
6. Only datapack owners and maintainers may promote. If a viewer/contributor receives 403, or any authentication/permission error occurs, report it and stop. Do not retry with a broader scope, another datapack, or altered identity.
|
|
242
|
+
7. After success, optionally verify visibility with `knowledgebase_search`. Do not claim rollback is possible.
|
|
243
|
+
|
|
244
|
+
The Cloud UI's Learnings tab remains an alternative user-driven path.
|
|
241
245
|
|
|
242
246
|
### Critical parameter rules
|
|
243
247
|
|
|
244
248
|
- **agent_id**: Per-session value, injected via `additionalContext` by the SessionStart hook. Shape: `<client>:<repo-basename>`. Pass verbatim on project-scoped writes and reads. Pass `"meko_agent"` for the cross-project common bucket (or empty/omit — server rewrites empty to `meko_agent`). Ignored on `knowledgebase_search`. See `tools-agent-id-conventions.md`.
|
|
245
249
|
- **conversation_id**: Behavior varies by tool. On write tools (`memory_add`, `conversation_add_message`) pass a real UUID from `conversation_create` or the SessionStart hook — 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.
|
|
246
|
-
- **scope**: Only `"read"`, `"write"`, or `"admin"`. Nothing else. Use the minimum the code actually requires (the per-tool cookbook shows it).
|
|
247
250
|
- **When in doubt about optional parameters, omit them.** The server has sensible defaults.
|
|
248
251
|
|
|
249
252
|
### Verify after writing
|
|
@@ -262,7 +265,6 @@ On the first Meko tool call in a fresh session (no prior Meko tool call since pr
|
|
|
262
265
|
|
|
263
266
|
**Canary memory shape.** This is the spec; keep the fields stable so support can grep for them.
|
|
264
267
|
|
|
265
|
-
- `scope`: `"write"`
|
|
266
268
|
- `agent_id`: the session's `agent_id` (from `additionalContext`); not a constant
|
|
267
269
|
- `conversation_id`: the session's `conversation_id` (from `additionalContext`). If the hook failed and you truly have no conversation_id, call `conversation_create` first and use the returned id — do not use a nil UUID, it orphans the canary trace.
|
|
268
270
|
- `text`: `"Meko connection test: <client> @ <installer-version> — <ISO timestamp>. Safe to delete."`
|
|
@@ -276,31 +278,27 @@ On the first Meko tool call in a fresh session (no prior Meko tool call since pr
|
|
|
276
278
|
|
|
277
279
|
## Key concepts
|
|
278
280
|
|
|
279
|
-
1. **
|
|
280
|
-
2. **
|
|
281
|
-
3. **
|
|
282
|
-
4. **
|
|
283
|
-
5. **
|
|
284
|
-
6. **
|
|
285
|
-
7. **
|
|
286
|
-
8. **
|
|
287
|
-
9. **
|
|
288
|
-
10. **
|
|
289
|
-
11. **Error recovery**: Connection errors are common with memory tools — see `tools-troubleshooting.md` for retry strategies and fallbacks.
|
|
281
|
+
1. **23 tools in 6 groups**: Memory (8 — including `memory_promote`), Conversation (6), Knowledge Base (1 — `knowledgebase_search`), Datapack (5), Artifacts (2 — `artifact_put`, `artifact_get`), Observability (1 — `track_token_usage`). KB ingestion is UI-only (Datapack → Actions → Add Knowledge); raw SQL is not exposed. See `tools-overview.md`.
|
|
282
|
+
2. **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.
|
|
283
|
+
3. **agent_id is multi-agent**: Each client+project uses its own `agent_id` (shape `<client>:<repo-basename>`). Writes are attributed to `(datapack_id, user_id, agent_id)`. Personal **memory** reads (`memory_search`, `memory_get_all`) are NOT filtered by `agent_id` — one call returns all of your memories for this user across every agent, scoped to `(datapack_id, user_id)`. Empty/missing `agent_id` on a write lands in the `meko_agent` common bucket. `knowledgebase_search` ignores `agent_id` entirely and returns the team-shared knowledge on the datapack. See `tools-agent-id-conventions.md`.
|
|
284
|
+
4. **Personal memory vs. team-shared knowledge**: Un-promoted memories (`mem0_collection`) are scoped per-user — readable across all of your agents, but no other user can see them. With explicit confirmation, `memory_promote` moves exact memories into Shared Knowledge; the Cloud UI's Learnings tab is an alternative. Promoted content is visible to every datapack member (user_id filter stripped). `knowledgebase_search` is the MCP read path for both Shared Knowledge and uploaded documents. See `tools-memory-vs-conversation.md`.
|
|
285
|
+
5. **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 (`/observe-hub?project=<langfuse_pid>&session=<conversation_id>`) or directly from a datapack's Conversations tab via the **Open in Observe** button. See `tools-memory-vs-conversation.md`.
|
|
286
|
+
6. **Adding documents or growing a knowledge base is UI-only on Cloud today**: users upload 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`.
|
|
287
|
+
7. **Conversation dedup**: `conversation_add_message` supports seed-based deterministic trace IDs to prevent duplicates.
|
|
288
|
+
8. **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.
|
|
289
|
+
9. **Known limitations**: see `tools-known-limitations.md` before attempting write operations on tools that appear in the catalog but aren't available on Cloud.
|
|
290
|
+
10. **Error recovery**: Connection errors are common with memory tools — see `tools-troubleshooting.md` for retry strategies and fallbacks.
|
|
290
291
|
|
|
291
292
|
## Reference sections
|
|
292
293
|
|
|
293
294
|
| File | What it covers |
|
|
294
295
|
|------|---------------|
|
|
295
|
-
| `tools-overview.md` | Complete catalog of all
|
|
296
|
+
| `tools-overview.md` | Complete catalog of all 23 tools with decision tree |
|
|
296
297
|
| `tools-cookbook.md` | Per-tool examples with correct parameters, responses, and error cases |
|
|
297
298
|
| `tools-memory-vs-conversation.md` | When to use memory tools vs conversation tools |
|
|
298
299
|
| `tools-datapack-workflow.md` | Datapack lifecycle and datapack_id routing |
|
|
299
300
|
| `tools-rag-workflow.md` | End-to-end RAG pipeline flow |
|
|
300
|
-
| `tools-write-guardrails.md` | Blocked SQL patterns and configurable limits |
|
|
301
|
-
| `tools-scope-permissions.md` | read/write/admin permission hierarchy |
|
|
302
301
|
| `tools-agent-id-conventions.md` | Naming rules and constraints for agent_id |
|
|
303
302
|
| `tools-conversation-dedup.md` | Seed-based trace deduplication |
|
|
304
|
-
| `tools-db-query-patterns.md` | Read-only vs write query execution patterns |
|
|
305
303
|
| `tools-troubleshooting.md` | Error recovery, retry strategies, stuck pipeline diagnosis |
|
|
306
304
|
| `tools-known-limitations.md` | Broken tools, missing capabilities, permission gaps |
|
|
@@ -6,17 +6,15 @@ description: Maps reference files to their topics for the meko-mcp-tools skill
|
|
|
6
6
|
# Reference Sections
|
|
7
7
|
|
|
8
8
|
## Tool Selection & Catalog
|
|
9
|
-
- [tools-overview.md](tools-overview.md) — Complete catalog of all
|
|
9
|
+
- [tools-overview.md](tools-overview.md) — Complete catalog of all 23 tools with a decision tree
|
|
10
10
|
|
|
11
11
|
## Tool-Specific Guidance
|
|
12
12
|
- [tools-memory-vs-conversation.md](tools-memory-vs-conversation.md) — Decision framework: memory_add vs conversation_create/conversation_add_message
|
|
13
|
+
- [tools-conversation-reasoning.md](tools-conversation-reasoning.md) — Authoring the `reasoning` and `plan` fields on `conversation_add_message`, with worked examples
|
|
13
14
|
- [tools-datapack-workflow.md](tools-datapack-workflow.md) — Datapack lifecycle, datapack_id routing, and multi-database patterns
|
|
14
15
|
- [tools-rag-workflow.md](tools-rag-workflow.md) — End-to-end RAG pipeline: source registration, index creation, status polling
|
|
15
|
-
- [tools-db-query-patterns.md](tools-db-query-patterns.md) — Read-only vs write query execution patterns and SQL conventions
|
|
16
16
|
|
|
17
17
|
## Safety & Permissions
|
|
18
|
-
- [tools-write-guardrails.md](tools-write-guardrails.md) — Blocked SQL operations, bulk insert limits, WHERE clause enforcement
|
|
19
|
-
- [tools-scope-permissions.md](tools-scope-permissions.md) — read/write/admin permission hierarchy and per-tool requirements
|
|
20
18
|
|
|
21
19
|
## Conventions & Deduplication
|
|
22
20
|
- [tools-agent-id-conventions.md](tools-agent-id-conventions.md) — agent_id naming rules, hyphen prohibition, and namespace isolation
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# agent_id — multi-agent identity on Cloud Meko
|
|
2
2
|
|
|
3
|
-
`agent_id` identifies **which agent wrote a memory or created a conversation**. It is not a constant. Pick a value that represents the specific agent + project you're acting for
|
|
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 and use it consistently for writes and trace attribution within this session.
|
|
4
4
|
|
|
5
|
-
The Cloud UI (`cloud.mekodata.ai`) renders `agent_id` as a badge on every memory and conversation row — so the value you pick is user-visible. Multiple different agents with different `agent_id` values can write into the same datapack;
|
|
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; the badge records who wrote each row, and both the UI and a `memory_search` show the full cross-agent picture for the user.
|
|
6
6
|
|
|
7
7
|
## The three buckets
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Each memory is written under an `agent_id` (stored on the row, shown as the UI badge). It labels *who wrote* the row — it does not restrict who can later read it (`memory_search` spans all your agents for the user). Still, pick the right value up front so attribution is meaningful:
|
|
10
10
|
|
|
11
11
|
| Pattern | When to use | Example |
|
|
12
12
|
|---|---|---|
|
|
@@ -16,13 +16,15 @@ Memories segregate strictly by `agent_id`. Pick the right bucket up front:
|
|
|
16
16
|
|
|
17
17
|
**Discover the value at session start.** The SessionStart hook injects the chosen `agent_id` into the first-turn `additionalContext` based on the cwd's repo basename. Use that value verbatim — do not re-derive it. If the block is absent, fall back to `<client>:<basename(cwd)>` or ask the user.
|
|
18
18
|
|
|
19
|
-
For genuinely cross-project facts ("the user's name is Amiram", "the user prefers dark mode") write with `agent_id="meko_agent"` so
|
|
19
|
+
For genuinely cross-project facts ("the user's name is Amiram", "the user prefers dark mode") write with `agent_id="meko_agent"` so their attribution clearly identifies the common cross-project bucket.
|
|
20
|
+
|
|
21
|
+
**Pick a value that matches the running client — don't invent another client's shape.** A Claude Desktop session that writes with `agent_id="claude_code"` (or `claude_code:something`) creates rows the UI will attribute to Claude Code — a misleading badge for both clients. Use the pattern from the table that matches the client you're actually running under.
|
|
20
22
|
|
|
21
23
|
## Valid characters
|
|
22
24
|
|
|
23
25
|
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.
|
|
24
26
|
|
|
25
|
-
Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`, `claude-code`, `claude_code`, `cursor:<slug>`, `claude-code:-Users-...`. None of them cause errors
|
|
27
|
+
Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`, `claude-code`, `claude_code`, `cursor:<slug>`, `claude-code:-Users-...`. None of them cause errors or prevent memory recall. New writes should follow the table above.
|
|
26
28
|
|
|
27
29
|
## How agent_id filters reads and writes
|
|
28
30
|
|
|
@@ -31,15 +33,19 @@ Pre-existing data in real datapacks includes a mix of legacy shapes — `agent`,
|
|
|
31
33
|
- 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.
|
|
32
34
|
- If you pass an empty or whitespace-only `agent_id`, the server stores `meko_agent`. That's the common bucket — fine for cross-project facts; not what you want for project-scoped writes.
|
|
33
35
|
|
|
34
|
-
### Personal reads — `memory_search`, `memory_get_all
|
|
36
|
+
### Personal memory reads — `memory_search`, `memory_get_all`
|
|
37
|
+
|
|
38
|
+
Filter tuple: `(datapack_id, user_id)`. `agent_id` is **not** applied on memory reads.
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
- `user_id` is **always enforced**: you can only see memories 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.
|
|
41
|
+
- `agent_id` does **not** filter results. A single `memory_search` returns your memories for this user across *every* `agent_id`: a memory written under `agent_id="cursor:foo"` IS returned by a search passing `agent_id="claude_code:meko-mcp-server"` — or empty, or any value. The tool passes `meko_agent_id=None` to mem0, so `agent_id` scopes only the Langfuse trace, not the result set. There is nothing to "fan out"; one call already sees all of your agents' memories (including the `meko_agent` common bucket).
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
- `agent_id` is **strictly matched**: a search with `agent_id="claude_code:meko-mcp-server"` returns only rows whose stored value is exactly that. A memory written by `agent_id="cursor:foo"` is invisible to it.
|
|
40
|
-
- 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-agent fan-out. To search across multiple agent_ids, call once per known value.
|
|
43
|
+
Empirically verified 2026-07-23 on Cloud prod: memories written under two distinct `agent_id`s were both returned by a `memory_search` passing a third, never-written `agent_id` (and by one passing empty string).
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
### Personal conversation reads — `conversation_get`, `conversation_list`
|
|
46
|
+
|
|
47
|
+
- `conversation_get` — agent-owned. Filter tuple `(datapack_id, user_id, agent_id)`: pass the exact `agent_id` that created the conversation; a wrong value returns `agent_id_mismatch`.
|
|
48
|
+
- `conversation_list` — **not** agent-filtered. It lists by `(datapack_id, user_id)` only; `agent_id` on the call is trace-attribution only (like memory reads), so one call returns the datapack's conversations for your user regardless of which agent created them.
|
|
43
49
|
|
|
44
50
|
### Team-shared reads — `knowledgebase_search`
|
|
45
51
|
|
|
@@ -57,9 +63,10 @@ The originating `agent_id` is preserved in each result's `metadata_filters.agent
|
|
|
57
63
|
memory_add(agent_id=X, text=...)
|
|
58
64
|
│
|
|
59
65
|
▼
|
|
60
|
-
mem0_collection ── personal memories,
|
|
66
|
+
mem0_collection ── personal memories, tagged (datapack, user, agent)
|
|
61
67
|
│
|
|
62
|
-
│
|
|
68
|
+
│ memory_promote (exact UUIDs + explicit confirmation)
|
|
69
|
+
│ or UI "Promote to Knowledge" (Learnings tab)
|
|
63
70
|
│ ─────────────────────────────────────────
|
|
64
71
|
│ Strips user_id, keeps agent_id as metadata,
|
|
65
72
|
│ copies into team-shared table
|
|
@@ -72,23 +79,20 @@ knowledgebase_search(agent_id=anything, query=...)
|
|
|
72
79
|
|
|
73
80
|
- **Personal memories** are what you get from `memory_search` / `memory_get_all`. Private to you.
|
|
74
81
|
- **Shared Knowledge** is what you get from `knowledgebase_search`. Visible to every user and every agent on the datapack.
|
|
75
|
-
- **Promotion
|
|
82
|
+
- **Promotion has MCP and UI paths.** `memory_promote` moves exact, user-confirmed memories into Shared Knowledge and evicts the private records; the Learnings tab is the user-driven alternative. Only datapack owners and maintainers may use the MCP path.
|
|
76
83
|
|
|
77
84
|
## When to use what — broad-query guidance
|
|
78
85
|
|
|
79
|
-
If the user asks "what do you know about X?"
|
|
80
|
-
|
|
81
|
-
1. **First call**: `memory_search(agent_id="<your agent_id>", query="X")` — returns your own project's memories. Most relevant if the context is "what have you and I done in this repo."
|
|
82
|
-
2. **Second call**: `memory_search(agent_id="meko_agent", query="X")` — returns the common cross-project bucket (user identity, global preferences). Anything you wrote with `agent_id="meko_agent"` from any agent or project, plus rows the server stored under that name when called with empty `agent_id`.
|
|
83
|
-
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.
|
|
86
|
+
If the user asks "what do you know about X?":
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
1. **`memory_search(agent_id="<your agent_id>", query="X")`** — returns all of your personal memories for this user, across every `agent_id` (your project bucket, the `meko_agent` common bucket, and any other project's rows). One call is the whole personal surface — `agent_id` doesn't filter memory reads, so there's nothing to fan out.
|
|
89
|
+
2. **`knowledgebase_search(agent_id="<anything>", datapack_id="<datapack>", query="X")`** — returns team-shared knowledge. Useful when the answer may have been promoted by the user or a teammate.
|
|
86
90
|
|
|
87
|
-
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
|
|
91
|
+
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 personal memories" vs. "I found this in your team's shared knowledge."
|
|
88
92
|
|
|
89
|
-
##
|
|
93
|
+
## Optional sub-scoping
|
|
90
94
|
|
|
91
|
-
Optional parameters narrow
|
|
95
|
+
Optional parameters can narrow a call further:
|
|
92
96
|
- `user_id` — explicitly scope writes/reads to a specific end-user if your agent serves multiple (rare in Claude Code; more common in API products)
|
|
93
97
|
- `run_id` — per-execution run
|
|
94
98
|
|
|
@@ -96,6 +100,6 @@ Available on `memory_add`, `memory_search`, `memory_get_all`, `memory_delete_all
|
|
|
96
100
|
|
|
97
101
|
## Things I checked and found in-data on real Cloud datapacks
|
|
98
102
|
|
|
99
|
-
- `agent_id="agent"` appears on many legacy rows — it was the previous canonical constant. New writes should use the schema in the table above;
|
|
100
|
-
- 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.
|
|
103
|
+
- `agent_id="agent"` appears on many legacy rows — it was the previous canonical constant. New writes should use the schema in the table above; memory reads still return the legacy rows.
|
|
104
|
+
- 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. `memory_search` and `conversation_list` are likewise agent-agnostic (they return all your agents' rows for the user); only `conversation_get` enforces `agent_id` (agent ownership).
|
|
101
105
|
- 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.
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
When MCP clients have built-in Langfuse hooks (Cursor, Claude Code), both the client hook and the MCP server may write a trace for the same message → duplicate traces, doubled message counts, corrupted conversation retrieval.
|
|
6
6
|
|
|
7
|
-
**WRONG:**
|
|
7
|
+
**WRONG:** No `seed` provided → both sides generate random trace IDs → two traces per message.
|
|
8
8
|
|
|
9
9
|
## Solution: Use seed for deterministic trace IDs
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
conversation_add_message(
|
|
13
|
-
|
|
13
|
+
conversation_id="conv-uuid", agent_id="my_agent",
|
|
14
14
|
input="What is our Q3 revenue?",
|
|
15
15
|
output="Q3 revenue was $4.2M, up 15% from Q2.",
|
|
16
16
|
seed="conv-uuid:my_agent:What is our Q3 revenue?"
|
|
@@ -19,11 +19,10 @@ conversation_add_message(
|
|
|
19
19
|
|
|
20
20
|
Both sides hash the same seed string to produce the same trace ID. Langfuse treats the second write as an upsert → exactly one trace.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Trace ID Rules
|
|
23
23
|
|
|
24
|
-
1. **`
|
|
25
|
-
2.
|
|
26
|
-
3. **Neither** — random trace ID generated
|
|
24
|
+
1. **`seed`** — if provided, hashed to produce a deterministic trace ID
|
|
25
|
+
2. **Not provided** — a random trace ID is generated
|
|
27
26
|
|
|
28
27
|
## Choosing a Good Seed
|
|
29
28
|
|
|
@@ -41,7 +40,6 @@ seed = f"{conversation_id}:{agent_id}:{message_index}"
|
|
|
41
40
|
|----------|-----|
|
|
42
41
|
| Client hook + MCP server both write to Langfuse | `seed` |
|
|
43
42
|
| Only the MCP server writes (no client hook) | Neither (random is fine) |
|
|
44
|
-
| Migrating from another system with existing IDs | `trace_id` |
|
|
45
43
|
| Replaying messages idempotently | `seed` |
|
|
46
44
|
|
|
47
45
|
## session_id on conversation_create
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Authoring `reasoning` and `plan` on `conversation_add_message`
|
|
2
|
+
|
|
3
|
+
`conversation_add_message` accepts two optional fields — `reasoning` and `plan` — that capture *why* the assistant replied the way it did and *what* concrete steps it took. They are stored side-by-side on the per-turn `Reasoning` observation in Langfuse, independently, so consumers can read or render either one on its own.
|
|
4
|
+
|
|
5
|
+
Provide them on the large majority of substantive turns. Skip both only for genuinely trivial acknowledgements (a one-word reply, a pure restatement). Do not fabricate deliberation — but in practice, almost every substantive reply has at least a one-line *why* and a one-step plan.
|
|
6
|
+
|
|
7
|
+
## `reasoning`
|
|
8
|
+
|
|
9
|
+
A short paragraph (1–3 sentences) of the **why**. Plain English. Explain which trade-off you weighed, which user fact tipped the decision, why this answer beat the alternatives. Inline markdown (`**bold**`, `*italics*`, `` `code` ``) is fine.
|
|
10
|
+
|
|
11
|
+
Do NOT include a `**Plan:**` heading inside `reasoning` — put steps in the `plan` field instead.
|
|
12
|
+
|
|
13
|
+
## `plan`
|
|
14
|
+
|
|
15
|
+
A list of 2 to 4 concrete actions taken for this turn. Each entry is a single imperative sentence, like a checklist item. Pass a list of strings.
|
|
16
|
+
|
|
17
|
+
Do NOT pre-number entries. Do NOT include a `**Plan:**` heading inside the strings — `plan` is stored as a structured array on the observation's `metadata.plan`, independent of `reasoning`.
|
|
18
|
+
|
|
19
|
+
## Two examples
|
|
20
|
+
|
|
21
|
+
### Example A — database recommendation
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
reasoning:
|
|
25
|
+
"The user cares about low latency and predictable cost.
|
|
26
|
+
Option A wins on latency but costs more per month; option
|
|
27
|
+
B is cheaper but adds 30 ms p99. Latency was their top
|
|
28
|
+
priority, so I picked Option A."
|
|
29
|
+
|
|
30
|
+
plan: [
|
|
31
|
+
"Recommend Option A and call out the latency advantage.",
|
|
32
|
+
"Show the monthly cost delta in clear numbers.",
|
|
33
|
+
"Flag the cost difference so the user can decide if it fits."
|
|
34
|
+
]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Example B — book pick for a long flight
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
reasoning:
|
|
41
|
+
"The user wants a non-fiction book for a six-hour flight
|
|
42
|
+
and does not enjoy business memoirs. *Sapiens* fits the
|
|
43
|
+
time slot, is non-fiction, and is not a memoir."
|
|
44
|
+
|
|
45
|
+
plan: [
|
|
46
|
+
"Recommend *Sapiens* as the main pick.",
|
|
47
|
+
"Offer *Bad Blood* as a non-memoir backup.",
|
|
48
|
+
"Skip founder memoirs per the user's stated dislike."
|
|
49
|
+
]
|
|
50
|
+
```
|