vantage-peers-mcp 2.5.0 → 2.7.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 CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.7.0] — 2026-06-13 — Day 100 get_by_id surface Phase 2b (task k172735brsw6bc3j2dkkkfxqrx88kkjq)
4
+
5
+ Phase 2b wires 2 MCP wrappers calling the Phase 2a Convex queries deployed
6
+ in commit 2ebdaba (PR #735 + hotfix 7f958d0):
7
+
8
+ - **get_message** — `messages:getById` plumbing. Fetch full message row by
9
+ Convex doc ID (channel, sender, sessionDay, tenant scope) for read-receipt
10
+ audit, delete confirmation, or fix-pattern referencing.
11
+ - **get_recurring_task** — `recurringTasks:getById` plumbing. Fetch
12
+ recurring task definition (cron schedule, prompt, assignee, last-fire
13
+ metadata) before pause/update/delete.
14
+
15
+ Both follow the existing `get_memory` / `get_briefing_note` pattern:
16
+ `scopeFilterGet(oauthCtx, row)` for scope-aware cross-tenant collapse,
17
+ read-only annotations.
18
+
19
+ **get_episode** was DROPPED from Phase 2b scope: episodes are stored as
20
+ memories with episode metadata (no separate `episodes` table in
21
+ `convex/schema.ts`). Use existing `get_memory` to fetch episode rows by
22
+ their memory document ID. Hotfix 7f958d0 removed the invalid
23
+ `episodes:getById` query that broke `convex deploy` typecheck.
24
+
25
+ Phase 2a CHANGELOG entry deferred — Convex changes shipped in main repo
26
+ CHANGELOG, not mcp-server.
27
+
28
+ Total MCP `get_*` tools after Phase 2b: 16 (was 14 after Phase 1, 10 before
29
+ Day 100 task).
30
+
31
+ ## [2.6.0] — 2026-06-13 — Day 100 get_by_id surface Phase 1 (task k172735brsw6bc3j2dkkkfxqrx88kkjq)
32
+
33
+ Pi reported get_<entity>_by_id MCP surface gaps observed during Day 100 fleet ops.
34
+ Phase 1 adds 4 plumbing-only read tools mapping to pre-existing Convex queries:
35
+
36
+ - **get_task** — `tasks:getById` plumbing. Fetch full task record (description, dependsOn,
37
+ missionId, completionNote, claimedByInstance, startedAt) by Convex doc ID.
38
+ - **get_fix_pattern** — `fixPatterns:get` plumbing. Fetch fix pattern with full linked
39
+ fix attempts history.
40
+ - **get_mandate** — `mandates:get` plumbing. Fetch spending mandate with limits, current
41
+ spend, approver chain for validateSpending/settleMandate pre-checks.
42
+ - **get_repo_mapping** — `githubRepoMapping:getByRepo` plumbing. Fetch GitHub repo→VP project
43
+ mapping by repo slug.
44
+
45
+ All 4 tools apply `scopeFilterGet(oauthCtx, row)` for scope-aware cross-tenant collapse,
46
+ mirroring the existing `get_memory` / `get_briefing_note` pattern (Day 92 S3.1 wave).
47
+
48
+ Annotations test (chatgpt-tool-annotations.test.ts) READ_ONLY_TOOLS set extended with
49
+ the 4 new tools. Pre-existing 84/97 count mismatch in same test is unrelated (separate
50
+ F-list track).
51
+
52
+ Phase 2 (follow-on PR) will add get_message / get_episode / get_recurring_task
53
+ (Convex query additions required).
54
+ Phase 3 (separate mission) will audit deployment entity (table+queries+tool) and the
55
+ cross-backend cloud proxy redeploy cadence.
56
+
3
57
  ## [2.5.0] — 2026-06-06 — Day 92 VP MCP quality overhaul (mission k57a36y8)
4
58
 
5
59
  Day 92 mission `k57a36y8w5t085bqr23dsmvb2d882506` ships a fleet-wide VP MCP quality bump
package/dist/src/tools.js CHANGED
@@ -5725,4 +5725,172 @@ export function registerTools(server, convex, oauthCtx) {
5725
5725
  return mcpError(error.message ?? String(error));
5726
5726
  }
5727
5727
  });
