postproxy-mcp 1.1.0 → 1.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/worker/index.ts CHANGED
@@ -403,6 +403,8 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
403
403
  * @param platforms {string} Optional JSON string of platform-specific parameters
404
404
  * @param media_files {string} Optional JSON array of file objects with {filename, data (base64), content_type?}
405
405
  * @param thread {string} Optional JSON array of thread child posts [{body, media?}]. Supported on X and Threads only.
406
+ * @param queue_id {string} Optional queue ID to add the post to
407
+ * @param queue_priority {string} Optional priority when adding to a queue (high, medium, low)
406
408
  * @return {Promise<string>} Post creation result as JSON
407
409
  */
408
410
  async postPublish(
@@ -415,7 +417,9 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
415
417
  draft?: boolean,
416
418
  platforms?: string,
417
419
  media_files?: string,
418
- thread?: string
420
+ thread?: string,
421
+ queue_id?: string,
422
+ queue_priority?: string
419
423
  ): Promise<string> {
420
424
  this.getApiKey(); // Validate API key is present
421
425
 
@@ -576,6 +580,13 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
576
580
  apiPayload.thread = threadChildren;
577
581
  }
578
582
 
583
+ if (queue_id) {
584
+ apiPayload.queue_id = queue_id;
585
+ if (queue_priority) {
586
+ apiPayload.queue_priority = queue_priority;
587
+ }
588
+ }
589
+
579
590
  const extraHeaders: Record<string, string> = {
580
591
  "Idempotency-Key": finalIdempotencyKey,
581
592
  };
@@ -786,6 +797,171 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
786
797
  return JSON.stringify({ placements }, null, 2);
787
798
  }
788
799
 
