@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.
Files changed (115) hide show
  1. package/CHANGELOG.md +86 -4
  2. package/README.md +567 -55
  3. package/ROADMAP.md +114 -0
  4. package/SECURITY.md +90 -0
  5. package/SKILL.md +68 -2
  6. package/bin/agent-bridge +2 -2
  7. package/clients/claude-desktop.json +3 -1
  8. package/dist/archive.d.ts +163 -0
  9. package/dist/archive.js +50 -0
  10. package/dist/archive.js.map +1 -0
  11. package/dist/bridge-domain-CBX3IVqC.d.ts +153 -0
  12. package/dist/{bridge-service-CfqMcMAn.d.ts → bridge-service-hX1ZQp4W.d.ts} +15 -5
  13. package/dist/bridge-store-DPVSCwfs.d.ts +102 -0
  14. package/dist/bridge.d.ts +76 -17
  15. package/dist/bridge.js +52 -24
  16. package/dist/chunk-2DFNOLMO.js +618 -0
  17. package/dist/chunk-2DFNOLMO.js.map +1 -0
  18. package/dist/{chunk-KVR4JBRF.js → chunk-2EVLG3YA.js} +2 -2
  19. package/dist/{chunk-KVR4JBRF.js.map → chunk-2EVLG3YA.js.map} +1 -1
  20. package/dist/chunk-45BZGB77.js +709 -0
  21. package/dist/chunk-45BZGB77.js.map +1 -0
  22. package/dist/chunk-4VB44KJU.js +230 -0
  23. package/dist/chunk-4VB44KJU.js.map +1 -0
  24. package/dist/chunk-5GMB3A77.js +1013 -0
  25. package/dist/chunk-5GMB3A77.js.map +1 -0
  26. package/dist/chunk-A6W4QALF.js +1258 -0
  27. package/dist/chunk-A6W4QALF.js.map +1 -0
  28. package/dist/chunk-BZLMF5O5.js +328 -0
  29. package/dist/chunk-BZLMF5O5.js.map +1 -0
  30. package/dist/{chunk-AXL2I7FH.js → chunk-CEXBMOI5.js} +240 -79
  31. package/dist/chunk-CEXBMOI5.js.map +1 -0
  32. package/dist/chunk-GADH244D.js +527 -0
  33. package/dist/chunk-GADH244D.js.map +1 -0
  34. package/dist/chunk-MBPZXTJA.js +2428 -0
  35. package/dist/chunk-MBPZXTJA.js.map +1 -0
  36. package/dist/chunk-NCO7RLBM.js +146 -0
  37. package/dist/chunk-NCO7RLBM.js.map +1 -0
  38. package/dist/chunk-Q6PPMXJC.js +1050 -0
  39. package/dist/chunk-Q6PPMXJC.js.map +1 -0
  40. package/dist/{chunk-4KAOBC5X.js → chunk-SPSMZOCJ.js} +190 -165
  41. package/dist/chunk-SPSMZOCJ.js.map +1 -0
  42. package/dist/chunk-UAHMP6GC.js +54 -0
  43. package/dist/chunk-UAHMP6GC.js.map +1 -0
  44. package/dist/{chunk-YD6YJATN.js → chunk-VOQIDTCJ.js} +4 -2
  45. package/dist/chunk-VOQIDTCJ.js.map +1 -0
  46. package/dist/chunk-WAI2IYIQ.js +554 -0
  47. package/dist/chunk-WAI2IYIQ.js.map +1 -0
  48. package/dist/cli.d.ts +2 -1
  49. package/dist/cli.js +3555 -214
  50. package/dist/cli.js.map +1 -1
  51. package/dist/client-config.d.ts +1 -1
  52. package/dist/client-config.js +1 -1
  53. package/dist/client-runtime.d.ts +10 -6
  54. package/dist/client-runtime.js +9 -6
  55. package/dist/contracts/generate.d.ts +2 -0
  56. package/dist/contracts/generate.js +247 -0
  57. package/dist/contracts/generate.js.map +1 -0
  58. package/dist/dr.d.ts +324 -0
  59. package/dist/dr.js +124 -0
  60. package/dist/dr.js.map +1 -0
  61. package/dist/gateway-CggQ8vTC.d.ts +78 -0
  62. package/dist/gateway-main.js +190 -8
  63. package/dist/gateway-main.js.map +1 -1
  64. package/dist/gateway.d.ts +4 -3
  65. package/dist/gateway.js +4 -3
  66. package/dist/index.js +11 -8
  67. package/dist/index.js.map +1 -1
  68. package/dist/postgres-bridge-store-Bfd3hRId.d.ts +49 -0
  69. package/dist/server.d.ts +3 -2
  70. package/dist/server.js +13 -8
  71. package/dist/sqlite.d.ts +94 -12
  72. package/dist/sqlite.js +7 -4
  73. package/docs/architecture-v2.md +394 -0
  74. package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +85 -0
  75. package/docs/decisions/0002-canonical-operation-contract-registry.md +46 -0
  76. package/docs/decisions/0003-host-adapters-and-consumer-instance-keys.md +88 -0
  77. package/docs/ecosystem.md +86 -0
  78. package/docs/postmortems/2026-07-08-wrapper-source-drift.md +82 -0
  79. package/docs/troubleshooting.md +89 -0
  80. package/llms.txt +107 -6
  81. package/openapi/agent-bridge-v2.openapi.json +9610 -0
  82. package/package.json +24 -4
  83. package/schemas/agent-bridge-v2.capabilities.json +1829 -0
  84. package/schemas/agent-bridge-v2.mcp.json +2074 -0
  85. package/schemas/agent-bridge-v2.schema.json +4560 -0
  86. package/sql/migrations/008_message_projects.sql +36 -0
  87. package/sql/migrations/009_mailbox_query_indexes.sql +28 -0
  88. package/sql/migrations/010_publisher_delivery_policy.sql +210 -0
  89. package/sql/migrations/011_credential_security.sql +875 -0
  90. package/sql/migrations/012_request_authority.sql +177 -0
  91. package/sql/migrations/013_row_isolation.sql +495 -0
  92. package/sql/migrations/014_owner_control_plane.sql +1641 -0
  93. package/sql/migrations/015_portable_archives.sql +1813 -0
  94. package/sql/migrations/016_native_dr_fence.sql +1005 -0
  95. package/bin/CLAUDE.md +0 -11
  96. package/dist/bridge-domain-BcnBeHOn.d.ts +0 -97
  97. package/dist/bridge-store-BuGjxTn4.d.ts +0 -61
  98. package/dist/chunk-4KAOBC5X.js.map +0 -1
  99. package/dist/chunk-6MAZ6YLZ.js +0 -146
  100. package/dist/chunk-6MAZ6YLZ.js.map +0 -1
  101. package/dist/chunk-AXL2I7FH.js.map +0 -1
  102. package/dist/chunk-BV6W4AJK.js +0 -211
  103. package/dist/chunk-BV6W4AJK.js.map +0 -1
  104. package/dist/chunk-CKSKUBDQ.js +0 -153
  105. package/dist/chunk-CKSKUBDQ.js.map +0 -1
  106. package/dist/chunk-JOUBDRYX.js +0 -272
  107. package/dist/chunk-JOUBDRYX.js.map +0 -1
  108. package/dist/chunk-JTC5YURG.js +0 -49
  109. package/dist/chunk-JTC5YURG.js.map +0 -1
  110. package/dist/chunk-O26W5QHS.js +0 -409
  111. package/dist/chunk-O26W5QHS.js.map +0 -1
  112. package/dist/chunk-WEULPMUY.js +0 -988
  113. package/dist/chunk-WEULPMUY.js.map +0 -1
  114. package/dist/chunk-YD6YJATN.js.map +0 -1
  115. package/dist/gateway-BULozv3K.d.ts +0 -54
