@yugabytedb/meko-mcp 1.0.8 → 1.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 +242 -44
- 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 +457 -107
- package/assets/hooks-handlers/lib/package.json +1 -0
- package/assets/hooks-handlers/test_single_conversation.sh +1 -1
- package/assets/scripts/package-desktop-skill.sh +36 -0
- package/assets/skills/meko-mcp-tools/SKILL.md +167 -53
- package/assets/skills/meko-mcp-tools/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +84 -22
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +89 -56
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +15 -7
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +17 -9
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +94 -5
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +52 -37
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +108 -37
- package/assets/skills/meko-mcp-tools/references/tools-scope-permissions.md +6 -10
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +30 -18
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +55 -69
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +251 -0
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +150 -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 +406 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +69 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +217 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +112 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +134 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-scope-permissions.md +75 -0
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +155 -0
- package/bin/create-meko-setup.mjs +151 -22
- package/lib/clients/claude-code.mjs +378 -68
- package/lib/clients/claude-desktop.mjs +45 -8
- package/lib/clients/codex.mjs +1209 -0
- package/lib/clients/common.mjs +223 -1
- package/lib/clients/cursor.mjs +118 -13
- package/lib/clients/index.mjs +2 -0
- package/lib/config.mjs +56 -0
- package/lib/detect.mjs +52 -44
- package/lib/installer.mjs +11 -4
- package/lib/mcp-transport.mjs +61 -2
- package/lib/migrate/adapters/memory-md.mjs +13 -6
- package/lib/migrate/datapack.mjs +167 -0
- package/lib/migrate/id.mjs +127 -9
- package/lib/migrate/orchestrator.mjs +68 -10
- package/lib/migrate.mjs +346 -3
- package/lib/prompt.mjs +22 -4
- package/lib/validate.mjs +313 -9
- package/lib/version-check.mjs +178 -0
- package/package.json +2 -1
- package/scripts/bundle-assets.mjs +8 -0
|
@@ -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.
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Tool Cookbook — Complete Usage Examples
|
|
2
|
+
|
|
3
|
+
Every tool example below shows the correct parameters, expected response, and common errors. Use `scope="read"` for reads and `scope="write"` for writes — never `"all"` or any other value.
|
|
4
|
+
|
|
5
|
+
> **Note on `agent_id` in the examples below.** The string `"agent"` appears in these examples as a placeholder shorthand; it is NOT a required constant. Substitute **your** client's bucket: for Claude Desktop, the bare client name `claude_desktop`; for Claude Code/Cursor, `<client>:<repo-basename>` (e.g. `claude_code:meko-mcp-server`). For genuinely cross-project facts (user identity, global preferences) write/read with `agent_id="meko_agent"` — the common bucket the server stores empty/missing values into. See `tools-agent-id-conventions.md`.
|
|
6
|
+
>
|
|
7
|
+
> **Note on availability on Cloud.** The `db_*` tools and the three KB ingestion tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) return `{"error": "not_available"}` on Cloud Meko today. This cookbook keeps their examples for reference but you can't call them from a Cloud client.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Database Tools
|
|
12
|
+
|
|
13
|
+
### db_summarize_database
|
|
14
|
+
|
|
15
|
+
**When to use:** First thing in a session to understand what's in the database. Prefer this over writing your own `information_schema` query.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
db_summarize_database(scope="read", schema="public")
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Response:**
|
|
22
|
+
```json
|
|
23
|
+
[
|
|
24
|
+
{
|
|
25
|
+
"table_name": "customers",
|
|
26
|
+
"schema": [
|
|
27
|
+
{"column_name": "id", "data_type": "uuid"},
|
|
28
|
+
{"column_name": "name", "data_type": "text"}
|
|
29
|
+
],
|
|
30
|
+
"row_count": 1523
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**With datapack:**
|
|
36
|
+
```
|
|
37
|
+
db_summarize_database(scope="read", schema="public", datapack_id="dp-uuid-123")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Common errors:**
|
|
41
|
+
- `Insufficient scope: 'all'` — Use `scope="read"`, not `"all"`
|
|
42
|
+
- Empty result — The schema may not exist, try `schema="public"`
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### db_run_read_only_query
|
|
47
|
+
|
|
48
|
+
**When to use:** Any SELECT query. Always add `LIMIT` on exploratory queries.
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
db_run_read_only_query(scope="read", query="SELECT id, name FROM customers LIMIT 10")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Response:** JSON array of row objects.
|
|
55
|
+
```json
|
|
56
|
+
[{"id": "abc-123", "name": "Alice"}, {"id": "def-456", "name": "Bob"}]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Best practices:**
|
|
60
|
+
- Always use `LIMIT` on unfamiliar tables to avoid flooding context
|
|
61
|
+
- Select specific columns rather than `SELECT *` to keep responses small
|
|
62
|
+
- For non-public schemas: `SELECT * FROM analytics."monthly_revenue" LIMIT 5`
|
|
63
|
+
- Escape single quotes in values: `WHERE name = 'O''Brien'`
|
|
64
|
+
|
|
65
|
+
**Common errors:**
|
|
66
|
+
- `cannot execute INSERT in a read-only transaction` — Use `db_run_write_query` for writes
|
|
67
|
+
- `permission denied for table X` — MCP user lacks access to this table (server-side config issue, not fixable via MCP)
|
|
68
|
+
- `connection already closed` — Retry once. If persistent, the DB pool is unhealthy.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### db_run_write_query
|
|
73
|
+
|
|
74
|
+
**When to use:** INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX.
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
db_run_write_query(scope="write", query="INSERT INTO customers (id, name) VALUES ('abc-123', 'Alice')")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Response:**
|
|
81
|
+
```json
|
|
82
|
+
{"rows_affected": 1}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**One statement per call.** This is wrong:
|
|
86
|
+
```
|
|
87
|
+
db_run_write_query(scope="write", query="CREATE TABLE a (id INT); CREATE TABLE b (id INT);")
|
|
88
|
+
```
|
|
89
|
+
Split into two separate calls.
|
|
90
|
+
|
|
91
|
+
**Bulk inserts:** Maximum 1000 rows per INSERT VALUES. For more, use `INSERT ... SELECT` or batch into multiple calls.
|
|
92
|
+
|
|
93
|
+
**Common errors:**
|
|
94
|
+
- `Multi-statement queries not allowed` — Send one statement per call
|
|
95
|
+
- `DROP SCHEMA is not allowed` — See `tools-write-guardrails.md` for blocked operations
|
|
96
|
+
- `'dict' object has no attribute 'guardrail_config'` — Known server bug in some deployments. Write operations may be unavailable.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Memory Tools
|
|
101
|
+
|
|
102
|
+
**Critical:** Pass your session's `agent_id` on every memory call. For Claude Desktop that's `claude_desktop` for client-personal context, or `meko_agent` for genuinely cross-project facts (user identity, global preferences). Personal writes are scoped strictly by `agent_id` — other agents won't see your writes on personal reads unless they pass the same exact value.
|
|
103
|
+
|
|
104
|
+
### memory_add
|
|
105
|
+
|
|
106
|
+
**When to use:** Store facts, preferences, user profile info, org conventions, corrections, learnings. Use proactively — don't wait for the user to ask.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
memory_add(scope="write", agent_id="agent",
|
|
110
|
+
text="User Amiram is VP of Product at YugabyteDB. Prefers concise responses.")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Response:**
|
|
114
|
+
```json
|
|
115
|
+
{"results": [{"id": "mem-uuid-123", "memory": "User Amiram is VP of Product at YugabyteDB. Prefers concise responses."}]}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**With user scoping:**
|
|
119
|
+
```
|
|
120
|
+
memory_add(scope="write", agent_id="agent", user_id="amiram",
|
|
121
|
+
text="Prefers Python for backend, Go for infrastructure.")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**What NOT to store via memory_add:**
|
|
125
|
+
- CSV rows or tabular data (use `db_run_write_query` instead)
|
|
126
|
+
- Full conversations (use `conversation_create` + `conversation_add_message`)
|
|
127
|
+
- Large documents (use knowledge base ingestion)
|
|
128
|
+
|
|
129
|
+
**Common errors:**
|
|
130
|
+
- `syntax error at or near "-"` — legacy error from the pre-multi-tenancy schema when `agent_id` became part of a PostgreSQL identifier. No longer applies on Cloud (agent_id is a TEXT column value, any string is accepted). If you hit it on a deployment that still uses the old schema, use underscores instead of hyphens.
|
|
131
|
+
- `connection already closed` — Retry once. If it fails again, the memory subsystem is down.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### memory_search
|
|
136
|
+
|
|
137
|
+
**When to use:** Find relevant memories by meaning. Always try this before asking the user to repeat information.
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
memory_search(scope="read", query="What programming language does the team use?", agent_id="agent")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Response:**
|
|
144
|
+
```json
|
|
145
|
+
{"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89}]}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**With limit:**
|
|
149
|
+
```
|
|
150
|
+
memory_search(scope="read", query="user preferences", agent_id="agent", limit=5)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### memory_get_all
|
|
156
|
+
|
|
157
|
+
**When to use:** List everything stored for an agent. Useful at session start to load context.
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
memory_get_all(scope="read", agent_id="agent")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**With user scoping:**
|
|
164
|
+
```
|
|
165
|
+
memory_get_all(scope="read", agent_id="agent", user_id="amiram")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### memory_get_by_id
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
memory_get_by_id(scope="read", memory_id="mem-uuid-123", agent_id="agent")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### memory_update
|
|
179
|
+
|
|
180
|
+
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
memory_update(scope="write", memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="agent")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### memory_delete_by_id
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
memory_delete_by_id(scope="write", memory_id="mem-uuid-123", agent_id="agent")
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### memory_delete_all
|
|
197
|
+
|
|
198
|
+
**Destructive. Requires admin scope.** Deletes all memories for the agent.
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
memory_delete_all(scope="admin", agent_id="agent")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Conversation Tools
|
|
207
|
+
|
|
208
|
+
### conversation_create
|
|
209
|
+
|
|
210
|
+
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
conversation_create(scope="write", agent_id="agent", user_id="amiram",
|
|
214
|
+
title="Debugging the auth middleware")
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Response:**
|
|
218
|
+
```json
|
|
219
|
+
{"id": "conv-uuid-123", "title": "Debugging the auth middleware"}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### conversation_add_message
|
|
225
|
+
|
|
226
|
+
**When to use:** Add a user/assistant exchange to an existing conversation. **All fields must be verbatim** — never summarize or rephrase.
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
230
|
+
input="Why is the auth middleware returning 401?",
|
|
231
|
+
output="The token validation is checking the wrong issuer claim...",
|
|
232
|
+
reasoning="Checked the middleware source, found issuer mismatch between config and JWT...")
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**With dedup seed (use when client hooks also write to Langfuse):**
|
|
236
|
+
```
|
|
237
|
+
conversation_add_message(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
238
|
+
input="Why is the auth middleware returning 401?",
|
|
239
|
+
output="The token validation is checking the wrong issuer claim...",
|
|
240
|
+
seed="conv-uuid-123:agent:Why is the auth middleware returning 401?")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### conversation_get
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
conversation_get(scope="read", conversation_id="conv-uuid-123", agent_id="agent",
|
|
249
|
+
include_messages=True, limit=50)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### conversation_list
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
conversation_list(scope="read", agent_id="agent", limit=20)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### conversation_update
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
conversation_update(scope="write", conversation_id="conv-uuid-123", agent_id="agent",
|
|
266
|
+
title="Resolved: Auth middleware issuer mismatch")
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
### conversation_delete
|
|
272
|
+
|
|
273
|
+
**Destructive. Requires admin scope.**
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
conversation_delete(scope="admin", conversation_id="conv-uuid-123", agent_id="agent")
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## RAG / Knowledge Base Tools
|
|
282
|
+
|
|
283
|
+
**On cloud Meko today, KB ingestion is a UI-only activity.** Users upload files via the datapack's Actions → **Add Knowledge** dialog (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). The three ingestion-side MCP tools below are Free-Tier-gated on cloud and brittle even when ungated. `knowledgebase_search` is the one KB tool to reach for.
|
|
284
|
+
|
|
285
|
+
See `tools-rag-workflow.md` for the decision table and why.
|
|
286
|
+
|
|
287
|
+
### knowledgebase_search
|
|
288
|
+
|
|
289
|
+
**When to use:** Retrieve chunks from a populated KB. Works on cloud today.
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
knowledgebase_search(
|
|
293
|
+
scope="read",
|
|
294
|
+
query="natural-language question",
|
|
295
|
+
agent_id="agent",
|
|
296
|
+
conversation_id="<uuid from conversation_create>",
|
|
297
|
+
datapack_id="<datapack UUID — REQUIRED here, no default>",
|
|
298
|
+
limit=10)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Unlike memory tools, `datapack_id` has no default — you must pass it explicitly.
|
|
302
|
+
|
|
303
|
+
**Response (empty KB, verified 2026-05-07):**
|
|
304
|
+
```json
|
|
305
|
+
{"results": [], "count": 0}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Populated KBs return results with chunk content and similarity scores. An empty/nonexistent KB is not an error — just `count: 0`.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### knowledgebase_trigger_index_creation
|
|
313
|
+
|
|
314
|
+
**When to use:** Self-hosted deployments where the ingestion worker has IAM access to the target S3 bucket. **Not available on cloud Free Tier** (returns `{"error": "not_available", "detail": "Vector index creation is not available on the free tier."}`).
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
knowledgebase_trigger_index_creation(
|
|
318
|
+
scope="write",
|
|
319
|
+
conversation_id="<uuid from conversation_create>",
|
|
320
|
+
source_uris="s3://my-bucket/docs/,s3://my-bucket/reports/",
|
|
321
|
+
index_name="company_docs")
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Optional parameters:**
|
|
325
|
+
- `ai_provider="OPENAI"` (default)
|
|
326
|
+
- `embedding_model="text-embedding-3-large"` (default)
|
|
327
|
+
- `embedding_dimensions=1536` (default)
|
|
328
|
+
- `chunk_size=1024` (default)
|
|
329
|
+
- `chunk_overlap=256` (default)
|
|
330
|
+
- `datapack_id=None`
|
|
331
|
+
|
|
332
|
+
**Success response:**
|
|
333
|
+
```json
|
|
334
|
+
{"source_ids": ["<uuid>", ...], "index_id": "<uuid>", "index_name": "company_docs",
|
|
335
|
+
"status": "build_triggered", "message": "... registered, index '...' initialised, and build triggered."}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Critical caveats:**
|
|
339
|
+
- URIs must start with `s3://`. The worker (`aws_source_processor.py:86-117`) rejects any other scheme with `ValueError("Invalid source URI")` — async, not surfaced through the MCP response.
|
|
340
|
+
- The worker uses the boto3 default credential chain (env vars, IAM role, `~/.aws/credentials` on the worker host). There is no way for the user to pass AWS credentials through the MCP tool. If the worker's identity can't read the bucket, the build stalls at INIT.
|
|
341
|
+
- Each call creates a new index. Do NOT retry on failure — you'll get duplicate indexes.
|
|
342
|
+
- Tracked as a gap: [yugabyte/meko-mcp-server#89](https://github.com/yugabyte/meko-mcp-server/issues/89) / MEKO-96.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
### knowledgebase_check_index_status
|
|
347
|
+
|
|
348
|
+
**When to use:** Poll a self-hosted build for completion. **Not available on cloud Free Tier** (returns `{"error": "not_available"}`).
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
knowledgebase_check_index_status(
|
|
352
|
+
scope="read",
|
|
353
|
+
conversation_id="<uuid from conversation_create>",
|
|
354
|
+
index_name="company_docs",
|
|
355
|
+
datapack_id=None)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Check `completion_rate_percent` in `pipeline_stats` and `document_status` in `pipeline_details`. If documents stay at `INIT` for >5 minutes, the worker probably can't reach the bucket. Stop polling after 3 consecutive no-progress checks.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
### knowledgebase_add_source_to_index
|
|
363
|
+
|
|
364
|
+
**When to use:** Grow an existing index with a new source URI (self-hosted / paid). **Not available on cloud Free Tier** (same "Vector index creation is not available" gate as `trigger_index_creation`).
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
knowledgebase_add_source_to_index(
|
|
368
|
+
scope="write",
|
|
369
|
+
conversation_id="<uuid from conversation_create>",
|
|
370
|
+
index_name="company_docs",
|
|
371
|
+
source_uri="s3://my-bucket/new-docs/")
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Param is **`source_uri`** (URI string), not `source_id` — older docs had this wrong.
|
|
375
|
+
|
|
376
|
+
The historical `r_index_name` vs `r_index_id` parameter-mismatch bug (reported in 2026-03) is **fixed** on main. The tool now resolves `index_name → index_id` internally via `SELECT id FROM dist_rag.vector_indexes WHERE index_name = %s` before calling the dist_rag function. If the name doesn't exist you get `{"error": "index_not_found", "detail": "No vector index found with name '...'"}`.
|
|
377
|
+
|
|
378
|
+
Same S3-only / worker-credentials caveats as `trigger_index_creation` apply.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Datapack Management Tools
|
|
383
|
+
|
|
384
|
+
### datapack_create / datapack_list / datapack_describe
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
datapack_create(scope="write", name="analytics_prod")
|
|
388
|
+
datapack_list(scope="read")
|
|
389
|
+
datapack_describe(scope="read", name="analytics_prod", include_status=True)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### datapack_update / datapack_delete
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
datapack_update(scope="write", name="analytics_prod", connection_string="postgresql://...")
|
|
396
|
+
datapack_delete(scope="admin", name="analytics_prod") # Irreversible!
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Agent and knowledge-base management (NOT MCP — control-plane only)
|
|
400
|
+
|
|
401
|
+
Agent and KB lifecycle does not ship as MCP tools. If the user asks to create/list/delete agents or KB sources, don't invent a tool call — point them at the control plane:
|
|
402
|
+
|
|
403
|
+
- REST: `POST/GET/DELETE /datapacks/:name/agents` (agents), `POST/GET/DELETE /datapacks/:name/knowledge-bases` (KB sources).
|
|
404
|
+
- Or the Meko UI at `app.mekodev.com` → Datapacks → agents / knowledge-bases.
|
|
405
|
+
|
|
406
|
+
To build a RAG index from inside a session (which IS MCP-exposed), use `knowledgebase_trigger_index_creation` / `knowledgebase_add_source_to_index` / `knowledgebase_check_index_status` — those operate on `dist_rag` tables inside the datapack's database.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Known Limitations
|
|
2
|
+
|
|
3
|
+
These are current limitations of the Meko MCP tools. Know them upfront to avoid wasted tool calls.
|
|
4
|
+
|
|
5
|
+
## No delete tools for RAG artifacts
|
|
6
|
+
|
|
7
|
+
There are no MCP tools to:
|
|
8
|
+
- Delete a vector index
|
|
9
|
+
- Remove a source from an index
|
|
10
|
+
- Clear stuck work queue entries
|
|
11
|
+
- Reset a failed pipeline
|
|
12
|
+
|
|
13
|
+
KB-source deletion happens via the Meko control plane (REST: `DELETE /datapacks/:name/knowledge-bases`, or the UI), which removes the registration from the Meko API — but does **not** touch the actual `dist_rag` index, source records, or vector data in the datapack's database.
|
|
14
|
+
|
|
15
|
+
**Workaround:** For stuck or failed indexes, create a new index with a different name. Stale indexes remain in the database until manually cleaned up by an admin.
|
|
16
|
+
|
|
17
|
+
## No MCP tool to query a built RAG index
|
|
18
|
+
|
|
19
|
+
The RAG tools (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) handle index **creation and monitoring** only.
|
|
20
|
+
|
|
21
|
+
To actually **query** a built index on Cloud, use `knowledgebase_search` — it returns both uploaded documents (UI "Add Knowledge" flow) and memories the user promoted from the Learnings tab. The `db_run_read_only_query` direct-DB path is Free-Tier-gated on Cloud.
|
|
22
|
+
|
|
23
|
+
## Memory tools unreliable for structured/tabular data
|
|
24
|
+
|
|
25
|
+
`memory_add` passes text through Mem0's fact extraction pipeline. This works well for:
|
|
26
|
+
- Facts: "Alice works at Acme Corp"
|
|
27
|
+
- Preferences: "User prefers dark mode"
|
|
28
|
+
- Entity relationships: "Amiram reports to Karthik"
|
|
29
|
+
|
|
30
|
+
It works **poorly** for:
|
|
31
|
+
- CSV rows or tabular data — columns and rows get dropped
|
|
32
|
+
- Data dictionaries — only partial information extracted
|
|
33
|
+
- Structured schemas — relationships between fields lost
|
|
34
|
+
|
|
35
|
+
**On Cloud, structured data is not MCP-supported today.** `db_run_write_query` / `db_run_read_only_query` / `db_summarize_database` all return `{"error": "not_available", "detail": "Free Tier: DB Tools access is not enabled. coming soon."}`. The options are:
|
|
36
|
+
|
|
37
|
+
1. **Write a single narrative summary** as a memory — one call, not row-by-row:
|
|
38
|
+
```
|
|
39
|
+
memory_add(scope="write",
|
|
40
|
+
agent_id="<your session agent_id>",
|
|
41
|
+
conversation_id="<session conversation_id>",
|
|
42
|
+
text="Customer Complaints dataset has fields: Complaint ID (int PK), Date Submitted (date), Product (text, e.g. Mortgage/Credit Card), Sub-product (text), Issue (text), Company Response (text), State (text, 2-letter code), ZIP Code (text)")
|
|
43
|
+
```
|
|
44
|
+
2. **Upload the schema doc** through the Cloud UI's **Add Knowledge** flow (Datapack → Actions → Add Knowledge). Accepts PDF/TXT/MD/JSON — convert CSV to MD or JSON first. That makes it queryable via `knowledgebase_search`.
|
|
45
|
+
3. **Tell the user** that structured-data storage via MCP isn't a Cloud feature today and let them decide how to proceed.
|
|
46
|
+
|
|
47
|
+
Never ingest CSV row-by-row into memory — each row becomes a fragmented fact with lost context.
|
|
48
|
+
|
|
49
|
+
## MCP user permission gaps
|
|
50
|
+
|
|
51
|
+
The MCP database user may not have read access to all tables within a datapack, particularly:
|
|
52
|
+
- Data tables created by the provisioning system
|
|
53
|
+
- Tables in non-public schemas
|
|
54
|
+
|
|
55
|
+
If `db_run_read_only_query` returns "permission denied", this is a server-side configuration issue. Use `db_summarize_database` to see which tables are accessible.
|
|
56
|
+
|
|
57
|
+
## Currently broken tools
|
|
58
|
+
|
|
59
|
+
**`db_run_write_query`** — May fail with `'dict' object has no attribute 'guardrail_config'` in some deployments. When this happens, all write operations are blocked for the session.
|
|
60
|
+
|
|
61
|
+
**Knowledge-base ingestion tools on cloud Meko** (`knowledgebase_trigger_index_creation`, `knowledgebase_add_source_to_index`, `knowledgebase_check_index_status`) return `{"error": "not_available"}` on Free Tier. Even when ungated, the async worker only reads `s3://` URIs and uses its own boto3 credential chain — it cannot read buckets the user provides credentials for. Tracked: [yugabyte/meko-mcp-server#89](https://github.com/yugabyte/meko-mcp-server/issues/89) / MEKO-96. Use the Meko UI's **Add Knowledge** file-upload dialog for ingestion on cloud. `knowledgebase_search` works on cloud today.
|
|
62
|
+
|
|
63
|
+
(Historical note: `knowledgebase_add_source_to_index` used to have a `r_index_name` vs `r_index_id` SQL-signature bug. That specific bug was fixed on main in commit `3ae724a` — the tool now resolves `index_name → index_id` internally.)
|
|
64
|
+
|
|
65
|
+
## No conversation search
|
|
66
|
+
|
|
67
|
+
`conversation_list` returns conversations by agent, but there is no semantic search across conversation content. To find a specific past exchange, you need to list conversations and inspect them individually with `conversation_get`.
|
|
68
|
+
|
|
69
|
+
For finding past knowledge by meaning, use `memory_search` instead — which is why storing key facts via `memory_add` alongside conversations is important.
|