@publishq/mcp 0.0.7 → 1.0.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
@@ -90,8 +90,13 @@ Any MCP client that launches a stdio server works the same way: run the command
90
90
  | `publishq_upload_media` | Upload a file and get a media ID: a local path (local server) or a link or chat attachment (hosted server) |
91
91
  | `publishq_create_media_upload` | Get a signed URL to upload a file from your own disk, up to 4 GB |
92
92
  | `publishq_delete_media` | Delete a media file no draft or scheduled post uses |
93
+ | `publishq_list_media_folders` | List media folders with their file counts |
94
+ | `publishq_move_media` | Move media files to a folder or to the top level |
95
+ | `publishq_rename_media_folder` | Rename a media folder |
96
+ | `publishq_preview_media_folder_deletion` | Count what deleting a folder would remove |
97
+ | `publishq_delete_media_folder` | Delete a folder and its files, after the preview |
93
98
 
94
- The tools are thin wrappers over [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk), so their behavior and scopes match the [PublishQ API](https://publishq.com/docs). `publishq_create_post` accepts an `accounts` array whose entries contain `accountId` plus optional `postOverrides` and `platformSpecificSettings`. `publishq_update_post` accepts content, scheduling, complete media replacement or removal, and thumbnail timestamp changes. `publishq_list_media` can filter by media IDs, types, and sources. For TikTok, the agent should call `publishq_get_tiktok_creator_info` first and then provide the required privacy and interaction settings in that account object. A tool call that hits an API error returns the API error so the agent can react.
99
+ The tools are thin wrappers over [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk), so their behavior and scopes match the [PublishQ API](https://publishq.com/docs). `publishq_create_post` accepts an `accounts` array whose entries contain `accountId` plus optional `postOverrides` and `platformSpecificSettings`. `publishq_update_post` accepts content, scheduling, complete media replacement or removal, and thumbnail timestamp changes. `publishq_list_media` can filter by media IDs, types, sources and folder, and `publishq_upload_media` takes a `folderPath`. Folder paths look like `Channel A/Shorts`. Before `publishq_delete_media_folder`, the agent calls `publishq_preview_media_folder_deletion`, shows the counts to the user and passes the `fileCount` back as `expectedFileCount`. For TikTok, the agent should call `publishq_get_tiktok_creator_info` first and then provide the required privacy and interaction settings in that account object. A tool call that hits an API error returns the API error so the agent can react.
95
100
 
96
101
  ## Scopes
97
102
 
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  zCreateMediaUploadBody,
20
20
  zCreatePostBody,
21
21
  zCreateWorkspaceBody,
22
+ zDeleteMediaFolderBody,
22
23
  zDeleteMediaPath,
23
24
  zDeletePostPath,
24
25
  zGetMediaPath,
@@ -28,7 +29,10 @@ import {
28
29
  zListAccountsQuery,
29
30
  zListMediaQuery,
30
31
  zListPostsQuery,
32
+ zMoveMediaBody,
33
+ zPreviewMediaFolderDeletionQuery,
31
34
  zRemovePostAccountPath,
35
+ zRenameMediaFolderBody,
32
36
  zUpdatePostBody,
33
37
  zUpdatePostPath
34
38
  } from "@publishq/sdk";
@@ -284,6 +288,56 @@ function publishqTools(publishq2) {
284
288
  },
285
289
  (args) => run(publishq2.media.delete(args.id))
286
290
  );
291
+ register(
292
+ {
293
+ name: "publishq_list_media_folders",
294
+ title: "List media folders",
295
+ description: 'List every folder in the media library, parents before subfolders, with the number of files in each folder and its subfolders. Folder paths look like "Channel A/Shorts". Use a path as folderPath in publishq_list_media, publishq_upload_media or publishq_move_media.',
296
+ inputSchema: { type: "object", properties: {}, additionalProperties: false },
297
+ annotations: { readOnlyHint: true, openWorldHint: true }
298
+ },
299
+ () => run(publishq2.media.listFolders())
300
+ );
301
+ register(
302
+ {
303
+ name: "publishq_move_media",
304
+ title: "Move media to a folder",
305
+ description: 'Move up to 100 media files to a folder by path, for example "Channel A/Shorts", or to the top level with folderPath null. A folder that does not exist yet is created by moving files into it. Posts keep working: they use media IDs, not folders.',
306
+ inputSchema: advertisedSchema(zMoveMediaBody),
307
+ annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: true }
308
+ },
309
+ (args) => run(publishq2.media.move(args))
310
+ );
311
+ register(
312
+ {
313
+ name: "publishq_rename_media_folder",
314
+ title: "Rename a media folder",
315
+ description: "Rename a media folder. Only the last part of the path changes, and its files and subfolders follow. Answers 404 when no folder has that path (check publishq_list_media_folders), and is refused when a folder with the new name already exists at the same level.",
316
+ inputSchema: advertisedSchema(zRenameMediaFolderBody),
317
+ annotations: { readOnlyHint: false, openWorldHint: true }
318
+ },
319
+ (args) => run(publishq2.media.renameFolder(args))
320
+ );
321
+ register(
322
+ {
323
+ name: "publishq_preview_media_folder_deletion",
324
+ title: "Preview deleting a media folder",
325
+ description: "Count what deleting a media folder would remove: files and subfolders at every level, and files kept because a draft or scheduled post uses them. Call this first, show the numbers to the user and get their confirmation before publishq_delete_media_folder.",
326
+ inputSchema: advertisedSchema(zPreviewMediaFolderDeletionQuery),
327
+ annotations: { readOnlyHint: true, openWorldHint: true }
328
+ },
329
+ (args) => run(publishq2.media.previewFolderDeletion(args.path))
330
+ );
331
+ register(
332
+ {
333
+ name: "publishq_delete_media_folder",
334
+ title: "Delete a media folder",
335
+ description: "Delete a media folder with every file in it and in its subfolders, from the media library and from storage. This cannot be undone. Files a draft or scheduled post uses are kept. Only call it after the user confirmed the numbers from publishq_preview_media_folder_deletion, and send that fileCount as expectedFileCount; if the folder changed since, nothing is deleted.",
336
+ inputSchema: advertisedSchema(zDeleteMediaFolderBody),
337
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true }
338
+ },
339
+ (args) => run(publishq2.media.deleteFolder(args))
340
+ );
287
341
  return tools;