5728
+ // ── get_task ────────────────────────────────────────────────────────────────
5729
+ // Day 100 — Phase 1 get_by_id surface fix (task k172735brsw6bc3j2dkkkfxqrx88kkjq).
5730
+ // Pi reported get_<entity>_by_id surface incomplete. Convex tasks:getById exists.
5731
+ server.tool("get_task", "Fetch a single task by its Convex document ID with all fields: title, description, status, priority, assignment, dependencies, mission link, completion note. " +
5732
+ "WHEN: use when you have a specific taskId from list_tasks/create_task and need the full record (brief, VERIFICATION block, completionNote). " +
5733
+ "EXAMPLE: get_task taskId='k172735brsw6bc3j2dkkkfxqrx88kkjq'.", {
5734
+ taskId: z.string().describe("Task document ID"),
5735
+ }, {
5736
+ readOnlyHint: true,
5737
+ openWorldHint: false,
5738
+ destructiveHint: false,
5739
+ title: "Get task",
5740
+ }, async ({ taskId }) => {
5741
+ try {
5742
+ const row = await convex.query("tasks:getById", { taskId });
5743
+ const filtered = scopeFilterGet(oauthCtx, row);
5744
+ if (filtered === null) {
5745
+ return mcpError(`Task not found: ${taskId}`);
5746
+ }
5747
+ return {
5748
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5749
+ };
5750
+ }
5751
+ catch (error) {
5752
+ return mcpError(error.message ?? String(error));
5753
+ }
5754
+ });
5755
+ // ── get_fix_pattern ─────────────────────────────────────────────────────────
5756
+ // Day 100 — Phase 1 get_by_id surface fix. Convex fixPatterns:get exists.
5757
+ server.tool("get_fix_pattern", "Fetch a single fix pattern by its Convex document ID, including all linked fix attempts. " +
5758
+ "WHEN: use when you have a patternId from list_fix_patterns/search_fix_patterns and need the full record with attempts history. " +
5759
+ "EXAMPLE: get_fix_pattern patternId='m9748paffd0emrbwyskj868e1x88kvhj'.", {
5760
+ patternId: z.string().describe("Fix pattern document ID"),
5761
+ }, {
5762
+ readOnlyHint: true,
5763
+ openWorldHint: false,
5764
+ destructiveHint: false,
5765
+ title: "Get fix pattern",
5766
+ }, async ({ patternId }) => {
5767
+ try {
5768
+ const row = await convex.query("fixPatterns:get", { patternId });
5769
+ const filtered = scopeFilterGet(oauthCtx, row);
5770
+ if (filtered === null) {
5771
+ return mcpError(`Fix pattern not found: ${patternId}`);
5772
+ }
5773
+ return {
5774
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5775
+ };
5776
+ }
5777
+ catch (error) {
5778
+ return mcpError(error.message ?? String(error));
5779
+ }
5780
+ });
5781
+ // ── get_mandate ─────────────────────────────────────────────────────────────
5782
+ // Day 100 — Phase 1 get_by_id surface fix. Convex mandates:get exists.
5783
+ server.tool("get_mandate", "Fetch a single spending mandate by its Convex document ID with limits, current spend, and approver chain. " +
5784
+ "WHEN: use when you have a mandateId from list_mandates and need the full record before validateSpending/settleMandate. " +
5785
+ "EXAMPLE: get_mandate mandateId='k57dy3049btafda9m2f5d2ggk987ph3f'.", {
5786
+ mandateId: z.string().describe("Mandate document ID"),
5787
+ }, {
5788
+ readOnlyHint: true,
5789
+ openWorldHint: false,
5790
+ destructiveHint: false,
5791
+ title: "Get mandate",
5792
+ }, async ({ mandateId }) => {
5793
+ try {
5794
+ const row = await convex.query("mandates:get", { mandateId });
5795
+ const filtered = scopeFilterGet(oauthCtx, row);
5796
+ if (filtered === null) {
5797
+ return mcpError(`Mandate not found: ${mandateId}`);
5798
+ }
5799
+ return {
5800
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5801
+ };
5802
+ }
5803
+ catch (error) {
5804
+ return mcpError(error.message ?? String(error));
5805
+ }
5806
+ });
5807
+ // ── get_repo_mapping ────────────────────────────────────────────────────────
5808
+ // Day 100 — Phase 1 get_by_id surface fix. Convex githubRepoMapping:getByRepo exists.
5809
+ // Lookup key is `repo` (string e.g. "vantageos-agency/vantage-peers-plugin"), not a doc ID.
5810
+ server.tool("get_repo_mapping", "Fetch a single GitHub repo→VP project mapping by repo slug (owner/name). " +
5811
+ "WHEN: use when you have a repo identifier (e.g. from a webhook or PR URL) and need the canonical VP project mapping. " +
5812
+ "EXAMPLE: get_repo_mapping repo='vantageos-agency/vantage-peers-plugin'.", {
5813
+ repo: z
5814
+ .string()
5815
+ .describe("GitHub repo slug in owner/name form (e.g. 'vantageos-agency/vantage-peers-plugin')"),
5816
+ }, {
5817
+ readOnlyHint: true,
5818
+ openWorldHint: false,
5819
+ destructiveHint: false,
5820
+ title: "Get repo mapping",
5821
+ }, async ({ repo }) => {
5822
+ try {
5823
+ const row = await convex.query("githubRepoMapping:getByRepo", {
5824
+ repo,
5825
+ });
5826
+ const filtered = scopeFilterGet(oauthCtx, row);
5827
+ if (filtered === null) {
5828
+ return mcpError(`Repo mapping not found: ${repo}`);
5829
+ }
5830
+ return {
5831
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5832
+ };
5833
+ }
5834
+ catch (error) {
5835
+ return mcpError(error.message ?? String(error));
5836
+ }
5837
+ });
5838
+ // ── get_message ─────────────────────────────────────────────────────────────
5839
+ // Day 100 — Phase 2b get_by_id surface fix (task k172735brsw6bc3j2dkkkfxqrx88kkjq).
5840
+ // Convex messages:getById landed in Phase 2a (PR #735, commit 2ebdaba).
5841
+ // Note: episodes were dropped from Phase 2b scope — episodes are stored as
5842
+ // memories with episode metadata (no separate table), use get_memory instead.
5843
+ server.tool("get_message", "Fetch a single peer message by its Convex document ID with full body, channel, sender, sessionDay, and tenant scope. " +
5844
+ "WHEN: use when you have a messageId from list_messages/check_messages and need the raw row (e.g. for read-receipt audit, delete confirmation, or referencing in a fix pattern). " +
5845
+ "EXAMPLE: get_message messageId='jn7eg21wdaxzdcpdxwkvhaxqnh88jqg2'.", {
5846
+ messageId: z.string().describe("Message document ID"),
5847
+ }, {
5848
+ readOnlyHint: true,
5849
+ openWorldHint: false,
5850
+ destructiveHint: false,
5851
+ title: "Get message",
5852
+ }, async ({ messageId }) => {
5853
+ try {
5854
+ const row = await convex.query("messages:getById", { messageId });
5855
+ const filtered = scopeFilterGet(oauthCtx, row);
5856
+ if (filtered === null) {
5857
+ return mcpError(`Message not found: ${messageId}`);
5858
+ }
5859
+ return {
5860
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5861
+ };
5862
+ }
5863
+ catch (error) {
5864
+ return mcpError(error.message ?? String(error));
5865
+ }
5866
+ });
5867
+ // ── get_recurring_task ──────────────────────────────────────────────────────
5868
+ // Day 100 — Phase 2b get_by_id surface fix. Convex recurringTasks:getById
5869
+ // landed in Phase 2a (PR #735, commit 2ebdaba).
5870
+ server.tool("get_recurring_task", "Fetch a single recurring task definition by its Convex document ID with cron schedule, prompt, assignee, and last-fire metadata. " +
5871
+ "WHEN: use when you have a recurringTaskId from list_recurring_tasks and need the full row before pause_recurring_task / update_recurring_task / delete_recurring_task. " +
5872
+ "EXAMPLE: get_recurring_task recurringTaskId='k57dy3049btafda9m2f5d2ggk987ph3f'.", {
5873
+ recurringTaskId: z.string().describe("Recurring task document ID"),
5874
+ }, {
5875
+ readOnlyHint: true,
5876
+ openWorldHint: false,
5877
+ destructiveHint: false,
5878
+ title: "Get recurring task",
5879
+ }, async ({ recurringTaskId }) => {
5880
+ try {
5881
+ const row = await convex.query("recurringTasks:getById", {
5882
+ recurringTaskId,
5883
+ });
5884
+ const filtered = scopeFilterGet(oauthCtx, row);
5885
+ if (filtered === null) {
5886
+ return mcpError(`Recurring task not found: ${recurringTaskId}`);
5887
+ }
5888
+ return {
5889
+ content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
5890
+ };
5891
+ }
5892
+ catch (error) {
5893
+ return mcpError(error.message ?? String(error));
5894
+ }
5895
+ });
5728
5896
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantage-peers-mcp",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "MCP server for VantagePeers — shared memory, messaging, and task coordination for AI agent teams",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",