@@ -2,21 +2,32 @@
2
2
  import {
3
3
  readClientConfigFile,
4
4
  resolveClientConfig
5
- } from "./chunk-KVR4JBRF.js";
5
+ } from "./chunk-2EVLG3YA.js";
6
6
  import {
7
7
  createStore
8
- } from "./chunk-JTC5YURG.js";
8
+ } from "./chunk-UAHMP6GC.js";
9
9
  import {
10
10
  legacyContextMetadata,
11
11
  legacyNumericMessageId
12
- } from "./chunk-AXL2I7FH.js";
12
+ } from "./chunk-CEXBMOI5.js";
13
13
  import {
14
14
  BridgeService
15
- } from "./chunk-CKSKUBDQ.js";
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
- } from "./chunk-BV6W4AJK.js";
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) ?? randomUUID();
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 packageVersion = createRequire(import.meta.url)("../package.json").version;
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 principal = config.agent ? { workspace: config.workspace ?? "default", agent: config.agent, instance: config.instance } : void 0;
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: config.provider ?? (config.gatewayToken ? "gateway" : config.supabaseUrl ? "legacy-supabase" : "local"),
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: packageVersion },
275
+ { name: "agent-bridge", version: MCP_IMPLEMENTATION_VERSION },
265
276
  { capabilities: { tools: {} } }
