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/dist/api/client.d.ts +27 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +91 -0
- package/dist/api/client.js.map +1 -1
- package/dist/server.d.ts +165 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +172 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/history.d.ts.map +1 -1
- package/dist/tools/history.js +1 -0
- package/dist/tools/history.js.map +1 -1
- package/dist/tools/post.d.ts +2 -0
- package/dist/tools/post.d.ts.map +1 -1
- package/dist/tools/post.js +2 -0
- package/dist/tools/post.js.map +1 -1
- package/dist/tools/queue.d.ts +73 -0
- package/dist/tools/queue.d.ts.map +1 -0
- package/dist/tools/queue.js +167 -0
- package/dist/tools/queue.js.map +1 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/client.ts +102 -0
- package/src/server.ts +179 -0
- package/src/tools/history.ts +1 -0
- package/src/tools/post.ts +4 -0
- package/src/tools/queue.ts +230 -0
- package/src/types/index.ts +50 -0
- package/worker/index.ts +292 -2
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",
|