@firfi/huly-mcp 0.7.0 → 0.8.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/README.md CHANGED
@@ -222,10 +222,10 @@ MCP_TRANSPORT=http MCP_HTTP_PORT=8080 MCP_HTTP_HOST=0.0.0.0 npx -y @firfi/huly-m
222
222
  | `create_teamspace` | Create a new Huly document teamspace. Idempotent: returns existing teamspace if one with the same name exists. |
223
223
  | `update_teamspace` | Update fields on an existing Huly document teamspace. Only provided fields are modified. Set description to null to clear it. |
224
224
  | `delete_teamspace` | Permanently delete a Huly document teamspace. This action cannot be undone. |
225
- | `list_documents` | List documents in a Huly teamspace. Returns documents sorted by modification date (newest first). Supports searching by title substring (titleSearch) and content (contentSearch). |
226
- | `get_document` | Retrieve full details for a Huly document including markdown content. Use this to view document content and metadata. |
227
- | `create_document` | Create a new document in a Huly teamspace. Content supports full markdown including native Mermaid diagrams (```mermaid blocks render interactively in Huly UI). Returns the created document id. Use link_document_to_issue to associate the document with a tracker issue. |
228
- | `edit_document` | Edit an existing Huly document. Two content modes (mutually exclusive): (1) 'content' for full replace, (2) 'old_text' + 'new_text' for targeted search-and-replace. Multiple matches error unless replace_all is true. Empty new_text deletes matched text. Also supports renaming via 'title'. Content supports full markdown including native Mermaid diagrams. |
225
+ | `list_documents` | List documents in a Huly teamspace. Returns documents sorted by modification date (newest first). Each result includes a 'url' field pointing to the document in the Huly web app. Supports searching by title substring (titleSearch) and content (contentSearch). |
226
+ | `get_document` | Retrieve full details for a Huly document including markdown content and a 'url' field pointing to the document in the Huly web app. Use this to view document content and metadata. |
227
+ | `create_document` | Create a new document in a Huly teamspace. Content supports full markdown including native Mermaid diagrams (```mermaid blocks render interactively in Huly UI). Returns the created document id and a 'url' field pointing to the document in the Huly web app. Use link_document_to_issue to associate the document with a tracker issue. |
228
+ | `edit_document` | Edit an existing Huly document. Two content modes (mutually exclusive): (1) 'content' for full replace, (2) 'old_text' + 'new_text' for targeted search-and-replace. Multiple matches error unless replace_all is true. Empty new_text deletes matched text. Also supports renaming via 'title'. Content supports full markdown including native Mermaid diagrams. Returns a 'url' field pointing to the document in the Huly web app. |
229
229
  | `list_inline_comments` | List inline comment threads from a Huly document. Extracts comments embedded in document content as ProseMirror marks. Each comment includes the highlighted text and thread ID. Set includeReplies=true to also fetch thread reply messages with sender names. |
230
230
  | `delete_document` | Permanently delete a Huly document. This action cannot be undone. |
231
231
 
@@ -282,6 +282,8 @@ MCP_TRANSPORT=http MCP_HTTP_PORT=8080 MCP_HTTP_HOST=0.0.0.0 npx -y @firfi/huly-m
282
282
  | `delete_channel` | Permanently delete a Huly channel. This action cannot be undone. |
283
283
  | `list_channel_messages` | List messages in a Huly channel. Returns messages sorted by date (newest first). |
284
284
  | `send_channel_message` | Send a message to a Huly channel. Message body supports markdown formatting. |
285
+ | `update_channel_message` | Update a channel message. Only the body can be modified. |
286
+ | `delete_channel_message` | Permanently delete a channel message. This action cannot be undone. |
285
287
  | `list_direct_messages` | List direct message conversations in Huly. Returns conversations sorted by date (newest first). |
286
288
  | `list_thread_replies` | List replies in a message thread. Returns replies sorted by date (oldest first). |
287
289
  | `add_thread_reply` | Add a reply to a message thread. Reply body supports markdown formatting. |