266
277
  );
267
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
268
- tools: [
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: "Scope to a project (e.g. project-a, project-b). Omit for cross-project."
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 scope"
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
- ...service ? [
427
- {
428
- name: "send",
429
- description: "Create an immutable Agent Bridge v2 message.",
430
- inputSchema: {
431
- type: "object",
432
- properties: {
433
- source: { type: "string", description: "Optional identity assertion; must match AGENT_BRIDGE_AGENT." },
434
- type: { type: "string" },
435
- content: { type: "string" },
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 postArgs = { ...args ?? {}, source };
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: args?.category,
539
- content: args?.content,
540
- priority: args?.priority || "info",
541
- project: args?.project || null,
542
- metadata: mergeEnvelopeMetadata(args?.metadata, envelope)
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
- if (args?.project && String(args.project) !== principal.workspace) {
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
- unacknowledgedBy: args?.unacked_by ? String(args.unacked_by) : config.agent,
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.workspace,
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: [{ type: "text", text: JSON.stringify(entries, null, 2) }],
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 (args?.project)
642
- params.push(`project=eq.${encodeURIComponent(String(args.project))}`);
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, args, requestedLimit);
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(args?.source, principal.agent);
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 result = await service.publish(principal, args);
705
- return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
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 result = await service.history(principal, args ?? {});
710
- return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
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 result = await service.claim(principal, { leaseMs: args?.leaseMs, maxAttempts: args?.maxAttempts });
715
- return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result ?? { delivery: null } };
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 id = String(args?.deliveryId ?? ""), token = String(args?.leaseToken ?? "");
722
- const result = name === "extend" ? await service.extend(principal, id, token, args?.leaseMs) : name === "acknowledge" ? await service.ack(principal, id, token) : await service.nack(
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
- args?.error ?? "negative acknowledgment",
727
- args?.dead ?? false,
728
- args?.retryPolicy
721
+ input.error,
722
+ input.disposition ?? input.dead ?? "retry",
723
+ input.retryPolicy
729
724
  );
730
- return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result ?? { delivery: null } };
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: args?.leaseMs,
736
- runtimeType: args?.runtimeType,
737
- capabilities: args?.capabilities
731
+ leaseMs: input.leaseMs,
732
+ runtimeType: input.runtimeType,
733
+ capabilities: input.capabilities
738
734
  });
739
- return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
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 { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
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 store?.close?.();
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-4KAOBC5X.js.map
798
+ //# sourceMappingURL=chunk-SPSMZOCJ.js.map