@burdenoff/mcp-libs 2026.1007.3 → 2026.1007.4

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.
@@ -3,7 +3,7 @@ import { z } from 'zod';
3
3
 
4
4
  // src/modules/conversations/operations.ts
5
5
  var LIST_CONVERSATIONS = `
6
- query ListConversations($filter: ConversationFilterInput, $first: Int, $after: String) {
6
+ query ListConversations($filter: ConversationFilter, $first: Int, $after: String) {
7
7
  conversations(filter: $filter, first: $first, after: $after) {
8
8
  edges { node { id title type description createdAt updatedAt unreadCount } }
9
9
  pageInfo { hasNextPage endCursor }
@@ -13,7 +13,7 @@ var LIST_CONVERSATIONS = `
13
13
  var GET_CONVERSATION = `
14
14
  query GetConversation($id: ID!) {
15
15
  conversation(id: $id) {
16
- id title type description avatarUrl settings
16
+ id title type description avatar settings
17
17
  createdAt updatedAt
18
18
  }
19
19
  }
@@ -49,7 +49,7 @@ var LIST_MESSAGES = `
49
49
  messages(conversationId: $conversationId, filter: $filter, first: $first, after: $after) {
50
50
  edges {
51
51
  cursor
52
- node { id conversationId senderId content type metadata createdAt updatedAt }
52
+ node { id conversationId authorId content type metadata createdAt updatedAt }
53
53
  }
54
54
  pageInfo { hasNextPage endCursor }
55
55
  }
@@ -188,7 +188,7 @@ var GET_THREAD = `
188
188
  `;
189
189
  var GET_OR_CREATE_DIRECT_CONVERSATION = `
190
190
  mutation GetOrCreateDirectConversation($userId: ID!) {
191
- getOrCreateDirectConversation(userId: $userId) {
191
+ resolveContextConversation(userId: $userId) {
192
192
  id title type createdAt
193
193
  }
194
194
  }
@@ -418,17 +418,24 @@ function registerConversationsTools(server, ctx, track) {
418
418
  title: z.string().describe("Conversation title"),
419
419
  description: z.string().optional().describe("Conversation description"),
420
420
  type: ConversationTypeEnum.optional().describe("Conversation type (default: GROUP)"),
421
- participantIds: z.array(z.string()).optional().describe("Participant user IDs")
421
+ // BOFF-8184: `participantIds` and `workspaceId` are required by
422
+ // `CreateConversationInput!` on the live schema. They must be
423
+ // supplied by the caller; the MCP does not auto-fill workspaceId
424
+ // because the live resolver rejects with `Forbidden` when the
425
+ // request arrives without a verified workspace context.
426
+ participantIds: z.array(z.string()).min(1).describe("Participant user IDs (required, \u2265 1)"),
427
+ workspaceId: z.string().describe("Workspace ID the conversation belongs to (required)")
422
428
  }
423
429
  },
424
- async ({ title, description, type, participantIds }) => {
430
+ async ({ title, description, type, participantIds, workspaceId }) => {
425
431
  try {
426
432
  const input = {
427
433
  title,
428
- type: type ?? "GROUP"
434
+ type: type ?? "GROUP",
435
+ participantIds,
436
+ workspaceId
429
437
  };
430
438
  if (description !== void 0) input.description = description;
431
- if (participantIds !== void 0) input.participantIds = participantIds;
432
439
  const data = await ctx.gql.workspace.request(CREATE_CONVERSATION, { input });
433
440
  return jsonResult(data.createConversation.conversation);
434
441
  } catch (error) {
@@ -496,15 +503,27 @@ function registerConversationsTools(server, ctx, track) {
496
503
  description: "Send a text message to a conversation. Optionally reply to a parent message.",
497
504
  inputSchema: {
498
505
  conversationId: z.string().describe("Conversation ID"),
499
- content: z.string().describe("Message content"),
506
+ // BOFF-8186: `SendMessageInput.content` is `MessageContentInput!` (an
507
+ // object), not a scalar. Accept a `content` object so callers can
508
+ // pass `{ text: "..." }`; the convenience alias `text` below
509
+ // accepts the scalar and wraps it. Object form wins if both are
510
+ // given.
511
+ content: z.record(z.unknown()).optional().describe('Message content as MessageContentInput object (e.g. { text: "..." })'),
512
+ text: z.string().optional().describe("Convenience alias: scalar text wrapped into { text }"),
500
513
  parentMessageId: z.string().optional().describe("Parent message ID (for replies)")
501
514
  }
502
515
  },
503
- async ({ conversationId, content, parentMessageId }) => {
516
+ async ({ conversationId, content, text, parentMessageId }) => {
504
517
  try {
518
+ if (content === void 0 && text === void 0) {
519
+ return errorResult(
520
+ "Provide either `content` (MessageContentInput object) or `text` (scalar convenience alias)"
521
+ );
522
+ }
523
+ const messageContent = content ?? (text !== void 0 ? { text } : {});
505
524
  const input = {
506
525
  conversationId,
507
- content,
526
+ content: messageContent,
508
527
  type: "TEXT"
509
528
  };
510
529
  if (parentMessageId !== void 0) input.parentMessageId = parentMessageId;
@@ -1067,7 +1086,7 @@ function registerThreadAndDirectTools(server, ctx, track) {
1067
1086
  async ({ userId }) => {
1068
1087
  try {
1069
1088
  const data = await ctx.gql.workspace.request(GET_OR_CREATE_DIRECT_CONVERSATION, { userId });
1070
- return jsonResult(data.getOrCreateDirectConversation);
1089
+ return jsonResult(data.resolveContextConversation);
1071
1090
  } catch (error) {
1072
1091
  ctx.logger.error("conversations_get_or_create_direct failed", { error });
1073
1092
  return errorResult(`Failed to open direct conversation: ${unwrap(error)}`);