@creatornader/agent-bridge 0.2.0 → 0.3.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/CHANGELOG.md +86 -4
- package/README.md +567 -55
- package/ROADMAP.md +114 -0
- package/SECURITY.md +90 -0
- package/SKILL.md +68 -2
- package/bin/agent-bridge +2 -2
- package/clients/claude-desktop.json +3 -1
- package/dist/archive.d.ts +163 -0
- package/dist/archive.js +50 -0
- package/dist/archive.js.map +1 -0
- package/dist/bridge-domain-CBX3IVqC.d.ts +153 -0
- package/dist/{bridge-service-CfqMcMAn.d.ts → bridge-service-hX1ZQp4W.d.ts} +15 -5
- package/dist/bridge-store-DPVSCwfs.d.ts +102 -0
- package/dist/bridge.d.ts +76 -17
- package/dist/bridge.js +52 -24
- package/dist/chunk-2DFNOLMO.js +618 -0
- package/dist/chunk-2DFNOLMO.js.map +1 -0
- package/dist/{chunk-KVR4JBRF.js → chunk-2EVLG3YA.js} +2 -2
- package/dist/{chunk-KVR4JBRF.js.map → chunk-2EVLG3YA.js.map} +1 -1
- package/dist/chunk-45BZGB77.js +709 -0
- package/dist/chunk-45BZGB77.js.map +1 -0
- package/dist/chunk-4VB44KJU.js +230 -0
- package/dist/chunk-4VB44KJU.js.map +1 -0
- package/dist/chunk-5GMB3A77.js +1013 -0
- package/dist/chunk-5GMB3A77.js.map +1 -0
- package/dist/chunk-A6W4QALF.js +1258 -0
- package/dist/chunk-A6W4QALF.js.map +1 -0
- package/dist/chunk-BZLMF5O5.js +328 -0
- package/dist/chunk-BZLMF5O5.js.map +1 -0
- package/dist/{chunk-AXL2I7FH.js → chunk-CEXBMOI5.js} +240 -79
- package/dist/chunk-CEXBMOI5.js.map +1 -0
- package/dist/chunk-GADH244D.js +527 -0
- package/dist/chunk-GADH244D.js.map +1 -0
- package/dist/chunk-MBPZXTJA.js +2428 -0
- package/dist/chunk-MBPZXTJA.js.map +1 -0
- package/dist/chunk-NCO7RLBM.js +146 -0
- package/dist/chunk-NCO7RLBM.js.map +1 -0
- package/dist/chunk-Q6PPMXJC.js +1050 -0
- package/dist/chunk-Q6PPMXJC.js.map +1 -0
- package/dist/{chunk-4KAOBC5X.js → chunk-SPSMZOCJ.js} +190 -165
- package/dist/chunk-SPSMZOCJ.js.map +1 -0
- package/dist/chunk-UAHMP6GC.js +54 -0
- package/dist/chunk-UAHMP6GC.js.map +1 -0
- package/dist/{chunk-YD6YJATN.js → chunk-VOQIDTCJ.js} +4 -2
- package/dist/chunk-VOQIDTCJ.js.map +1 -0
- package/dist/chunk-WAI2IYIQ.js +554 -0
- package/dist/chunk-WAI2IYIQ.js.map +1 -0
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +3555 -214
- package/dist/cli.js.map +1 -1
- package/dist/client-config.d.ts +1 -1
- package/dist/client-config.js +1 -1
- package/dist/client-runtime.d.ts +10 -6
- package/dist/client-runtime.js +9 -6
- package/dist/contracts/generate.d.ts +2 -0
- package/dist/contracts/generate.js +247 -0
- package/dist/contracts/generate.js.map +1 -0
- package/dist/dr.d.ts +324 -0
- package/dist/dr.js +124 -0
- package/dist/dr.js.map +1 -0
- package/dist/gateway-CggQ8vTC.d.ts +78 -0
- package/dist/gateway-main.js +190 -8
- package/dist/gateway-main.js.map +1 -1
- package/dist/gateway.d.ts +4 -3
- package/dist/gateway.js +4 -3
- package/dist/index.js +11 -8
- package/dist/index.js.map +1 -1
- package/dist/postgres-bridge-store-Bfd3hRId.d.ts +49 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.js +13 -8
- package/dist/sqlite.d.ts +94 -12
- package/dist/sqlite.js +7 -4
- package/docs/architecture-v2.md +394 -0
- package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +85 -0
- package/docs/decisions/0002-canonical-operation-contract-registry.md +46 -0
- package/docs/decisions/0003-host-adapters-and-consumer-instance-keys.md +88 -0
- package/docs/ecosystem.md +86 -0
- package/docs/postmortems/2026-07-08-wrapper-source-drift.md +82 -0
- package/docs/troubleshooting.md +89 -0
- package/llms.txt +107 -6
- package/openapi/agent-bridge-v2.openapi.json +9610 -0
- package/package.json +24 -4
- package/schemas/agent-bridge-v2.capabilities.json +1829 -0
- package/schemas/agent-bridge-v2.mcp.json +2074 -0
- package/schemas/agent-bridge-v2.schema.json +4560 -0
- package/sql/migrations/008_message_projects.sql +36 -0
- package/sql/migrations/009_mailbox_query_indexes.sql +28 -0
- package/sql/migrations/010_publisher_delivery_policy.sql +210 -0
- package/sql/migrations/011_credential_security.sql +875 -0
- package/sql/migrations/012_request_authority.sql +177 -0
- package/sql/migrations/013_row_isolation.sql +495 -0
- package/sql/migrations/014_owner_control_plane.sql +1641 -0
- package/sql/migrations/015_portable_archives.sql +1813 -0
- package/sql/migrations/016_native_dr_fence.sql +1005 -0
- package/bin/CLAUDE.md +0 -11
- package/dist/bridge-domain-BcnBeHOn.d.ts +0 -97
- package/dist/bridge-store-BuGjxTn4.d.ts +0 -61
- package/dist/chunk-4KAOBC5X.js.map +0 -1
- package/dist/chunk-6MAZ6YLZ.js +0 -146
- package/dist/chunk-6MAZ6YLZ.js.map +0 -1
- package/dist/chunk-AXL2I7FH.js.map +0 -1
- package/dist/chunk-BV6W4AJK.js +0 -211
- package/dist/chunk-BV6W4AJK.js.map +0 -1
- package/dist/chunk-CKSKUBDQ.js +0 -153
- package/dist/chunk-CKSKUBDQ.js.map +0 -1
- package/dist/chunk-JOUBDRYX.js +0 -272
- package/dist/chunk-JOUBDRYX.js.map +0 -1
- package/dist/chunk-JTC5YURG.js +0 -49
- package/dist/chunk-JTC5YURG.js.map +0 -1
- package/dist/chunk-O26W5QHS.js +0 -409
- package/dist/chunk-O26W5QHS.js.map +0 -1
- package/dist/chunk-WEULPMUY.js +0 -988
- package/dist/chunk-WEULPMUY.js.map +0 -1
- package/dist/chunk-YD6YJATN.js.map +0 -1
- package/dist/gateway-BULozv3K.d.ts +0 -54
|
@@ -2,21 +2,32 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readClientConfigFile,
|
|
4
4
|
resolveClientConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2EVLG3YA.js";
|
|
6
6
|
import {
|
|
7
7
|
createStore
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UAHMP6GC.js";
|
|
9
9
|
import {
|
|
10
10
|
legacyContextMetadata,
|
|
11
11
|
legacyNumericMessageId
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CEXBMOI5.js";
|
|
13
13
|
import {
|
|
14
14
|
BridgeService
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-4VB44KJU.js";
|
|
16
16
|
import {
|
|
17
|
+
ContractValidationError,
|
|
18
|
+
availableOperations,
|
|
19
|
+
capabilityDocument,
|
|
20
|
+
parseResponse,
|
|
21
|
+
validateRequest
|
|
22
|
+
} from "./chunk-GADH244D.js";
|
|
23
|
+
import {
|
|
24
|
+
BridgePrincipalMismatchError,
|
|
17
25
|
BridgeValidationError,
|
|
18
|
-
normalizeReceiptId
|
|
19
|
-
|
|
26
|
+
normalizeReceiptId,
|
|
27
|
+
uuidv7,
|
|
28
|
+
validateMessageDraft,
|
|
29
|
+
validateProject
|
|
30
|
+
} from "./chunk-BZLMF5O5.js";
|
|
20
31
|
|
|
21
32
|
// src/server.ts
|
|
22
33
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -28,11 +39,9 @@ import {
|
|
|
28
39
|
McpError
|
|
29
40
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
30
41
|
import { homedir } from "os";
|
|
31
|
-
import { createRequire } from "module";
|
|
32
42
|
import { join } from "path";
|
|
33
43
|
|
|
34
44
|
// src/message-envelope.ts
|
|
35
|
-
import { randomUUID } from "crypto";
|
|
36
45
|
var MESSAGE_ENVELOPE_SCHEMA = "agent-bridge.message-envelope.v1";
|
|
37
46
|
var RECORD_HASH_RE = /^sha256:[a-f0-9]{64}$/i;
|
|
38
47
|
function isRecord(value) {
|
|
@@ -77,7 +86,7 @@ function buildMessageEnvelope(args, receiptId) {
|
|
|
77
86
|
const source = normalizeString(args?.source) ?? "unknown";
|
|
78
87
|
const category = normalizeString(args?.category);
|
|
79
88
|
const kind = normalizeString(args?.kind) ?? category ?? "operational";
|
|
80
|
-
const messageId = normalizeString(args?.message_id) ??
|
|
89
|
+
const messageId = normalizeString(args?.message_id) ?? uuidv7();
|
|
81
90
|
const envelope = {
|
|
82
91
|
schema: MESSAGE_ENVELOPE_SCHEMA,
|
|
83
92
|
message_id: messageId,
|
|
@@ -168,7 +177,7 @@ function resolvePostSource(requestedSource, configuredAgent) {
|
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
// src/server.ts
|
|
171
|
-
var
|
|
180
|
+
var MCP_IMPLEMENTATION_VERSION = "2.0.0";
|
|
172
181
|
function normalizedConfigValue(value) {
|
|
173
182
|
const trimmed = value?.trim();
|
|
174
183
|
return trimmed || void 0;
|
|
@@ -244,9 +253,14 @@ function buildSupabaseRequest(config) {
|
|
|
244
253
|
}
|
|
245
254
|
function createAgentBridgeServer(config) {
|
|
246
255
|
const supabaseRequest = config.supabaseUrl && config.supabaseKey ? buildSupabaseRequest(config) : void 0;
|
|
247
|
-
const
|
|
256
|
+
const provider = config.provider ?? (config.gatewayToken ? "gateway" : config.supabaseUrl ? "legacy-supabase" : "local");
|
|
257
|
+
const principal = config.agent ? {
|
|
258
|
+
workspace: provider === "legacy-supabase" ? "*" : config.workspace ?? "default",
|
|
259
|
+
agent: config.agent,
|
|
260
|
+
instance: config.instance
|
|
261
|
+
} : void 0;
|
|
248
262
|
const clientConfig = principal ? {
|
|
249
|
-
provider
|
|
263
|
+
provider,
|
|
250
264
|
principal,
|
|
251
265
|
url: config.gatewayUrl ?? config.supabaseUrl,
|
|
252
266
|
credential: config.gatewayToken ?? config.supabaseKey,
|
|
@@ -257,15 +271,12 @@ function createAgentBridgeServer(config) {
|
|
|
257
271
|
} : void 0;
|
|
258
272
|
const store = clientConfig ? createStore(clientConfig) : void 0;
|
|
259
273
|
const service = store ? new BridgeService(store) : void 0;
|
|
260
|
-
const deliveryToolsAvailable = Boolean(
|
|
261
|
-
service && clientConfig?.provider !== "legacy-supabase"
|
|
262
|
-
);
|
|
263
274
|
const server = new Server(
|
|
264
|
-
{ name: "agent-bridge", version:
|
|
275
|
+
{ name: "agent-bridge", version: MCP_IMPLEMENTATION_VERSION },
|
|
265
276
|
{ capabilities: { tools: {} } }
|
|
266
277
|
);
|
|
267
|
-
server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
268
|
-
|
|
278
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
279
|
+
const legacyTools = [
|
|
269
280
|
{
|
|
270
281
|
name: "post_context",
|
|
271
282
|
description: "Post a shared context entry visible to all agents. Categories: operational, config-change, goal-update, flag, bridge-meta (for suggesting improvements to the Agent Bridge itself).",
|
|
@@ -290,7 +301,7 @@ function createAgentBridgeServer(config) {
|
|
|
290
301
|
},
|
|
291
302
|
project: {
|
|
292
303
|
type: "string",
|
|
293
|
-
description: "
|
|
304
|
+
description: "Optional immutable message label. Omit for an unlabeled message."
|
|
294
305
|
},
|
|
295
306
|
metadata: {
|
|
296
307
|
type: "object",
|
|
@@ -377,7 +388,7 @@ function createAgentBridgeServer(config) {
|
|
|
377
388
|
},
|
|
378
389
|
project: {
|
|
379
390
|
type: "string",
|
|
380
|
-
description: "Filter by project
|
|
391
|
+
description: "Filter by an exact project label"
|
|
381
392
|
},
|
|
382
393
|
unacked_by: {
|
|
383
394
|
type: "string",
|
|
@@ -402,6 +413,19 @@ function createAgentBridgeServer(config) {
|
|
|
402
413
|
description: "Filter by metadata.message_envelope.kind."
|
|
403
414
|
}
|
|
404
415
|
}
|
|
416
|
+
},
|
|
417
|
+
outputSchema: {
|
|
418
|
+
type: "object",
|
|
419
|
+
properties: {
|
|
420
|
+
entries: { type: "array", items: { type: "object", additionalProperties: true } },
|
|
421
|
+
source: { type: "string", enum: ["remote", "cache"] },
|
|
422
|
+
stale: { type: "boolean" },
|
|
423
|
+
degraded: { type: "boolean" },
|
|
424
|
+
acknowledgements: { type: "string", enum: ["authoritative", "unknown"] },
|
|
425
|
+
lastSyncedAt: { type: ["string", "null"] }
|
|
426
|
+
},
|
|
427
|
+
required: ["entries"],
|
|
428
|
+
additionalProperties: false
|
|
405
429
|
}
|
|
406
430
|
},
|
|
407
431
|
{
|
|
@@ -422,99 +446,31 @@ function createAgentBridgeServer(config) {
|
|
|
422
446
|
},
|
|
423
447
|
required: ["ids"]
|
|
424
448
|
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
contentType: { type: "string" },
|
|
437
|
-
data: {},
|
|
438
|
-
targets: { type: "array", items: { type: "string" } },
|
|
439
|
-
threadId: { type: "string" },
|
|
440
|
-
replyToId: { type: "string" },
|
|
441
|
-
correlationId: { type: "string" },
|
|
442
|
-
causationId: { type: "string" },
|
|
443
|
-
priority: { type: "string", enum: ["info", "high", "urgent"] },
|
|
444
|
-
expiresAt: { type: "string" },
|
|
445
|
-
idempotencyKey: { type: "string" },
|
|
446
|
-
atribReceiptId: { type: "string" },
|
|
447
|
-
informedBy: { type: "array", items: { type: "string" } },
|
|
448
|
-
metadata: {}
|
|
449
|
-
},
|
|
450
|
-
required: ["type", "content"],
|
|
451
|
-
additionalProperties: false
|
|
452
|
-
},
|
|
453
|
-
outputSchema: { type: "object", properties: { created: { type: "boolean" }, message: { type: "object", additionalProperties: true } }, required: ["created", "message"] }
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
name: "history",
|
|
457
|
-
description: "Read visible Agent Bridge v2 messages after an opaque cursor.",
|
|
458
|
-
inputSchema: { type: "object", properties: {
|
|
459
|
-
cursor: { type: "string" },
|
|
460
|
-
limit: { type: "number", minimum: 1, maximum: 200 },
|
|
461
|
-
types: { type: "array", items: { type: "string" } },
|
|
462
|
-
includeExpired: { type: "boolean" },
|
|
463
|
-
source: { type: "string" },
|
|
464
|
-
since: { type: "string" },
|
|
465
|
-
unacknowledgedBy: { type: "string" },
|
|
466
|
-
threadId: { type: "string" },
|
|
467
|
-
latest: { type: "boolean" }
|
|
468
|
-
}, additionalProperties: false },
|
|
469
|
-
outputSchema: { type: "object", properties: { messages: { type: "array", items: { type: "object", additionalProperties: true } }, cursor: { type: "string" } }, required: ["messages"] }
|
|
470
|
-
}
|
|
471
|
-
] : [],
|
|
472
|
-
...deliveryToolsAvailable ? [
|
|
473
|
-
{
|
|
474
|
-
name: "claim",
|
|
475
|
-
description: "Atomically claim the next targeted delivery.",
|
|
476
|
-
inputSchema: { type: "object", properties: { leaseMs: { type: "number" }, maxAttempts: { type: "number" } }, additionalProperties: false },
|
|
477
|
-
outputSchema: { type: "object", additionalProperties: true }
|
|
478
|
-
},
|
|
479
|
-
...["extend", "acknowledge", "negative_acknowledge"].map((name) => ({
|
|
480
|
-
name,
|
|
481
|
-
description: `Agent Bridge v2 ${name.replace(/_/g, " ")} delivery operation.`,
|
|
482
|
-
inputSchema: {
|
|
483
|
-
type: "object",
|
|
484
|
-
properties: {
|
|
485
|
-
deliveryId: { type: "string" },
|
|
486
|
-
leaseToken: { type: "string" },
|
|
487
|
-
...name === "extend" ? { leaseMs: { type: "number" } } : {},
|
|
488
|
-
...name === "negative_acknowledge" ? { error: { type: "string" }, dead: { type: "boolean" }, retryPolicy: { type: "object", additionalProperties: true } } : {}
|
|
489
|
-
},
|
|
490
|
-
required: ["deliveryId", "leaseToken"],
|
|
491
|
-
additionalProperties: false
|
|
492
|
-
},
|
|
493
|
-
outputSchema: { type: "object", additionalProperties: true }
|
|
494
|
-
})),
|
|
495
|
-
{
|
|
496
|
-
name: "heartbeat",
|
|
497
|
-
description: "Publish a leased runtime presence record and capabilities.",
|
|
498
|
-
inputSchema: { type: "object", properties: {
|
|
499
|
-
leaseMs: { type: "number", minimum: 1e3, maximum: 9e5 },
|
|
500
|
-
runtimeType: { type: "string" },
|
|
501
|
-
capabilities: { type: "array", items: { type: "string" } }
|
|
502
|
-
}, additionalProperties: false },
|
|
503
|
-
outputSchema: { type: "object", additionalProperties: true }
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
name: "presence",
|
|
507
|
-
description: "List active agent runtime instances in this workspace.",
|
|
508
|
-
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
509
|
-
outputSchema: { type: "object", properties: { agents: { type: "array", items: { type: "object", additionalProperties: true } } }, required: ["agents"] }
|
|
510
|
-
}
|
|
511
|
-
] : []
|
|
512
|
-
]
|
|
513
|
-
}));
|
|
514
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
449
|
+
}
|
|
450
|
+
];
|
|
451
|
+
const canonical = service ? availableOperations({ surface: "mcp", provider }).map((operation) => ({
|
|
452
|
+
name: operation.mcp.name,
|
|
453
|
+
description: operation.summary,
|
|
454
|
+
inputSchema: operation.request,
|
|
455
|
+
outputSchema: operation.response
|
|
456
|
+
})) : [];
|
|
457
|
+
return { tools: [...legacyTools, ...canonical] };
|
|
458
|
+
});
|
|
459
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
515
460
|
const { name, arguments: args } = request.params;
|
|
461
|
+
const canonicalResult = (operationId, value) => {
|
|
462
|
+
const parsed = parseResponse(operationId, value);
|
|
463
|
+
return {
|
|
464
|
+
content: [{ type: "text", text: JSON.stringify(parsed) }],
|
|
465
|
+
...parsed !== null && typeof parsed === "object" ? { structuredContent: parsed } : {}
|
|
466
|
+
};
|
|
467
|
+
};
|
|
516
468
|
try {
|
|
517
469
|
switch (name) {
|
|
470
|
+
case "capabilities": {
|
|
471
|
+
validateRequest("capabilities", args ?? {});
|
|
472
|
+
return canonicalResult("capabilities", capabilityDocument({ surface: "mcp", provider }));
|
|
473
|
+
}
|
|
518
474
|
case "post_context": {
|
|
519
475
|
let source;
|
|
520
476
|
try {
|
|
@@ -530,40 +486,40 @@ function createAgentBridgeServer(config) {
|
|
|
530
486
|
e instanceof Error ? e.message : "source identity mismatch"
|
|
531
487
|
);
|
|
532
488
|
}
|
|
533
|
-
const
|
|
489
|
+
const project = validateProject(args?.project);
|
|
490
|
+
const postArgs = { ...args ?? {}, source, project };
|
|
534
491
|
const receiptId = normalizeReceiptId(args?.atrib_receipt_id);
|
|
535
492
|
const envelope = buildMessageEnvelope(postArgs, receiptId);
|
|
493
|
+
const draft = validateMessageDraft({
|
|
494
|
+
id: String(envelope.message_id),
|
|
495
|
+
project,
|
|
496
|
+
type: String(args?.kind ?? args?.category),
|
|
497
|
+
content: String(args?.content ?? ""),
|
|
498
|
+
contentType: String(args?.payload_mime ?? "text/plain"),
|
|
499
|
+
data: args?.payload,
|
|
500
|
+
targets: Array.isArray(args?.target_agents) ? args.target_agents.map(String) : [],
|
|
501
|
+
threadId: args?.thread_id,
|
|
502
|
+
replyToId: args?.reply_to_id,
|
|
503
|
+
priority: args?.priority ?? "info",
|
|
504
|
+
expiresAt: args?.expires_at,
|
|
505
|
+
atribReceiptId: receiptId,
|
|
506
|
+
informedBy: Array.isArray(args?.informed_by) ? args.informed_by.map(String) : [],
|
|
507
|
+
metadata: mergeEnvelopeMetadata(args?.metadata, envelope)
|
|
508
|
+
});
|
|
536
509
|
const body = {
|
|
537
510
|
source,
|
|
538
|
-
category:
|
|
539
|
-
content:
|
|
540
|
-
priority:
|
|
541
|
-
project:
|
|
542
|
-
metadata:
|
|
511
|
+
category: draft.type,
|
|
512
|
+
content: draft.content,
|
|
513
|
+
priority: draft.priority,
|
|
514
|
+
project: draft.project ?? null,
|
|
515
|
+
metadata: draft.metadata
|
|
543
516
|
};
|
|
544
517
|
if (receiptId) {
|
|
545
518
|
body.atrib_receipt_id = receiptId;
|
|
546
519
|
}
|
|
547
520
|
if (!supabaseRequest) {
|
|
548
521
|
if (!service || !principal) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
549
|
-
|
|
550
|
-
throw new McpError(ErrorCode.InvalidParams, "project must match AGENT_BRIDGE_WORKSPACE");
|
|
551
|
-
}
|
|
552
|
-
const result = await service.publish(principal, {
|
|
553
|
-
id: String(envelope.message_id),
|
|
554
|
-
type: String(args?.kind ?? args?.category),
|
|
555
|
-
content: String(args?.content ?? ""),
|
|
556
|
-
contentType: String(args?.payload_mime ?? "text/plain"),
|
|
557
|
-
data: args?.payload,
|
|
558
|
-
targets: Array.isArray(args?.target_agents) ? args.target_agents.map(String) : [],
|
|
559
|
-
threadId: args?.thread_id,
|
|
560
|
-
replyToId: args?.reply_to_id,
|
|
561
|
-
priority: args?.priority ?? "info",
|
|
562
|
-
expiresAt: args?.expires_at,
|
|
563
|
-
atribReceiptId: receiptId,
|
|
564
|
-
informedBy: Array.isArray(args?.informed_by) ? args.informed_by.map(String) : [],
|
|
565
|
-
metadata: body.metadata
|
|
566
|
-
});
|
|
522
|
+
const result = await service.publish(principal, draft);
|
|
567
523
|
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
|
|
568
524
|
}
|
|
569
525
|
if (!supabaseRequest) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
@@ -576,16 +532,18 @@ function createAgentBridgeServer(config) {
|
|
|
576
532
|
};
|
|
577
533
|
}
|
|
578
534
|
case "get_context": {
|
|
535
|
+
const project = validateProject(args?.project);
|
|
536
|
+
const contextArgs = { ...args ?? {}, project };
|
|
579
537
|
const rawLimit = args?.limit;
|
|
580
538
|
if (rawLimit !== void 0 && (typeof rawLimit !== "number" || !Number.isSafeInteger(rawLimit) || rawLimit < 1 || rawLimit > 200)) {
|
|
581
539
|
throw new McpError(ErrorCode.InvalidParams, "limit must be between 1 and 200");
|
|
582
540
|
}
|
|
583
541
|
const requestedLimit = rawLimit ?? 20;
|
|
542
|
+
if (args?.unacked_by !== void 0 && String(args.unacked_by) !== config.agent) {
|
|
543
|
+
throw new McpError(ErrorCode.InvalidParams, "unacked_by must equal the configured principal");
|
|
544
|
+
}
|
|
584
545
|
if (service && principal) {
|
|
585
546
|
if (!service || !principal) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
586
|
-
if (args?.project && String(args.project) !== principal.workspace) {
|
|
587
|
-
return { content: [{ type: "text", text: "[]" }], structuredContent: { entries: [] } };
|
|
588
|
-
}
|
|
589
547
|
if (args?.target_agent && String(args.target_agent) !== principal.agent) {
|
|
590
548
|
return { content: [{ type: "text", text: "[]" }], structuredContent: { entries: [] } };
|
|
591
549
|
}
|
|
@@ -593,8 +551,9 @@ function createAgentBridgeServer(config) {
|
|
|
593
551
|
limit: requestedLimit,
|
|
594
552
|
types: args?.kind ? [String(args.kind)] : args?.category ? [String(args.category)] : void 0,
|
|
595
553
|
source: args?.source ? String(args.source) : void 0,
|
|
554
|
+
project,
|
|
596
555
|
since: args?.since ? String(args.since) : void 0,
|
|
597
|
-
|
|
556
|
+
receiptState: "unread",
|
|
598
557
|
threadId: args?.thread_id ? String(args.thread_id) : void 0,
|
|
599
558
|
latest: true
|
|
600
559
|
});
|
|
@@ -604,7 +563,7 @@ function createAgentBridgeServer(config) {
|
|
|
604
563
|
category: message.type,
|
|
605
564
|
content: message.content,
|
|
606
565
|
priority: message.priority,
|
|
607
|
-
project: message.
|
|
566
|
+
project: message.project ?? null,
|
|
608
567
|
metadata: legacyContextMetadata(message),
|
|
609
568
|
atrib_receipt_id: message.atribReceiptId ?? null,
|
|
610
569
|
created_at: message.createdAt
|
|
@@ -613,10 +572,18 @@ function createAgentBridgeServer(config) {
|
|
|
613
572
|
const cacheMetadata = cachedResult.source ? {
|
|
614
573
|
source: cachedResult.source,
|
|
615
574
|
stale: Boolean(cachedResult.stale),
|
|
575
|
+
degraded: Boolean(cachedResult.degraded),
|
|
576
|
+
acknowledgements: cachedResult.acknowledgements ?? "authoritative",
|
|
616
577
|
lastSyncedAt: cachedResult.lastSyncedAt ?? null
|
|
617
578
|
} : {};
|
|
618
579
|
return {
|
|
619
|
-
content: [
|
|
580
|
+
content: [
|
|
581
|
+
{ type: "text", text: JSON.stringify(entries, null, 2) },
|
|
582
|
+
...cachedResult.stale || cachedResult.degraded ? [{
|
|
583
|
+
type: "text",
|
|
584
|
+
text: `WARNING: cached Agent Bridge context is ${cachedResult.stale ? "stale" : "degraded"}; acknowledgement authority is ${cachedResult.acknowledgements ?? "unknown"}.`
|
|
585
|
+
}] : []
|
|
586
|
+
],
|
|
620
587
|
structuredContent: { entries, ...cacheMetadata }
|
|
621
588
|
};
|
|
622
589
|
}
|
|
@@ -638,8 +605,8 @@ function createAgentBridgeServer(config) {
|
|
|
638
605
|
params.push(
|
|
639
606
|
`category=eq.${encodeURIComponent(String(args.category))}`
|
|
640
607
|
);
|
|
641
|
-
if (
|
|
642
|
-
params.push(`project=eq.${encodeURIComponent(
|
|
608
|
+
if (project)
|
|
609
|
+
params.push(`project=eq.${encodeURIComponent(project)}`);
|
|
643
610
|
const unackedBy = args?.unacked_by ?? config.agent;
|
|
644
611
|
if (unackedBy)
|
|
645
612
|
params.push(
|
|
@@ -649,9 +616,10 @@ function createAgentBridgeServer(config) {
|
|
|
649
616
|
const data = await supabaseRequest(
|
|
650
617
|
`/shared_context?${params.join("&")}`
|
|
651
618
|
);
|
|
652
|
-
const filtered = filterContextRows(data,
|
|
619
|
+
const filtered = filterContextRows(data, contextArgs, requestedLimit);
|
|
653
620
|
return {
|
|
654
|
-
content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }]
|
|
621
|
+
content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }],
|
|
622
|
+
structuredContent: { entries: filtered }
|
|
655
623
|
};
|
|
656
624
|
}
|
|
657
625
|
case "ack_context": {
|
|
@@ -696,66 +664,122 @@ function createAgentBridgeServer(config) {
|
|
|
696
664
|
}
|
|
697
665
|
case "send": {
|
|
698
666
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
667
|
+
const input = validateRequest("publish_message", args ?? {});
|
|
699
668
|
try {
|
|
700
|
-
resolvePostSource(
|
|
669
|
+
resolvePostSource(input.source, principal.agent);
|
|
701
670
|
} catch (error) {
|
|
702
671
|
throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : "source identity mismatch");
|
|
703
672
|
}
|
|
704
|
-
const
|
|
705
|
-
return
|
|
673
|
+
const { source: _source, ...draft } = input;
|
|
674
|
+
return canonicalResult("publish_message", await service.publish(principal, draft));
|
|
706
675
|
}
|
|
707
676
|
case "history": {
|
|
708
677
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
709
|
-
const
|
|
710
|
-
return
|
|
678
|
+
const input = validateRequest("history", args ?? {});
|
|
679
|
+
return canonicalResult("history", await service.history(principal, input));
|
|
680
|
+
}
|
|
681
|
+
case "sync": {
|
|
682
|
+
if (!store?.sync) throw new McpError(ErrorCode.InvalidParams, "sync is available only with the gateway provider");
|
|
683
|
+
const input = validateRequest("sync", args ?? {});
|
|
684
|
+
const result = await store.sync({
|
|
685
|
+
maxPush: input.maxPush,
|
|
686
|
+
maxPages: input.maxPages,
|
|
687
|
+
signal: extra.signal
|
|
688
|
+
});
|
|
689
|
+
return canonicalResult("sync", result);
|
|
711
690
|
}
|
|
712
691
|
case "claim": {
|
|
713
692
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
714
|
-
const
|
|
715
|
-
|
|
693
|
+
const input = validateRequest("claim_delivery", args ?? {});
|
|
694
|
+
const result = await service.claim(principal, {
|
|
695
|
+
leaseMs: input.leaseMs,
|
|
696
|
+
maxAttempts: input.maxAttempts
|
|
697
|
+
});
|
|
698
|
+
return canonicalResult("claim_delivery", result ?? { delivery: null });
|
|
699
|
+
}
|
|
700
|
+
case "list_deliveries":
|
|
701
|
+
case "list_delivery_events":
|
|
702
|
+
case "cancel_delivery":
|
|
703
|
+
case "requeue_delivery": {
|
|
704
|
+
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
705
|
+
const operationId = name === "list_deliveries" ? "list_deliveries" : name === "list_delivery_events" ? "list_delivery_events" : name === "cancel_delivery" ? "cancel_delivery" : "requeue_delivery";
|
|
706
|
+
const input = validateRequest(operationId, args ?? {});
|
|
707
|
+
const result = name === "list_deliveries" ? await service.deliveries(principal, input) : name === "list_delivery_events" ? await service.deliveryEvents(principal, String(input.deliveryId), input) : name === "cancel_delivery" ? await service.cancel(principal, String(input.deliveryId)) : await service.requeue(principal, String(input.deliveryId));
|
|
708
|
+
return canonicalResult(operationId, name === "list_deliveries" || name === "list_delivery_events" ? result : { delivery: result });
|
|
716
709
|
}
|
|
717
710
|
case "extend":
|
|
718
711
|
case "acknowledge":
|
|
719
712
|
case "negative_acknowledge": {
|
|
720
713
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
721
|
-
const
|
|
722
|
-
const
|
|
714
|
+
const operationId = name === "extend" ? "extend_delivery" : name === "acknowledge" ? "acknowledge_delivery" : "negative_acknowledge_delivery";
|
|
715
|
+
const input = validateRequest(operationId, args ?? {});
|
|
716
|
+
const id = String(input.deliveryId), token = String(input.leaseToken);
|
|
717
|
+
const result = name === "extend" ? await service.extend(principal, id, token, input.leaseMs) : name === "acknowledge" ? await service.ack(principal, id, token) : await service.nack(
|
|
723
718
|
principal,
|
|
724
719
|
id,
|
|
725
720
|
token,
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
721
|
+
input.error,
|
|
722
|
+
input.disposition ?? input.dead ?? "retry",
|
|
723
|
+
input.retryPolicy
|
|
729
724
|
);
|
|
730
|
-
return
|
|
725
|
+
return canonicalResult(operationId, { delivery: result });
|
|
731
726
|
}
|
|
732
727
|
case "heartbeat": {
|
|
733
728
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
729
|
+
const input = validateRequest("heartbeat", args ?? {});
|
|
734
730
|
const result = await service.heartbeat(principal, {
|
|
735
|
-
leaseMs:
|
|
736
|
-
runtimeType:
|
|
737
|
-
capabilities:
|
|
731
|
+
leaseMs: input.leaseMs,
|
|
732
|
+
runtimeType: input.runtimeType,
|
|
733
|
+
capabilities: input.capabilities
|
|
738
734
|
});
|
|
739
|
-
return
|
|
735
|
+
return canonicalResult("heartbeat", result);
|
|
740
736
|
}
|
|
741
737
|
case "presence": {
|
|
742
738
|
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
739
|
+
validateRequest("presence", args ?? {});
|
|
743
740
|
const result = { agents: await service.presence(principal) };
|
|
744
|
-
return
|
|
741
|
+
return canonicalResult("presence", result);
|
|
745
742
|
}
|
|
746
743
|
default:
|
|
747
744
|
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
748
745
|
}
|
|
749
746
|
} catch (error) {
|
|
750
747
|
if (error instanceof McpError) throw error;
|
|
751
|
-
if (error instanceof BridgeValidationError) {
|
|
748
|
+
if (error instanceof ContractValidationError || error instanceof BridgeValidationError || error instanceof BridgePrincipalMismatchError) {
|
|
752
749
|
throw new McpError(ErrorCode.InvalidParams, error.message);
|
|
753
750
|
}
|
|
754
751
|
throw error;
|
|
755
752
|
}
|
|
756
753
|
});
|
|
754
|
+
let initialization;
|
|
755
|
+
const initializeStore = () => initialization ?? (initialization = clientConfig?.provider === "gateway" ? store?.initialize() ?? Promise.resolve() : Promise.resolve());
|
|
756
|
+
let closure;
|
|
757
|
+
const closeStore = () => closure ?? (closure = store?.close?.() ?? Promise.resolve());
|
|
758
|
+
const connect = server.connect.bind(server);
|
|
759
|
+
server.connect = async (transport) => {
|
|
760
|
+
await initializeStore();
|
|
761
|
+
await connect(transport);
|
|
762
|
+
};
|
|
763
|
+
const close = server.close.bind(server);
|
|
764
|
+
server.close = async () => {
|
|
765
|
+
let transportError;
|
|
766
|
+
try {
|
|
767
|
+
await close();
|
|
768
|
+
} catch (error) {
|
|
769
|
+
transportError = error;
|
|
770
|
+
}
|
|
771
|
+
try {
|
|
772
|
+
await closeStore();
|
|
773
|
+
} catch (error) {
|
|
774
|
+
if (transportError) throw Object.assign(new Error("failed to close Agent Bridge server"), {
|
|
775
|
+
errors: [transportError, error]
|
|
776
|
+
});
|
|
777
|
+
throw error;
|
|
778
|
+
}
|
|
779
|
+
if (transportError) throw transportError;
|
|
780
|
+
};
|
|
757
781
|
server.onclose = () => {
|
|
758
|
-
void
|
|
782
|
+
void closeStore().catch((error) => server.onerror?.(error instanceof Error ? error : new Error(String(error))));
|
|
759
783
|
};
|
|
760
784
|
return server;
|
|
761
785
|
}
|
|
@@ -766,8 +790,9 @@ async function startServer(config = configFromEnv()) {
|
|
|
766
790
|
}
|
|
767
791
|
|
|
768
792
|
export {
|
|
793
|
+
MCP_IMPLEMENTATION_VERSION,
|
|
769
794
|
configFromEnv,
|
|
770
795
|
createAgentBridgeServer,
|
|
771
796
|
startServer
|
|
772
797
|
};
|
|
773
|
-
//# sourceMappingURL=chunk-
|
|
798
|
+
//# sourceMappingURL=chunk-SPSMZOCJ.js.map
|