package/dist/index.cjs CHANGED
@@ -82791,7 +82791,7 @@ var require_client6 = __commonJS({
82791
82791
  var import_core48 = require_lib4();
82792
82792
  var import_platform2 = require_lib();
82793
82793
  var import_config8 = require_config();
82794
- var import_markup9 = require_markup();
82794
+ var import_markup10 = require_markup();
82795
82795
  var import_utils14 = require_utils9();
82796
82796
  async function connect(url4, options) {
82797
82797
  const config3 = await (0, import_config8.loadServerConfig)(url4);
@@ -82832,7 +82832,7 @@ var require_client6 = __commonJS({
82832
82832
  this.connection = connection;
82833
82833
  this.account = account;
82834
82834
  this.client = new import_core48.TxOperations(connection, account.primarySocialId);
82835
- this.markup = (0, import_markup9.createMarkupOperations)(url4, workspace, token, config3);
82835
+ this.markup = (0, import_markup10.createMarkupOperations)(url4, workspace, token, config3);
82836
82836
  }
82837
82837
  static {
82838
82838
  __name(this, "PlatformClientImpl");
@@ -82861,7 +82861,7 @@ var require_client6 = __commonJS({
82861
82861
  async processMarkup(_class, id, data) {
82862
82862
  const result = {};
82863
82863
  for (const [key, value3] of Object.entries(data)) {
82864
- if (value3 instanceof import_markup9.MarkupContent) {
82864
+ if (value3 instanceof import_markup10.MarkupContent) {
82865
82865
  result[key] = this.markup.uploadMarkup(_class, id, key, value3.content, value3.kind);
82866
82866
  } else {
82867
82867
  result[key] = value3;
@@ -150609,6 +150609,7 @@ var NotificationProviderId = NonEmptyString2.pipe(Schema_exports.brand("Notifica
150609
150609
  var NotificationTypeId = NonEmptyString2.pipe(Schema_exports.brand("NotificationTypeId"));
150610
150610
  var WorkspaceName = NonEmptyString2.pipe(Schema_exports.brand("WorkspaceName"));
150611
150611
  var UrlString = NonEmptyString2.pipe(Schema_exports.brand("UrlString"));
150612
+ var WorkspaceUrlSlug = NonEmptyString2.pipe(Schema_exports.brand("WorkspaceUrlSlug"));
150612
150613
  var WorkspaceVersion = NonEmptyString2.pipe(Schema_exports.brand("WorkspaceVersion"));
150613
150614
  var WorkspaceMode = NonEmptyString2.pipe(Schema_exports.brand("WorkspaceMode"));
150614
150615
  var WorkspaceUuid = NonEmptyString2.pipe(Schema_exports.brand("WorkspaceUuid"));
@@ -151501,7 +151502,7 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
151501
151502
  _HulyClient,
151502
151503
  Effect_exports.gen(function* () {
151503
151504
  const config3 = yield* HulyConfigService;
151504
- const { accountUuid, client, imageUrl, markupOps, refUrl } = yield* connectRestWithRetry({
151505
+ const { accountUuid, client, imageUrl, markupOps, refUrl, workspaceUrlSlug } = yield* connectRestWithRetry({
151505
151506
  url: config3.url,
151506
151507
  auth: config3.auth,
151507
151508
  workspace: config3.workspace
@@ -151510,6 +151511,10 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
151510
151511
  refUrl: UrlString.make(refUrl),
151511
151512
  imageUrl: UrlString.make(imageUrl)
151512
151513
  };
151514
+ const documentUrlConfig = {
151515
+ baseUrl: UrlString.make(config3.url),
151516
+ workspaceUrlSlug
151517
+ };
151513
151518
  const withClient = (op, errorMsg) => Effect_exports.tryPromise({
151514
151519
  try: () => op(client),
151515
151520
  catch: (e) => new HulyConnectionError({
@@ -151519,6 +151524,7 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
151519
151524
  });
151520
151525
  const operations = {
151521
151526
  getAccountUuid: () => accountUuid,
151527
+ documentUrlConfig,
151522
151528
  markupUrlConfig,
151523
151529
  findAll: (_class, query, options) => withClient(
151524
151530
  (client2) => client2.findAll(_class, query, options),
@@ -151598,6 +151604,10 @@ var HulyClient = class _HulyClient extends Context_exports.Tag("@hulymcp/HulyCli
151598
151604
  // AccountUuid is a double-branded string type with no public constructor
151599
151605
  // eslint-disable-next-line no-restricted-syntax -- see above
151600
151606
  getAccountUuid: () => "test-account-uuid",
151607
+ documentUrlConfig: {
151608
+ baseUrl: UrlString.make("https://test.huly.local"),
151609
+ workspaceUrlSlug: WorkspaceUrlSlug.make("test-workspace")
151610
+ },
151601
151611
  markupUrlConfig: testMarkupUrlConfig,
151602
151612
  findAll: noopFindAll,
151603
151613
  findOne: noopFindOne,
@@ -151642,7 +151652,7 @@ function createMarkupOps(url4, workspace, token, collaboratorUrl) {
151642
151652
  var connectRest = async (config3) => {
151643
151653
  const serverConfig = await (0, import_api_client.loadServerConfig)(config3.url);
151644
151654
  const authOptions = authToOptions(config3.auth, config3.workspace);
151645
- const { endpoint, token, workspaceId } = await (0, import_api_client.getWorkspaceToken)(
151655
+ const { endpoint, info, token, workspaceId } = await (0, import_api_client.getWorkspaceToken)(
151646
151656
  config3.url,
151647
151657
  authOptions,
151648
151658
  serverConfig
@@ -151656,7 +151666,14 @@ var connectRest = async (config3) => {
151656
151666
  token,
151657
151667
  serverConfig.COLLABORATOR_URL
151658
151668
  );
151659
- return { client, accountUuid: account.uuid, markupOps, refUrl, imageUrl };
151669
+ return {
151670
+ client,
151671
+ accountUuid: account.uuid,
151672
+ workspaceUrlSlug: WorkspaceUrlSlug.make(info.workspaceUrl),
151673
+ markupOps,
151674
+ refUrl,
151675
+ imageUrl
151676
+ };
151660
151677
  };
151661
151678
  var connectRestWithRetry = (config3) => connectWithRetry(() => connectRest(config3), "Connection failed");
151662
151679
 
@@ -172329,6 +172346,22 @@ var import_core24 = __toESM(require_lib4(), 1);
172329
172346
  var import_core23 = __toESM(require_lib4(), 1);
172330
172347
  var import_rank = __toESM(require_lib32(), 1);
172331
172348
 
172349
+ // src/huly/url-builders.ts
172350
+ var slugifyTitle = (title) => {
172351
+ const lowered = title.toLowerCase();
172352
+ const stripped = lowered.replace(/[^a-z0-9.\-\s]/g, "");
172353
+ const hyphenated = stripped.replace(/\s+/g, "-");
172354
+ const collapsed = hyphenated.replace(/-+/g, "-");
172355
+ return collapsed.replace(/^-+|-+$/g, "");
172356
+ };
172357
+ var buildDocumentUrl = (baseUrl, workspaceUrlSlug, title, id) => {
172358
+ const trimmedBase = baseUrl.replace(/\/+$/, "");
172359
+ const slug = slugifyTitle(title);
172360
+ const pathSegment = slug === "" ? id : `${slug}-${id}`;
172361
+ return UrlString.make(`${trimmedBase}/workbench/${workspaceUrlSlug}/document/${pathSegment}`);
172362
+ };
172363
+ var buildDocumentUrlFromConfig = (config3, title, id) => buildDocumentUrl(config3.baseUrl, config3.workspaceUrlSlug, title, id);
172364
+
172332
172365
  // src/huly/operations/documents-edit.ts
172333
172366
  var editDocument = (params) => Effect_exports.gen(function* () {
172334
172367
  const { client, doc, teamspace } = yield* findTeamspaceAndDocument(params);
@@ -172392,8 +172425,10 @@ var editDocument = (params) => Effect_exports.gen(function* () {
172392
172425
  );
172393
172426
  contentUpdatedInPlace = true;
172394
172427
  }
172428
+ const finalTitle = updateOps.title ?? doc.title;
172429
+ const url4 = buildDocumentUrlFromConfig(client.documentUrlConfig, finalTitle, DocumentId.make(doc._id));
172395
172430
  if (Object.keys(updateOps).length === 0 && !contentUpdatedInPlace) {
172396
- return { id: DocumentId.make(doc._id), updated: false };
172431
+ return { id: DocumentId.make(doc._id), updated: false, url: url4 };
172397
172432
  }
172398
172433
  if (Object.keys(updateOps).length > 0) {
172399
172434
  yield* client.updateDoc(
@@ -172403,7 +172438,7 @@ var editDocument = (params) => Effect_exports.gen(function* () {
172403
172438
  updateOps
172404
172439
  );
172405
172440
  }
172406
- return { id: DocumentId.make(doc._id), updated: true };
172441
+ return { id: DocumentId.make(doc._id), updated: true, url: url4 };
172407
172442
  });
172408
172443
  var countOccurrences = (text, search) => {
172409
172444
  let count3 = 0;
@@ -172421,6 +172456,55 @@ var import_text3 = __toESM(require_lib9(), 1);
172421
172456
 
172422
172457
  // src/huly/operations/channels.ts
172423
172458
  var import_core21 = __toESM(require_lib4(), 1);
172459
+
172460
+ // src/huly/operations/channel-messages-shared.ts
172461
+ var findChannelMessage = (params) => Effect_exports.gen(function* () {
172462
+ const { channel, client } = yield* findChannel(params.channel);
172463
+ const message = yield* client.findOne(
172464
+ chunter.class.ChatMessage,
172465
+ {
172466
+ _id: toRef(params.messageId),
172467
+ space: channel._id
172468
+ }
172469
+ );
172470
+ if (message === void 0) {
172471
+ return yield* new MessageNotFoundError({
172472
+ messageId: params.messageId,
172473
+ channel: params.channel
172474
+ });
172475
+ }
172476
+ return { client, channel, message };
172477
+ });
172478
+
172479
+ // src/huly/operations/channels-messages.ts
172480
+ var updateChannelMessage = (params) => Effect_exports.gen(function* () {
172481
+ const { channel, client, message } = yield* findChannelMessage(params);
172482
+ const markupUrlConfig = client.markupUrlConfig;
172483
+ const markup = markdownToMarkupString(params.body, markupUrlConfig);
172484
+ const now2 = yield* Clock_exports.currentTimeMillis;
172485
+ const updateOps = {
172486
+ message: markup,
172487
+ editedOn: now2
172488
+ };
172489
+ yield* client.updateDoc(
172490
+ chunter.class.ChatMessage,
172491
+ channel._id,
172492
+ message._id,
172493
+ updateOps
172494
+ );
172495
+ return { id: MessageId.make(message._id), updated: true };
172496
+ });
172497
+ var deleteChannelMessage = (params) => Effect_exports.gen(function* () {
172498
+ const { channel, client, message } = yield* findChannelMessage(params);
172499
+ yield* client.removeDoc(
172500
+ chunter.class.ChatMessage,
172501
+ channel._id,
172502
+ message._id
172503
+ );
172504
+ return { id: MessageId.make(message._id), deleted: true };
172505
+ });
172506
+
172507
+ // src/huly/operations/channels.ts
172424
172508
  var personIdsAsSocialIdentityRefs = (ids3) => ids3;
172425
172509
  var findChannel = (identifier2) => Effect_exports.gen(function* () {
172426
172510
  const client = yield* HulyClient;
@@ -172939,6 +173023,7 @@ var listDocuments = (params) => Effect_exports.gen(function* () {
172939
173023
  id: DocumentId.make(doc._id),
172940
173024
  title: doc.title,
172941
173025
  teamspace: teamspace.name,
173026
+ url: buildDocumentUrlFromConfig(client.documentUrlConfig, doc.title, DocumentId.make(doc._id)),
172942
173027
  modifiedOn: doc.modifiedOn
172943
173028
  }));
172944
173029
  return {
@@ -172963,6 +173048,7 @@ var getDocument = (params) => Effect_exports.gen(function* () {
172963
173048
  title: doc.title,
172964
173049
  content,
172965
173050
  teamspace: teamspace.name,
173051
+ url: buildDocumentUrlFromConfig(client.documentUrlConfig, doc.title, DocumentId.make(doc._id)),
172966
173052
  modifiedOn: doc.modifiedOn,
172967
173053
  createdOn: doc.createdOn
172968
173054
  };
@@ -173012,7 +173098,11 @@ var createDocument = (params) => Effect_exports.gen(function* () {
173012
173098
  documentData,
173013
173099
  documentId
173014
173100
  );
173015
- return { id: DocumentId.make(documentId), title: params.title };
173101
+ return {
173102
+ id: DocumentId.make(documentId),
173103
+ title: params.title,
173104
+ url: buildDocumentUrlFromConfig(client.documentUrlConfig, params.title, DocumentId.make(documentId))
173105
+ };
173016
173106
  });
173017
173107
  var deleteDocument = (params) => Effect_exports.gen(function* () {
173018
173108
  const { client, doc, teamspace } = yield* findTeamspaceAndDocument(params);
@@ -176044,6 +176134,31 @@ var SendChannelMessageParamsSchema = Schema_exports.Struct({
176044
176134
  title: "SendChannelMessageParams",
176045
176135
  description: "Parameters for sending a message to a channel"
176046
176136
  });
176137
+ var UpdateChannelMessageParamsSchema = Schema_exports.Struct({
176138
+ channel: ChannelIdentifier.annotations({
176139
+ description: "Channel name or ID"
176140
+ }),
176141
+ messageId: MessageId.annotations({
176142
+ description: "Message ID to update"
176143
+ }),
176144
+ body: NonEmptyString2.annotations({
176145
+ description: "New message body (markdown supported)"
176146
+ })
176147
+ }).annotations({
176148
+ title: "UpdateChannelMessageParams",
176149
+ description: "Parameters for updating a channel message"
176150
+ });
176151
+ var DeleteChannelMessageParamsSchema = Schema_exports.Struct({
176152
+ channel: ChannelIdentifier.annotations({
176153
+ description: "Channel name or ID"
176154
+ }),
176155
+ messageId: MessageId.annotations({
176156
+ description: "Message ID to delete"
176157
+ })
176158
+ }).annotations({
176159
+ title: "DeleteChannelMessageParams",
176160
+ description: "Parameters for deleting a channel message"
176161
+ });
176047
176162
  var ListDirectMessagesParamsSchema = Schema_exports.Struct({
176048
176163
  limit: Schema_exports.optional(
176049
176164
  LimitParam.annotations({
@@ -176122,6 +176237,8 @@ var updateChannelParamsJsonSchema = JSONSchema_exports.make(UpdateChannelParamsS
176122
176237
  var deleteChannelParamsJsonSchema = JSONSchema_exports.make(DeleteChannelParamsSchema);
176123
176238
  var listChannelMessagesParamsJsonSchema = JSONSchema_exports.make(ListChannelMessagesParamsSchema);
176124
176239
  var sendChannelMessageParamsJsonSchema = JSONSchema_exports.make(SendChannelMessageParamsSchema);
176240
+ var updateChannelMessageParamsJsonSchema = JSONSchema_exports.make(UpdateChannelMessageParamsSchema);
176241
+ var deleteChannelMessageParamsJsonSchema = JSONSchema_exports.make(DeleteChannelMessageParamsSchema);
176125
176242
  var listDirectMessagesParamsJsonSchema = JSONSchema_exports.make(ListDirectMessagesParamsSchema);
176126
176243
  var listThreadRepliesParamsJsonSchema = JSONSchema_exports.make(ListThreadRepliesParamsSchema);
176127
176244
  var addThreadReplyParamsJsonSchema = JSONSchema_exports.make(AddThreadReplyParamsSchema);
@@ -176134,6 +176251,8 @@ var parseUpdateChannelParams = Schema_exports.decodeUnknown(UpdateChannelParamsS
176134
176251
  var parseDeleteChannelParams = Schema_exports.decodeUnknown(DeleteChannelParamsSchema);
176135
176252
  var parseListChannelMessagesParams = Schema_exports.decodeUnknown(ListChannelMessagesParamsSchema);
176136
176253
  var parseSendChannelMessageParams = Schema_exports.decodeUnknown(SendChannelMessageParamsSchema);
176254
+ var parseUpdateChannelMessageParams = Schema_exports.decodeUnknown(UpdateChannelMessageParamsSchema);
176255
+ var parseDeleteChannelMessageParams = Schema_exports.decodeUnknown(DeleteChannelMessageParamsSchema);
176137
176256
  var parseListDirectMessagesParams = Schema_exports.decodeUnknown(ListDirectMessagesParamsSchema);
176138
176257
  var parseListThreadRepliesParams = Schema_exports.decodeUnknown(ListThreadRepliesParamsSchema);
176139
176258
  var parseAddThreadReplyParams = Schema_exports.decodeUnknown(AddThreadReplyParamsSchema);
@@ -177564,20 +177683,6 @@ var cardTools = [
177564
177683
 
177565
177684
  // src/huly/operations/threads.ts
177566
177685
  var import_core28 = __toESM(require_lib4(), 1);
177567
- var findMessage = (channelIdentifier, messageId) => Effect_exports.gen(function* () {
177568
- const { channel, client } = yield* findChannel(channelIdentifier);
177569
- const message = yield* client.findOne(
177570
- chunter.class.ChatMessage,
177571
- {
177572
- _id: toRef(messageId),
177573
- space: channel._id
177574
- }
177575
- );
177576
- if (message === void 0) {
177577
- return yield* new MessageNotFoundError({ messageId, channel: channelIdentifier });
177578
- }
177579
- return { client, channel, message };
177580
- });
177581
177686
  var findReply = (client, channel, message, replyId) => Effect_exports.gen(function* () {
177582
177687
  const reply = yield* client.findOne(
177583
177688
  chunter.class.ThreadMessage,
@@ -177596,7 +177701,7 @@ var findReply = (client, channel, message, replyId) => Effect_exports.gen(functi
177596
177701
  return reply;
177597
177702
  });
177598
177703
  var listThreadReplies = (params) => Effect_exports.gen(function* () {
177599
- const { channel, client, message } = yield* findMessage(params.channel, params.messageId);
177704
+ const { channel, client, message } = yield* findChannelMessage(params);
177600
177705
  const markupUrlConfig = client.markupUrlConfig;
177601
177706
  const limit = Math.min(params.limit ?? 50, 200);
177602
177707
  const replies = yield* client.findAll(
@@ -177634,7 +177739,7 @@ var listThreadReplies = (params) => Effect_exports.gen(function* () {
177634
177739
  return { replies: threadMessages, total };
177635
177740
  });
177636
177741
  var addThreadReply = (params) => Effect_exports.gen(function* () {
177637
- const { channel, client, message } = yield* findMessage(params.channel, params.messageId);
177742
+ const { channel, client, message } = yield* findChannelMessage(params);
177638
177743
  const markupUrlConfig = client.markupUrlConfig;
177639
177744
  const replyId = (0, import_core28.generateId)();
177640
177745
  const markup = markdownToMarkupString(params.body, markupUrlConfig);
@@ -177660,7 +177765,7 @@ var addThreadReply = (params) => Effect_exports.gen(function* () {
177660
177765
  };
177661
177766
  });
177662
177767
  var updateThreadReply = (params) => Effect_exports.gen(function* () {
177663
- const { channel, client, message } = yield* findMessage(params.channel, params.messageId);
177768
+ const { channel, client, message } = yield* findChannelMessage(params);
177664
177769
  const reply = yield* findReply(client, channel, message, params.replyId);
177665
177770
  const markupUrlConfig = client.markupUrlConfig;
177666
177771
  const markup = markdownToMarkupString(params.body, markupUrlConfig);
@@ -177678,7 +177783,7 @@ var updateThreadReply = (params) => Effect_exports.gen(function* () {
177678
177783
  return { id: ThreadReplyId.make(reply._id), updated: true };
177679
177784
  });
177680
177785
  var deleteThreadReply = (params) => Effect_exports.gen(function* () {
177681
- const { channel, client, message } = yield* findMessage(params.channel, params.messageId);
177786
+ const { channel, client, message } = yield* findChannelMessage(params);
177682
177787
  const reply = yield* findReply(client, channel, message, params.replyId);
177683
177788
  yield* client.removeDoc(
177684
177789
  chunter.class.ThreadMessage,
@@ -177768,6 +177873,28 @@ var channelTools = [
177768
177873
  sendChannelMessage
177769
177874
  )
177770
177875
  },
177876
+ {
177877
+ name: "update_channel_message",
177878
+ description: "Update a channel message. Only the body can be modified.",
177879
+ category: CATEGORY5,
177880
+ inputSchema: updateChannelMessageParamsJsonSchema,
177881
+ handler: createToolHandler(
177882
+ "update_channel_message",
177883
+ parseUpdateChannelMessageParams,
177884
+ updateChannelMessage
177885
+ )
177886
+ },
177887
+ {
177888
+ name: "delete_channel_message",
177889
+ description: "Permanently delete a channel message. This action cannot be undone.",
177890
+ category: CATEGORY5,
177891
+ inputSchema: deleteChannelMessageParamsJsonSchema,
177892
+ handler: createToolHandler(
177893
+ "delete_channel_message",
177894
+ parseDeleteChannelMessageParams,
177895
+ deleteChannelMessage
177896
+ )
177897
+ },
177771
177898
  {
177772
177899
  name: "list_direct_messages",
177773
177900
  description: "List direct message conversations in Huly. Returns conversations sorted by date (newest first).",
@@ -179407,7 +179534,7 @@ var documentTools = [
179407
179534
  },
179408
179535
  {
179409
179536
  name: "list_documents",
179410
- description: "List documents in a Huly teamspace. Returns documents sorted by modification date (newest first). Supports searching by title substring (titleSearch) and content (contentSearch).",
179537
+ description: "List documents in a Huly teamspace. Returns documents sorted by modification date (newest first). Each result includes a 'url' field pointing to the document in the Huly web app. Supports searching by title substring (titleSearch) and content (contentSearch).",
179411
179538
  category: CATEGORY10,
179412
179539
  inputSchema: listDocumentsParamsJsonSchema,
179413
179540
  handler: createToolHandler(
@@ -179418,7 +179545,7 @@ var documentTools = [
179418
179545
  },
179419
179546
  {
179420
179547
  name: "get_document",
179421
- description: "Retrieve full details for a Huly document including markdown content. Use this to view document content and metadata.",
179548
+ description: "Retrieve full details for a Huly document including markdown content and a 'url' field pointing to the document in the Huly web app. Use this to view document content and metadata.",
179422
179549
  category: CATEGORY10,
179423
179550
  inputSchema: getDocumentParamsJsonSchema,
179424
179551
  handler: createToolHandler(
@@ -179429,7 +179556,7 @@ var documentTools = [
179429
179556
  },
179430
179557
  {
179431
179558
  name: "create_document",
179432
- description: "Create a new document in a Huly teamspace. Content supports full markdown including native Mermaid diagrams (```mermaid blocks render interactively in Huly UI). Returns the created document id. Use link_document_to_issue to associate the document with a tracker issue.",
179559
+ description: "Create a new document in a Huly teamspace. Content supports full markdown including native Mermaid diagrams (```mermaid blocks render interactively in Huly UI). Returns the created document id and a 'url' field pointing to the document in the Huly web app. Use link_document_to_issue to associate the document with a tracker issue.",
179433
179560
  category: CATEGORY10,
179434
179561
  inputSchema: createDocumentParamsJsonSchema,
179435
179562
  handler: createToolHandler(
@@ -179440,7 +179567,7 @@ var documentTools = [
179440
179567
  },
179441
179568
  {
179442
179569
  name: "edit_document",
179443
- description: "Edit an existing Huly document. Two content modes (mutually exclusive): (1) 'content' for full replace, (2) 'old_text' + 'new_text' for targeted search-and-replace. Multiple matches error unless replace_all is true. Empty new_text deletes matched text. Also supports renaming via 'title'. Content supports full markdown including native Mermaid diagrams.",
179570
+ description: "Edit an existing Huly document. Two content modes (mutually exclusive): (1) 'content' for full replace, (2) 'old_text' + 'new_text' for targeted search-and-replace. Multiple matches error unless replace_all is true. Empty new_text deletes matched text. Also supports renaming via 'title'. Content supports full markdown including native Mermaid diagrams. Returns a 'url' field pointing to the document in the Huly web app.",
179444
179571
  category: CATEGORY10,
179445
179572
  inputSchema: editDocumentParamsJsonSchema,
179446
179573
  handler: createToolHandler(