800
+ /**
801
+ * List all queues
802
+ * @param profile_group_id {string} Optional profile group ID to filter queues
803
+ * @return {Promise<string>} List of queues as JSON
804
+ */
805
+ async queuesList(profile_group_id?: string): Promise<string> {
806
+ this.getApiKey();
807
+
808
+ const path = profile_group_id
809
+ ? `/post_queues?profile_group_id=${profile_group_id}`
810
+ : "/post_queues";
811
+ const response = await this.apiRequest<any>("GET", path);
812
+ const queues = this.extractArray<any>(response);
813
+
814
+ return JSON.stringify({ queues }, null, 2);
815
+ }
816
+
817
+ /**
818
+ * Get a single queue by ID
819
+ * @param queue_id {string} Queue ID
820
+ * @return {Promise<string>} Queue details as JSON
821
+ */
822
+ async queuesGet(queue_id: string): Promise<string> {
823
+ if (!queue_id) {
824
+ throw new Error("queue_id is required");
825
+ }
826
+
827
+ const queue = await this.apiRequest<any>("GET", `/post_queues/${queue_id}`);
828
+ return JSON.stringify(queue, null, 2);
829
+ }
830
+
831
+ /**
832
+ * Create a new posting queue
833
+ * @param profile_group_id {string} Profile group ID to connect the queue to
834
+ * @param name {string} Queue name
835
+ * @param description {string} Optional description
836
+ * @param timezone {string} Optional IANA timezone (default: UTC)
837
+ * @param jitter {number} Optional random offset in minutes (0-60)
838
+ * @param timeslots {string} Optional JSON array of timeslots [{day, time}]
839
+ * @return {Promise<string>} Created queue as JSON
840
+ */
841
+ async queuesCreate(
842
+ profile_group_id: string,
843
+ name: string,
844
+ description?: string,
845
+ timezone?: string,
846
+ jitter?: number,
847
+ timeslots?: string
848
+ ): Promise<string> {
849
+ this.getApiKey();
850
+
851
+ if (!profile_group_id) {
852
+ throw new Error("profile_group_id is required");
853
+ }
854
+ if (!name) {
855
+ throw new Error("name is required");
856
+ }
857
+
858
+ const apiPayload: any = {
859
+ profile_group_id,
860
+ post_queue: { name },
861
+ };
862
+ if (description !== undefined) {
863
+ apiPayload.post_queue.description = description;
864
+ }
865
+ if (timezone) {
866
+ apiPayload.post_queue.timezone = timezone;
867
+ }
868
+ if (jitter !== undefined) {
869
+ apiPayload.post_queue.jitter = jitter;
870
+ }
871
+ if (timeslots) {
872
+ try {
873
+ const parsed = JSON.parse(timeslots);
874
+ if (Array.isArray(parsed)) {
875
+ apiPayload.post_queue.queue_timeslots_attributes = parsed;
876
+ }
877
+ } catch {
878
+ throw new Error("Invalid timeslots parameter: must be valid JSON array");
879
+ }
880
+ }
881
+
882
+ const queue = await this.apiRequest<any>("POST", "/post_queues", apiPayload);
883
+ return JSON.stringify({ ...queue, message: "Queue created successfully" }, null, 2);
884
+ }
885
+
886
+ /**
887
+ * Update a queue's settings
888
+ * @param queue_id {string} Queue ID to update
889
+ * @param name {string} Optional new name
890
+ * @param description {string} Optional new description
891
+ * @param timezone {string} Optional IANA timezone
892
+ * @param enabled {boolean} Optional pause/unpause
893
+ * @param jitter {number} Optional random offset in minutes (0-60)
894
+ * @param timeslots {string} Optional JSON array of timeslots to add/remove
895
+ * @return {Promise<string>} Updated queue as JSON
896
+ */
897
+ async queuesUpdate(
898
+ queue_id: string,
899
+ name?: string,
900
+ description?: string,
901
+ timezone?: string,
902
+ enabled?: boolean,
903
+ jitter?: number,
904
+ timeslots?: string
905
+ ): Promise<string> {
906
+ this.getApiKey();
907
+
908
+ if (!queue_id) {
909
+ throw new Error("queue_id is required");
910
+ }
911
+
912
+ const apiPayload: any = { post_queue: {} };
913
+ if (name !== undefined) apiPayload.post_queue.name = name;
914
+ if (description !== undefined) apiPayload.post_queue.description = description;
915
+ if (timezone !== undefined) apiPayload.post_queue.timezone = timezone;
916
+ if (enabled !== undefined) apiPayload.post_queue.enabled = enabled;
917
+ if (jitter !== undefined) apiPayload.post_queue.jitter = jitter;
918
+ if (timeslots) {
919
+ try {
920
+ const parsed = JSON.parse(timeslots);
921
+ if (Array.isArray(parsed)) {
922
+ apiPayload.post_queue.queue_timeslots_attributes = parsed;
923
+ }
924
+ } catch {
925
+ throw new Error("Invalid timeslots parameter: must be valid JSON array");
926
+ }
927
+ }
928
+
929
+ const queue = await this.apiRequest<any>("PATCH", `/post_queues/${queue_id}`, apiPayload);
930
+ return JSON.stringify({ ...queue, message: "Queue updated successfully" }, null, 2);
931
+ }
932
+
933
+ /**
934
+ * Delete a posting queue
935
+ * @param queue_id {string} Queue ID to delete
936
+ * @return {Promise<string>} Deletion confirmation as JSON
937
+ */
938
+ async queuesDelete(queue_id: string): Promise<string> {
939
+ this.getApiKey();
940
+
941
+ if (!queue_id) {
942
+ throw new Error("queue_id is required");
943
+ }
944
+
945
+ await this.apiRequest<void>("DELETE", `/post_queues/${queue_id}`);
946
+ return JSON.stringify({ queue_id, deleted: true }, null, 2);
947
+ }
948
+
949
+ /**
950
+ * Get the next available timeslot for a queue
951
+ * @param queue_id {string} Queue ID
952
+ * @return {Promise<string>} Next slot as JSON
953
+ */
954
+ async queuesNextSlot(queue_id: string): Promise<string> {
955
+ this.getApiKey();
956
+
957
+ if (!queue_id) {
958
+ throw new Error("queue_id is required");
959
+ }
960
+
961
+ const result = await this.apiRequest<any>("GET", `/post_queues/${queue_id}/next_slot`);
962
+ return JSON.stringify(result, null, 2);
963
+ }
964
+
789
965
  /**
790
966
  * MCP tool definitions
791
967
  */
@@ -817,6 +993,8 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
817
993
  platforms: { type: "string", description: "Optional JSON string of platform-specific parameters. YouTube supports: title, privacy_status, cover_url, made_for_kids. TikTok supports: format (video|image), privacy_status, and more." },
818
994
  media_files: { type: "string", description: "Optional JSON array of file objects for direct upload. Each object must have 'filename' and 'data' (base64-encoded file content), optionally 'content_type'. Example: [{\"filename\":\"photo.jpg\",\"data\":\"base64...\"}]" },
819
995
  thread: { type: "string", description: "Optional JSON array of thread child posts. Supported on X and Threads only. Each object must have 'body' (string), optionally 'media' (array of URLs). Example: [{\"body\":\"Reply 1\"},{\"body\":\"Reply 2\",\"media\":[\"https://...\"]}]" },
996
+ queue_id: { type: "string", description: "Optional queue ID to add the post to. The queue will automatically assign a timeslot. Do not use together with 'schedule'." },
997
+ queue_priority: { type: "string", description: "Optional priority when adding to a queue: high, medium (default), or low" },
820
998
  },
821
999
  required: ["content", "targets"],
822
1000
  },
@@ -890,6 +1068,83 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
890
1068
  required: ["profile_id"],
891
1069
  },
892
1070
  },
