@creatornader/agent-bridge 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/LICENSE +216 -0
- package/README.md +338 -0
- package/SKILL.md +24 -0
- package/bin/CLAUDE.md +11 -0
- package/bin/agent-bridge +7 -0
- package/clients/claude-code.json +20 -0
- package/clients/claude-desktop.json +20 -0
- package/clients/codex.json +20 -0
- package/clients/generic-mcp.json +13 -0
- package/clients/openclaw.json +13 -0
- package/dist/bridge-domain-BcnBeHOn.d.ts +97 -0
- package/dist/bridge-service-CfqMcMAn.d.ts +28 -0
- package/dist/bridge-store-BuGjxTn4.d.ts +61 -0
- package/dist/bridge.d.ts +102 -0
- package/dist/bridge.js +83 -0
- package/dist/bridge.js.map +1 -0
- package/dist/chunk-4KAOBC5X.js +773 -0
- package/dist/chunk-4KAOBC5X.js.map +1 -0
- package/dist/chunk-6MAZ6YLZ.js +146 -0
- package/dist/chunk-6MAZ6YLZ.js.map +1 -0
- package/dist/chunk-AXL2I7FH.js +423 -0
- package/dist/chunk-AXL2I7FH.js.map +1 -0
- package/dist/chunk-BV6W4AJK.js +211 -0
- package/dist/chunk-BV6W4AJK.js.map +1 -0
- package/dist/chunk-CKSKUBDQ.js +153 -0
- package/dist/chunk-CKSKUBDQ.js.map +1 -0
- package/dist/chunk-JOUBDRYX.js +272 -0
- package/dist/chunk-JOUBDRYX.js.map +1 -0
- package/dist/chunk-JTC5YURG.js +49 -0
- package/dist/chunk-JTC5YURG.js.map +1 -0
- package/dist/chunk-KVR4JBRF.js +80 -0
- package/dist/chunk-KVR4JBRF.js.map +1 -0
- package/dist/chunk-O26W5QHS.js +409 -0
- package/dist/chunk-O26W5QHS.js.map +1 -0
- package/dist/chunk-WEULPMUY.js +988 -0
- package/dist/chunk-WEULPMUY.js.map +1 -0
- package/dist/chunk-YD6YJATN.js +48 -0
- package/dist/chunk-YD6YJATN.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +670 -0
- package/dist/cli.js.map +1 -0
- package/dist/client-config.d.ts +30 -0
- package/dist/client-config.js +10 -0
- package/dist/client-config.js.map +1 -0
- package/dist/client-runtime.d.ts +15 -0
- package/dist/client-runtime.js +15 -0
- package/dist/client-runtime.js.map +1 -0
- package/dist/gateway-BULozv3K.d.ts +54 -0
- package/dist/gateway-main.d.ts +2 -0
- package/dist/gateway-main.js +105 -0
- package/dist/gateway-main.js.map +1 -0
- package/dist/gateway.d.ts +4 -0
- package/dist/gateway.js +10 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +34 -0
- package/dist/server.js +19 -0
- package/dist/server.js.map +1 -0
- package/dist/sqlite.d.ts +156 -0
- package/dist/sqlite.js +24 -0
- package/dist/sqlite.js.map +1 -0
- package/llms.txt +39 -0
- package/package.json +104 -0
- package/sql/migrations/001_schema_state.sql +34 -0
- package/sql/migrations/002_workspaces_agents_credentials.sql +77 -0
- package/sql/migrations/003_messages_receipts_deliveries.sql +116 -0
- package/sql/migrations/004_message_query_indexes.sql +31 -0
- package/sql/migrations/005_delivery_events_presence.sql +79 -0
- package/sql/migrations/006_legacy_shared_context_import.sql +139 -0
- package/sql/migrations/007_runtime_role.sql +59 -0
- package/sql/setup.sql +68 -0
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
readClientConfigFile,
|
|
4
|
+
resolveClientConfig
|
|
5
|
+
} from "./chunk-KVR4JBRF.js";
|
|
6
|
+
import {
|
|
7
|
+
createStore
|
|
8
|
+
} from "./chunk-JTC5YURG.js";
|
|
9
|
+
import {
|
|
10
|
+
legacyContextMetadata,
|
|
11
|
+
legacyNumericMessageId
|
|
12
|
+
} from "./chunk-AXL2I7FH.js";
|
|
13
|
+
import {
|
|
14
|
+
BridgeService
|
|
15
|
+
} from "./chunk-CKSKUBDQ.js";
|
|
16
|
+
import {
|
|
17
|
+
BridgeValidationError,
|
|
18
|
+
normalizeReceiptId
|
|
19
|
+
} from "./chunk-BV6W4AJK.js";
|
|
20
|
+
|
|
21
|
+
// src/server.ts
|
|
22
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
23
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
24
|
+
import {
|
|
25
|
+
CallToolRequestSchema,
|
|
26
|
+
ErrorCode,
|
|
27
|
+
ListToolsRequestSchema,
|
|
28
|
+
McpError
|
|
29
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
30
|
+
import { homedir } from "os";
|
|
31
|
+
import { createRequire } from "module";
|
|
32
|
+
import { join } from "path";
|
|
33
|
+
|
|
34
|
+
// src/message-envelope.ts
|
|
35
|
+
import { randomUUID } from "crypto";
|
|
36
|
+
var MESSAGE_ENVELOPE_SCHEMA = "agent-bridge.message-envelope.v1";
|
|
37
|
+
var RECORD_HASH_RE = /^sha256:[a-f0-9]{64}$/i;
|
|
38
|
+
function isRecord(value) {
|
|
39
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40
|
+
}
|
|
41
|
+
function normalizeString(value) {
|
|
42
|
+
if (typeof value !== "string") return void 0;
|
|
43
|
+
const trimmed = value.trim();
|
|
44
|
+
return trimmed ? trimmed : void 0;
|
|
45
|
+
}
|
|
46
|
+
function normalizeStringList(value) {
|
|
47
|
+
const raw = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
for (const item of raw) {
|
|
50
|
+
const normalized = normalizeString(item);
|
|
51
|
+
if (normalized) seen.add(normalized);
|
|
52
|
+
}
|
|
53
|
+
return seen.size ? [...seen] : void 0;
|
|
54
|
+
}
|
|
55
|
+
function normalizeRecordHashes(value) {
|
|
56
|
+
const raw = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
|
|
57
|
+
const seen = /* @__PURE__ */ new Set();
|
|
58
|
+
for (const item of raw) {
|
|
59
|
+
const normalized = normalizeString(item);
|
|
60
|
+
if (normalized && RECORD_HASH_RE.test(normalized)) {
|
|
61
|
+
seen.add(normalized.toLowerCase());
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return seen.size ? [...seen] : void 0;
|
|
65
|
+
}
|
|
66
|
+
function normalizeIsoTimestamp(value) {
|
|
67
|
+
const text = normalizeString(value);
|
|
68
|
+
if (!text) return void 0;
|
|
69
|
+
const parsed = Date.parse(text);
|
|
70
|
+
if (Number.isNaN(parsed)) return void 0;
|
|
71
|
+
return new Date(parsed).toISOString();
|
|
72
|
+
}
|
|
73
|
+
function normalizeMetadata(value) {
|
|
74
|
+
return isRecord(value) ? { ...value } : {};
|
|
75
|
+
}
|
|
76
|
+
function buildMessageEnvelope(args, receiptId) {
|
|
77
|
+
const source = normalizeString(args?.source) ?? "unknown";
|
|
78
|
+
const category = normalizeString(args?.category);
|
|
79
|
+
const kind = normalizeString(args?.kind) ?? category ?? "operational";
|
|
80
|
+
const messageId = normalizeString(args?.message_id) ?? randomUUID();
|
|
81
|
+
const envelope = {
|
|
82
|
+
schema: MESSAGE_ENVELOPE_SCHEMA,
|
|
83
|
+
message_id: messageId,
|
|
84
|
+
source_agent: source,
|
|
85
|
+
kind,
|
|
86
|
+
priority: normalizeString(args?.priority) ?? "info",
|
|
87
|
+
payload_mime: normalizeString(args?.payload_mime) ?? "text/plain"
|
|
88
|
+
};
|
|
89
|
+
const targetAgents = normalizeStringList(args?.target_agents);
|
|
90
|
+
if (targetAgents) envelope.target_agents = targetAgents;
|
|
91
|
+
const project = normalizeString(args?.project);
|
|
92
|
+
if (project) envelope.project = project;
|
|
93
|
+
const threadId = normalizeString(args?.thread_id);
|
|
94
|
+
if (threadId) envelope.thread_id = threadId;
|
|
95
|
+
const replyToId = normalizeString(args?.reply_to_id);
|
|
96
|
+
if (replyToId) envelope.reply_to_id = replyToId;
|
|
97
|
+
if (Object.prototype.hasOwnProperty.call(args ?? {}, "payload")) {
|
|
98
|
+
envelope.payload = args?.payload;
|
|
99
|
+
}
|
|
100
|
+
const payloadRef = normalizeString(args?.payload_ref);
|
|
101
|
+
if (payloadRef) envelope.payload_ref = payloadRef;
|
|
102
|
+
const payloadCiphertext = normalizeString(args?.payload_ciphertext);
|
|
103
|
+
if (payloadCiphertext) envelope.payload_ciphertext = payloadCiphertext;
|
|
104
|
+
if (receiptId) envelope.atrib_receipt_id = receiptId;
|
|
105
|
+
const informedBy = normalizeRecordHashes(args?.informed_by);
|
|
106
|
+
if (informedBy) envelope.informed_by = informedBy;
|
|
107
|
+
const expiresAt = normalizeIsoTimestamp(args?.expires_at);
|
|
108
|
+
if (expiresAt) envelope.expires_at = expiresAt;
|
|
109
|
+
return envelope;
|
|
110
|
+
}
|
|
111
|
+
function mergeEnvelopeMetadata(metadataInput, envelope) {
|
|
112
|
+
return {
|
|
113
|
+
...normalizeMetadata(metadataInput),
|
|
114
|
+
message_envelope: envelope
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function getEnvelope(row) {
|
|
118
|
+
if (!isRecord(row)) return void 0;
|
|
119
|
+
const metadata = row.metadata;
|
|
120
|
+
if (!isRecord(metadata)) return void 0;
|
|
121
|
+
const envelope = metadata.message_envelope;
|
|
122
|
+
return isRecord(envelope) ? envelope : void 0;
|
|
123
|
+
}
|
|
124
|
+
function rowMatchesMessageFilters(row, filters) {
|
|
125
|
+
const targetAgent = normalizeString(filters?.target_agent);
|
|
126
|
+
const threadId = normalizeString(filters?.thread_id);
|
|
127
|
+
const kind = normalizeString(filters?.kind);
|
|
128
|
+
if (!targetAgent && !threadId && !kind) return true;
|
|
129
|
+
const envelope = getEnvelope(row);
|
|
130
|
+
if (!envelope) {
|
|
131
|
+
return !threadId && !kind;
|
|
132
|
+
}
|
|
133
|
+
if (targetAgent) {
|
|
134
|
+
const targets = normalizeStringList(envelope.target_agents);
|
|
135
|
+
if (targets && !targets.includes(targetAgent)) return false;
|
|
136
|
+
}
|
|
137
|
+
if (threadId && normalizeString(envelope.thread_id) !== threadId) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (kind && normalizeString(envelope.kind) !== kind) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
function filterContextRows(rows, filters, limit) {
|
|
146
|
+
if (!Array.isArray(rows)) return rows;
|
|
147
|
+
return rows.filter((row) => rowMatchesMessageFilters(row, filters)).slice(0, limit);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/source-identity.ts
|
|
151
|
+
function normalizeSource(value) {
|
|
152
|
+
if (typeof value !== "string") return void 0;
|
|
153
|
+
const trimmed = value.trim();
|
|
154
|
+
return trimmed ? trimmed : void 0;
|
|
155
|
+
}
|
|
156
|
+
function resolveAgentIdentity(requestedAgent, configuredAgent, field = "agent") {
|
|
157
|
+
const requested = normalizeSource(requestedAgent);
|
|
158
|
+
const configured = normalizeSource(configuredAgent);
|
|
159
|
+
if (requested && configured && requested !== configured) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`${field} must match AGENT_BRIDGE_AGENT (${configured}); got ${requested}`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return requested ?? configured;
|
|
165
|
+
}
|
|
166
|
+
function resolvePostSource(requestedSource, configuredAgent) {
|
|
167
|
+
return resolveAgentIdentity(requestedSource, configuredAgent, "source");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/server.ts
|
|
171
|
+
var packageVersion = createRequire(import.meta.url)("../package.json").version;
|
|
172
|
+
function normalizedConfigValue(value) {
|
|
173
|
+
const trimmed = value?.trim();
|
|
174
|
+
return trimmed || void 0;
|
|
175
|
+
}
|
|
176
|
+
function defaultConfigPath(env) {
|
|
177
|
+
return normalizedConfigValue(env.AGENT_BRIDGE_CONFIG) ?? join(normalizedConfigValue(env.HOME) ?? homedir(), ".agent-bridge", "config");
|
|
178
|
+
}
|
|
179
|
+
function configFromEnv(env = process.env) {
|
|
180
|
+
const sharedFile = readClientConfigFile(defaultConfigPath(env));
|
|
181
|
+
const value = (key) => normalizedConfigValue(env[key]) ?? normalizedConfigValue(sharedFile[key]);
|
|
182
|
+
const runtimeAgent = normalizedConfigValue(env.AGENT_BRIDGE_AGENT);
|
|
183
|
+
const rawProvider = normalizedConfigValue(env.AGENT_BRIDGE_PROVIDER) ?? normalizedConfigValue(sharedFile.AGENT_BRIDGE_PROVIDER);
|
|
184
|
+
const provider = rawProvider === "legacy" || rawProvider === "supabase" ? "legacy-supabase" : rawProvider ?? (value("AGENT_BRIDGE_TOKEN") ? "gateway" : "legacy-supabase");
|
|
185
|
+
if (!["local", "gateway", "legacy-supabase"].includes(provider)) {
|
|
186
|
+
throw new Error(`Unsupported AGENT_BRIDGE_PROVIDER: ${rawProvider}`);
|
|
187
|
+
}
|
|
188
|
+
if (provider === "local" || provider === "gateway") {
|
|
189
|
+
const client = resolveClientConfig(env);
|
|
190
|
+
return {
|
|
191
|
+
provider: client.provider,
|
|
192
|
+
agent: client.principal.agent,
|
|
193
|
+
workspace: client.principal.workspace,
|
|
194
|
+
instance: client.principal.instance,
|
|
195
|
+
databasePath: client.databasePath,
|
|
196
|
+
edgeDatabasePath: client.edgeDatabasePath,
|
|
197
|
+
cursorPath: client.cursorPath,
|
|
198
|
+
gatewayUrl: client.provider === "gateway" ? client.url : void 0,
|
|
199
|
+
gatewayToken: client.provider === "gateway" ? client.credential : void 0
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const supabaseUrl = value("AGENT_BRIDGE_URL");
|
|
203
|
+
const supabaseKey = value("AGENT_BRIDGE_KEY");
|
|
204
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
"Missing AGENT_BRIDGE_URL or AGENT_BRIDGE_KEY environment variables or ~/.agent-bridge/config"
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
supabaseUrl,
|
|
211
|
+
supabaseKey,
|
|
212
|
+
agent: runtimeAgent,
|
|
213
|
+
provider,
|
|
214
|
+
workspace: value("AGENT_BRIDGE_WORKSPACE") ?? "*",
|
|
215
|
+
instance: normalizedConfigValue(env.AGENT_BRIDGE_INSTANCE)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function buildSupabaseRequest(config) {
|
|
219
|
+
const parsed = new URL(config.supabaseUrl);
|
|
220
|
+
const loopback = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]";
|
|
221
|
+
if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && loopback)) {
|
|
222
|
+
throw new Error("Agent Bridge requires HTTPS for non-loopback legacy providers");
|
|
223
|
+
}
|
|
224
|
+
const restUrl = `${config.supabaseUrl.replace(/\/$/, "")}/rest/v1`;
|
|
225
|
+
const headers = {
|
|
226
|
+
apikey: config.supabaseKey,
|
|
227
|
+
Authorization: `Bearer ${config.supabaseKey}`,
|
|
228
|
+
"Content-Type": "application/json",
|
|
229
|
+
Prefer: "return=representation"
|
|
230
|
+
};
|
|
231
|
+
return async function supabaseRequest(path, options = {}) {
|
|
232
|
+
const url = `${restUrl}${path}`;
|
|
233
|
+
const res = await fetch(url, {
|
|
234
|
+
...options,
|
|
235
|
+
signal: options.signal ?? AbortSignal.timeout(1e4),
|
|
236
|
+
headers: { ...headers, ...options.headers }
|
|
237
|
+
});
|
|
238
|
+
if (!res.ok) {
|
|
239
|
+
throw new Error(`Supabase request failed (${res.status})`);
|
|
240
|
+
}
|
|
241
|
+
const text = await res.text();
|
|
242
|
+
return text ? JSON.parse(text) : null;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function createAgentBridgeServer(config) {
|
|
246
|
+
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;
|
|
248
|
+
const clientConfig = principal ? {
|
|
249
|
+
provider: config.provider ?? (config.gatewayToken ? "gateway" : config.supabaseUrl ? "legacy-supabase" : "local"),
|
|
250
|
+
principal,
|
|
251
|
+
url: config.gatewayUrl ?? config.supabaseUrl,
|
|
252
|
+
credential: config.gatewayToken ?? config.supabaseKey,
|
|
253
|
+
databasePath: config.databasePath ?? ":memory:",
|
|
254
|
+
edgeDatabasePath: config.edgeDatabasePath ?? config.databasePath ?? ":memory:",
|
|
255
|
+
cursorPath: config.cursorPath ?? "",
|
|
256
|
+
configPath: ""
|
|
257
|
+
} : void 0;
|
|
258
|
+
const store = clientConfig ? createStore(clientConfig) : void 0;
|
|
259
|
+
const service = store ? new BridgeService(store) : void 0;
|
|
260
|
+
const deliveryToolsAvailable = Boolean(
|
|
261
|
+
service && clientConfig?.provider !== "legacy-supabase"
|
|
262
|
+
);
|
|
263
|
+
const server = new Server(
|
|
264
|
+
{ name: "agent-bridge", version: packageVersion },
|
|
265
|
+
{ capabilities: { tools: {} } }
|
|
266
|
+
);
|
|
267
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
268
|
+
tools: [
|
|
269
|
+
{
|
|
270
|
+
name: "post_context",
|
|
271
|
+
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).",
|
|
272
|
+
inputSchema: {
|
|
273
|
+
type: "object",
|
|
274
|
+
properties: {
|
|
275
|
+
source: {
|
|
276
|
+
type: "string",
|
|
277
|
+
description: "Optional posting agent. Defaults to AGENT_BRIDGE_AGENT when configured; an explicit value must match it."
|
|
278
|
+
},
|
|
279
|
+
category: {
|
|
280
|
+
type: "string",
|
|
281
|
+
description: "Entry type: operational | config-change | goal-update | flag | bridge-meta"
|
|
282
|
+
},
|
|
283
|
+
content: {
|
|
284
|
+
type: "string",
|
|
285
|
+
description: "The context message"
|
|
286
|
+
},
|
|
287
|
+
priority: {
|
|
288
|
+
type: "string",
|
|
289
|
+
description: "info (default) | high | urgent"
|
|
290
|
+
},
|
|
291
|
+
project: {
|
|
292
|
+
type: "string",
|
|
293
|
+
description: "Scope to a project (e.g. project-a, project-b). Omit for cross-project."
|
|
294
|
+
},
|
|
295
|
+
metadata: {
|
|
296
|
+
type: "object",
|
|
297
|
+
description: "Arbitrary structured data"
|
|
298
|
+
},
|
|
299
|
+
message_id: {
|
|
300
|
+
type: "string",
|
|
301
|
+
description: "Stable message id. Generated by the bridge when omitted."
|
|
302
|
+
},
|
|
303
|
+
target_agents: {
|
|
304
|
+
type: "array",
|
|
305
|
+
items: { type: "string" },
|
|
306
|
+
description: "Optional target agent names. Empty or omitted means broadcast."
|
|
307
|
+
},
|
|
308
|
+
thread_id: {
|
|
309
|
+
type: "string",
|
|
310
|
+
description: "Optional conversation/thread id."
|
|
311
|
+
},
|
|
312
|
+
reply_to_id: {
|
|
313
|
+
type: "string",
|
|
314
|
+
description: "Optional parent message id for reply threading."
|
|
315
|
+
},
|
|
316
|
+
kind: {
|
|
317
|
+
type: "string",
|
|
318
|
+
description: "Message kind: operational | config-change | goal-update | flag | bridge-meta | handoff | request | result"
|
|
319
|
+
},
|
|
320
|
+
payload_mime: {
|
|
321
|
+
type: "string",
|
|
322
|
+
description: "Payload MIME type. Defaults to text/plain for the content column."
|
|
323
|
+
},
|
|
324
|
+
payload: {
|
|
325
|
+
anyOf: [
|
|
326
|
+
{ type: "object" },
|
|
327
|
+
{ type: "array" },
|
|
328
|
+
{ type: "string" },
|
|
329
|
+
{ type: "number" },
|
|
330
|
+
{ type: "boolean" },
|
|
331
|
+
{ type: "null" }
|
|
332
|
+
],
|
|
333
|
+
description: "Optional structured payload stored in metadata.message_envelope."
|
|
334
|
+
},
|
|
335
|
+
payload_ref: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Optional external blob pointer for large payloads."
|
|
338
|
+
},
|
|
339
|
+
payload_ciphertext: {
|
|
340
|
+
type: "string",
|
|
341
|
+
description: "Optional inline encrypted payload for small encrypted messages."
|
|
342
|
+
},
|
|
343
|
+
informed_by: {
|
|
344
|
+
type: "array",
|
|
345
|
+
items: { type: "string" },
|
|
346
|
+
description: "Optional atrib record hashes (sha256:<64-hex>) this message depends on."
|
|
347
|
+
},
|
|
348
|
+
expires_at: {
|
|
349
|
+
type: "string",
|
|
350
|
+
description: "Optional ISO timestamp retention boundary."
|
|
351
|
+
},
|
|
352
|
+
atrib_receipt_id: {
|
|
353
|
+
type: "string",
|
|
354
|
+
description: "Optional. Signed atrib record receipt_id for the wrapper that signed this post_context call. Set automatically by an atrib-signing wrapper; consumers reading the row use this as the informed_by anchor for cross-process causal edges."
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
required: ["category", "content"]
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: "get_context",
|
|
362
|
+
description: "Read shared context entries, newest first. Filter by source, category, project, or unacknowledged entries.",
|
|
363
|
+
inputSchema: {
|
|
364
|
+
type: "object",
|
|
365
|
+
properties: {
|
|
366
|
+
since: {
|
|
367
|
+
type: "string",
|
|
368
|
+
description: "ISO timestamp. Only entries after this time"
|
|
369
|
+
},
|
|
370
|
+
source: {
|
|
371
|
+
type: "string",
|
|
372
|
+
description: "Filter by posting agent"
|
|
373
|
+
},
|
|
374
|
+
category: {
|
|
375
|
+
type: "string",
|
|
376
|
+
description: "Filter by category"
|
|
377
|
+
},
|
|
378
|
+
project: {
|
|
379
|
+
type: "string",
|
|
380
|
+
description: "Filter by project scope"
|
|
381
|
+
},
|
|
382
|
+
unacked_by: {
|
|
383
|
+
type: "string",
|
|
384
|
+
description: "Only entries NOT yet acknowledged by this agent name. Defaults to AGENT_BRIDGE_AGENT when configured."
|
|
385
|
+
},
|
|
386
|
+
limit: {
|
|
387
|
+
type: "number",
|
|
388
|
+
description: "Max entries to return (default 20)",
|
|
389
|
+
minimum: 1,
|
|
390
|
+
maximum: 200
|
|
391
|
+
},
|
|
392
|
+
target_agent: {
|
|
393
|
+
type: "string",
|
|
394
|
+
description: "Return broadcast entries plus entries targeted to this agent."
|
|
395
|
+
},
|
|
396
|
+
thread_id: {
|
|
397
|
+
type: "string",
|
|
398
|
+
description: "Filter by metadata.message_envelope.thread_id."
|
|
399
|
+
},
|
|
400
|
+
kind: {
|
|
401
|
+
type: "string",
|
|
402
|
+
description: "Filter by metadata.message_envelope.kind."
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
name: "ack_context",
|
|
409
|
+
description: "Acknowledge context entries so they won't appear in unacked queries for this agent.",
|
|
410
|
+
inputSchema: {
|
|
411
|
+
type: "object",
|
|
412
|
+
properties: {
|
|
413
|
+
ids: {
|
|
414
|
+
type: "array",
|
|
415
|
+
items: { anyOf: [{ type: "number" }, { type: "string" }] },
|
|
416
|
+
description: "Legacy numeric entry IDs or v2 UUID message IDs to acknowledge"
|
|
417
|
+
},
|
|
418
|
+
agent: {
|
|
419
|
+
type: "string",
|
|
420
|
+
description: "Optional acknowledging agent. Defaults to AGENT_BRIDGE_AGENT when configured; an explicit value must match it."
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
required: ["ids"]
|
|
424
|
+
}
|
|
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) => {
|
|
515
|
+
const { name, arguments: args } = request.params;
|
|
516
|
+
try {
|
|
517
|
+
switch (name) {
|
|
518
|
+
case "post_context": {
|
|
519
|
+
let source;
|
|
520
|
+
try {
|
|
521
|
+
source = resolvePostSource(args?.source, config.agent);
|
|
522
|
+
if (!source) {
|
|
523
|
+
throw new Error(
|
|
524
|
+
"source is required when AGENT_BRIDGE_AGENT is not configured"
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
} catch (e) {
|
|
528
|
+
throw new McpError(
|
|
529
|
+
ErrorCode.InvalidParams,
|
|
530
|
+
e instanceof Error ? e.message : "source identity mismatch"
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
const postArgs = { ...args ?? {}, source };
|
|
534
|
+
const receiptId = normalizeReceiptId(args?.atrib_receipt_id);
|
|
535
|
+
const envelope = buildMessageEnvelope(postArgs, receiptId);
|
|
536
|
+
const body = {
|
|
537
|
+
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)
|
|
543
|
+
};
|
|
544
|
+
if (receiptId) {
|
|
545
|
+
body.atrib_receipt_id = receiptId;
|
|
546
|
+
}
|
|
547
|
+
if (!supabaseRequest) {
|
|
548
|
+
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
|
+
});
|
|
567
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
|
|
568
|
+
}
|
|
569
|
+
if (!supabaseRequest) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
570
|
+
const data = await supabaseRequest("/shared_context", {
|
|
571
|
+
method: "POST",
|
|
572
|
+
body: JSON.stringify(body)
|
|
573
|
+
});
|
|
574
|
+
return {
|
|
575
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
case "get_context": {
|
|
579
|
+
const rawLimit = args?.limit;
|
|
580
|
+
if (rawLimit !== void 0 && (typeof rawLimit !== "number" || !Number.isSafeInteger(rawLimit) || rawLimit < 1 || rawLimit > 200)) {
|
|
581
|
+
throw new McpError(ErrorCode.InvalidParams, "limit must be between 1 and 200");
|
|
582
|
+
}
|
|
583
|
+
const requestedLimit = rawLimit ?? 20;
|
|
584
|
+
if (service && principal) {
|
|
585
|
+
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
|
+
if (args?.target_agent && String(args.target_agent) !== principal.agent) {
|
|
590
|
+
return { content: [{ type: "text", text: "[]" }], structuredContent: { entries: [] } };
|
|
591
|
+
}
|
|
592
|
+
const result = await service.history(principal, {
|
|
593
|
+
limit: requestedLimit,
|
|
594
|
+
types: args?.kind ? [String(args.kind)] : args?.category ? [String(args.category)] : void 0,
|
|
595
|
+
source: args?.source ? String(args.source) : void 0,
|
|
596
|
+
since: args?.since ? String(args.since) : void 0,
|
|
597
|
+
unacknowledgedBy: args?.unacked_by ? String(args.unacked_by) : config.agent,
|
|
598
|
+
threadId: args?.thread_id ? String(args.thread_id) : void 0,
|
|
599
|
+
latest: true
|
|
600
|
+
});
|
|
601
|
+
const entries = result.messages.slice(0, requestedLimit).map((message) => ({
|
|
602
|
+
id: clientConfig?.provider === "legacy-supabase" && /^\d+$/.test(message.sequence) ? Number.isSafeInteger(Number(message.sequence)) ? Number(message.sequence) : message.sequence : message.id,
|
|
603
|
+
source: message.source,
|
|
604
|
+
category: message.type,
|
|
605
|
+
content: message.content,
|
|
606
|
+
priority: message.priority,
|
|
607
|
+
project: message.workspace,
|
|
608
|
+
metadata: legacyContextMetadata(message),
|
|
609
|
+
atrib_receipt_id: message.atribReceiptId ?? null,
|
|
610
|
+
created_at: message.createdAt
|
|
611
|
+
}));
|
|
612
|
+
const cachedResult = result;
|
|
613
|
+
const cacheMetadata = cachedResult.source ? {
|
|
614
|
+
source: cachedResult.source,
|
|
615
|
+
stale: Boolean(cachedResult.stale),
|
|
616
|
+
lastSyncedAt: cachedResult.lastSyncedAt ?? null
|
|
617
|
+
} : {};
|
|
618
|
+
return {
|
|
619
|
+
content: [{ type: "text", text: JSON.stringify(entries, null, 2) }],
|
|
620
|
+
structuredContent: { entries, ...cacheMetadata }
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
const hasEnvelopeFilter = Boolean(
|
|
624
|
+
args?.target_agent || args?.thread_id || args?.kind
|
|
625
|
+
);
|
|
626
|
+
const fetchLimit = hasEnvelopeFilter ? Math.min(Math.max(requestedLimit * 5, 50), 200) : requestedLimit;
|
|
627
|
+
const params = [
|
|
628
|
+
"order=created_at.desc",
|
|
629
|
+
`limit=${fetchLimit}`
|
|
630
|
+
];
|
|
631
|
+
if (args?.since)
|
|
632
|
+
params.push(
|
|
633
|
+
`created_at=gte.${encodeURIComponent(String(args.since))}`
|
|
634
|
+
);
|
|
635
|
+
if (args?.source)
|
|
636
|
+
params.push(`source=eq.${encodeURIComponent(String(args.source))}`);
|
|
637
|
+
if (args?.category)
|
|
638
|
+
params.push(
|
|
639
|
+
`category=eq.${encodeURIComponent(String(args.category))}`
|
|
640
|
+
);
|
|
641
|
+
if (args?.project)
|
|
642
|
+
params.push(`project=eq.${encodeURIComponent(String(args.project))}`);
|
|
643
|
+
const unackedBy = args?.unacked_by ?? config.agent;
|
|
644
|
+
if (unackedBy)
|
|
645
|
+
params.push(
|
|
646
|
+
`acked_by=not.cs.%7B${encodeURIComponent(String(unackedBy))}%7D`
|
|
647
|
+
);
|
|
648
|
+
if (!supabaseRequest) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
649
|
+
const data = await supabaseRequest(
|
|
650
|
+
`/shared_context?${params.join("&")}`
|
|
651
|
+
);
|
|
652
|
+
const filtered = filterContextRows(data, args, requestedLimit);
|
|
653
|
+
return {
|
|
654
|
+
content: [{ type: "text", text: JSON.stringify(filtered, null, 2) }]
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
case "ack_context": {
|
|
658
|
+
const ids = args?.ids;
|
|
659
|
+
let agent;
|
|
660
|
+
try {
|
|
661
|
+
agent = resolveAgentIdentity(args?.agent, config.agent);
|
|
662
|
+
} catch (e) {
|
|
663
|
+
throw new McpError(
|
|
664
|
+
ErrorCode.InvalidParams,
|
|
665
|
+
e instanceof Error ? e.message : "agent identity mismatch"
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if (!ids?.length || !agent) {
|
|
669
|
+
throw new McpError(
|
|
670
|
+
ErrorCode.InvalidParams,
|
|
671
|
+
"ids are required; agent is required when AGENT_BRIDGE_AGENT is not configured"
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
if (service && principal) {
|
|
675
|
+
if (!service || !principal) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
676
|
+
const rawIds = ids.map(String);
|
|
677
|
+
const acknowledged = clientConfig?.provider === "legacy-supabase" && store?.recordLegacyReceipt && rawIds.every((id) => /^\d+$/.test(id)) ? await store.recordLegacyReceipt(rawIds, principal.agent) : await service.acknowledge(
|
|
678
|
+
principal,
|
|
679
|
+
ids.map((id) => legacyNumericMessageId(id))
|
|
680
|
+
);
|
|
681
|
+
return { content: [{ type: "text", text: JSON.stringify({ acknowledged, agent }) }], structuredContent: { acknowledged, agent } };
|
|
682
|
+
}
|
|
683
|
+
if (!supabaseRequest) throw new McpError(ErrorCode.InternalError, "bridge provider is not configured");
|
|
684
|
+
const data = await supabaseRequest("/rpc/ack_context", {
|
|
685
|
+
method: "POST",
|
|
686
|
+
body: JSON.stringify({ entry_ids: ids.map(String), agent_name: agent })
|
|
687
|
+
});
|
|
688
|
+
return {
|
|
689
|
+
content: [
|
|
690
|
+
{
|
|
691
|
+
type: "text",
|
|
692
|
+
text: JSON.stringify({ acknowledged: data, agent })
|
|
693
|
+
}
|
|
694
|
+
]
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
case "send": {
|
|
698
|
+
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
699
|
+
try {
|
|
700
|
+
resolvePostSource(args?.source, principal.agent);
|
|
701
|
+
} catch (error) {
|
|
702
|
+
throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : "source identity mismatch");
|
|
703
|
+
}
|
|
704
|
+
const result = await service.publish(principal, args);
|
|
705
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
|
|
706
|
+
}
|
|
707
|
+
case "history": {
|
|
708
|
+
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 };
|
|
711
|
+
}
|
|
712
|
+
case "claim": {
|
|
713
|
+
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 } };
|
|
716
|
+
}
|
|
717
|
+
case "extend":
|
|
718
|
+
case "acknowledge":
|
|
719
|
+
case "negative_acknowledge": {
|
|
720
|
+
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(
|
|
723
|
+
principal,
|
|
724
|
+
id,
|
|
725
|
+
token,
|
|
726
|
+
args?.error ?? "negative acknowledgment",
|
|
727
|
+
args?.dead ?? false,
|
|
728
|
+
args?.retryPolicy
|
|
729
|
+
);
|
|
730
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result ?? { delivery: null } };
|
|
731
|
+
}
|
|
732
|
+
case "heartbeat": {
|
|
733
|
+
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
734
|
+
const result = await service.heartbeat(principal, {
|
|
735
|
+
leaseMs: args?.leaseMs,
|
|
736
|
+
runtimeType: args?.runtimeType,
|
|
737
|
+
capabilities: args?.capabilities
|
|
738
|
+
});
|
|
739
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
|
|
740
|
+
}
|
|
741
|
+
case "presence": {
|
|
742
|
+
if (!service || !principal) throw new McpError(ErrorCode.InvalidParams, "AGENT_BRIDGE_AGENT is required");
|
|
743
|
+
const result = { agents: await service.presence(principal) };
|
|
744
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
|
|
745
|
+
}
|
|
746
|
+
default:
|
|
747
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
748
|
+
}
|
|
749
|
+
} catch (error) {
|
|
750
|
+
if (error instanceof McpError) throw error;
|
|
751
|
+
if (error instanceof BridgeValidationError) {
|
|
752
|
+
throw new McpError(ErrorCode.InvalidParams, error.message);
|
|
753
|
+
}
|
|
754
|
+
throw error;
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
server.onclose = () => {
|
|
758
|
+
void store?.close?.();
|
|
759
|
+
};
|
|
760
|
+
return server;
|
|
761
|
+
}
|
|
762
|
+
async function startServer(config = configFromEnv()) {
|
|
763
|
+
const server = createAgentBridgeServer(config);
|
|
764
|
+
const transport = new StdioServerTransport();
|
|
765
|
+
await server.connect(transport);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
export {
|
|
769
|
+
configFromEnv,
|
|
770
|
+
createAgentBridgeServer,
|
|
771
|
+
startServer
|
|
772
|
+
};
|
|
773
|
+
//# sourceMappingURL=chunk-4KAOBC5X.js.map
|