vantage-peers-mcp 2.10.0 → 2.11.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/CHANGELOG.md +54 -0
- package/README.md +1 -1
- package/dist/server.js +1 -1
- package/dist/src/tools.js +156 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.11.0] — 2026-06-14 — Day 102 CRUD baseline PR-C-bis option B: 3-entity Convex searchIndex (mission k575kc1ryps0n8br95jw3q7d0x88m2v9)
|
|
4
|
+
|
|
5
|
+
Mission `mcp-crud-baseline-standard` PR-C-bis under T2. Pi-sequenced follow-up after PR-C (rename-only safe subset) — implements **option B SCOPED** per Pi arbitrage msg `jn7abynmghy5qdr9ga0b914wmh88n99w` ("GO option B SCOPED — démarre PR-C avec 3 entités prioritaires"): tasks + messages + briefingNotes get native Convex BM25 search via `.searchIndex()` schema additions + per-entity Convex queries + MCP tool wrappers.
|
|
6
|
+
|
|
7
|
+
Backend choice (B over A): Convex native `.searchIndex()` is BM25-only, no embeddings, no RAG per-entity pipeline. Sub-linear scan stays in the same backend without spinning up an embedding pipeline per table. Hybrid/semantic per entity remains a future RFC.
|
|
8
|
+
|
|
9
|
+
### Added — Convex schema searchIndex (3 tables)
|
|
10
|
+
|
|
11
|
+
- `tasks` → `searchIndex("search_title", { searchField: "title", filterFields: ["assignedTo", "status", "project", "missionId", "orgId"] })`
|
|
12
|
+
- `messages` → `searchIndex("search_content", { searchField: "content", filterFields: ["from", "channel", "sessionDay", "tenantId"] })`
|
|
13
|
+
- `briefingNotes` → `searchIndex("search_content", { searchField: "content", filterFields: ["topic", "createdBy", "orgId"] })`
|
|
14
|
+
|
|
15
|
+
### Added — Convex query functions
|
|
16
|
+
|
|
17
|
+
- `tasks:searchTasksByKeyword` — BM25 over title with assignedTo/status/project/missionId filters + scope gate via `withOrgScope` + `filterByOrgScope` + `requireScope("view-own-tasks")`. Lite/full projection.
|
|
18
|
+
- `messages:searchMessagesByKeyword` — BM25 over content with from/channel/sessionDay/tenantId filters.
|
|
19
|
+
- `briefingNotes:searchBriefingNotesByKeyword` — BM25 over content with topic/createdBy filters.
|
|
20
|
+
|
|
21
|
+
All three: 20-item default limit, 200 cap, lite projection on demand.
|
|
22
|
+
|
|
23
|
+
### Added — MCP tool wrappers (3 canonical)
|
|
24
|
+
|
|
25
|
+
- **`search_tasks_by_keyword`** — wires to `tasks:searchTasksByKeyword`. `readOnlyHint=true`.
|
|
26
|
+
- **`search_messages_by_keyword`** — wires to `messages:searchMessagesByKeyword`. `readOnlyHint=true`.
|
|
27
|
+
- **`search_briefing_notes_by_keyword`** — wires to `briefingNotes:searchBriefingNotesByKeyword`. `readOnlyHint=true`.
|
|
28
|
+
|
|
29
|
+
### Why option B (and why scoped to 3)
|
|
30
|
+
|
|
31
|
+
`grep searchIndex convex/schema.ts` previously returned zero hits; only `memories` had search infrastructure (via `@convex-dev/rag`). The original "13-entity cluster" full scope was deferred via PR-C (rename-only) after arbitrage timeout. Pi's arbitrage landed shortly after: **option B SCOPED to 3 priority entities** is the right blend of doctrine progress + bounded scope:
|
|
32
|
+
- `tasks` — largest fleet audience (Eta T13 close-issue scan, dispatch-task-find, etc.).
|
|
33
|
+
- `messages` — post-incident audit + messages-history skill demand.
|
|
34
|
+
- `briefingNotes` — daily snapshot recall narrative.
|
|
35
|
+
|
|
36
|
+
The remaining 10 entities (mission/mandate/fix_pattern/component/repo_mapping/bu/profile/deployment/diary/error/issue/recurring_task/summary) go to a per-entity RFC (mission walk-through scheduled Wed 17 June 15h with Laurent) — each entity decides B (searchIndex), A (RAG if semantic justified, e.g. episodes/diary), or N/A semantic documented (deployment/repo_mapping).
|
|
37
|
+
|
|
38
|
+
### Version sync
|
|
39
|
+
|
|
40
|
+
- `mcp-server/server.ts:115` SERVER_VERSION 2.10.0 → 2.11.0
|
|
41
|
+
- `mcp-server/package.json` → 2.11.0
|
|
42
|
+
- README + 4 cloud docs bumped to 2.11.0 markers (`enforce-release-sync` v1.0.1 gate).
|
|
43
|
+
|
|
44
|
+
### Test fixture catch-up
|
|
45
|
+
|
|
46
|
+
- `READ_ONLY_TOOLS` set in `mcp-server/src/__tests__/chatgpt-tool-annotations.test.ts` extended with the 3 new canonical tool names.
|
|
47
|
+
|
|
48
|
+
### Refs
|
|
49
|
+
|
|
50
|
+
- Mission `k575kc1ryps0n8br95jw3q7d0x88m2v9`.
|
|
51
|
+
- Pi sequencing dispatch: msg `jn76360ckrrkwpqbfwa6tst7k588mpsh` ("(1) T2 PR-C-bis option B SCOPED 3 entities").
|
|
52
|
+
- Pi arbitrage that selected option B: msg `jn7abynmghy5qdr9ga0b914wmh88n99w`.
|
|
53
|
+
- Audit T1: `analysis/mcp-crud-baseline-vp-audit-2026-06-14.md` rows 1 (task), 3 (message), 4 (briefing_note).
|
|
54
|
+
- Doctrine memory: `j57dhrmkzjerjtssnr0z9ba57n88n7q7` (5 ops per entity).
|
|
55
|
+
- Predecessors: PR-A 2.8.0 (memories canonical), PR-B 2.9.0 (episode 5-op), PR-C 2.10.0 (rename-only safe subset).
|
|
56
|
+
|
|
3
57
|
## [2.10.0] — 2026-06-14 — Day 102 CRUD baseline PR-C: rename-only safe subset (mission k575kc1ryps0n8br95jw3q7d0x88m2v9)
|
|
4
58
|
|
|
5
59
|
Mission `mcp-crud-baseline-standard` PR-C under T2. Third of 4 sub-PRs aligning the MCP surface with the Day 101 doctrine `j57dhrmkzjerjtssnr0z9ba57n88n7q7`. Sigma autonomous default after arbitrage timeout on the original "13-entity search_by_keyword cluster" scope — that fuller scope requires a backend search-infrastructure decision (RAG-index per entity vs Convex `.searchIndex()` per table) that is NOT a thin-wrapper PR. PR-C ships the rename-only safe subset now to keep doctrine velocity; the full cluster is deferred to a backend-RFC mission.
|
package/README.md
CHANGED
|
@@ -242,7 +242,7 @@ Example:
|
|
|
242
242
|
### Session (1)
|
|
243
243
|
`set_summary`
|
|
244
244
|
|
|
245
|
-
## Compact payloads and status aliases (v2.
|
|
245
|
+
## Compact payloads and status aliases (v2.11.0 — feature since v2.3.0)
|
|
246
246
|
|
|
247
247
|
### `fields=lite` — reduced token payloads
|
|
248
248
|
|
package/dist/server.js
CHANGED
|
@@ -102,7 +102,7 @@ const convexUrl = loadConvexUrl();
|
|
|
102
102
|
const convex = new ConvexHttpClient(convexUrl);
|
|
103
103
|
const server = new McpServer({
|
|
104
104
|
name: "vantage-peers",
|
|
105
|
-
version: "2.
|
|
105
|
+
version: "2.11.0",
|
|
106
106
|
});
|
|
107
107
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
108
108
|
// Helper: structured error response for MCP tool handlers
|
package/dist/src/tools.js
CHANGED
|
@@ -2111,6 +2111,60 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2111
2111
|
return mcpConvexError(error);
|
|
2112
2112
|
}
|
|
2113
2113
|
});
|
|
2114
|
+
// ── search_messages_by_keyword ─────────────────────────────────────────────
|
|
2115
|
+
// Day 102 v2.11.0 — CRUD baseline PR-C-bis option B (mission k575kc1r).
|
|
2116
|
+
// BM25 keyword search over message content. Backed by Convex
|
|
2117
|
+
// `messages:searchMessagesByKeyword` using the `search_content` searchIndex.
|
|
2118
|
+
server.tool("search_messages_by_keyword", "BM25 full-text keyword search over message content, ranked by relevance. " +
|
|
2119
|
+
"WHEN: use for post-incident audit or to find peer DMs by topic — e.g. 'find messages about deploy' across the recent sessionDay window. " +
|
|
2120
|
+
"EXAMPLE: search_messages_by_keyword query='convex deploy' from='pi' sessionDay=102 limit=10.", {
|
|
2121
|
+
query: z.string().describe("Search term to match against message content"),
|
|
2122
|
+
from: z.string().optional().describe("Filter by sender role"),
|
|
2123
|
+
channel: z
|
|
2124
|
+
.string()
|
|
2125
|
+
.optional()
|
|
2126
|
+
.describe("Filter by channel — e.g. 'sigma', 'broadcast'"),
|
|
2127
|
+
sessionDay: z
|
|
2128
|
+
.number()
|
|
2129
|
+
.int()
|
|
2130
|
+
.optional()
|
|
2131
|
+
.describe("Filter to a specific session day"),
|
|
2132
|
+
tenantId: z.string().optional().describe("Filter by tenant id"),
|
|
2133
|
+
limit: z
|
|
2134
|
+
.number()
|
|
2135
|
+
.int()
|
|
2136
|
+
.min(1)
|
|
2137
|
+
.max(200)
|
|
2138
|
+
.optional()
|
|
2139
|
+
.describe("Max items to return. Default 20 (envelope-safe). Cap 200."),
|
|
2140
|
+
fields: z
|
|
2141
|
+
.enum(["lite", "full"])
|
|
2142
|
+
.optional()
|
|
2143
|
+
.describe("'lite' returns compact payload (less tokens), 'full' is default."),
|
|
2144
|
+
}, {
|
|
2145
|
+
readOnlyHint: true,
|
|
2146
|
+
openWorldHint: false,
|
|
2147
|
+
destructiveHint: false,
|
|
2148
|
+
title: "Search messages by keyword (BM25)",
|
|
2149
|
+
}, async ({ query, from, channel, sessionDay, tenantId, limit, fields }) => {
|
|
2150
|
+
try {
|
|
2151
|
+
const results = await convex.query("messages:searchMessagesByKeyword", {
|
|
2152
|
+
query,
|
|
2153
|
+
from,
|
|
2154
|
+
channel,
|
|
2155
|
+
sessionDay,
|
|
2156
|
+
tenantId,
|
|
2157
|
+
limit: limit ?? 20,
|
|
2158
|
+
fields: fields ?? "lite",
|
|
2159
|
+
});
|
|
2160
|
+
return {
|
|
2161
|
+
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
catch (error) {
|
|
2165
|
+
return mcpConvexError(error);
|
|
2166
|
+
}
|
|
2167
|
+
});
|
|
2114
2168
|
// ── list_broadcast_status ───────────────────────────────────────────────────
|
|
2115
2169
|
// S3.3 B8 follow-up batch 3 FINAL — DOCTRINE EXCEPTION.
|
|
2116
2170
|
// @cursorPagingException single-object-shape-not-list
|
|
@@ -2351,6 +2405,63 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2351
2405
|
return mcpConvexError(error);
|
|
2352
2406
|
}
|
|
2353
2407
|
});
|
|
2408
|
+
// ── search_tasks_by_keyword ────────────────────────────────────────────────
|
|
2409
|
+
// Day 102 v2.11.0 — CRUD baseline PR-C-bis option B (mission k575kc1r).
|
|
2410
|
+
// BM25 keyword search over task titles. Backed by Convex `tasks:searchTasksByKeyword`
|
|
2411
|
+
// which uses the `search_title` searchIndex. Filter axes: assignedTo, status,
|
|
2412
|
+
// project, missionId — all pushed into the index for sub-linear scan.
|
|
2413
|
+
server.tool("search_tasks_by_keyword", "BM25 full-text keyword search over task titles, ranked by relevance. " +
|
|
2414
|
+
"WHEN: use to find tasks by topic/keyword when list_tasks filters are too broad — e.g. 'find tasks about hook' across all assignees. " +
|
|
2415
|
+
"EXAMPLE: search_tasks_by_keyword query='hook PostToolUse' status='todo' limit=10.", {
|
|
2416
|
+
query: z.string().describe("Search term to match against task title"),
|
|
2417
|
+
assignedTo: z
|
|
2418
|
+
.string()
|
|
2419
|
+
.optional()
|
|
2420
|
+
.describe("Filter by assignee role"),
|
|
2421
|
+
status: z
|
|
2422
|
+
.enum(["todo", "in_progress", "review", "blocked", "done"])
|
|
2423
|
+
.optional()
|
|
2424
|
+
.describe("Filter by status"),
|
|
2425
|
+
project: z.string().optional().describe("Filter by project name"),
|
|
2426
|
+
missionId: z
|
|
2427
|
+
.string()
|
|
2428
|
+
.optional()
|
|
2429
|
+
.describe("Filter by mission Convex ID"),
|
|
2430
|
+
limit: z
|
|
2431
|
+
.number()
|
|
2432
|
+
.int()
|
|
2433
|
+
.min(1)
|
|
2434
|
+
.max(200)
|
|
2435
|
+
.optional()
|
|
2436
|
+
.describe("Max items to return. Default 20 (envelope-safe). Cap 200."),
|
|
2437
|
+
fields: z
|
|
2438
|
+
.enum(["lite", "full"])
|
|
2439
|
+
.optional()
|
|
2440
|
+
.describe("'lite' returns compact payload (less tokens), 'full' is default."),
|
|
2441
|
+
}, {
|
|
2442
|
+
readOnlyHint: true,
|
|
2443
|
+
openWorldHint: false,
|
|
2444
|
+
destructiveHint: false,
|
|
2445
|
+
title: "Search tasks by keyword (BM25)",
|
|
2446
|
+
}, async ({ query, assignedTo, status, project, missionId, limit, fields }) => {
|
|
2447
|
+
try {
|
|
2448
|
+
const results = await convex.query("tasks:searchTasksByKeyword", {
|
|
2449
|
+
query,
|
|
2450
|
+
assignedTo,
|
|
2451
|
+
status,
|
|
2452
|
+
project,
|
|
2453
|
+
missionId,
|
|
2454
|
+
limit: limit ?? 20,
|
|
2455
|
+
fields: fields ?? "lite",
|
|
2456
|
+
});
|
|
2457
|
+
return {
|
|
2458
|
+
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
|
|
2459
|
+
};
|
|
2460
|
+
}
|
|
2461
|
+
catch (error) {
|
|
2462
|
+
return mcpConvexError(error);
|
|
2463
|
+
}
|
|
2464
|
+
});
|
|
2354
2465
|
// ── update_task ─────────────────────────────────────────────────────────────
|
|
2355
2466
|
server.tool("update_task", "Update any mutable field on a task; only provided fields are patched, updatedAt auto-set. " +
|
|
2356
2467
|
"WHEN: use to reassign, reprioritize, or add context to an existing task without recreating it. " +
|
|
@@ -3477,6 +3588,51 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3477
3588
|
return mcpConvexError(error);
|
|
3478
3589
|
}
|
|
3479
3590
|
});
|
|
3591
|
+
// ── search_briefing_notes_by_keyword ────────────────────────────────────────
|
|
3592
|
+
// Day 102 v2.11.0 — CRUD baseline PR-C-bis option B (mission k575kc1r).
|
|
3593
|
+
// BM25 keyword search over briefing note content. Backed by Convex
|
|
3594
|
+
// `briefingNotes:searchBriefingNotesByKeyword` using the `search_content` searchIndex.
|
|
3595
|
+
server.tool("search_briefing_notes_by_keyword", "BM25 full-text keyword search over briefing note content, ranked by relevance. " +
|
|
3596
|
+
"WHEN: use to recall briefings about a topic/decision when list_briefing_notes filters are too coarse — e.g. 'find briefings about migration plan'. " +
|
|
3597
|
+
"EXAMPLE: search_briefing_notes_by_keyword query='migration plan' topic='daily' limit=10.", {
|
|
3598
|
+
query: z
|
|
3599
|
+
.string()
|
|
3600
|
+
.describe("Search term to match against briefing note content"),
|
|
3601
|
+
topic: z.string().optional().describe("Filter by topic"),
|
|
3602
|
+
createdBy: z.string().optional().describe("Filter by creator role"),
|
|
3603
|
+
limit: z
|
|
3604
|
+
.number()
|
|
3605
|
+
.int()
|
|
3606
|
+
.min(1)
|
|
3607
|
+
.max(200)
|
|
3608
|
+
.optional()
|
|
3609
|
+
.describe("Max items to return. Default 20 (envelope-safe). Cap 200."),
|
|
3610
|
+
fields: z
|
|
3611
|
+
.enum(["lite", "full"])
|
|
3612
|
+
.optional()
|
|
3613
|
+
.describe("'lite' returns compact payload (less tokens), 'full' is default."),
|
|
3614
|
+
}, {
|
|
3615
|
+
readOnlyHint: true,
|
|
3616
|
+
openWorldHint: false,
|
|
3617
|
+
destructiveHint: false,
|
|
3618
|
+
title: "Search briefing notes by keyword (BM25)",
|
|
3619
|
+
}, async ({ query, topic, createdBy, limit, fields }) => {
|
|
3620
|
+
try {
|
|
3621
|
+
const results = await convex.query("briefingNotes:searchBriefingNotesByKeyword", {
|
|
3622
|
+
query,
|
|
3623
|
+
topic,
|
|
3624
|
+
createdBy,
|
|
3625
|
+
limit: limit ?? 20,
|
|
3626
|
+
fields: fields ?? "lite",
|
|
3627
|
+
});
|
|
3628
|
+
return {
|
|
3629
|
+
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
|
|
3630
|
+
};
|
|
3631
|
+
}
|
|
3632
|
+
catch (error) {
|
|
3633
|
+
return mcpConvexError(error);
|
|
3634
|
+
}
|
|
3635
|
+
});
|
|
3480
3636
|
// ── register_component ──────────────────────────────────────────────────────
|
|
3481
3637
|
server.tool("register_component", "Register or upsert a component (agent/skill/hook/plugin) in the VantagePeers registry by name+type. " +
|
|
3482
3638
|
"WHEN: use when publishing a new version of an agent skill or hook so peers can discover and use it. " +
|
package/package.json
CHANGED