1071
+ {
1072
+ name: "queuesList",
1073
+ description: "List all posting queues. Queues automatically schedule posts into recurring weekly timeslots.",
1074
+ inputSchema: {
1075
+ type: "object",
1076
+ properties: {
1077
+ profile_group_id: { type: "string", description: "Optional profile group ID to filter queues" },
1078
+ },
1079
+ required: [],
1080
+ },
1081
+ },
1082
+ {
1083
+ name: "queuesGet",
1084
+ description: "Get details of a single posting queue including its timeslots and post count",
1085
+ inputSchema: {
1086
+ type: "object",
1087
+ properties: {
1088
+ queue_id: { type: "string", description: "Queue ID" },
1089
+ },
1090
+ required: ["queue_id"],
1091
+ },
1092
+ },
1093
+ {
1094
+ name: "queuesCreate",
1095
+ description: "Create a new posting queue with weekly timeslots",
1096
+ inputSchema: {
1097
+ type: "object",
1098
+ properties: {
1099
+ profile_group_id: { type: "string", description: "Profile group ID to connect the queue to" },
1100
+ name: { type: "string", description: "Queue name" },
1101
+ description: { type: "string", description: "Optional description" },
1102
+ timezone: { type: "string", description: "IANA timezone name (default: UTC)" },
1103
+ jitter: { type: "number", description: "Random offset in minutes (0-60, default: 0)" },
1104
+ timeslots: { type: "string", description: "Optional JSON array of timeslots [{\"day\":1,\"time\":\"09:00\"}]. Day: 0=Sun..6=Sat" },
1105
+ },
1106
+ required: ["profile_group_id", "name"],
1107
+ },
1108
+ },
1109
+ {
1110
+ name: "queuesUpdate",
1111
+ description: "Update a queue's settings, timeslots, or pause/unpause it",
1112
+ inputSchema: {
1113
+ type: "object",
1114
+ properties: {
1115
+ queue_id: { type: "string", description: "Queue ID to update" },
1116
+ name: { type: "string", description: "New queue name" },
1117
+ description: { type: "string", description: "New description" },
1118
+ timezone: { type: "string", description: "IANA timezone name" },
1119
+ enabled: { type: "boolean", description: "Set false to pause, true to unpause" },
1120
+ jitter: { type: "number", description: "Random offset in minutes (0-60)" },
1121
+ timeslots: { type: "string", description: "JSON array of timeslots to add [{\"day\":1,\"time\":\"09:00\"}] or remove [{\"id\":42,\"_destroy\":true}]" },
1122
+ },
1123
+ required: ["queue_id"],
1124
+ },
1125
+ },
1126
+ {
1127
+ name: "queuesDelete",
1128
+ description: "Delete a posting queue. Posts in the queue will not be deleted.",
1129
+ inputSchema: {
1130
+ type: "object",
1131
+ properties: {
1132
+ queue_id: { type: "string", description: "Queue ID to delete" },
1133
+ },
1134
+ required: ["queue_id"],
1135
+ },
1136
+ },
1137
+ {
1138
+ name: "queuesNextSlot",
1139
+ description: "Get the next available timeslot for a queue",
1140
+ inputSchema: {
1141
+ type: "object",
1142
+ properties: {
1143
+ queue_id: { type: "string", description: "Queue ID" },
1144
+ },
1145
+ required: ["queue_id"],
1146
+ },
1147
+ },
893
1148
  ];
894
1149
  }
895
1150
 
@@ -947,7 +1202,9 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
947
1202
  args.draft,
948
1203
  args.platforms,
949
1204
  args.media_files,
950
- args.thread
1205
+ args.thread,
1206
+ args.queue_id,
1207
+ args.queue_priority
951
1208
  );
952
1209
  break;
953
1210
  case "postStatus":
@@ -968,6 +1225,39 @@ export default class PostProxyMCP extends WorkerEntrypoint<Env> {
968
1225
  case "profilesPlacements":
969
1226
  result = await this.profilesPlacements(args.profile_id);
970
1227
  break;
1228
+ case "queuesList":
1229
+ result = await this.queuesList(args?.profile_group_id);
1230
+ break;
1231
+ case "queuesGet":
1232
+ result = await this.queuesGet(args.queue_id);
1233
+ break;
1234
+ case "queuesCreate":
1235
+ result = await this.queuesCreate(
1236
+ args.profile_group_id,
1237
+ args.name,
1238
+ args.description,
1239
+ args.timezone,
1240
+ args.jitter,
1241
+ args.timeslots
1242
+ );
1243
+ break;
1244
+ case "queuesUpdate":
1245
+ result = await this.queuesUpdate(
1246
+ args.queue_id,
1247
+ args.name,
1248
+ args.description,
1249
+ args.timezone,
1250
+ args.enabled,
1251
+ args.jitter,
1252
+ args.timeslots
1253
+ );
1254
+ break;
1255
+ case "queuesDelete":
1256
+ result = await this.queuesDelete(args.queue_id);
1257
+ break;
1258
+ case "queuesNextSlot":
1259
+ result = await this.queuesNextSlot(args.queue_id);
1260
+ break;
971
1261
  default:
972
1262
  return {
973
1263
  jsonrpc: "2.0",