@band-ai/sdk 0.1.6 → 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.
Files changed (85) hide show
  1. package/README.md +372 -0
  2. package/dist/{ClaudeSDKAdapter-CRq4R-WB.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +14 -10
  3. package/dist/{ClaudeSDKAdapter-BHOkjN3X.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +14 -10
  4. package/dist/{acp-server-B1Da7L6u.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
  5. package/dist/{acp-server-BdRz9_UN.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
  6. package/dist/adapters.cjs +734 -279
  7. package/dist/adapters.d.cts +21 -19
  8. package/dist/adapters.d.ts +21 -19
  9. package/dist/adapters.js +65 -44
  10. package/dist/backends-D-dBdDm-.d.ts +27 -0
  11. package/dist/backends-ZLxmQrTZ.d.cts +27 -0
  12. package/dist/{chunk-MSL6CWHY.js → chunk-4IAXZBXX.js} +77 -37
  13. package/dist/{chunk-SG4WLD2H.js → chunk-EAI2M3WM.js} +38 -94
  14. package/dist/{chunk-YR3BOQNW.js → chunk-JY75VSQK.js} +7 -7
  15. package/dist/{chunk-INA6YZTZ.js → chunk-LBWKISBS.js} +51 -31
  16. package/dist/{chunk-I5EZG52P.js → chunk-N2QTUMGO.js} +532 -327
  17. package/dist/{chunk-RHVH2GZR.js → chunk-NMZLX7TP.js} +110 -56
  18. package/dist/{chunk-EDPKUUJL.js → chunk-NT7TBFX2.js} +9 -1
  19. package/dist/{chunk-GVEQ3RAH.js → chunk-RV76SKFT.js} +169 -54
  20. package/dist/{chunk-W5NDZSYE.js → chunk-TLBCKDQO.js} +23 -23
  21. package/dist/chunk-US226AS4.js +130 -0
  22. package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
  23. package/dist/chunk-WLCM2OXG.js +181 -0
  24. package/dist/config.cjs +40 -13
  25. package/dist/config.d.cts +7 -1
  26. package/dist/config.d.ts +7 -1
  27. package/dist/config.js +2 -2
  28. package/dist/converters.cjs +491 -35
  29. package/dist/converters.d.cts +5 -5
  30. package/dist/converters.d.ts +5 -5
  31. package/dist/converters.js +4 -3
  32. package/dist/core.cjs +53 -10
  33. package/dist/core.d.cts +10 -9
  34. package/dist/core.d.ts +10 -9
  35. package/dist/core.js +8 -4
  36. package/dist/disconnectReason-IuADl6TH.d.cts +34 -0
  37. package/dist/disconnectReason-IuADl6TH.d.ts +34 -0
  38. package/dist/{dtos-DUpbIu8k.d.ts → dtos-B8KU_q4d.d.cts} +26 -6
  39. package/dist/{dtos-DUpbIu8k.d.cts → dtos-B8KU_q4d.d.ts} +26 -6
  40. package/dist/index.cjs +1510 -735
  41. package/dist/index.d.cts +18 -16
  42. package/dist/index.d.ts +18 -16
  43. package/dist/index.js +21 -13
  44. package/dist/linear.cjs +1044 -112
  45. package/dist/linear.d.cts +146 -16
  46. package/dist/linear.d.ts +146 -16
  47. package/dist/linear.js +1031 -110
  48. package/dist/mcp-claude.cjs +338 -66
  49. package/dist/mcp-claude.d.cts +3 -3
  50. package/dist/mcp-claude.d.ts +3 -3
  51. package/dist/mcp-claude.js +215 -16
  52. package/dist/mcp.cjs +414 -105
  53. package/dist/mcp.d.cts +29 -16
  54. package/dist/mcp.d.ts +29 -16
  55. package/dist/mcp.js +14 -14
  56. package/dist/{opencode-BBcDchcN.d.cts → opencode-2YdscIc1.d.cts} +5 -5
  57. package/dist/{opencode-DthQQUsZ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
  58. package/dist/{pagination-CcDkVFxK.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
  59. package/dist/{pagination-BPiys10t.d.cts → pagination-DqdkQArT.d.cts} +2 -2
  60. package/dist/{protocols-DrhzOH6K.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
  61. package/dist/{protocols-CInhtFpA.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
  62. package/dist/rest.cjs +41 -97
  63. package/dist/rest.d.cts +7 -7
  64. package/dist/rest.d.ts +7 -7
  65. package/dist/rest.js +2 -2
  66. package/dist/runtime.cjs +998 -620
  67. package/dist/runtime.d.cts +22 -29
  68. package/dist/runtime.d.ts +22 -29
  69. package/dist/runtime.js +19 -67
  70. package/dist/{schemas-BpEBkq5V.d.cts → schemas-BotL3ZLH.d.cts} +51 -56
  71. package/dist/{schemas-vos1AaBc.d.ts → schemas-DBsC4J1g.d.ts} +51 -56
  72. package/dist/{sdk-CwTAxhwI.d.cts → sdk-BTciSLRQ.d.cts} +35 -5
  73. package/dist/{sdk-CcnQ5OUC.d.ts → sdk-qKJtMma_.d.ts} +35 -5
  74. package/dist/{simpleAdapter-9OE_p6QW.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
  75. package/dist/{simpleAdapter-DqhvjsGr.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
  76. package/dist/testing.d.cts +3 -3
  77. package/dist/testing.d.ts +3 -3
  78. package/dist/{types-7jVzOeOP.d.ts → types-BTN_ZETM.d.ts} +2 -2
  79. package/dist/{types-CxII3XkA.d.ts → types-BgYFd_Yw.d.cts} +5 -5
  80. package/dist/{types-CSHFipIc.d.cts → types-BivGO7I9.d.ts} +5 -5
  81. package/dist/{types-CovcHpYf.d.cts → types-D958TC71.d.cts} +2 -2
  82. package/package.json +25 -23
  83. package/dist/backends-CzDbiQar.d.ts +0 -20
  84. package/dist/backends-SVMT-7l4.d.cts +0 -20
  85. package/dist/chunk-SFVKOEQH.js +0 -103
package/dist/mcp.cjs CHANGED
@@ -48,6 +48,84 @@ var init_chatEvents = __esm({
48
48
  }
49
49
  });
50
50
 
51
+ // src/contracts/memory.ts
52
+ function namedValues(values) {
53
+ return Object.fromEntries(values.map((value) => [value, value]));
54
+ }
55
+ var SENSORY_MEMORY_TYPES, COGNITIVE_MEMORY_TYPES, MEMORY_SYSTEM_TYPES, MEMORY_SYSTEMS, MEMORY_TYPES, MEMORY_SEGMENTS, MEMORY_STORE_SCOPES, MEMORY_LIST_SCOPES, MEMORY_STATUSES, MEMORY_SYSTEM, MEMORY_TYPE, MEMORY_SEGMENT, MEMORY_STORE_SCOPE;
56
+ var init_memory = __esm({
57
+ "src/contracts/memory.ts"() {
58
+ "use strict";
59
+ SENSORY_MEMORY_TYPES = [
60
+ "iconic",
61
+ // Visual input
62
+ "echoic",
63
+ // Auditory input
64
+ "haptic"
65
+ // Tactile input
66
+ ];
67
+ COGNITIVE_MEMORY_TYPES = [
68
+ "episodic",
69
+ // Events that occurred
70
+ "semantic",
71
+ // Facts, preferences, learned knowledge
72
+ "procedural"
73
+ // How to perform tasks
74
+ ];
75
+ MEMORY_SYSTEM_TYPES = {
76
+ sensory: SENSORY_MEMORY_TYPES,
77
+ // Brief sensory inputs
78
+ working: COGNITIVE_MEMORY_TYPES,
79
+ // Short-term session context
80
+ long_term: COGNITIVE_MEMORY_TYPES
81
+ // Persistent cross-conversation memory
82
+ };
83
+ MEMORY_SYSTEMS = Object.keys(MEMORY_SYSTEM_TYPES);
84
+ MEMORY_TYPES = [
85
+ ...SENSORY_MEMORY_TYPES,
86
+ ...COGNITIVE_MEMORY_TYPES
87
+ ];
88
+ MEMORY_SEGMENTS = [
89
+ "user",
90
+ // User preferences or profile info
91
+ "agent",
92
+ // Facts or events about agents/entities
93
+ "tool",
94
+ // Tool usage or task procedures
95
+ "guideline"
96
+ // Behavioral rules or policies
97
+ ];
98
+ MEMORY_STORE_SCOPES = [
99
+ "subject",
100
+ // About one person/agent; requires subject_id
101
+ "organization"
102
+ // Shared org-wide
103
+ ];
104
+ MEMORY_LIST_SCOPES = [
105
+ "subject",
106
+ // Subject-scoped memories only
107
+ "organization",
108
+ // Organization-scoped memories only
109
+ "all"
110
+ // Both scopes (no scope filter)
111
+ ];
112
+ MEMORY_STATUSES = [
113
+ "active",
114
+ // Normal, visible memories
115
+ "superseded",
116
+ // Outdated; soft-deleted via band_supersede_memory
117
+ "archived",
118
+ // Hidden but preserved via band_archive_memory
119
+ "all"
120
+ // Any status (no filter)
121
+ ];
122
+ MEMORY_SYSTEM = namedValues(MEMORY_SYSTEMS);
123
+ MEMORY_TYPE = namedValues(MEMORY_TYPES);
124
+ MEMORY_SEGMENT = namedValues(MEMORY_SEGMENTS);
125
+ MEMORY_STORE_SCOPE = namedValues(MEMORY_STORE_SCOPES);
126
+ }
127
+ });
128
+
51
129
  // src/runtime/tools/schemas.ts
52
130
  function mcpToolNames(names) {
53
131
  return [...names].sort((a, b) => a.localeCompare(b)).map((name) => `${MCP_TOOL_PREFIX}${name}`);
@@ -56,13 +134,14 @@ function getToolDescription(name) {
56
134
  const model = TOOL_MODELS[name];
57
135
  return model?.description ?? `Execute ${name}`;
58
136
  }
59
- var TOOL_MODELS, ALL_TOOL_NAMES, MEMORY_TOOL_NAMES, CONTACT_TOOL_NAMES, BASE_TOOL_NAMES, CHAT_TOOL_NAMES, MCP_TOOL_PREFIX;
137
+ var TOOL_MODELS, ALL_TOOL_NAMES, MEMORY_TOOL_NAMES, CONTACT_TOOL_NAMES, BASE_TOOL_NAMES, CHAT_TOOL_NAMES, MCP_TOOL_PREFIX, MCP_SERVER_NAME;
60
138
  var init_schemas = __esm({
61
139
  "src/runtime/tools/schemas.ts"() {
62
140
  "use strict";
63
141
  init_chatEvents();
142
+ init_memory();
64
143
  TOOL_MODELS = {
65
- thenvoi_send_message: {
144
+ band_send_message: {
66
145
  description: "Send a message to the chat room. Use this to respond to users or other agents. Messages require at least one @mention in the mentions array. You MUST use this tool to communicate \u2014 plain text responses won't reach users. When delegating, send the full task context in this message instead of assuming hidden state.",
67
146
  properties: {
68
147
  content: {
@@ -78,7 +157,7 @@ var init_schemas = __esm({
78
157
  },
79
158
  required: ["content", "mentions"]
80
159
  },
81
- thenvoi_send_event: {
160
+ band_send_event: {
82
161
  description: "Send an event to the chat room. No mentions required. 'thought': Share your reasoning or plan BEFORE taking actions. Explain what you're about to do and why. 'error': Report an error or problem that occurred. 'task': Report task progress or completion status. Always send a thought before complex actions to keep users informed.",
83
162
  properties: {
84
163
  content: {
@@ -97,12 +176,12 @@ var init_schemas = __esm({
97
176
  },
98
177
  required: ["content", "message_type"]
99
178
  },
100
- thenvoi_add_participant: {
101
- description: "Add a participant (agent or user) to the chat room by name. IMPORTANT: Use thenvoi_lookup_peers() first to find available agents. Pass the exact peer name from thenvoi_lookup_peers, not the handle. For normal delegation, omit role or use 'member'.",
179
+ band_add_participant: {
180
+ description: "Add a participant (agent or user) to the chat room by name. IMPORTANT: Use band_lookup_peers() first to find available agents. Pass the exact peer name from band_lookup_peers, not the handle. For normal delegation, omit role or use 'member'.",
102
181
  properties: {
103
182
  name: {
104
183
  type: "string",
105
- description: "Name of participant to add (must match a name from thenvoi_lookup_peers)."
184
+ description: "Name of participant to add (must match a name from band_lookup_peers)."
106
185
  },
107
186
  role: {
108
187
  type: "string",
@@ -112,7 +191,7 @@ var init_schemas = __esm({
112
191
  },
113
192
  required: ["name"]
114
193
  },
115
- thenvoi_remove_participant: {
194
+ band_remove_participant: {
116
195
  description: "Remove a participant from the chat room by name.",
117
196
  properties: {
118
197
  name: {
@@ -122,12 +201,12 @@ var init_schemas = __esm({
122
201
  },
123
202
  required: ["name"]
124
203
  },
125
- thenvoi_get_participants: {
204
+ band_get_participants: {
126
205
  description: "Get a list of all participants in the current chat room.",
127
206
  properties: {},
128
207
  required: []
129
208
  },
130
- thenvoi_lookup_peers: {
209
+ band_lookup_peers: {
131
210
  description: "List available peers (agents and users) that can be added to this room. Automatically excludes peers already in the room. Returns dict with 'peers' list and 'metadata' (page, page_size, total_count, total_pages). Use this to find specialized agents (e.g., Weather Agent) when you cannot answer a question directly.",
132
211
  properties: {
133
212
  page: {
@@ -142,7 +221,7 @@ var init_schemas = __esm({
142
221
  },
143
222
  required: []
144
223
  },
145
- thenvoi_create_chatroom: {
224
+ band_create_chatroom: {
146
225
  description: "Create a new chat room for a specific task or conversation.",
147
226
  properties: {
148
227
  task_id: {
@@ -152,7 +231,7 @@ var init_schemas = __esm({
152
231
  },
153
232
  required: []
154
233
  },
155
- thenvoi_list_contacts: {
234
+ band_list_contacts: {
156
235
  description: "List agent's contacts with pagination.",
157
236
  properties: {
158
237
  page: {
@@ -169,7 +248,7 @@ var init_schemas = __esm({
169
248
  },
170
249
  required: []
171
250
  },
172
- thenvoi_add_contact: {
251
+ band_add_contact: {
173
252
  description: "Send a contact request to add someone as a contact. Returns 'pending' when request is created. Returns 'approved' when inverse request existed and was auto-accepted.",
174
253
  properties: {
175
254
  handle: {
@@ -183,7 +262,7 @@ var init_schemas = __esm({
183
262
  },
184
263
  required: ["handle"]
185
264
  },
186
- thenvoi_remove_contact: {
265
+ band_remove_contact: {
187
266
  description: "Remove an existing contact by handle or ID.",
188
267
  properties: {
189
268
  handle: {
@@ -197,7 +276,7 @@ var init_schemas = __esm({
197
276
  },
198
277
  required: []
199
278
  },
200
- thenvoi_list_contact_requests: {
279
+ band_list_contact_requests: {
201
280
  description: "List both received and sent contact requests. Received requests are always filtered to pending status. Sent requests can be filtered by status.",
202
281
  properties: {
203
282
  page: {
@@ -219,7 +298,7 @@ var init_schemas = __esm({
219
298
  },
220
299
  required: []
221
300
  },
222
- thenvoi_respond_contact_request: {
301
+ band_respond_contact_request: {
223
302
  description: "Respond to a contact request. 'approve'/'reject': For requests you RECEIVED (handle = requester's handle). 'cancel': For requests you SENT (handle = recipient's handle).",
224
303
  properties: {
225
304
  action: {
@@ -238,7 +317,7 @@ var init_schemas = __esm({
238
317
  },
239
318
  required: ["action"]
240
319
  },
241
- thenvoi_list_memories: {
320
+ band_list_memories: {
242
321
  description: "List memories accessible to the agent. Returns memories about the specified subject (cross-agent sharing) and organization-wide shared memories.",
243
322
  properties: {
244
323
  subject_id: {
@@ -247,29 +326,22 @@ var init_schemas = __esm({
247
326
  },
248
327
  scope: {
249
328
  type: "string",
250
- enum: ["subject", "organization", "all"],
329
+ enum: [...MEMORY_LIST_SCOPES],
251
330
  description: "Filter by scope."
252
331
  },
253
332
  system: {
254
333
  type: "string",
255
- enum: ["sensory", "working", "long_term"],
334
+ enum: [...MEMORY_SYSTEMS],
256
335
  description: "Filter by memory system."
257
336
  },
258
337
  type: {
259
338
  type: "string",
260
- enum: [
261
- "iconic",
262
- "echoic",
263
- "haptic",
264
- "episodic",
265
- "semantic",
266
- "procedural"
267
- ],
339
+ enum: [...MEMORY_TYPES],
268
340
  description: "Filter by memory type."
269
341
  },
270
342
  segment: {
271
343
  type: "string",
272
- enum: ["user", "agent", "tool", "guideline"],
344
+ enum: [...MEMORY_SEGMENTS],
273
345
  description: "Filter by segment."
274
346
  },
275
347
  content_query: {
@@ -284,13 +356,13 @@ var init_schemas = __esm({
284
356
  },
285
357
  status: {
286
358
  type: "string",
287
- enum: ["active", "superseded", "archived", "all"],
359
+ enum: [...MEMORY_STATUSES],
288
360
  description: "Filter by status."
289
361
  }
290
362
  },
291
363
  required: []
292
364
  },
293
- thenvoi_store_memory: {
365
+ band_store_memory: {
294
366
  description: "Store a new memory entry. The memory will be associated with the authenticated agent as the source. For subject-scoped memories, provide a subject_id. For organization-scoped memories, omit subject_id.",
295
367
  properties: {
296
368
  content: {
@@ -299,24 +371,17 @@ var init_schemas = __esm({
299
371
  },
300
372
  system: {
301
373
  type: "string",
302
- enum: ["sensory", "working", "long_term"],
374
+ enum: [...MEMORY_SYSTEMS],
303
375
  description: "Memory system tier."
304
376
  },
305
377
  type: {
306
378
  type: "string",
307
- enum: [
308
- "iconic",
309
- "echoic",
310
- "haptic",
311
- "episodic",
312
- "semantic",
313
- "procedural"
314
- ],
379
+ enum: [...MEMORY_TYPES],
315
380
  description: "Memory type (must be valid for selected system)."
316
381
  },
317
382
  segment: {
318
383
  type: "string",
319
- enum: ["user", "agent", "tool", "guideline"],
384
+ enum: [...MEMORY_SEGMENTS],
320
385
  description: "Logical segment."
321
386
  },
322
387
  thought: {
@@ -325,7 +390,7 @@ var init_schemas = __esm({
325
390
  },
326
391
  scope: {
327
392
  type: "string",
328
- enum: ["subject", "organization"],
393
+ enum: [...MEMORY_STORE_SCOPES],
329
394
  description: "Visibility scope."
330
395
  },
331
396
  subject_id: {
@@ -339,7 +404,7 @@ var init_schemas = __esm({
339
404
  },
340
405
  required: ["content", "system", "type", "segment", "thought"]
341
406
  },
342
- thenvoi_get_memory: {
407
+ band_get_memory: {
343
408
  description: "Retrieve a specific memory by ID.",
344
409
  properties: {
345
410
  memory_id: {
@@ -349,7 +414,7 @@ var init_schemas = __esm({
349
414
  },
350
415
  required: ["memory_id"]
351
416
  },
352
- thenvoi_supersede_memory: {
417
+ band_supersede_memory: {
353
418
  description: "Mark a memory as superseded (soft delete). Use when information is outdated or incorrect. The memory remains for audit trail but won't appear in normal queries. Only the source agent can supersede.",
354
419
  properties: {
355
420
  memory_id: {
@@ -359,7 +424,7 @@ var init_schemas = __esm({
359
424
  },
360
425
  required: ["memory_id"]
361
426
  },
362
- thenvoi_archive_memory: {
427
+ band_archive_memory: {
363
428
  description: "Archive a memory (hide but preserve). Use when memory is valid but not currently needed. Archived memories can be restored later by humans. Only the source agent can archive.",
364
429
  properties: {
365
430
  memory_id: {
@@ -372,18 +437,18 @@ var init_schemas = __esm({
372
437
  };
373
438
  ALL_TOOL_NAMES = new Set(Object.keys(TOOL_MODELS));
374
439
  MEMORY_TOOL_NAMES = /* @__PURE__ */ new Set([
375
- "thenvoi_list_memories",
376
- "thenvoi_store_memory",
377
- "thenvoi_get_memory",
378
- "thenvoi_supersede_memory",
379
- "thenvoi_archive_memory"
440
+ "band_list_memories",
441
+ "band_store_memory",
442
+ "band_get_memory",
443
+ "band_supersede_memory",
444
+ "band_archive_memory"
380
445
  ]);
381
446
  CONTACT_TOOL_NAMES = /* @__PURE__ */ new Set([
382
- "thenvoi_list_contacts",
383
- "thenvoi_add_contact",
384
- "thenvoi_remove_contact",
385
- "thenvoi_list_contact_requests",
386
- "thenvoi_respond_contact_request"
447
+ "band_list_contacts",
448
+ "band_add_contact",
449
+ "band_remove_contact",
450
+ "band_list_contact_requests",
451
+ "band_respond_contact_request"
387
452
  ]);
388
453
  BASE_TOOL_NAMES = new Set(
389
454
  [...ALL_TOOL_NAMES].filter((name) => !MEMORY_TOOL_NAMES.has(name))
@@ -391,7 +456,8 @@ var init_schemas = __esm({
391
456
  CHAT_TOOL_NAMES = new Set(
392
457
  [...BASE_TOOL_NAMES].filter((name) => !CONTACT_TOOL_NAMES.has(name))
393
458
  );
394
- MCP_TOOL_PREFIX = "mcp__thenvoi__";
459
+ MCP_TOOL_PREFIX = "mcp__band__";
460
+ MCP_SERVER_NAME = "band";
395
461
  }
396
462
  });
397
463
 
@@ -542,6 +608,13 @@ function serializeValue(value) {
542
608
  return String(value);
543
609
  }
544
610
  }
611
+ function resolveSingleRoomTools(getToolsForRoom) {
612
+ const tools = getToolsForRoom("");
613
+ if (!tools) {
614
+ throw new Error('Single-room mode requires getToolsForRoom("") to return a tools instance');
615
+ }
616
+ return tools;
617
+ }
545
618
  var init_registrations = __esm({
546
619
  "src/mcp/registrations.ts"() {
547
620
  "use strict";
@@ -597,29 +670,225 @@ var init_zod = __esm({
597
670
  // src/mcp/sdk.ts
598
671
  var sdk_exports = {};
599
672
  __export(sdk_exports, {
600
- createThenvoiSdkMcpServer: () => createThenvoiSdkMcpServer
673
+ createBandSdkMcpServer: () => createBandSdkMcpServer
601
674
  });
602
- function createThenvoiSdkMcpServer(options) {
603
- const registrations = buildRoomScopedRegistrations(
604
- options.getToolsForRoom,
605
- {
606
- enableMemoryTools: options.enableMemoryTools,
607
- enableContactTools: true,
608
- additionalTools: options.additionalTools
609
- }
610
- );
675
+ function createBandSdkMcpServer(options) {
676
+ const registrationOptions = {
677
+ enableMemoryTools: options.enableMemoryTools,
678
+ enableContactTools: true,
679
+ additionalTools: options.additionalTools
680
+ };
681
+ const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolveSingleRoomTools(options.getToolsForRoom), registrationOptions) : buildRoomScopedRegistrations(options.getToolsForRoom, registrationOptions);
611
682
  const toolDefinitions = registrations.map(toSdkToolDefinition);
612
683
  const toolNames = new Set(registrations.map((r) => r.name));
684
+ const contextCache = /* @__PURE__ */ new Map();
685
+ const MAX_CONTEXT_CACHE_ENTRIES = 100;
613
686
  const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
614
- name: "thenvoi",
687
+ name: MCP_SERVER_NAME,
615
688
  tools: toolDefinitions
616
689
  });
617
690
  return {
618
691
  serverConfig,
619
692
  allowedTools: mcpToolNames(toolNames),
620
- toolDefinitions
693
+ toolDefinitions,
694
+ getSystemPromptContext: async (roomId, contextOptions) => {
695
+ const context = await getOrBuildSystemPromptContext(
696
+ roomId,
697
+ contextOptions,
698
+ options.getToolsForRoom,
699
+ contextCache,
700
+ MAX_CONTEXT_CACHE_ENTRIES
701
+ );
702
+ return context.markdown;
703
+ },
704
+ getSystemPromptContextData: (roomId, contextOptions) => {
705
+ return getOrBuildSystemPromptContext(
706
+ roomId,
707
+ contextOptions,
708
+ options.getToolsForRoom,
709
+ contextCache,
710
+ MAX_CONTEXT_CACHE_ENTRIES
711
+ );
712
+ }
713
+ };
714
+ }
715
+ async function getOrBuildSystemPromptContext(roomId, contextOptions, getToolsForRoom, contextCache, maxEntries) {
716
+ const ttlMs = contextOptions?.ttlMs ?? 3e4;
717
+ const now = Date.now();
718
+ const cached = contextCache.get(roomId);
719
+ if (cached && cached.expiresAt > now) {
720
+ cached.lastAccessedAt = now;
721
+ return cached.value;
722
+ }
723
+ if (cached) {
724
+ contextCache.delete(roomId);
725
+ }
726
+ const tools = getToolsForRoom(roomId);
727
+ if (!tools) {
728
+ return buildUnavailableSystemPromptContext(roomId);
729
+ }
730
+ const context = await buildSystemPromptContext(roomId, tools);
731
+ contextCache.set(roomId, {
732
+ value: context,
733
+ expiresAt: now + ttlMs,
734
+ lastAccessedAt: now
735
+ });
736
+ evictLeastRecentlyUsedContext(contextCache, maxEntries);
737
+ return context;
738
+ }
739
+ async function buildSystemPromptContext(roomId, tools) {
740
+ const participants = await tools.getParticipants();
741
+ const warnings = [];
742
+ const agentResolution = await resolveAgentIdentity(tools);
743
+ if (agentResolution.warning) {
744
+ warnings.push(agentResolution.warning);
745
+ }
746
+ const roomResolution = await resolveRoomTitle(tools, roomId);
747
+ if (roomResolution.warning) {
748
+ warnings.push(roomResolution.warning);
749
+ }
750
+ const agentIdentity = agentResolution.value;
751
+ const roomTitle = roomResolution.value;
752
+ const normalizedParticipants = participants.map((participant) => ({
753
+ id: String(participant.id),
754
+ name: String(participant.name ?? "Unknown"),
755
+ type: String(participant.type ?? "Unknown"),
756
+ handle: normalizeHandle(participant.handle),
757
+ isSelf: participant.id === agentIdentity?.id
758
+ }));
759
+ const selfHandle = normalizeHandle(agentIdentity?.handle);
760
+ const selfName = agentIdentity?.name ?? "Agent";
761
+ const mentionHandles = normalizedParticipants.filter((participant) => !participant.isSelf).map((participant) => participant.handle).filter((handle) => Boolean(handle));
762
+ const mentionFormat = mentionHandles.length > 0 ? mentionHandles.join(", ") : "No participant handles available";
763
+ const roomLabel = roomTitle ? `"${roomTitle}"` : "this room";
764
+ const agentLabel = selfHandle ? `${selfName} (${selfHandle})` : selfName;
765
+ const participantLines = normalizedParticipants.length > 0 ? normalizedParticipants.map((participant) => {
766
+ const suffix = participant.isSelf ? " (you)" : "";
767
+ const handle = participant.handle ? ` (${participant.handle})` : "";
768
+ return `- **${participant.name}**${handle} -- ${participant.type}${suffix}`;
769
+ }).join("\n") : "- No participants found";
770
+ const markdown = [
771
+ "## Room Context",
772
+ "",
773
+ `You are **${agentLabel}** in room ${roomLabel} (id: ${roomId}).`,
774
+ "",
775
+ "### Participants",
776
+ participantLines,
777
+ "",
778
+ "### Mention Format",
779
+ `To address someone, use their exact handle: ${mentionFormat}`,
780
+ ...warnings.length > 0 ? ["", "### Warnings", ...warnings.map((warning) => `- ${warning}`)] : []
781
+ ].join("\n");
782
+ return {
783
+ roomId,
784
+ roomTitle,
785
+ agent: {
786
+ id: agentIdentity?.id ?? "unknown-agent",
787
+ name: selfName,
788
+ handle: selfHandle,
789
+ description: agentIdentity?.description ?? null
790
+ },
791
+ participants: normalizedParticipants,
792
+ mentionFormat,
793
+ warnings,
794
+ markdown
621
795
  };
622
796
  }
797
+ async function resolveAgentIdentity(tools) {
798
+ const maybeTools = tools;
799
+ try {
800
+ if (maybeTools.getAgentIdentity) {
801
+ return { value: await maybeTools.getAgentIdentity(), warning: null };
802
+ }
803
+ if (maybeTools.rest?.getAgentMe) {
804
+ return { value: await maybeTools.rest.getAgentMe(), warning: null };
805
+ }
806
+ } catch (error) {
807
+ return {
808
+ value: null,
809
+ warning: `Unable to resolve agent identity: ${error instanceof Error ? error.message : String(error)}`
810
+ };
811
+ }
812
+ return { value: null, warning: null };
813
+ }
814
+ async function resolveRoomTitle(tools, roomId) {
815
+ const maybeTools = tools;
816
+ const rest = maybeTools.rest;
817
+ if (!rest?.listChats) {
818
+ return { value: null, warning: null };
819
+ }
820
+ try {
821
+ let page = 1;
822
+ const pageSize = 100;
823
+ while (true) {
824
+ const response = await rest.listChats({ page, pageSize });
825
+ const room = response?.data?.find((entry) => entry.id === roomId);
826
+ if (typeof room?.title === "string" && room.title.length > 0) {
827
+ return { value: room.title, warning: null };
828
+ }
829
+ const totalPages = response?.metadata?.totalPages ?? page;
830
+ if (page >= totalPages) {
831
+ return { value: null, warning: null };
832
+ }
833
+ page += 1;
834
+ }
835
+ } catch (error) {
836
+ return {
837
+ value: null,
838
+ warning: `Unable to resolve room title: ${error instanceof Error ? error.message : String(error)}`
839
+ };
840
+ }
841
+ }
842
+ function buildUnavailableSystemPromptContext(roomId) {
843
+ const warnings = [`No tool context found for room_id ${roomId}`];
844
+ const markdown = [
845
+ "## Room Context",
846
+ "",
847
+ `You are **Agent** in this room (id: ${roomId}).`,
848
+ "",
849
+ "### Participants",
850
+ "- No participants found",
851
+ "",
852
+ "### Mention Format",
853
+ "No participant handles available",
854
+ "",
855
+ "### Warnings",
856
+ ...warnings.map((warning) => `- ${warning}`)
857
+ ].join("\n");
858
+ return {
859
+ roomId,
860
+ roomTitle: null,
861
+ agent: {
862
+ id: "unknown-agent",
863
+ name: "Agent",
864
+ handle: null,
865
+ description: null
866
+ },
867
+ participants: [],
868
+ mentionFormat: "No participant handles available",
869
+ warnings,
870
+ markdown
871
+ };
872
+ }
873
+ function evictLeastRecentlyUsedContext(contextCache, maxEntries) {
874
+ if (contextCache.size <= maxEntries) {
875
+ return;
876
+ }
877
+ let oldestKey = null;
878
+ let oldestAccessedAt = Number.POSITIVE_INFINITY;
879
+ for (const [key, entry] of contextCache.entries()) {
880
+ if (entry.lastAccessedAt < oldestAccessedAt) {
881
+ oldestAccessedAt = entry.lastAccessedAt;
882
+ oldestKey = key;
883
+ }
884
+ }
885
+ if (oldestKey) {
886
+ contextCache.delete(oldestKey);
887
+ }
888
+ }
889
+ function normalizeHandle(handle) {
890
+ return typeof handle === "string" && handle.trim().length > 0 ? handle.trim() : null;
891
+ }
623
892
  function toSdkToolDefinition(registration) {
624
893
  const shape = buildZodShape(
625
894
  import_zod4.z,
@@ -648,14 +917,14 @@ var init_sdk = __esm({
648
917
  // src/mcp/index.ts
649
918
  var mcp_exports = {};
650
919
  __export(mcp_exports, {
651
- ThenvoiMcpServer: () => ThenvoiMcpServer,
652
- ThenvoiMcpSseServer: () => ThenvoiMcpSseServer,
653
- ThenvoiMcpStdioServer: () => ThenvoiMcpStdioServer,
920
+ BandMcpServer: () => BandMcpServer,
921
+ BandMcpSseServer: () => BandMcpSseServer,
922
+ BandMcpStdioServer: () => BandMcpStdioServer,
654
923
  buildRoomScopedRegistrations: () => buildRoomScopedRegistrations,
655
924
  buildSingleContextRegistrations: () => buildSingleContextRegistrations,
656
- createThenvoiMcpBackend: () => createThenvoiMcpBackend,
925
+ createBandMcpBackend: () => createBandMcpBackend,
657
926
  errorResult: () => errorResult,
658
- getThenvoiSdkMcpServerConfig: () => getThenvoiSdkMcpServerConfig,
927
+ getBandSdkMcpServerConfig: () => getBandSdkMcpServerConfig,
659
928
  successResult: () => successResult
660
929
  });
661
930
  module.exports = __toCommonJS(mcp_exports);
@@ -664,10 +933,31 @@ module.exports = __toCommonJS(mcp_exports);
664
933
  init_schemas();
665
934
  init_registrations();
666
935
 
936
+ // src/mcp/auth.ts
937
+ var import_node_crypto = require("crypto");
938
+ function generateAuthToken() {
939
+ return (0, import_node_crypto.randomBytes)(32).toString("hex");
940
+ }
941
+ function isAuthorizedRequest(authorizationHeader, authToken) {
942
+ if (!authToken) {
943
+ return true;
944
+ }
945
+ if (!authorizationHeader) {
946
+ return false;
947
+ }
948
+ const expected = Buffer.from(`Bearer ${authToken}`);
949
+ const actual = Buffer.from(authorizationHeader);
950
+ if (expected.length !== actual.length) {
951
+ return false;
952
+ }
953
+ return (0, import_node_crypto.timingSafeEqual)(expected, actual);
954
+ }
955
+
667
956
  // src/mcp/stdio.ts
668
957
  init_registrations();
669
958
  init_zod();
670
- var ThenvoiMcpStdioServer = class {
959
+ init_schemas();
960
+ var BandMcpStdioServer = class {
671
961
  options;
672
962
  registrations;
673
963
  mcpServer = null;
@@ -696,7 +986,7 @@ var ThenvoiMcpStdioServer = class {
696
986
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
697
987
  const { z: z2 } = await import("zod");
698
988
  const mcpServer = new McpServer({
699
- name: this.options.name ?? "thenvoi",
989
+ name: this.options.name ?? MCP_SERVER_NAME,
700
990
  version: "1.0.0"
701
991
  });
702
992
  registerTools(mcpServer, z2, this.registrations);
@@ -729,12 +1019,13 @@ function registerTools(mcpServer, z2, registrations) {
729
1019
  // src/mcp/server.ts
730
1020
  init_registrations();
731
1021
  init_zod();
1022
+ init_schemas();
732
1023
  var PORT_RANGE_START = 5e4;
733
1024
  var PORT_RANGE_END = 6e4;
734
1025
  var MCP_SERVER_VERSION = "1.0.0";
735
1026
  var SESSION_IDLE_TTL_MS = 15 * 60 * 1e3;
736
1027
  var SESSION_SWEEP_INTERVAL_MS = 60 * 1e3;
737
- var ThenvoiMcpServer = class {
1028
+ var BandMcpServer = class {
738
1029
  options;
739
1030
  registrations;
740
1031
  httpServer = null;
@@ -778,7 +1069,7 @@ var ThenvoiMcpServer = class {
778
1069
  const http = await import("http");
779
1070
  const { randomUUID } = await import("crypto");
780
1071
  const { z: z2 } = await import("zod");
781
- const serverName = this.options.name ?? "thenvoi";
1072
+ const serverName = this.options.name ?? MCP_SERVER_NAME;
782
1073
  const app = express();
783
1074
  app.use(express.json());
784
1075
  app.get("/healthz", (_req, res) => {
@@ -786,6 +1077,10 @@ var ThenvoiMcpServer = class {
786
1077
  });
787
1078
  const handleMcpRequest = async (req, res) => {
788
1079
  try {
1080
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1081
+ sendMcpError(res, 401, "Unauthorized");
1082
+ return;
1083
+ }
789
1084
  const sessionId = getSessionIdHeader(req.headers["mcp-session-id"]);
790
1085
  let session = sessionId ? this.sessions.get(sessionId) : void 0;
791
1086
  if (!session) {
@@ -961,11 +1256,12 @@ function checkPort(http, port) {
961
1256
  // src/mcp/sse.ts
962
1257
  init_registrations();
963
1258
  init_zod();
1259
+ init_schemas();
964
1260
  var PORT_RANGE_START2 = 5e4;
965
1261
  var PORT_RANGE_END2 = 6e4;
966
1262
  var SESSION_IDLE_TTL_MS2 = 15 * 60 * 1e3;
967
1263
  var SESSION_SWEEP_INTERVAL_MS2 = 60 * 1e3;
968
- var ThenvoiMcpSseServer = class {
1264
+ var BandMcpSseServer = class {
969
1265
  options;
970
1266
  registrations;
971
1267
  httpServer = null;
@@ -1012,10 +1308,14 @@ var ThenvoiMcpSseServer = class {
1012
1308
  app.get("/healthz", (_req, res) => {
1013
1309
  res.json({ status: "ok" });
1014
1310
  });
1015
- app.get("/sse", async (_req, res) => {
1311
+ app.get("/sse", async (req, res) => {
1312
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1313
+ res.status(401).send("Unauthorized");
1314
+ return;
1315
+ }
1016
1316
  const transport = new SSEServerTransport("/messages", res);
1017
1317
  const mcpServer = new McpServer({
1018
- name: this.options.name ?? "thenvoi",
1318
+ name: this.options.name ?? MCP_SERVER_NAME,
1019
1319
  version: "1.0.0"
1020
1320
  });
1021
1321
  registerTools3(mcpServer, z2, this.registrations);
@@ -1037,6 +1337,10 @@ var ThenvoiMcpSseServer = class {
1037
1337
  });
1038
1338
  });
1039
1339
  app.post("/messages", async (req, res) => {
1340
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1341
+ res.status(401).send("Unauthorized");
1342
+ return;
1343
+ }
1040
1344
  const sessionId = typeof req.query.sessionId === "string" ? req.query.sessionId : null;
1041
1345
  if (!sessionId) {
1042
1346
  res.status(400).send("Missing sessionId");
@@ -1150,21 +1454,18 @@ function checkPort2(http, port) {
1150
1454
  }
1151
1455
 
1152
1456
  // src/mcp/backends.ts
1153
- async function createThenvoiMcpBackend(options) {
1154
- const registrations = buildRoomScopedRegistrations(
1155
- options.getToolsForRoom,
1156
- {
1157
- enableMemoryTools: options.enableMemoryTools,
1158
- enableContactTools: true,
1159
- additionalTools: options.additionalTools
1160
- }
1161
- );
1162
- const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
1457
+ async function createBandMcpBackend(options) {
1458
+ const registrationOptions = {
1459
+ enableMemoryTools: options.enableMemoryTools,
1460
+ enableContactTools: true,
1461
+ additionalTools: options.additionalTools
1462
+ };
1163
1463
  if (options.kind === "sdk") {
1164
- const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
1165
- const server2 = createThenvoiSdkMcpServer2({
1166
- enableMemoryTools: options.enableMemoryTools,
1464
+ const { createBandSdkMcpServer: createBandSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
1465
+ const server2 = createBandSdkMcpServer2({
1167
1466
  getToolsForRoom: options.getToolsForRoom,
1467
+ multiRoom: options.multiRoom,
1468
+ enableMemoryTools: options.enableMemoryTools,
1168
1469
  additionalTools: options.additionalTools
1169
1470
  });
1170
1471
  return {
@@ -1174,9 +1475,12 @@ async function createThenvoiMcpBackend(options) {
1174
1475
  stop: async () => void 0
1175
1476
  };
1176
1477
  }
1478
+ const resolvedTools = options.multiRoom === false ? resolveSingleRoomTools(options.getToolsForRoom) : options.getToolsForRoom;
1479
+ const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
1480
+ const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
1177
1481
  if (options.kind === "stdio") {
1178
- const server2 = new ThenvoiMcpStdioServer({
1179
- tools: options.getToolsForRoom,
1482
+ const server2 = new BandMcpStdioServer({
1483
+ tools: resolvedTools,
1180
1484
  enableMemoryTools: options.enableMemoryTools,
1181
1485
  enableContactTools: true,
1182
1486
  additionalTools: options.additionalTools
@@ -1191,40 +1495,45 @@ async function createThenvoiMcpBackend(options) {
1191
1495
  }
1192
1496
  };
1193
1497
  }
1498
+ const authToken = generateAuthToken();
1194
1499
  if (options.kind === "sse") {
1195
- const server2 = new ThenvoiMcpSseServer({
1196
- tools: options.getToolsForRoom,
1500
+ const server2 = new BandMcpSseServer({
1501
+ tools: resolvedTools,
1197
1502
  enableMemoryTools: options.enableMemoryTools,
1198
1503
  enableContactTools: true,
1199
- additionalTools: options.additionalTools
1504
+ additionalTools: options.additionalTools,
1505
+ authToken
1200
1506
  });
1201
1507
  await server2.start();
1202
1508
  return {
1203
1509
  kind: "sse",
1204
1510
  server: server2,
1205
1511
  allowedTools,
1512
+ authToken,
1206
1513
  stop: async () => {
1207
1514
  await server2.stop();
1208
1515
  }
1209
1516
  };
1210
1517
  }
1211
- const server = new ThenvoiMcpServer({
1212
- tools: options.getToolsForRoom,
1518
+ const server = new BandMcpServer({
1519
+ tools: resolvedTools,
1213
1520
  enableMemoryTools: options.enableMemoryTools,
1214
1521
  enableContactTools: true,
1215
- additionalTools: options.additionalTools
1522
+ additionalTools: options.additionalTools,
1523
+ authToken
1216
1524
  });
1217
1525
  await server.start();
1218
1526
  return {
1219
1527
  kind: "http",
1220
1528
  server,
1221
1529
  allowedTools,
1530
+ authToken,
1222
1531
  stop: async () => {
1223
1532
  await server.stop();
1224
1533
  }
1225
1534
  };
1226
1535
  }
1227
- function getThenvoiSdkMcpServerConfig(backend) {
1536
+ function getBandSdkMcpServerConfig(backend) {
1228
1537
  if (backend.kind !== "sdk") {
1229
1538
  throw new Error(`Expected sdk MCP backend, received ${backend.kind}`);
1230
1539
  }
@@ -1235,13 +1544,13 @@ function getThenvoiSdkMcpServerConfig(backend) {
1235
1544
  init_registrations();
1236
1545
  // Annotate the CommonJS export names for ESM import in node:
1237
1546
  0 && (module.exports = {
1238
- ThenvoiMcpServer,
1239
- ThenvoiMcpSseServer,
1240
- ThenvoiMcpStdioServer,
1547
+ BandMcpServer,
1548
+ BandMcpSseServer,
1549
+ BandMcpStdioServer,
1241
1550
  buildRoomScopedRegistrations,
1242
1551
  buildSingleContextRegistrations,
1243
- createThenvoiMcpBackend,
1552
+ createBandMcpBackend,
1244
1553
  errorResult,
1245
- getThenvoiSdkMcpServerConfig,
1554
+ getBandSdkMcpServerConfig,
1246
1555
  successResult
1247
1556
  });