288
342
  }
289
343
  function createPublishQServer(tools) {
@@ -342,6 +396,10 @@ var server = createPublishQServer([
342
396
  filename: {
343
397
  type: "string",
344
398
  description: "Override the uploaded file name"
399
+ },
400
+ folderPath: {
401
+ type: "string",
402
+ description: 'Folder to put the file in, for example "Channel A/Shorts". Leave it out for the top level. See publishq_list_media_folders.'
345
403
  }
346
404
  },
347
405
  required: ["filePath"],
@@ -352,6 +410,7 @@ var server = createPublishQServer([
352
410
  handler: async (args) => {
353
411
  const filePath = args.filePath;
354
412
  const filename = args.filename;
413
+ const folderPath = args.folderPath;
355
414
  if (statSync(filePath).size >= OPEN_AS_BLOB_MAX_BYTES) {
356
415
  return {
357
416
  content: [
@@ -367,7 +426,12 @@ var server = createPublishQServer([
367
426
  [await openAsBlob(filePath)],
368
427
  filename ?? basename(filePath)
369
428
  );
370
- return run(publishq.media.upload({ file }));
429
+ return run(
430
+ publishq.media.upload(
431
+ { file },
432
+ folderPath !== void 0 ? { folderPath } : void 0
433
+ )
434
+ );
371
435
  }
372
436
  }
373
437
  ]);
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@publishq/mcp",
3
- "version": "0.0.7",
3
+ "version": "1.0.0",
4
+ "mcpName": "com.publishq/publishq",
4
5
  "private": false,
5
6
  "description": "Model Context Protocol (MCP) server for PublishQ. Let AI agents schedule and publish across your social platforms.",
6
7
  "license": "Apache-2.0",
@@ -31,7 +32,7 @@
31
32
  "dependencies": {
32
33
  "@modelcontextprotocol/sdk": "1.29.0",
33
34
  "zod": "4.4.3",
34
- "@publishq/sdk": "^0.0.7"
35
+ "@publishq/sdk": "^1.0.0"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/node": "^20",