vantage-peers-mcp 2.4.0 → 2.4.1
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 +14 -3
- package/dist/src/auth.js +9 -3
- package/dist/src/tools.js +438 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/vantage-peers-mcp)
|
|
4
4
|
[](https://www.npmjs.com/package/vantage-peers-mcp)
|
|
5
5
|
[](https://github.com/vantageos-agency/vantage-peers/blob/main/LICENSE)
|
|
6
|
-
[]()
|
|
7
7
|
|
|
8
8
|
MCP server for [VantagePeers](https://vantagepeers.com) — shared memory, messaging, and task coordination for AI agent teams.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
84 tools across 18 categories: memory, profiles, tasks, missions, mission templates, messages, diary, briefing notes, search (RAG), issues, fix patterns, error monitoring, deployments, business units, components, mandates, recurring tasks, and session. All tools ship with ChatGPT Apps SDK annotations (`readOnlyHint`, `openWorldHint`, `destructiveHint`) for native UX in ChatGPT custom connectors.
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
@@ -74,7 +74,7 @@ VantagePeers ships a built-in OAuth 2.1 authorization server so Claude.ai web ca
|
|
|
74
74
|
|
|
75
75
|
The server also reads `CONVEX_URL` from `.env.local` in the parent directory if not set via environment.
|
|
76
76
|
|
|
77
|
-
## Tools (
|
|
77
|
+
## Tools (84)
|
|
78
78
|
|
|
79
79
|
### Memory (6)
|
|
80
80
|
`store_memory`, `recall`, `list_memories`, `soft_delete_memory`, `get_memory`, `store_episode`
|
|
@@ -400,6 +400,17 @@ All orchestrator names are open strings — any lowercase name is accepted. The
|
|
|
400
400
|
|
|
401
401
|
## Changelog
|
|
402
402
|
|
|
403
|
+
### 2.4.1 — 2026-05-30 (Day 88)
|
|
404
|
+
- fix(dcr): `oauthDcr:validateAccessToken` exposed as PUBLIC `query` (was `internalQuery`, unreachable via `ConvexHttpClient.query()` → Path 3 DCR returned 401 even with valid token) — issue #556 / PR #557.
|
|
405
|
+
- fix(dcr): `WWW-Authenticate` header now emits `Bearer resource_metadata="..."` per MCP spec §Protected Resource Metadata Discovery (was `resource="..."` — broke Claude.ai PRM discovery bootstrap on 401) — PR #557.
|
|
406
|
+
- feat(mcp): ChatGPT Apps SDK tool annotations on all 84 tools (`readOnlyHint`, `openWorldHint`, `destructiveHint`) — 34 read-only + 41 write + 9 destructive — PR #555.
|
|
407
|
+
- security(dcr): DCR scope isolation — new `public-readonly` profile + cross-tenant assertion tests + `scopeProfile` forced to `client-generic` for auto-discovery flow (never `master`) — PR #554.
|
|
408
|
+
- docs(cloud): dedicated `/docs/cloud/` section in vantage-peers-site for VantagePeers Cloud (multi-tenant, multi-clients MCP: Claude.ai, ChatGPT, Claude Code, Codex) — site PR #120.
|
|
409
|
+
|
|
410
|
+
### 2.4.0 — 2026-05-29 (Day 86)
|
|
411
|
+
- feat(m3): `iframeEmbedSessions` table + `__VP_TOOL_RESULT__` stream marker + ack-checklist primitive — PR #545.
|
|
412
|
+
- feat(v0.0.2-auth): `credentials:issueBearerFromClerk` httpAction + audit log + iter 2 P1 fixes — PR #546.
|
|
413
|
+
|
|
403
414
|
### 2.3.0 — 2026-05-26
|
|
404
415
|
- `list_tasks`, `list_missions`, `list_tasks_by_mission`, `list_briefing_notes` now accept `fields=lite` for compact payloads (less tokens).
|
|
405
416
|
- Status filters now accept arrays and aliases: `status=["todo","in_progress"]`, `status="open"` (expands to non-terminal), `status="active"` (in_progress only on tasks; plan+execute on missions), `status="all"` (no filter).
|
package/dist/src/auth.js
CHANGED
|
@@ -139,11 +139,13 @@ export function checkNamespaceWrite(ctx, namespace) {
|
|
|
139
139
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
140
140
|
export function bearerAuthMiddleware() {
|
|
141
141
|
return async (c, next) => {
|
|
142
|
-
//
|
|
143
|
-
//
|
|
142
|
+
// MCP spec §"Protected Resource Metadata Discovery Requirements" + RFC 6750 §3 —
|
|
143
|
+
// the param MUST be `resource_metadata=` (not `resource=`). Claude.ai's OAuth
|
|
144
|
+
// connector looks for `resource_metadata=` to bootstrap PRM discovery; with
|
|
145
|
+
// `resource=` the entire DCR chain breaks before any token is issued.
|
|
144
146
|
const publicBaseUrl = process.env.PUBLIC_BASE_URL ??
|
|
145
147
|
"https://vantage-peers-production.up.railway.app";
|
|
146
|
-
const wwwAuthHeader = `Bearer
|
|
148
|
+
const wwwAuthHeader = `Bearer resource_metadata="${publicBaseUrl}/.well-known/oauth-protected-resource"`;
|
|
147
149
|
const authHeader = c.req.header("Authorization");
|
|
148
150
|
if (!authHeader?.startsWith("Bearer ")) {
|
|
149
151
|
c.header("WWW-Authenticate", wwwAuthHeader);
|
|
@@ -215,6 +217,10 @@ export function bearerAuthMiddleware() {
|
|
|
215
217
|
// ── (3) DCR OAuth token — check oauthTokens via oauthDcr:validateAccessToken
|
|
216
218
|
// Uses raw token (not hashed) — the DCR table stores tokens in plaintext.
|
|
217
219
|
// This path handles Claude.ai clients registered via POST /register.
|
|
220
|
+
// NOTE: validateAccessToken is exposed as a PUBLIC query (not internalQuery)
|
|
221
|
+
// because ConvexHttpClient.query() only resolves public functions. Making it
|
|
222
|
+
// internal silently breaks the DCR path (#556). Security: lookup is keyed
|
|
223
|
+
// on the high-entropy opaque token; returns null on miss with no PII echo.
|
|
218
224
|
let dcrResult = null;
|
|
219
225
|
try {
|
|
220
226
|
dcrResult = (await internalClient().query(
|
package/dist/src/tools.js
CHANGED
|
@@ -153,7 +153,9 @@ const taskStatusValues = [
|
|
|
153
153
|
"done",
|
|
154
154
|
];
|
|
155
155
|
const taskStatusAliases = ["open", "active", "all"];
|
|
156
|
-
export const taskStatusSchema = z
|
|
156
|
+
export const taskStatusSchema = z
|
|
157
|
+
.enum(taskStatusValues)
|
|
158
|
+
.describe("Task status");
|
|
157
159
|
const missionStatusValues = [
|
|
158
160
|
"brainstorm",
|
|
159
161
|
"plan",
|
|
@@ -176,7 +178,7 @@ export const taskStatusFilterSchema = z
|
|
|
176
178
|
])
|
|
177
179
|
.describe('Task status filter. Single status ("todo"|"in_progress"|"review"|"blocked"|"done"), ' +
|
|
178
180
|
'alias ("open" = todo+in_progress+review+blocked, "active" = todo+in_progress, "all" = no filter), ' +
|
|
179
|
-
|
|
181
|
+
"or array of direct statuses (no aliases inside array).");
|
|
180
182
|
export const missionStatusFilterSchema = z
|
|
181
183
|
.union([
|
|
182
184
|
z.enum([...missionStatusValues, ...missionStatusAliases]),
|
|
@@ -184,13 +186,13 @@ export const missionStatusFilterSchema = z
|
|
|
184
186
|
])
|
|
185
187
|
.describe('Mission status filter. Single status ("brainstorm"|"plan"|"execute"|"validate"|"complete"), ' +
|
|
186
188
|
'alias ("open" = brainstorm+plan+execute+validate, "active" = plan+execute, "all" = no filter), ' +
|
|
187
|
-
|
|
189
|
+
"or array of direct statuses (no aliases inside array).");
|
|
188
190
|
// v2.3.2 — fields projection toggle. "lite" returns compact projection
|
|
189
191
|
// (5-10× smaller payload), "full" (default) returns full doc.
|
|
190
192
|
export const fieldsSchema = z
|
|
191
193
|
.enum(["lite", "full"])
|
|
192
194
|
.describe('Field projection — "lite" returns compact fields only ' +
|
|
193
|
-
|
|
195
|
+
"(typical 5-10× smaller payload for large list scans), " +
|
|
194
196
|
'"full" (default) returns the full document.');
|
|
195
197
|
// v2.3.3 — Unix timestamp ms filter for "updated since".
|
|
196
198
|
// Pass `Date.now() - 24*60*60*1000` for "last 24h" pattern.
|
|
@@ -296,7 +298,8 @@ export function parseConvexError(rawMessage) {
|
|
|
296
298
|
let code = "ServerError";
|
|
297
299
|
let remainder = stripped;
|
|
298
300
|
for (const candidate of knownCodes) {
|
|
299
|
-
if (stripped.startsWith(candidate + ":") ||
|
|
301
|
+
if (stripped.startsWith(candidate + ":") ||
|
|
302
|
+
stripped.startsWith(candidate + " ")) {
|
|
300
303
|
code = candidate;
|
|
301
304
|
remainder = stripped.slice(candidate.length).replace(/^[:\s]+/, "");
|
|
302
305
|
break;
|
|
@@ -305,10 +308,13 @@ export function parseConvexError(rawMessage) {
|
|
|
305
308
|
// Extract "Path: .<fieldPath>" from the tail of the message
|
|
306
309
|
// Convex appends this as the last sentence: "Path: .linkedMemoryIds[4]"
|
|
307
310
|
let path = null;
|
|
308
|
-
const pathMatch = remainder.match(/\bPath:\s*([\w
|
|
311
|
+
const pathMatch = remainder.match(/\bPath:\s*([\w.[\]"']+)\s*$/);
|
|
309
312
|
if (pathMatch) {
|
|
310
313
|
path = pathMatch[1];
|
|
311
|
-
remainder = remainder
|
|
314
|
+
remainder = remainder
|
|
315
|
+
.slice(0, pathMatch.index)
|
|
316
|
+
.trim()
|
|
317
|
+
.replace(/\.\s*$/, "");
|
|
312
318
|
}
|
|
313
319
|
// Build a concise hint for common patterns
|
|
314
320
|
let hint = null;
|
|
@@ -412,6 +418,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
412
418
|
.string()
|
|
413
419
|
.optional()
|
|
414
420
|
.describe("Optional expiry ISO timestamp e.g. '2026-06-01T00:00:00Z'"),
|
|
421
|
+
}, {
|
|
422
|
+
readOnlyHint: false,
|
|
423
|
+
openWorldHint: false,
|
|
424
|
+
destructiveHint: false,
|
|
425
|
+
title: "Store memory",
|
|
415
426
|
}, async ({ namespace, type, content, createdBy, relatesTo, ttl }) => {
|
|
416
427
|
let contentBytes = 0;
|
|
417
428
|
try {
|
|
@@ -461,6 +472,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
461
472
|
memoryId: z
|
|
462
473
|
.string()
|
|
463
474
|
.describe("Convex document ID of the memory to soft-delete"),
|
|
475
|
+
}, {
|
|
476
|
+
readOnlyHint: false,
|
|
477
|
+
openWorldHint: false,
|
|
478
|
+
destructiveHint: true,
|
|
479
|
+
title: "Delete memory (soft)",
|
|
464
480
|
}, async ({ memoryId }) => {
|
|
465
481
|
try {
|
|
466
482
|
const denied = guardMasterOnly("soft_delete_memory");
|
|
@@ -485,6 +501,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
485
501
|
// ── get_memory ──────────────────────────────────────────────────────────────
|
|
486
502
|
server.tool("get_memory", "Fetch a single memory by its ID. Returns full memory content including relations and episode data.", {
|
|
487
503
|
memoryId: z.string().describe("Memory document ID"),
|
|
504
|
+
}, {
|
|
505
|
+
readOnlyHint: true,
|
|
506
|
+
openWorldHint: false,
|
|
507
|
+
destructiveHint: false,
|
|
508
|
+
title: "Get memory",
|
|
488
509
|
}, async ({ memoryId }) => {
|
|
489
510
|
try {
|
|
490
511
|
const memory = await convex.query("memories:getMemory", {
|
|
@@ -519,6 +540,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
519
540
|
.optional()
|
|
520
541
|
.default(5)
|
|
521
542
|
.describe("Maximum number of results to return (default 5)"),
|
|
543
|
+
}, {
|
|
544
|
+
readOnlyHint: true,
|
|
545
|
+
openWorldHint: false,
|
|
546
|
+
destructiveHint: false,
|
|
547
|
+
title: "Recall memories",
|
|
522
548
|
}, async ({ query, namespace, type, limit }) => {
|
|
523
549
|
try {
|
|
524
550
|
const nsDenied = guardRead(namespace);
|
|
@@ -559,6 +585,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
559
585
|
.optional()
|
|
560
586
|
.default(10)
|
|
561
587
|
.describe("Max results"),
|
|
588
|
+
}, {
|
|
589
|
+
readOnlyHint: true,
|
|
590
|
+
openWorldHint: false,
|
|
591
|
+
destructiveHint: false,
|
|
592
|
+
title: "Search memories (text)",
|
|
562
593
|
}, async ({ query, namespace, type, limit }) => {
|
|
563
594
|
try {
|
|
564
595
|
const nsDenied = guardRead(namespace);
|
|
@@ -603,6 +634,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
603
634
|
.max(1)
|
|
604
635
|
.optional()
|
|
605
636
|
.describe("Weight for text results in RRF (default: 0.5)"),
|
|
637
|
+
}, {
|
|
638
|
+
readOnlyHint: true,
|
|
639
|
+
openWorldHint: false,
|
|
640
|
+
destructiveHint: false,
|
|
641
|
+
title: "Search memories (hybrid)",
|
|
606
642
|
}, async ({ query, namespace, type, limit, vectorWeight, textWeight }) => {
|
|
607
643
|
try {
|
|
608
644
|
const nsDenied = guardRead(namespace);
|
|
@@ -642,6 +678,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
642
678
|
.string()
|
|
643
679
|
.describe("The lesson extracted — procedural memory, what to do differently"),
|
|
644
680
|
severity: severitySchema,
|
|
681
|
+
}, {
|
|
682
|
+
readOnlyHint: false,
|
|
683
|
+
openWorldHint: false,
|
|
684
|
+
destructiveHint: false,
|
|
685
|
+
title: "Store episode",
|
|
645
686
|
}, async ({ namespace, createdBy, context, goal, action, outcome, insight, severity, }) => {
|
|
646
687
|
try {
|
|
647
688
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -677,6 +718,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
677
718
|
server.tool("get_profile", "Fetch an orchestrator profile (static identity + dynamic session state). " +
|
|
678
719
|
"Returns null if the profile does not exist yet — call update_profile to create it.", {
|
|
679
720
|
orchestratorId: z.string().describe("Orchestrator identifier"),
|
|
721
|
+
}, {
|
|
722
|
+
readOnlyHint: true,
|
|
723
|
+
openWorldHint: false,
|
|
724
|
+
destructiveHint: false,
|
|
725
|
+
title: "Get orchestrator profile",
|
|
680
726
|
}, async ({ orchestratorId }) => {
|
|
681
727
|
try {
|
|
682
728
|
const profile = await convex.query("profiles:getProfile", {
|
|
@@ -724,6 +770,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
724
770
|
})
|
|
725
771
|
.optional()
|
|
726
772
|
.describe("Mutable session state — updated each session"),
|
|
773
|
+
}, {
|
|
774
|
+
readOnlyHint: false,
|
|
775
|
+
openWorldHint: false,
|
|
776
|
+
destructiveHint: false,
|
|
777
|
+
title: "Update orchestrator profile",
|
|
727
778
|
}, async ({ orchestratorId, name, static: staticFields, dynamic }) => {
|
|
728
779
|
try {
|
|
729
780
|
const fromDenied = guardFrom(orchestratorId);
|
|
@@ -766,6 +817,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
766
817
|
.optional()
|
|
767
818
|
.default(20)
|
|
768
819
|
.describe("Maximum number of memories to return (default 20)"),
|
|
820
|
+
}, {
|
|
821
|
+
readOnlyHint: true,
|
|
822
|
+
openWorldHint: false,
|
|
823
|
+
destructiveHint: false,
|
|
824
|
+
title: "List memories",
|
|
769
825
|
}, async ({ namespace, type, limit }) => {
|
|
770
826
|
try {
|
|
771
827
|
const nsDenied = guardRead(namespace);
|
|
@@ -822,6 +878,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
822
878
|
.string()
|
|
823
879
|
.optional()
|
|
824
880
|
.describe("Tenant identifier for multi-tenant isolation"),
|
|
881
|
+
}, {
|
|
882
|
+
readOnlyHint: false,
|
|
883
|
+
openWorldHint: false,
|
|
884
|
+
destructiveHint: false,
|
|
885
|
+
title: "Send message",
|
|
825
886
|
}, async ({ from, fromInstanceId, channel, content, sessionDay, tenantId, }) => {
|
|
826
887
|
let contentBytes = 0;
|
|
827
888
|
try {
|
|
@@ -876,6 +937,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
876
937
|
.int()
|
|
877
938
|
.optional()
|
|
878
939
|
.describe("Unix timestamp (ms). If provided, only messages with _creationTime > since are returned. Use for incremental polling — pass the timestamp of your last check to get only new messages. Omit for full unread backlog."),
|
|
940
|
+
}, {
|
|
941
|
+
readOnlyHint: true,
|
|
942
|
+
openWorldHint: false,
|
|
943
|
+
destructiveHint: false,
|
|
944
|
+
title: "Check messages",
|
|
879
945
|
}, async ({ recipient, recipientInstanceId, tenantId, since }) => {
|
|
880
946
|
try {
|
|
881
947
|
const messages = await convex.query("messages:checkNewMessages", {
|
|
@@ -915,6 +981,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
915
981
|
receiptIds: z
|
|
916
982
|
.union([z.array(receiptIdSchema).min(1), receiptIdSchema])
|
|
917
983
|
.describe("Receipt IDs to mark as read — array or single string"),
|
|
984
|
+
}, {
|
|
985
|
+
readOnlyHint: false,
|
|
986
|
+
openWorldHint: false,
|
|
987
|
+
destructiveHint: false,
|
|
988
|
+
title: "Mark messages as read",
|
|
918
989
|
}, async ({ receiptIds }) => {
|
|
919
990
|
try {
|
|
920
991
|
let receiptIdsArray;
|
|
@@ -957,6 +1028,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
957
1028
|
callerOrchestrator: creatorSchema
|
|
958
1029
|
.optional()
|
|
959
1030
|
.describe("Optional RBAC — must be the sender or system"),
|
|
1031
|
+
}, {
|
|
1032
|
+
readOnlyHint: false,
|
|
1033
|
+
openWorldHint: false,
|
|
1034
|
+
destructiveHint: true,
|
|
1035
|
+
title: "Delete message",
|
|
960
1036
|
}, async ({ messageId, callerOrchestrator }) => {
|
|
961
1037
|
try {
|
|
962
1038
|
if (callerOrchestrator) {
|
|
@@ -991,6 +1067,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
991
1067
|
.optional()
|
|
992
1068
|
.describe("Instance ID — e.g. 'pi-chromebook', 'pi-vps', 'tau-vps-1'"),
|
|
993
1069
|
summary: z.string().describe("1-2 sentence summary of current work"),
|
|
1070
|
+
}, {
|
|
1071
|
+
readOnlyHint: false,
|
|
1072
|
+
openWorldHint: false,
|
|
1073
|
+
destructiveHint: false,
|
|
1074
|
+
title: "Set instance summary",
|
|
994
1075
|
}, async ({ orchestratorId, instanceId, summary }) => {
|
|
995
1076
|
try {
|
|
996
1077
|
const fromDenied = guardFrom(orchestratorId);
|
|
@@ -1017,7 +1098,12 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1017
1098
|
});
|
|
1018
1099
|
// ── list_peers ──────────────────────────────────────────────────────────────
|
|
1019
1100
|
server.tool("list_peers", "List all orchestrator profiles with their current status and summary. " +
|
|
1020
|
-
"Replaces claude-peers list_peers.", {},
|
|
1101
|
+
"Replaces claude-peers list_peers.", {}, {
|
|
1102
|
+
readOnlyHint: true,
|
|
1103
|
+
openWorldHint: false,
|
|
1104
|
+
destructiveHint: false,
|
|
1105
|
+
title: "List peers",
|
|
1106
|
+
}, async () => {
|
|
1021
1107
|
try {
|
|
1022
1108
|
const profiles = await convex.query("profiles:listProfiles", {});
|
|
1023
1109
|
const peers = profiles.map((p) => ({
|
|
@@ -1059,6 +1145,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1059
1145
|
.optional()
|
|
1060
1146
|
.default(100)
|
|
1061
1147
|
.describe("Max messages to return (default 100)"),
|
|
1148
|
+
}, {
|
|
1149
|
+
readOnlyHint: true,
|
|
1150
|
+
openWorldHint: false,
|
|
1151
|
+
destructiveHint: false,
|
|
1152
|
+
title: "List messages",
|
|
1062
1153
|
}, async ({ sessionDay, from, limit }) => {
|
|
1063
1154
|
try {
|
|
1064
1155
|
const messages = await convex.query("messages:listMessages", {
|
|
@@ -1092,6 +1183,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1092
1183
|
messageId: z
|
|
1093
1184
|
.string()
|
|
1094
1185
|
.describe("Convex document ID of the broadcast message"),
|
|
1186
|
+
}, {
|
|
1187
|
+
readOnlyHint: true,
|
|
1188
|
+
openWorldHint: false,
|
|
1189
|
+
destructiveHint: false,
|
|
1190
|
+
title: "List broadcast status",
|
|
1095
1191
|
}, async ({ messageId }) => {
|
|
1096
1192
|
try {
|
|
1097
1193
|
const status = await convex.query("messages:listBroadcastStatus", {
|
|
@@ -1144,6 +1240,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1144
1240
|
.optional()
|
|
1145
1241
|
.describe("Optional due date as Unix timestamp (ms)"),
|
|
1146
1242
|
createdBy: creatorSchema,
|
|
1243
|
+
}, {
|
|
1244
|
+
readOnlyHint: false,
|
|
1245
|
+
openWorldHint: false,
|
|
1246
|
+
destructiveHint: false,
|
|
1247
|
+
title: "Create task",
|
|
1147
1248
|
}, async ({ title, description, project, tags, assignedTo, assignedToInstance, priority, status, dependsOn, missionId, estimatedMinutes, dueDate, createdBy, }) => {
|
|
1148
1249
|
try {
|
|
1149
1250
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -1206,6 +1307,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1206
1307
|
.optional()
|
|
1207
1308
|
.describe("Filter by task creator (e.g. 'pi' to find Pi-dispatched tasks)"),
|
|
1208
1309
|
updatedSince: updatedSinceSchema.optional(),
|
|
1310
|
+
}, {
|
|
1311
|
+
readOnlyHint: true,
|
|
1312
|
+
openWorldHint: false,
|
|
1313
|
+
destructiveHint: false,
|
|
1314
|
+
title: "List tasks",
|
|
1209
1315
|
}, async ({ assignedTo, assignedToInstance, status, project, limit, fields, createdBy, updatedSince, }) => {
|
|
1210
1316
|
try {
|
|
1211
1317
|
const tasks = await convex.query("tasks:list", {
|
|
@@ -1276,6 +1382,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1276
1382
|
callerOrchestrator: creatorSchema
|
|
1277
1383
|
.optional()
|
|
1278
1384
|
.describe("Optional RBAC — if provided, must be creator or assignee"),
|
|
1385
|
+
}, {
|
|
1386
|
+
readOnlyHint: false,
|
|
1387
|
+
openWorldHint: false,
|
|
1388
|
+
destructiveHint: false,
|
|
1389
|
+
title: "Update task",
|
|
1279
1390
|
}, async ({ taskId, title, description, project, tags, assignedTo, priority, status, dependsOn, missionId, estimatedMinutes, actualMinutes, startedAt, completedAt, dueDate, callerOrchestrator, }) => {
|
|
1280
1391
|
try {
|
|
1281
1392
|
if (callerOrchestrator) {
|
|
@@ -1330,6 +1441,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1330
1441
|
callerOrchestrator: creatorSchema
|
|
1331
1442
|
.optional()
|
|
1332
1443
|
.describe("Optional RBAC — if provided, must be creator or assignee"),
|
|
1444
|
+
}, {
|
|
1445
|
+
readOnlyHint: false,
|
|
1446
|
+
openWorldHint: false,
|
|
1447
|
+
destructiveHint: false,
|
|
1448
|
+
title: "Complete task",
|
|
1333
1449
|
}, async ({ taskId, completionNote, callerOrchestrator }) => {
|
|
1334
1450
|
try {
|
|
1335
1451
|
if (callerOrchestrator) {
|
|
@@ -1362,6 +1478,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1362
1478
|
callerOrchestrator: creatorSchema
|
|
1363
1479
|
.optional()
|
|
1364
1480
|
.describe("Optional RBAC — if provided, must be creator or assignee"),
|
|
1481
|
+
}, {
|
|
1482
|
+
readOnlyHint: false,
|
|
1483
|
+
openWorldHint: false,
|
|
1484
|
+
destructiveHint: false,
|
|
1485
|
+
title: "Start task",
|
|
1365
1486
|
}, async ({ taskId, callerOrchestrator }) => {
|
|
1366
1487
|
try {
|
|
1367
1488
|
if (callerOrchestrator) {
|
|
@@ -1395,6 +1516,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1395
1516
|
.string()
|
|
1396
1517
|
.optional()
|
|
1397
1518
|
.describe("Instance identifier, e.g. 'sigma-vps'"),
|
|
1519
|
+
}, {
|
|
1520
|
+
readOnlyHint: false,
|
|
1521
|
+
openWorldHint: false,
|
|
1522
|
+
destructiveHint: false,
|
|
1523
|
+
title: "Checkout task",
|
|
1398
1524
|
}, async ({ taskId, callerOrchestrator, callerInstance }) => {
|
|
1399
1525
|
try {
|
|
1400
1526
|
const fromDenied = guardFrom(callerOrchestrator);
|
|
@@ -1424,6 +1550,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1424
1550
|
callerOrchestrator: creatorSchema
|
|
1425
1551
|
.optional()
|
|
1426
1552
|
.describe("Optional RBAC — must be creator or system"),
|
|
1553
|
+
}, {
|
|
1554
|
+
readOnlyHint: false,
|
|
1555
|
+
openWorldHint: false,
|
|
1556
|
+
destructiveHint: true,
|
|
1557
|
+
title: "Delete task",
|
|
1427
1558
|
}, async ({ taskId, callerOrchestrator }) => {
|
|
1428
1559
|
try {
|
|
1429
1560
|
if (callerOrchestrator) {
|
|
@@ -1459,6 +1590,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1459
1590
|
callerOrchestrator: creatorSchema
|
|
1460
1591
|
.optional()
|
|
1461
1592
|
.describe("Optional RBAC — must be creator or assignee"),
|
|
1593
|
+
}, {
|
|
1594
|
+
readOnlyHint: false,
|
|
1595
|
+
openWorldHint: false,
|
|
1596
|
+
destructiveHint: true,
|
|
1597
|
+
title: "Block task",
|
|
1462
1598
|
}, async ({ taskId, reason, blockedBy, callerOrchestrator }) => {
|
|
1463
1599
|
try {
|
|
1464
1600
|
if (callerOrchestrator) {
|
|
@@ -1502,6 +1638,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1502
1638
|
callerOrchestrator: creatorSchema
|
|
1503
1639
|
.optional()
|
|
1504
1640
|
.describe("Optional RBAC — must be creator or assignee"),
|
|
1641
|
+
}, {
|
|
1642
|
+
readOnlyHint: false,
|
|
1643
|
+
openWorldHint: false,
|
|
1644
|
+
destructiveHint: false,
|
|
1645
|
+
title: "Add task dependency",
|
|
1505
1646
|
}, async ({ taskId, dependsOn, callerOrchestrator }) => {
|
|
1506
1647
|
try {
|
|
1507
1648
|
if (callerOrchestrator) {
|
|
@@ -1545,10 +1686,13 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1545
1686
|
fields: fieldsSchema
|
|
1546
1687
|
.optional()
|
|
1547
1688
|
.describe('Field projection ("lite"|"full")'),
|
|
1548
|
-
createdBy: assigneeSchema
|
|
1549
|
-
.optional()
|
|
1550
|
-
.describe("Filter by task creator"),
|
|
1689
|
+
createdBy: assigneeSchema.optional().describe("Filter by task creator"),
|
|
1551
1690
|
updatedSince: updatedSinceSchema.optional(),
|
|
1691
|
+
}, {
|
|
1692
|
+
readOnlyHint: true,
|
|
1693
|
+
openWorldHint: false,
|
|
1694
|
+
destructiveHint: false,
|
|
1695
|
+
title: "List tasks by mission",
|
|
1552
1696
|
}, async ({ missionId, status, limit, fields, createdBy, updatedSince }) => {
|
|
1553
1697
|
try {
|
|
1554
1698
|
const tasks = await convex.query("tasks:listByMission", {
|
|
@@ -1592,6 +1736,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1592
1736
|
.describe("Target completion date (Unix ms)"),
|
|
1593
1737
|
progress: z.number().optional().describe("Progress percentage (0-100)"),
|
|
1594
1738
|
createdBy: creatorSchema,
|
|
1739
|
+
}, {
|
|
1740
|
+
readOnlyHint: false,
|
|
1741
|
+
openWorldHint: false,
|
|
1742
|
+
destructiveHint: false,
|
|
1743
|
+
title: "Create mission",
|
|
1595
1744
|
}, async ({ name, description, project, status, priority, pilot, agents, brief, startDate, targetDate, progress, createdBy, }) => {
|
|
1596
1745
|
try {
|
|
1597
1746
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -1646,6 +1795,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1646
1795
|
.optional()
|
|
1647
1796
|
.describe('Field projection ("lite"|"full")'),
|
|
1648
1797
|
updatedSince: updatedSinceSchema.optional(),
|
|
1798
|
+
}, {
|
|
1799
|
+
readOnlyHint: true,
|
|
1800
|
+
openWorldHint: false,
|
|
1801
|
+
destructiveHint: false,
|
|
1802
|
+
title: "List missions",
|
|
1649
1803
|
}, async ({ project, pilot, status, limit, fields, updatedSince }) => {
|
|
1650
1804
|
try {
|
|
1651
1805
|
const missions = await convex.query("missions:list", {
|
|
@@ -1682,6 +1836,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1682
1836
|
// ── get_mission ─────────────────────────────────────────────────────────────
|
|
1683
1837
|
server.tool("get_mission", "Fetch a single mission by ID. Returns full mission details including status, pilot, agents, progress, and dates.", {
|
|
1684
1838
|
missionId: z.string().describe("Convex document ID of the mission"),
|
|
1839
|
+
}, {
|
|
1840
|
+
readOnlyHint: true,
|
|
1841
|
+
openWorldHint: false,
|
|
1842
|
+
destructiveHint: false,
|
|
1843
|
+
title: "Get mission",
|
|
1685
1844
|
}, async ({ missionId }) => {
|
|
1686
1845
|
try {
|
|
1687
1846
|
const mission = await convex.query("missions:get", {
|
|
@@ -1717,6 +1876,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1717
1876
|
startDate: z.number().optional().describe("New start date (Unix ms)"),
|
|
1718
1877
|
targetDate: z.number().optional().describe("New target date (Unix ms)"),
|
|
1719
1878
|
progress: z.number().optional().describe("New progress (0-100)"),
|
|
1879
|
+
}, {
|
|
1880
|
+
readOnlyHint: false,
|
|
1881
|
+
openWorldHint: false,
|
|
1882
|
+
destructiveHint: false,
|
|
1883
|
+
title: "Update mission",
|
|
1720
1884
|
}, async ({ missionId, name, description, project, status, priority, pilot, agents, brief, startDate, targetDate, progress, }) => {
|
|
1721
1885
|
try {
|
|
1722
1886
|
if (pilot) {
|
|
@@ -1755,6 +1919,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1755
1919
|
server.tool("update_mission_status", "Change a mission's status. Shortcut for updating only the status field.", {
|
|
1756
1920
|
missionId: z.string().describe("Convex document ID of the mission"),
|
|
1757
1921
|
status: missionStatusSchema.describe("New status"),
|
|
1922
|
+
}, {
|
|
1923
|
+
readOnlyHint: false,
|
|
1924
|
+
openWorldHint: false,
|
|
1925
|
+
destructiveHint: false,
|
|
1926
|
+
title: "Update mission status",
|
|
1758
1927
|
}, async ({ missionId, status }) => {
|
|
1759
1928
|
try {
|
|
1760
1929
|
await convex.mutation("missions:updateStatus", {
|
|
@@ -1782,6 +1951,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1782
1951
|
content: z.string().describe("Full diary entry content"),
|
|
1783
1952
|
highlights: flexArrayOptional.describe("Key highlights of the day"),
|
|
1784
1953
|
blockers: flexArrayOptional.describe("Blockers encountered"),
|
|
1954
|
+
}, {
|
|
1955
|
+
readOnlyHint: false,
|
|
1956
|
+
openWorldHint: false,
|
|
1957
|
+
destructiveHint: false,
|
|
1958
|
+
title: "Write diary entry",
|
|
1785
1959
|
}, async ({ date, orchestrator, content, highlights, blockers }) => {
|
|
1786
1960
|
let contentBytes = 0;
|
|
1787
1961
|
try {
|
|
@@ -1821,6 +1995,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1821
1995
|
server.tool("get_diary", "Fetch a diary entry for a specific date and orchestrator. Returns null if no entry exists.", {
|
|
1822
1996
|
date: z.string().describe("ISO date string — e.g. '2026-03-25'"),
|
|
1823
1997
|
orchestrator: creatorSchema.describe("Which orchestrator's diary to fetch"),
|
|
1998
|
+
}, {
|
|
1999
|
+
readOnlyHint: true,
|
|
2000
|
+
openWorldHint: false,
|
|
2001
|
+
destructiveHint: false,
|
|
2002
|
+
title: "Get diary entry",
|
|
1824
2003
|
}, async ({ date, orchestrator }) => {
|
|
1825
2004
|
try {
|
|
1826
2005
|
const entry = await convex.query("diary:get", {
|
|
@@ -1864,6 +2043,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1864
2043
|
.optional()
|
|
1865
2044
|
.default(20)
|
|
1866
2045
|
.describe("Maximum entries to return (default 20)"),
|
|
2046
|
+
}, {
|
|
2047
|
+
readOnlyHint: true,
|
|
2048
|
+
openWorldHint: false,
|
|
2049
|
+
destructiveHint: false,
|
|
2050
|
+
title: "List diary entries",
|
|
1867
2051
|
}, async ({ orchestrator, limit }) => {
|
|
1868
2052
|
try {
|
|
1869
2053
|
const entries = await convex.query("diary:list", {
|
|
@@ -1906,6 +2090,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1906
2090
|
"Passing a briefingNotes ID will fail with ArgumentValidationError at path .linkedMemoryIds[N]. " +
|
|
1907
2091
|
"If cross-linking briefings is needed, request the linkedBriefingIds feature instead."),
|
|
1908
2092
|
createdBy: creatorSchema,
|
|
2093
|
+
}, {
|
|
2094
|
+
readOnlyHint: false,
|
|
2095
|
+
openWorldHint: false,
|
|
2096
|
+
destructiveHint: false,
|
|
2097
|
+
title: "Create briefing note",
|
|
1909
2098
|
}, async ({ title, topic, participants, content, decisions, linkedMemoryIds, createdBy, }) => {
|
|
1910
2099
|
let contentBytes = 0;
|
|
1911
2100
|
try {
|
|
@@ -1945,7 +2134,12 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
1945
2134
|
}
|
|
1946
2135
|
});
|
|
1947
2136
|
// ── update_briefing_note ────────────────────────────────────────────────────
|
|
1948
|
-
server.tool("update_briefing_note", updateBriefingNoteDescription, updateBriefingNoteSchema.shape,
|
|
2137
|
+
server.tool("update_briefing_note", updateBriefingNoteDescription, updateBriefingNoteSchema.shape, {
|
|
2138
|
+
readOnlyHint: false,
|
|
2139
|
+
openWorldHint: false,
|
|
2140
|
+
destructiveHint: false,
|
|
2141
|
+
title: "Update briefing note",
|
|
2142
|
+
}, async ({ noteId, callerOrchestrator, title, topic, participants, content, decisions, linkedMemoryIds, }) => {
|
|
1949
2143
|
let contentBytes = 0;
|
|
1950
2144
|
try {
|
|
1951
2145
|
if (content !== undefined) {
|
|
@@ -2002,6 +2196,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2002
2196
|
.optional()
|
|
2003
2197
|
.describe('Field projection ("lite"|"full")'),
|
|
2004
2198
|
updatedSince: updatedSinceSchema.optional(),
|
|
2199
|
+
}, {
|
|
2200
|
+
readOnlyHint: true,
|
|
2201
|
+
openWorldHint: false,
|
|
2202
|
+
destructiveHint: false,
|
|
2203
|
+
title: "List briefing notes",
|
|
2005
2204
|
}, async ({ topic, limit, fields, updatedSince }) => {
|
|
2006
2205
|
try {
|
|
2007
2206
|
const notes = await convex.query("briefingNotes:list", {
|
|
@@ -2055,6 +2254,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2055
2254
|
.optional()
|
|
2056
2255
|
.describe("Project this component belongs to"),
|
|
2057
2256
|
createdBy: creatorSchema,
|
|
2257
|
+
}, {
|
|
2258
|
+
readOnlyHint: false,
|
|
2259
|
+
openWorldHint: false,
|
|
2260
|
+
destructiveHint: false,
|
|
2261
|
+
title: "Register component",
|
|
2058
2262
|
}, async ({ name, type, team, content, version, project, createdBy }) => {
|
|
2059
2263
|
let contentBytes = 0;
|
|
2060
2264
|
try {
|
|
@@ -2105,6 +2309,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2105
2309
|
.optional()
|
|
2106
2310
|
.default(100)
|
|
2107
2311
|
.describe("Maximum components to return (default 100)"),
|
|
2312
|
+
}, {
|
|
2313
|
+
readOnlyHint: true,
|
|
2314
|
+
openWorldHint: false,
|
|
2315
|
+
destructiveHint: false,
|
|
2316
|
+
title: "List components",
|
|
2108
2317
|
}, async ({ type, team, limit }) => {
|
|
2109
2318
|
try {
|
|
2110
2319
|
const components = await convex.query("components:list", {
|
|
@@ -2129,6 +2338,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2129
2338
|
server.tool("get_component", "Fetch a single component by name and type. Returns the full content.", {
|
|
2130
2339
|
name: z.string().describe("Component name"),
|
|
2131
2340
|
type: componentTypeSchema,
|
|
2341
|
+
}, {
|
|
2342
|
+
readOnlyHint: true,
|
|
2343
|
+
openWorldHint: false,
|
|
2344
|
+
destructiveHint: false,
|
|
2345
|
+
title: "Get component",
|
|
2132
2346
|
}, async ({ name, type }) => {
|
|
2133
2347
|
try {
|
|
2134
2348
|
const component = await convex.query("components:get", {
|
|
@@ -2156,6 +2370,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2156
2370
|
content: z.string().optional().describe("New content/source code"),
|
|
2157
2371
|
version: z.string().optional().describe("New version string"),
|
|
2158
2372
|
project: z.string().optional().describe("New project name"),
|
|
2373
|
+
}, {
|
|
2374
|
+
readOnlyHint: false,
|
|
2375
|
+
openWorldHint: false,
|
|
2376
|
+
destructiveHint: false,
|
|
2377
|
+
title: "Update component",
|
|
2159
2378
|
}, async ({ componentId, ...fields }) => {
|
|
2160
2379
|
let contentBytes = 0;
|
|
2161
2380
|
try {
|
|
@@ -2191,6 +2410,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2191
2410
|
componentId: z
|
|
2192
2411
|
.string()
|
|
2193
2412
|
.describe("Convex document ID of the component to delete"),
|
|
2413
|
+
}, {
|
|
2414
|
+
readOnlyHint: false,
|
|
2415
|
+
openWorldHint: false,
|
|
2416
|
+
destructiveHint: true,
|
|
2417
|
+
title: "Delete component",
|
|
2194
2418
|
}, async ({ componentId }) => {
|
|
2195
2419
|
try {
|
|
2196
2420
|
const result = await convex.mutation("components:remove", {
|
|
@@ -2211,6 +2435,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2211
2435
|
.describe("Search term to match against component name or team"),
|
|
2212
2436
|
type: componentTypeSchema.optional().describe("Filter by component type"),
|
|
2213
2437
|
limit: z.number().int().optional().describe("Max results (default 50)"),
|
|
2438
|
+
}, {
|
|
2439
|
+
readOnlyHint: true,
|
|
2440
|
+
openWorldHint: false,
|
|
2441
|
+
destructiveHint: false,
|
|
2442
|
+
title: "Search components",
|
|
2214
2443
|
}, async ({ query, type, limit }) => {
|
|
2215
2444
|
try {
|
|
2216
2445
|
const results = await convex.query("components:search", {
|
|
@@ -2243,6 +2472,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2243
2472
|
.string()
|
|
2244
2473
|
.describe("5-field cron: minute hour day-of-month month day-of-week"),
|
|
2245
2474
|
createdBy: creatorSchema,
|
|
2475
|
+
}, {
|
|
2476
|
+
readOnlyHint: false,
|
|
2477
|
+
openWorldHint: false,
|
|
2478
|
+
destructiveHint: false,
|
|
2479
|
+
title: "Create recurring task",
|
|
2246
2480
|
}, async ({ title, description, assignedTo, priority, project, tags, cronExpression, createdBy, }) => {
|
|
2247
2481
|
try {
|
|
2248
2482
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -2291,6 +2525,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2291
2525
|
.optional()
|
|
2292
2526
|
.default(50)
|
|
2293
2527
|
.describe("Max results"),
|
|
2528
|
+
}, {
|
|
2529
|
+
readOnlyHint: true,
|
|
2530
|
+
openWorldHint: false,
|
|
2531
|
+
destructiveHint: false,
|
|
2532
|
+
title: "List recurring tasks",
|
|
2294
2533
|
}, async ({ assignedTo, active, limit }) => {
|
|
2295
2534
|
try {
|
|
2296
2535
|
const tasks = await convex.query("recurringTasks:list", {
|
|
@@ -2309,6 +2548,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2309
2548
|
// ── pause_recurring_task ────────────────────────────────────────────────────
|
|
2310
2549
|
server.tool("pause_recurring_task", "Pause a recurring task — stops auto-creating tasks until resumed.", {
|
|
2311
2550
|
taskId: z.string().describe("Recurring task ID"),
|
|
2551
|
+
}, {
|
|
2552
|
+
readOnlyHint: false,
|
|
2553
|
+
openWorldHint: false,
|
|
2554
|
+
destructiveHint: false,
|
|
2555
|
+
title: "Pause recurring task",
|
|
2312
2556
|
}, async ({ taskId }) => {
|
|
2313
2557
|
try {
|
|
2314
2558
|
const result = await convex.mutation("recurringTasks:pause", {
|
|
@@ -2325,6 +2569,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2325
2569
|
// ── resume_recurring_task ───────────────────────────────────────────────────
|
|
2326
2570
|
server.tool("resume_recurring_task", "Resume a paused recurring task — recalculates next run time.", {
|
|
2327
2571
|
taskId: z.string().describe("Recurring task ID"),
|
|
2572
|
+
}, {
|
|
2573
|
+
readOnlyHint: false,
|
|
2574
|
+
openWorldHint: false,
|
|
2575
|
+
destructiveHint: false,
|
|
2576
|
+
title: "Resume recurring task",
|
|
2328
2577
|
}, async ({ taskId }) => {
|
|
2329
2578
|
try {
|
|
2330
2579
|
const result = await convex.mutation("recurringTasks:resume", {
|
|
@@ -2341,6 +2590,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2341
2590
|
// ── delete_recurring_task ───────────────────────────────────────────────────
|
|
2342
2591
|
server.tool("delete_recurring_task", "Permanently delete a recurring task template.", {
|
|
2343
2592
|
taskId: z.string().describe("Recurring task ID"),
|
|
2593
|
+
}, {
|
|
2594
|
+
readOnlyHint: false,
|
|
2595
|
+
openWorldHint: false,
|
|
2596
|
+
destructiveHint: true,
|
|
2597
|
+
title: "Delete recurring task",
|
|
2344
2598
|
}, async ({ taskId }) => {
|
|
2345
2599
|
try {
|
|
2346
2600
|
const result = await convex.mutation("recurringTasks:remove", {
|
|
@@ -2370,6 +2624,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2370
2624
|
.string()
|
|
2371
2625
|
.optional()
|
|
2372
2626
|
.describe("New cron expression (5-field)"),
|
|
2627
|
+
}, {
|
|
2628
|
+
readOnlyHint: false,
|
|
2629
|
+
openWorldHint: false,
|
|
2630
|
+
destructiveHint: false,
|
|
2631
|
+
title: "Update recurring task",
|
|
2373
2632
|
}, async ({ recurringTaskId, ...fields }) => {
|
|
2374
2633
|
try {
|
|
2375
2634
|
if (fields.assignedTo) {
|
|
@@ -2417,6 +2676,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2417
2676
|
.string()
|
|
2418
2677
|
.optional()
|
|
2419
2678
|
.describe("Signed authorization document or reference"),
|
|
2679
|
+
}, {
|
|
2680
|
+
readOnlyHint: false,
|
|
2681
|
+
openWorldHint: false,
|
|
2682
|
+
destructiveHint: false,
|
|
2683
|
+
title: "Create mandate",
|
|
2420
2684
|
}, async ({ requestedBy, fulfilledBy, service, budget, spendingLimits, approvedCategories, mandateDocument, }) => {
|
|
2421
2685
|
try {
|
|
2422
2686
|
const fromDenied = guardFrom(requestedBy);
|
|
@@ -2453,6 +2717,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2453
2717
|
.string()
|
|
2454
2718
|
.describe("Convex document ID of the mandate to accept"),
|
|
2455
2719
|
callerOrchestrator: creatorSchema.describe("Must be the fulfilledBy orchestrator or system"),
|
|
2720
|
+
}, {
|
|
2721
|
+
readOnlyHint: false,
|
|
2722
|
+
openWorldHint: false,
|
|
2723
|
+
destructiveHint: false,
|
|
2724
|
+
title: "Accept mandate",
|
|
2456
2725
|
}, async ({ mandateId, callerOrchestrator }) => {
|
|
2457
2726
|
try {
|
|
2458
2727
|
const fromDenied = guardFrom(callerOrchestrator);
|
|
@@ -2488,6 +2757,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2488
2757
|
.array(z.string())
|
|
2489
2758
|
.optional()
|
|
2490
2759
|
.describe("Task IDs created to fulfill this mandate"),
|
|
2760
|
+
}, {
|
|
2761
|
+
readOnlyHint: false,
|
|
2762
|
+
openWorldHint: false,
|
|
2763
|
+
destructiveHint: false,
|
|
2764
|
+
title: "Update mandate",
|
|
2491
2765
|
}, async ({ mandateId, callerOrchestrator, status, tokensCost, linkedTaskIds, }) => {
|
|
2492
2766
|
try {
|
|
2493
2767
|
const fromDenied = guardFrom(callerOrchestrator);
|
|
@@ -2521,6 +2795,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2521
2795
|
.describe("Convex document ID of the mandate to settle"),
|
|
2522
2796
|
callerOrchestrator: creatorSchema.describe("Must be the requestedBy orchestrator or system"),
|
|
2523
2797
|
finalCost: z.number().describe("Final actual token cost to record"),
|
|
2798
|
+
}, {
|
|
2799
|
+
readOnlyHint: false,
|
|
2800
|
+
openWorldHint: false,
|
|
2801
|
+
destructiveHint: false,
|
|
2802
|
+
title: "Settle mandate",
|
|
2524
2803
|
}, async ({ mandateId, callerOrchestrator, finalCost }) => {
|
|
2525
2804
|
try {
|
|
2526
2805
|
const fromDenied = guardFrom(callerOrchestrator);
|
|
@@ -2550,6 +2829,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2550
2829
|
proposedAmount: z
|
|
2551
2830
|
.number()
|
|
2552
2831
|
.describe("Proposed token spend amount to validate"),
|
|
2832
|
+
}, {
|
|
2833
|
+
readOnlyHint: true,
|
|
2834
|
+
openWorldHint: false,
|
|
2835
|
+
destructiveHint: false,
|
|
2836
|
+
title: "Validate mandate spending",
|
|
2553
2837
|
}, async ({ mandateId, proposedAmount }) => {
|
|
2554
2838
|
try {
|
|
2555
2839
|
const result = await convex.query("mandates:validateSpending", {
|
|
@@ -2584,6 +2868,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2584
2868
|
.optional()
|
|
2585
2869
|
.default(50)
|
|
2586
2870
|
.describe("Maximum mandates to return (default 50)"),
|
|
2871
|
+
}, {
|
|
2872
|
+
readOnlyHint: true,
|
|
2873
|
+
openWorldHint: false,
|
|
2874
|
+
destructiveHint: false,
|
|
2875
|
+
title: "List mandates",
|
|
2587
2876
|
}, async ({ requestedBy, fulfilledBy, status, limit }) => {
|
|
2588
2877
|
try {
|
|
2589
2878
|
const mandates = await convex.query("mandates:list", {
|
|
@@ -2633,6 +2922,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2633
2922
|
.optional()
|
|
2634
2923
|
.default(10)
|
|
2635
2924
|
.describe("Management fee percentage (default 10)"),
|
|
2925
|
+
}, {
|
|
2926
|
+
readOnlyHint: false,
|
|
2927
|
+
openWorldHint: false,
|
|
2928
|
+
destructiveHint: false,
|
|
2929
|
+
title: "Create BU",
|
|
2636
2930
|
}, async ({ name, description, purpose, domain, orchestratorId, status, businessModel, targetCustomers, services, pricing, revenueProjections, coreTeam, coreProcesses, dependencies, kpis, managementFee, }) => {
|
|
2637
2931
|
try {
|
|
2638
2932
|
const fromDenied = guardFrom(orchestratorId);
|
|
@@ -2693,6 +2987,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2693
2987
|
dependencies: flexArrayOptional.describe("New dependencies"),
|
|
2694
2988
|
kpis: flexArrayOptional.describe("New KPIs"),
|
|
2695
2989
|
managementFee: z.number().optional().describe("New management fee %"),
|
|
2990
|
+
}, {
|
|
2991
|
+
readOnlyHint: false,
|
|
2992
|
+
openWorldHint: false,
|
|
2993
|
+
destructiveHint: false,
|
|
2994
|
+
title: "Update BU",
|
|
2696
2995
|
}, async ({ buId, name, description, purpose, domain, orchestratorId, status, businessModel, targetCustomers, services, pricing, revenueProjections, coreTeam, coreProcesses, dependencies, kpis, managementFee, }) => {
|
|
2697
2996
|
try {
|
|
2698
2997
|
if (orchestratorId) {
|
|
@@ -2735,6 +3034,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2735
3034
|
// ── get_bu ──────────────────────────────────────────────────────────────────
|
|
2736
3035
|
server.tool("get_bu", "Fetch a single business unit by its Convex document ID. Returns null if not found.", {
|
|
2737
3036
|
buId: z.string().describe("Convex document ID of the business unit"),
|
|
3037
|
+
}, {
|
|
3038
|
+
readOnlyHint: true,
|
|
3039
|
+
openWorldHint: false,
|
|
3040
|
+
destructiveHint: false,
|
|
3041
|
+
title: "Get BU",
|
|
2738
3042
|
}, async ({ buId }) => {
|
|
2739
3043
|
try {
|
|
2740
3044
|
const bu = await convex.query("businessUnits:get", {
|
|
@@ -2769,6 +3073,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2769
3073
|
.optional()
|
|
2770
3074
|
.default(50)
|
|
2771
3075
|
.describe("Maximum BUs to return (default 50)"),
|
|
3076
|
+
}, {
|
|
3077
|
+
readOnlyHint: true,
|
|
3078
|
+
openWorldHint: false,
|
|
3079
|
+
destructiveHint: false,
|
|
3080
|
+
title: "List BUs",
|
|
2772
3081
|
}, async ({ orchestratorId, status, limit }) => {
|
|
2773
3082
|
try {
|
|
2774
3083
|
const bus = await convex.query("businessUnits:list", {
|
|
@@ -2794,6 +3103,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2794
3103
|
buId: z
|
|
2795
3104
|
.string()
|
|
2796
3105
|
.describe("Convex document ID of the business unit to delete"),
|
|
3106
|
+
}, {
|
|
3107
|
+
readOnlyHint: false,
|
|
3108
|
+
openWorldHint: false,
|
|
3109
|
+
destructiveHint: true,
|
|
3110
|
+
title: "Delete BU",
|
|
2797
3111
|
}, async ({ buId }) => {
|
|
2798
3112
|
try {
|
|
2799
3113
|
const result = await convex.mutation("businessUnits:remove", {
|
|
@@ -2828,6 +3142,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2828
3142
|
.optional()
|
|
2829
3143
|
.default(true)
|
|
2830
3144
|
.describe("Whether this mapping is active (default true)"),
|
|
3145
|
+
}, {
|
|
3146
|
+
readOnlyHint: false,
|
|
3147
|
+
openWorldHint: false,
|
|
3148
|
+
destructiveHint: false,
|
|
3149
|
+
title: "Add repo mapping",
|
|
2831
3150
|
}, async ({ repo, orchestrator, project, active }) => {
|
|
2832
3151
|
try {
|
|
2833
3152
|
const id = await convex.mutation("githubRepoMapping:add", {
|
|
@@ -2850,7 +3169,12 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2850
3169
|
}
|
|
2851
3170
|
});
|
|
2852
3171
|
// ── list_repo_mappings ──────────────────────────────────────────────────────
|
|
2853
|
-
server.tool("list_repo_mappings", "List all GitHub repo → orchestrator mappings. Shows which repos are monitored and which orchestrator handles each.", {},
|
|
3172
|
+
server.tool("list_repo_mappings", "List all GitHub repo → orchestrator mappings. Shows which repos are monitored and which orchestrator handles each.", {}, {
|
|
3173
|
+
readOnlyHint: true,
|
|
3174
|
+
openWorldHint: false,
|
|
3175
|
+
destructiveHint: false,
|
|
3176
|
+
title: "List repo mappings",
|
|
3177
|
+
}, async () => {
|
|
2854
3178
|
try {
|
|
2855
3179
|
const mappings = await convex.query("githubRepoMapping:list", {});
|
|
2856
3180
|
return {
|
|
@@ -2871,6 +3195,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2871
3195
|
repo: z
|
|
2872
3196
|
.string()
|
|
2873
3197
|
.describe("Full repo name to remove — e.g. 'vantageos-agency/vantage-peers'"),
|
|
3198
|
+
}, {
|
|
3199
|
+
readOnlyHint: false,
|
|
3200
|
+
openWorldHint: false,
|
|
3201
|
+
destructiveHint: true,
|
|
3202
|
+
title: "Remove repo mapping",
|
|
2874
3203
|
}, async ({ repo }) => {
|
|
2875
3204
|
try {
|
|
2876
3205
|
const result = await convex.mutation("githubRepoMapping:remove", {
|
|
@@ -2911,6 +3240,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2911
3240
|
.optional()
|
|
2912
3241
|
.default(50)
|
|
2913
3242
|
.describe("Maximum number of issues to return (default 50)"),
|
|
3243
|
+
}, {
|
|
3244
|
+
readOnlyHint: true,
|
|
3245
|
+
openWorldHint: false,
|
|
3246
|
+
destructiveHint: false,
|
|
3247
|
+
title: "List issues",
|
|
2914
3248
|
}, async ({ project, status, assignedTo, limit }) => {
|
|
2915
3249
|
try {
|
|
2916
3250
|
let results;
|
|
@@ -2959,6 +3293,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2959
3293
|
.string()
|
|
2960
3294
|
.describe("Full repo name — e.g. 'myreeldream-ai/MyShortReel-beta'"),
|
|
2961
3295
|
issueNumber: z.number().int().describe("GitHub issue number"),
|
|
3296
|
+
}, {
|
|
3297
|
+
readOnlyHint: true,
|
|
3298
|
+
openWorldHint: false,
|
|
3299
|
+
destructiveHint: false,
|
|
3300
|
+
title: "Get issue",
|
|
2962
3301
|
}, async ({ repo, issueNumber }) => {
|
|
2963
3302
|
try {
|
|
2964
3303
|
const issue = await convex.query("issues:getByRepoNumber", {
|
|
@@ -2987,6 +3326,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
2987
3326
|
status: z
|
|
2988
3327
|
.enum(["open", "in_progress", "fixed", "verified", "closed"])
|
|
2989
3328
|
.describe("New status for the issue"),
|
|
3329
|
+
}, {
|
|
3330
|
+
readOnlyHint: false,
|
|
3331
|
+
openWorldHint: false,
|
|
3332
|
+
destructiveHint: false,
|
|
3333
|
+
title: "Update issue status",
|
|
2990
3334
|
}, async ({ repo, issueNumber, status }) => {
|
|
2991
3335
|
try {
|
|
2992
3336
|
await convex.mutation("issues:updateStatus", {
|
|
@@ -3017,6 +3361,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3017
3361
|
fixedBy: z
|
|
3018
3362
|
.string()
|
|
3019
3363
|
.describe("Who fixed it — orchestrator name or person"),
|
|
3364
|
+
}, {
|
|
3365
|
+
readOnlyHint: false,
|
|
3366
|
+
openWorldHint: false,
|
|
3367
|
+
destructiveHint: false,
|
|
3368
|
+
title: "Link commit to issue",
|
|
3020
3369
|
}, async ({ repo, issueNumber, commitSha, fixedBy }) => {
|
|
3021
3370
|
try {
|
|
3022
3371
|
await convex.mutation("issues:linkCommit", {
|
|
@@ -3047,6 +3396,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3047
3396
|
verifiedBy: z
|
|
3048
3397
|
.string()
|
|
3049
3398
|
.describe("Who verified the fix — orchestrator name or person"),
|
|
3399
|
+
}, {
|
|
3400
|
+
readOnlyHint: false,
|
|
3401
|
+
openWorldHint: false,
|
|
3402
|
+
destructiveHint: false,
|
|
3403
|
+
title: "Verify issue",
|
|
3050
3404
|
}, async ({ repo, issueNumber, verifiedBy }) => {
|
|
3051
3405
|
try {
|
|
3052
3406
|
await convex.mutation("issues:verify", {
|
|
@@ -3073,6 +3427,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3073
3427
|
.string()
|
|
3074
3428
|
.optional()
|
|
3075
3429
|
.describe("Filter stats to a specific project — omit for all projects"),
|
|
3430
|
+
}, {
|
|
3431
|
+
readOnlyHint: true,
|
|
3432
|
+
openWorldHint: false,
|
|
3433
|
+
destructiveHint: false,
|
|
3434
|
+
title: "Issue statistics",
|
|
3076
3435
|
}, async ({ project }) => {
|
|
3077
3436
|
try {
|
|
3078
3437
|
const stats = await convex.query("issues:getStats", {
|
|
@@ -3112,6 +3471,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3112
3471
|
.describe("The fix that worked — set later if not known yet"),
|
|
3113
3472
|
files: flexArrayOptional.describe("Files involved in the fix"),
|
|
3114
3473
|
linkedIssueIds: flexArrayOptional.describe("VantagePeers issue IDs linked to this pattern"),
|
|
3474
|
+
}, {
|
|
3475
|
+
readOnlyHint: false,
|
|
3476
|
+
openWorldHint: false,
|
|
3477
|
+
destructiveHint: false,
|
|
3478
|
+
title: "Create fix pattern",
|
|
3115
3479
|
}, async ({ symptom, rootCause, tags, stack, sourceProject, createdBy, severity, validatedFix, files, linkedIssueIds, }) => {
|
|
3116
3480
|
try {
|
|
3117
3481
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -3150,6 +3514,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3150
3514
|
why: z.string().describe("Why it worked or didn't — the reasoning"),
|
|
3151
3515
|
createdBy: creatorSchema,
|
|
3152
3516
|
commit: z.string().optional().describe("Git commit hash of this attempt"),
|
|
3517
|
+
}, {
|
|
3518
|
+
readOnlyHint: false,
|
|
3519
|
+
openWorldHint: false,
|
|
3520
|
+
destructiveHint: false,
|
|
3521
|
+
title: "Add fix attempt",
|
|
3153
3522
|
}, async ({ patternId, description, worked, why, createdBy, commit }) => {
|
|
3154
3523
|
try {
|
|
3155
3524
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -3180,6 +3549,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3180
3549
|
server.tool("validate_fix", "Set or update the validated fix on a pattern. Use after confirming a fix works.", {
|
|
3181
3550
|
patternId: z.string().describe("ID of the fix pattern"),
|
|
3182
3551
|
validatedFix: z.string().describe("Description of the validated fix"),
|
|
3552
|
+
}, {
|
|
3553
|
+
readOnlyHint: false,
|
|
3554
|
+
openWorldHint: false,
|
|
3555
|
+
destructiveHint: false,
|
|
3556
|
+
title: "Validate fix",
|
|
3183
3557
|
}, async ({ patternId, validatedFix }) => {
|
|
3184
3558
|
try {
|
|
3185
3559
|
await convex.mutation("fixPatterns:validate", {
|
|
@@ -3209,6 +3583,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3209
3583
|
.int()
|
|
3210
3584
|
.optional()
|
|
3211
3585
|
.describe("Max results to return (default 10)"),
|
|
3586
|
+
}, {
|
|
3587
|
+
readOnlyHint: true,
|
|
3588
|
+
openWorldHint: false,
|
|
3589
|
+
destructiveHint: false,
|
|
3590
|
+
title: "Search fix patterns",
|
|
3212
3591
|
}, async ({ query, limit }) => {
|
|
3213
3592
|
try {
|
|
3214
3593
|
const results = await convex.action("search:searchFixPatterns", {
|
|
@@ -3235,6 +3614,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3235
3614
|
.optional()
|
|
3236
3615
|
.describe("Filter by source project — omit for all"),
|
|
3237
3616
|
limit: z.number().int().optional().describe("Max results (default 50)"),
|
|
3617
|
+
}, {
|
|
3618
|
+
readOnlyHint: true,
|
|
3619
|
+
openWorldHint: false,
|
|
3620
|
+
destructiveHint: false,
|
|
3621
|
+
title: "List fix patterns",
|
|
3238
3622
|
}, async ({ project, limit }) => {
|
|
3239
3623
|
try {
|
|
3240
3624
|
if (project) {
|
|
@@ -3263,6 +3647,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3263
3647
|
server.tool("link_issue_to_pattern", "Link a VantagePeers issue to a fix pattern. Creates a bidirectional reference.", {
|
|
3264
3648
|
patternId: z.string().describe("ID of the fix pattern"),
|
|
3265
3649
|
issueId: z.string().describe("VantagePeers issue ID to link"),
|
|
3650
|
+
}, {
|
|
3651
|
+
readOnlyHint: false,
|
|
3652
|
+
openWorldHint: false,
|
|
3653
|
+
destructiveHint: false,
|
|
3654
|
+
title: "Link issue to fix pattern",
|
|
3266
3655
|
}, async ({ patternId, issueId }) => {
|
|
3267
3656
|
try {
|
|
3268
3657
|
await convex.mutation("fixPatterns:linkIssue", {
|
|
@@ -3286,6 +3675,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3286
3675
|
server.tool("get_mission_template", "Fetch a mission template by name. Returns the template with all steps, or null if not found. " +
|
|
3287
3676
|
"Use 'issue-resolution-v2' for the default Issue Resolution Protocol.", {
|
|
3288
3677
|
name: z.string().describe("Template name — e.g. 'issue-resolution-v2'"),
|
|
3678
|
+
}, {
|
|
3679
|
+
readOnlyHint: true,
|
|
3680
|
+
openWorldHint: false,
|
|
3681
|
+
destructiveHint: false,
|
|
3682
|
+
title: "Get mission template",
|
|
3289
3683
|
}, async ({ name }) => {
|
|
3290
3684
|
try {
|
|
3291
3685
|
const template = await convex.query("missionTemplates:getByName", { name });
|
|
@@ -3340,6 +3734,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3340
3734
|
.boolean()
|
|
3341
3735
|
.optional()
|
|
3342
3736
|
.describe("Mark as the default template for its type"),
|
|
3737
|
+
}, {
|
|
3738
|
+
readOnlyHint: false,
|
|
3739
|
+
openWorldHint: false,
|
|
3740
|
+
destructiveHint: false,
|
|
3741
|
+
title: "Update mission template",
|
|
3343
3742
|
}, async ({ name, description, steps, createdBy, isDefault }) => {
|
|
3344
3743
|
try {
|
|
3345
3744
|
const fromDenied = guardFrom(createdBy);
|
|
@@ -3385,7 +3784,12 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3385
3784
|
.string()
|
|
3386
3785
|
.optional()
|
|
3387
3786
|
.describe("Orchestrator making this call — used as createdBy on tasks. Defaults to 'system'."),
|
|
3388
|
-
},
|
|
3787
|
+
}, {
|
|
3788
|
+
readOnlyHint: false,
|
|
3789
|
+
openWorldHint: false,
|
|
3790
|
+
destructiveHint: false,
|
|
3791
|
+
title: "Instantiate mission template",
|
|
3792
|
+
}, async ({ templateName, missionId, context, titlePrefix, callerOrchestrator, }) => {
|
|
3389
3793
|
try {
|
|
3390
3794
|
const denied = guardMasterOnly("instantiate_template_into_mission");
|
|
3391
3795
|
if (denied)
|
|
@@ -3429,6 +3833,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3429
3833
|
orchestrator: z
|
|
3430
3834
|
.string()
|
|
3431
3835
|
.describe("Orchestrator responsible for this deployment — e.g. 'sigma'"),
|
|
3836
|
+
}, {
|
|
3837
|
+
readOnlyHint: false,
|
|
3838
|
+
openWorldHint: false,
|
|
3839
|
+
destructiveHint: false,
|
|
3840
|
+
title: "Add deployment",
|
|
3432
3841
|
}, async ({ name, deploymentUrl, deployKeyEnvVar, githubRepo, orchestrator, }) => {
|
|
3433
3842
|
try {
|
|
3434
3843
|
const id = await convex.mutation("errorMonitor:addDeployment", {
|
|
@@ -3456,6 +3865,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3456
3865
|
name: z
|
|
3457
3866
|
.string()
|
|
3458
3867
|
.describe("Name of the deployment to deactivate — e.g. 'your-deployment-123'"),
|
|
3868
|
+
}, {
|
|
3869
|
+
readOnlyHint: false,
|
|
3870
|
+
openWorldHint: false,
|
|
3871
|
+
destructiveHint: true,
|
|
3872
|
+
title: "Remove deployment",
|
|
3459
3873
|
}, async ({ name }) => {
|
|
3460
3874
|
try {
|
|
3461
3875
|
await convex.mutation("errorMonitor:removeDeployment", { name });
|
|
@@ -3487,6 +3901,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3487
3901
|
.optional()
|
|
3488
3902
|
.default(50)
|
|
3489
3903
|
.describe("Maximum number of errors to return (default 50)"),
|
|
3904
|
+
}, {
|
|
3905
|
+
readOnlyHint: true,
|
|
3906
|
+
openWorldHint: false,
|
|
3907
|
+
destructiveHint: false,
|
|
3908
|
+
title: "List errors",
|
|
3490
3909
|
}, async ({ deployment, limit }) => {
|
|
3491
3910
|
try {
|
|
3492
3911
|
const errors = await convex.query("errorMonitor:listErrors", {
|
|
@@ -3509,6 +3928,11 @@ export function registerTools(server, convex, oauthCtx) {
|
|
|
3509
3928
|
// ── get_error ───────────────────────────────────────────────────────────────
|
|
3510
3929
|
server.tool("get_error", "Fetch a single error log entry by its Convex document ID, including stack trace and issue linkage.", {
|
|
3511
3930
|
errorId: z.string().describe("Convex document ID of the errorLogs entry"),
|
|
3931
|
+
}, {
|
|
3932
|
+
readOnlyHint: true,
|
|
3933
|
+
openWorldHint: false,
|
|
3934
|
+
destructiveHint: false,
|
|
3935
|
+
title: "Get error",
|
|
3512
3936
|
}, async ({ errorId }) => {
|
|
3513
3937
|
try {
|
|
3514
3938
|
const error = await convex.query("errorMonitor:getError", {
|
package/package.json
CHANGED