@omnisocials/mcp-server 1.35.0 → 1.46.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 +106 -8
- package/build/client.d.ts +147 -1
- package/build/client.js +51 -0
- package/build/index.js +3 -1
- package/build/metrics.d.ts +5 -3
- package/build/metrics.js +41 -4
- package/build/tools/accounts.js +35 -3
- package/build/tools/analytics.js +2 -2
- package/build/tools/automations.d.ts +25 -0
- package/build/tools/automations.js +199 -0
- package/build/tools/inbox.js +17 -8
- package/build/tools/media.js +53 -6
- package/build/tools/posts.js +486 -38
- package/build/tools/webhooks.js +3 -3
- package/build/types.d.ts +372 -6
- package/package.json +3 -3
package/build/tools/webhooks.js
CHANGED
|
@@ -28,9 +28,9 @@ export function registerWebhookTools(server, getClient) {
|
|
|
28
28
|
content: [{ type: "text", text: md }],
|
|
29
29
|
};
|
|
30
30
|
});
|
|
31
|
-
server.tool("create_webhook", "Create a new webhook to receive event notifications. Available events: post.scheduled, post.published, post.failed", {
|
|
31
|
+
server.tool("create_webhook", "Create a new webhook to receive event notifications. Available events: post.scheduled, post.published, post.failed, post.approved (the last approval of a post's approval workflow is in), post.rejected (an approver rejected the post)", {
|
|
32
32
|
url: z.string().describe("The HTTPS URL to send webhook events to"),
|
|
33
|
-
events: z.array(z.string()).describe("Events to subscribe to: post.scheduled, post.published, post.failed"),
|
|
33
|
+
events: z.array(z.string()).describe("Events to subscribe to: post.scheduled, post.published, post.failed, post.approved, post.rejected"),
|
|
34
34
|
}, { title: "Create Webhook", readOnlyHint: false, destructiveHint: false, openWorldHint: false }, async (params) => {
|
|
35
35
|
const result = await getClient().createWebhook(params);
|
|
36
36
|
if (result.error) {
|
|
@@ -95,7 +95,7 @@ export function registerWebhookTools(server, getClient) {
|
|
|
95
95
|
server.tool("update_webhook", "Update a webhook's URL, events, or active status.", {
|
|
96
96
|
id: z.string().describe("The webhook ID to update"),
|
|
97
97
|
url: z.string().optional().describe("Updated HTTPS URL"),
|
|
98
|
-
events: z.array(z.string()).optional().describe("Updated event list"),
|
|
98
|
+
events: z.array(z.string()).optional().describe("Updated event list: post.scheduled, post.published, post.failed, post.approved, post.rejected"),
|
|
99
99
|
is_active: z.boolean().optional().describe("Enable or disable the webhook"),
|
|
100
100
|
}, { title: "Update Webhook", readOnlyHint: false, destructiveHint: false, openWorldHint: false }, async ({ id, ...data }) => {
|
|
101
101
|
const result = await getClient().updateWebhook(id, data);
|
package/build/types.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ export interface ApiResponse<T = unknown> {
|
|
|
11
11
|
credits_balance?: number | null;
|
|
12
12
|
enforced?: boolean;
|
|
13
13
|
enforce_from?: string;
|
|
14
|
+
platform?: string;
|
|
15
|
+
media_url?: string;
|
|
16
|
+
ratio?: string;
|
|
17
|
+
target?: string;
|
|
18
|
+
action?: "cropped" | "kept" | "crop_failed";
|
|
19
|
+
crop_url?: string;
|
|
14
20
|
}>;
|
|
15
21
|
pagination?: {
|
|
16
22
|
next_cursor: string | null;
|
|
@@ -84,13 +90,23 @@ export interface InboxMessage {
|
|
|
84
90
|
}
|
|
85
91
|
/** What GET /inbox/next serves (and what `reply_to_inbox` returns as `next`
|
|
86
92
|
* when `include_next` is set). `message` is the unanswered incoming item: its
|
|
87
|
-
* `id` is what hide/delete take
|
|
93
|
+
* `id` is what hide/delete take and the `message_id` to pass to reply for a
|
|
94
|
+
* comment thread, its `conversation_id` is what reply takes as the path.
|
|
88
95
|
* `messages` is the thread oldest first (the most recent 50, plus the target
|
|
89
96
|
* and its parent when they fall outside that window). */
|
|
90
97
|
export interface InboxNextUnanswered {
|
|
91
98
|
conversation: InboxConversation;
|
|
92
99
|
message: InboxMessage;
|
|
93
100
|
messages: InboxMessage[];
|
|
101
|
+
/** Only Instagram and Facebook DMs have a reply window (Meta's 24 hours
|
|
102
|
+
* after the customer's last message): `closes_at` is that deadline and
|
|
103
|
+
* `open` is false once it has passed, in which case reply_to_inbox answers
|
|
104
|
+
* 422 outside_messaging_window. Every other item: open true, closes_at
|
|
105
|
+
* null. */
|
|
106
|
+
reply_window: {
|
|
107
|
+
open: boolean;
|
|
108
|
+
closes_at: string | null;
|
|
109
|
+
};
|
|
94
110
|
}
|
|
95
111
|
/** Response of DELETE /inbox/messages/:id. Replies under the comment are
|
|
96
112
|
* removed with it; their inbox ids are listed in `removed_reply_ids`. */
|
|
@@ -105,6 +121,17 @@ export type ApiPostMediaEntry = string | {
|
|
|
105
121
|
id?: string | number;
|
|
106
122
|
url?: string;
|
|
107
123
|
alt?: string;
|
|
124
|
+
/** Image fit of this channel's copy: 'crop' = url is a crop of crop.of. */
|
|
125
|
+
fit?: "crop" | "keep";
|
|
126
|
+
crop?: {
|
|
127
|
+
of: string;
|
|
128
|
+
id?: string;
|
|
129
|
+
ratio: string;
|
|
130
|
+
focus: {
|
|
131
|
+
x: number;
|
|
132
|
+
y: number;
|
|
133
|
+
} | null;
|
|
134
|
+
};
|
|
108
135
|
[k: string]: unknown;
|
|
109
136
|
};
|
|
110
137
|
/** A thread part as echoed back by the API (X / Bluesky / Mastodon / Threads). */
|
|
@@ -170,6 +197,10 @@ export interface ApiPost {
|
|
|
170
197
|
status: string;
|
|
171
198
|
/** "post" | "story" | "reel" */
|
|
172
199
|
type?: string;
|
|
200
|
+
/** The comment-to-DM automations bound to this post (get_post on a post
|
|
201
|
+
* that goes to Instagram or Facebook, create/update when the request
|
|
202
|
+
* carried it); null = none. */
|
|
203
|
+
comment_dm_automation?: PostCommentDmAutomation | null;
|
|
173
204
|
/** Per-platform captions keyed by platform id plus "default". Legacy
|
|
174
205
|
* servers returned a plain string. */
|
|
175
206
|
content?: Record<string, string> | string;
|
|
@@ -237,6 +268,12 @@ export interface ApiPost {
|
|
|
237
268
|
bluesky?: ApiPlatformOptionsOut;
|
|
238
269
|
mastodon?: ApiPlatformOptionsOut;
|
|
239
270
|
threads?: ApiPlatformOptionsOut;
|
|
271
|
+
/** Telegram options (silent, pin, buttons, poll ...) and, once sent,
|
|
272
|
+
* `result` with the message ids and the links. */
|
|
273
|
+
telegram?: ApiPlatformOptionsOut;
|
|
274
|
+
/** Discord options (silent, thread_name, buttons, poll ...) and, once
|
|
275
|
+
* sent, `result` with the message id and the link. */
|
|
276
|
+
discord?: ApiPlatformOptionsOut;
|
|
240
277
|
/** platform → user-friendly error message; only failed platforms appear.
|
|
241
278
|
* null while draft/scheduled/processing or when every platform succeeded. */
|
|
242
279
|
errors?: Record<string, string> | null;
|
|
@@ -274,6 +311,68 @@ export interface RejectPostResult {
|
|
|
274
311
|
approval_status: "rejected";
|
|
275
312
|
message?: string;
|
|
276
313
|
}
|
|
314
|
+
/** One approver of a step in GET /posts/:id/approval. */
|
|
315
|
+
export interface PostApprovalApprover {
|
|
316
|
+
id: string;
|
|
317
|
+
name: string | null;
|
|
318
|
+
email: string | null;
|
|
319
|
+
status: "pending" | "approved" | "rejected";
|
|
320
|
+
decided_at: string | null;
|
|
321
|
+
/** The reason this approver gave with a rejection. */
|
|
322
|
+
comment: string | null;
|
|
323
|
+
}
|
|
324
|
+
export interface PostApprovalStep {
|
|
325
|
+
order: number;
|
|
326
|
+
name: string;
|
|
327
|
+
/** `all` = every approver of the step must approve. `any` = one approval is enough. */
|
|
328
|
+
require_mode: "all" | "any";
|
|
329
|
+
status: "pending" | "approved" | "rejected";
|
|
330
|
+
approvers: PostApprovalApprover[];
|
|
331
|
+
}
|
|
332
|
+
export interface PostApprovalComment {
|
|
333
|
+
id: string;
|
|
334
|
+
author: {
|
|
335
|
+
id: string;
|
|
336
|
+
name: string | null;
|
|
337
|
+
} | null;
|
|
338
|
+
message: string;
|
|
339
|
+
/** The channel the comment is about (`instagram`, `linkedin_page`, ...). Null = the whole post. */
|
|
340
|
+
account: string | null;
|
|
341
|
+
created_at: string;
|
|
342
|
+
}
|
|
343
|
+
/** `data` of GET /posts/:id/approval (backend/routes/api/v1/posts.js).
|
|
344
|
+
* `status: "none"` = the post has no approval workflow: `workflow`,
|
|
345
|
+
* `requested_by`, `requested_at`, `current_step` and `rejection` are null and
|
|
346
|
+
* `steps` and `comments` are empty. */
|
|
347
|
+
export interface PostApproval {
|
|
348
|
+
post_id: string;
|
|
349
|
+
status: "none" | "pending" | "approved" | "rejected";
|
|
350
|
+
/** `id` is null for a one-off approval that was not made from a saved workflow. */
|
|
351
|
+
workflow: {
|
|
352
|
+
id: string | null;
|
|
353
|
+
name: string;
|
|
354
|
+
} | null;
|
|
355
|
+
requested_by: {
|
|
356
|
+
id: string;
|
|
357
|
+
name: string | null;
|
|
358
|
+
} | null;
|
|
359
|
+
requested_at: string | null;
|
|
360
|
+
/** Order of the step the post waits on. Null when the review is finished. */
|
|
361
|
+
current_step: number | null;
|
|
362
|
+
steps: PostApprovalStep[];
|
|
363
|
+
rejection: {
|
|
364
|
+
by: {
|
|
365
|
+
id: string;
|
|
366
|
+
name: string | null;
|
|
367
|
+
};
|
|
368
|
+
reason: string | null;
|
|
369
|
+
at: string | null;
|
|
370
|
+
step: number | null;
|
|
371
|
+
} | null;
|
|
372
|
+
/** The review thread, oldest first. Includes the entries OmniSocials
|
|
373
|
+
* writes when a reviewer edits the post. */
|
|
374
|
+
comments: PostApprovalComment[];
|
|
375
|
+
}
|
|
277
376
|
/** One place from GET /locations/search
|
|
278
377
|
* (@openapi block in backend/routes/api/v1/locations.js). */
|
|
279
378
|
export interface LocationPlace {
|
|
@@ -314,6 +413,59 @@ export interface LocationSearchResult {
|
|
|
314
413
|
};
|
|
315
414
|
needsPermission?: boolean;
|
|
316
415
|
}
|
|
416
|
+
/** One product Pin from GET /pinterest/products
|
|
417
|
+
* (@openapi block in backend/routes/api/v1/pinterest.js). */
|
|
418
|
+
export interface PinterestProduct {
|
|
419
|
+
/** Use in `pinterest.product_tags`. */
|
|
420
|
+
pin_id: string;
|
|
421
|
+
title?: string | null;
|
|
422
|
+
description?: string | null;
|
|
423
|
+
link?: string | null;
|
|
424
|
+
image_url?: string | null;
|
|
425
|
+
/** Catalog source only. */
|
|
426
|
+
price?: number | null;
|
|
427
|
+
currency?: string | null;
|
|
428
|
+
availability?: string | null;
|
|
429
|
+
item_id?: string | null;
|
|
430
|
+
}
|
|
431
|
+
/** GET /pinterest/products envelope: NOT the standard data/error envelope.
|
|
432
|
+
* Success: `products` + `bookmark` + `source` + `catalog_access` (and, for
|
|
433
|
+
* the catalog source, `product_groups` + `product_group_id`). When the list
|
|
434
|
+
* could not be read, `error` is a { code, message } object with code one of
|
|
435
|
+
* pinterest_not_connected | pinterest_catalog_access_required |
|
|
436
|
+
* platform_error, and `products` is absent. */
|
|
437
|
+
export interface PinterestProductsResult {
|
|
438
|
+
products?: PinterestProduct[];
|
|
439
|
+
bookmark?: string | null;
|
|
440
|
+
source?: "catalog" | "pins";
|
|
441
|
+
catalog_access?: boolean;
|
|
442
|
+
/** The connection has catalog access but the account has no catalog yet. */
|
|
443
|
+
no_catalog?: boolean;
|
|
444
|
+
product_groups?: Array<{
|
|
445
|
+
id: string;
|
|
446
|
+
name?: string | null;
|
|
447
|
+
}>;
|
|
448
|
+
product_group_id?: string | null;
|
|
449
|
+
error?: string | {
|
|
450
|
+
code: string;
|
|
451
|
+
message: string;
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
/** GET /pinterest/products/validate result. `unverified` = the check could
|
|
455
|
+
* not run; the publish step is then the final check. */
|
|
456
|
+
export interface PinterestProductCheck {
|
|
457
|
+
valid?: boolean;
|
|
458
|
+
pin_id?: string | null;
|
|
459
|
+
title?: string | null;
|
|
460
|
+
link?: string | null;
|
|
461
|
+
image_url?: string | null;
|
|
462
|
+
unverified?: boolean;
|
|
463
|
+
reason?: string;
|
|
464
|
+
error?: string | {
|
|
465
|
+
code: string;
|
|
466
|
+
message: string;
|
|
467
|
+
};
|
|
468
|
+
}
|
|
317
469
|
/** One track from GET /audio/search
|
|
318
470
|
* (@openapi block in backend/routes/api/v1/audio.js). */
|
|
319
471
|
export interface InstagramAudioTrack {
|
|
@@ -364,16 +516,33 @@ export interface MediaItem {
|
|
|
364
516
|
filename: string;
|
|
365
517
|
folder_id?: string | null;
|
|
366
518
|
size: string;
|
|
519
|
+
width?: number | null;
|
|
520
|
+
height?: number | null;
|
|
367
521
|
status?: string;
|
|
368
522
|
created_at: string;
|
|
523
|
+
pdf?: {
|
|
524
|
+
id: string;
|
|
525
|
+
name: string;
|
|
526
|
+
url: string;
|
|
527
|
+
page?: number;
|
|
528
|
+
total_pages: number;
|
|
529
|
+
rendered_pages: number;
|
|
530
|
+
truncated?: boolean;
|
|
531
|
+
pages?: Array<{
|
|
532
|
+
url: string;
|
|
533
|
+
width?: number | null;
|
|
534
|
+
height?: number | null;
|
|
535
|
+
}>;
|
|
536
|
+
};
|
|
369
537
|
}
|
|
370
538
|
/**
|
|
371
539
|
* Extra top-level fields returned by /media/upload* when the uploaded file is a
|
|
372
|
-
* PDF. A PDF is rasterized into one image slide per page (max 20)
|
|
373
|
-
* mirrors the first slide (back-compat), while
|
|
374
|
-
* whole carousel in page order. Pass ALL of
|
|
375
|
-
* LinkedIn the slides post as a native
|
|
376
|
-
*
|
|
540
|
+
* PDF. A PDF is rasterized into one image slide per page (max 20) and the
|
|
541
|
+
* original file is kept: `data` mirrors the first slide (back-compat), while
|
|
542
|
+
* `slides` + `media_ids` carry the whole carousel in page order. Pass ALL of
|
|
543
|
+
* `media_ids` to create_post. On LinkedIn the slides post as a native
|
|
544
|
+
* swipeable document made from the original PDF (unless the post's
|
|
545
|
+
* linkedin.document_source is "slides"); elsewhere as an image carousel.
|
|
377
546
|
*/
|
|
378
547
|
export interface PdfUploadResult {
|
|
379
548
|
slides: MediaItem[];
|
|
@@ -382,6 +551,10 @@ export interface PdfUploadResult {
|
|
|
382
551
|
total_pages: number;
|
|
383
552
|
rendered_pages: number;
|
|
384
553
|
truncated: boolean;
|
|
554
|
+
id?: string;
|
|
555
|
+
name?: string;
|
|
556
|
+
url?: string;
|
|
557
|
+
size_bytes?: number;
|
|
385
558
|
};
|
|
386
559
|
}
|
|
387
560
|
export interface Account {
|
|
@@ -407,6 +580,29 @@ export interface Account {
|
|
|
407
580
|
}[];
|
|
408
581
|
platform_details?: {
|
|
409
582
|
subscription_type?: string;
|
|
583
|
+
/** Telegram: "channel", "supergroup" or "group". */
|
|
584
|
+
chat_type?: string | null;
|
|
585
|
+
/** Telegram chat id (a negative number as a string). */
|
|
586
|
+
chat_id?: string | null;
|
|
587
|
+
/** Telegram: subscribers of a channel, members of a group. */
|
|
588
|
+
subscribers?: number | null;
|
|
589
|
+
/** Telegram: t.me link of a public chat, else the chat's private link.
|
|
590
|
+
* Discord: discord.com/channels link to the channel. */
|
|
591
|
+
url?: string | null;
|
|
592
|
+
/** Discord: the server id. */
|
|
593
|
+
guild_id?: string | null;
|
|
594
|
+
/** Discord: the server name (Continue with Discord, or a pasted URL in a server the OmniSocials bot is in). */
|
|
595
|
+
guild_name?: string | null;
|
|
596
|
+
/** Discord: the channel id. */
|
|
597
|
+
channel_id?: string | null;
|
|
598
|
+
/** Discord: the channel name without the # (read by the OmniSocials bot, or given by the person); null when unknown. */
|
|
599
|
+
channel_name?: string | null;
|
|
600
|
+
/** Discord: text, voice, announcement, stage, forum or media, as the bot read it; null when it cannot see the channel. */
|
|
601
|
+
channel_type?: "text" | "voice" | "announcement" | "stage" | "forum" | "media" | null;
|
|
602
|
+
/** Discord: the webhook's name, shown as the sender of every post. */
|
|
603
|
+
webhook_name?: string | null;
|
|
604
|
+
/** Discord: "oauth" (Continue with Discord) or "url" (a pasted webhook URL). */
|
|
605
|
+
connect_method?: string | null;
|
|
410
606
|
};
|
|
411
607
|
}
|
|
412
608
|
export interface Webhook {
|
|
@@ -435,6 +631,162 @@ export interface HashtagSet {
|
|
|
435
631
|
created_at: string;
|
|
436
632
|
updated_at: string;
|
|
437
633
|
}
|
|
634
|
+
/** The channel an automation runs on: the Instagram account or the Facebook Page. */
|
|
635
|
+
export type AutomationPlatform = "instagram" | "facebook";
|
|
636
|
+
/** `story_reply` is Instagram only: Facebook has no story replies. */
|
|
637
|
+
export type AutomationTriggerKind = "comment" | "dm" | "story_reply";
|
|
638
|
+
export type AutomationScope = "post" | "next_post" | "any";
|
|
639
|
+
export type AutomationMatch = "word" | "contains" | "any";
|
|
640
|
+
export interface AutomationPost {
|
|
641
|
+
/** `omnisocials` = a post of this workspace, `instagram` / `facebook` = read from that platform */
|
|
642
|
+
source: "omnisocials" | "instagram" | "facebook";
|
|
643
|
+
id: string;
|
|
644
|
+
caption: string;
|
|
645
|
+
thumbnail_url: string | null;
|
|
646
|
+
permalink: string | null;
|
|
647
|
+
media_type: string | null;
|
|
648
|
+
status?: string;
|
|
649
|
+
post_date_time?: string | null;
|
|
650
|
+
/** omnisocials source only: the post is live on the automation's platform */
|
|
651
|
+
live?: boolean;
|
|
652
|
+
timestamp?: string | null;
|
|
653
|
+
}
|
|
654
|
+
export interface Automation {
|
|
655
|
+
id: string;
|
|
656
|
+
type: "comment_to_dm";
|
|
657
|
+
platform: AutomationPlatform;
|
|
658
|
+
status: "active" | "paused" | "completed";
|
|
659
|
+
name: string | null;
|
|
660
|
+
/** The OmniSocials post the automation listens on (scope post), else null */
|
|
661
|
+
post_id: string | null;
|
|
662
|
+
/** The Instagram media id, set once the post is live (null on Facebook) */
|
|
663
|
+
instagram_media_id: string | null;
|
|
664
|
+
/** The Facebook Page post id ({page-id}_{post-id}), set once the post is live (null on Instagram) */
|
|
665
|
+
facebook_post_id: string | null;
|
|
666
|
+
post: AutomationPost | null;
|
|
667
|
+
trigger: {
|
|
668
|
+
kinds: AutomationTriggerKind[];
|
|
669
|
+
scope: AutomationScope | null;
|
|
670
|
+
keywords: string[];
|
|
671
|
+
match: AutomationMatch;
|
|
672
|
+
};
|
|
673
|
+
actions: {
|
|
674
|
+
dm: {
|
|
675
|
+
text: string;
|
|
676
|
+
};
|
|
677
|
+
public_reply: {
|
|
678
|
+
enabled: boolean;
|
|
679
|
+
variations: string[];
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
limits: {
|
|
683
|
+
max_sends: number | null;
|
|
684
|
+
stop_at: string | null;
|
|
685
|
+
};
|
|
686
|
+
stats: {
|
|
687
|
+
matched: number;
|
|
688
|
+
sent: number;
|
|
689
|
+
skipped: number;
|
|
690
|
+
failed: number;
|
|
691
|
+
last_event_at: string | null;
|
|
692
|
+
};
|
|
693
|
+
created_at: string;
|
|
694
|
+
updated_at: string;
|
|
695
|
+
}
|
|
696
|
+
/** The body of POST /automations; every section is optional on PATCH. */
|
|
697
|
+
export interface AutomationInput {
|
|
698
|
+
name?: string | null;
|
|
699
|
+
/** Default instagram; cannot change on PATCH (400 platform_immutable) */
|
|
700
|
+
platform?: AutomationPlatform;
|
|
701
|
+
post_id?: string;
|
|
702
|
+
instagram_media_id?: string;
|
|
703
|
+
/** A Page post published outside OmniSocials; implies platform facebook */
|
|
704
|
+
facebook_post_id?: string;
|
|
705
|
+
trigger?: {
|
|
706
|
+
kinds?: AutomationTriggerKind[];
|
|
707
|
+
scope?: AutomationScope;
|
|
708
|
+
keywords?: string[];
|
|
709
|
+
match?: AutomationMatch;
|
|
710
|
+
};
|
|
711
|
+
actions?: {
|
|
712
|
+
dm: {
|
|
713
|
+
text: string;
|
|
714
|
+
};
|
|
715
|
+
public_reply?: {
|
|
716
|
+
enabled?: boolean;
|
|
717
|
+
variations?: string[];
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
limits?: {
|
|
721
|
+
max_sends?: number | null;
|
|
722
|
+
stop_at?: string | null;
|
|
723
|
+
};
|
|
724
|
+
status?: "active" | "paused";
|
|
725
|
+
}
|
|
726
|
+
/** `comment_dm_automation` on a post: the automations bound to that post. */
|
|
727
|
+
export interface CommentDmAutomationInput {
|
|
728
|
+
/** One automation per listed channel; default Instagram when the post goes there, else Facebook */
|
|
729
|
+
platforms?: AutomationPlatform[];
|
|
730
|
+
trigger?: {
|
|
731
|
+
keywords?: string[];
|
|
732
|
+
match?: AutomationMatch;
|
|
733
|
+
};
|
|
734
|
+
actions: {
|
|
735
|
+
dm: {
|
|
736
|
+
text: string;
|
|
737
|
+
};
|
|
738
|
+
public_reply?: {
|
|
739
|
+
enabled?: boolean;
|
|
740
|
+
variations?: string[];
|
|
741
|
+
};
|
|
742
|
+
};
|
|
743
|
+
limits?: {
|
|
744
|
+
max_sends?: number | null;
|
|
745
|
+
stop_at?: string | null;
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
/** `comment_dm_automation` on a post: the first automation's fields (Instagram
|
|
749
|
+
* first), plus the channels and the id of each automation. */
|
|
750
|
+
export interface PostCommentDmAutomation extends Automation {
|
|
751
|
+
platforms?: AutomationPlatform[];
|
|
752
|
+
automations?: Array<{
|
|
753
|
+
id: string;
|
|
754
|
+
platform: AutomationPlatform;
|
|
755
|
+
status: Automation["status"];
|
|
756
|
+
}>;
|
|
757
|
+
}
|
|
758
|
+
export interface AutomationEvent {
|
|
759
|
+
id: string;
|
|
760
|
+
automation_id: string;
|
|
761
|
+
kind: AutomationTriggerKind;
|
|
762
|
+
outcome: "sent" | "skipped" | "failed" | "pending";
|
|
763
|
+
reason: string | null;
|
|
764
|
+
reason_label: string | null;
|
|
765
|
+
/** `username` = the Instagram @handle, or the person's name on Facebook */
|
|
766
|
+
person: {
|
|
767
|
+
id: string;
|
|
768
|
+
username: string | null;
|
|
769
|
+
};
|
|
770
|
+
trigger_id: string | null;
|
|
771
|
+
/** The comment; a DM's text only with the inbox:read scope */
|
|
772
|
+
trigger_text: string | null;
|
|
773
|
+
/** The DM that was sent */
|
|
774
|
+
message: string | null;
|
|
775
|
+
public_reply: string | null;
|
|
776
|
+
platform_message_id: string | null;
|
|
777
|
+
created_at: string;
|
|
778
|
+
sent_at: string | null;
|
|
779
|
+
}
|
|
780
|
+
export interface AutomationEventsResult {
|
|
781
|
+
data: AutomationEvent[];
|
|
782
|
+
counts: Record<string, number>;
|
|
783
|
+
pagination: {
|
|
784
|
+
total: number;
|
|
785
|
+
limit: number;
|
|
786
|
+
offset: number;
|
|
787
|
+
has_more: boolean;
|
|
788
|
+
};
|
|
789
|
+
}
|
|
438
790
|
/** Per-platform stats block inside AnalyticsOverview.platform_breakdown.
|
|
439
791
|
* Shape from backend/routes/api/v1/analytics.js (overview route). */
|
|
440
792
|
export interface AnalyticsPlatformBreakdown {
|
|
@@ -476,6 +828,16 @@ export interface MediaCompatibility {
|
|
|
476
828
|
/** POST /media/check response — the compatibility block is spread top-level
|
|
477
829
|
* next to `file` and `connected_platforms`; there is no `data` key
|
|
478
830
|
* (backend/routes/api/v1/media.js check route). */
|
|
831
|
+
export interface MediaFitRow {
|
|
832
|
+
platform: string;
|
|
833
|
+
display_name: string;
|
|
834
|
+
fits: boolean;
|
|
835
|
+
ratio: string;
|
|
836
|
+
shown: "whole" | "cut";
|
|
837
|
+
target: string | null;
|
|
838
|
+
default_action: "crop" | "keep" | null;
|
|
839
|
+
message: string | null;
|
|
840
|
+
}
|
|
479
841
|
export interface MediaCheckResult {
|
|
480
842
|
error?: {
|
|
481
843
|
code: string;
|
|
@@ -485,11 +847,15 @@ export interface MediaCheckResult {
|
|
|
485
847
|
size_bytes: number | null;
|
|
486
848
|
mime: string | null;
|
|
487
849
|
size_known: boolean;
|
|
850
|
+
width?: number | null;
|
|
851
|
+
height?: number | null;
|
|
488
852
|
};
|
|
489
853
|
connected_platforms?: string[];
|
|
490
854
|
compatible?: boolean;
|
|
491
855
|
warnings?: MediaCompatWarning[];
|
|
492
856
|
summary?: string | null;
|
|
857
|
+
/** How each connected channel with a fit rule shows this image as a feed post. */
|
|
858
|
+
fit?: MediaFitRow[];
|
|
493
859
|
}
|
|
494
860
|
/** One folder from GET /folders — formatFolder in
|
|
495
861
|
* backend/routes/api/v1/folders.js (:15-23). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnisocials/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.0",
|
|
4
4
|
"mcpName": "io.github.omnisocials/mcp-server",
|
|
5
5
|
"description": "MCP server for OmniSocials API - manage social media posts, media, accounts, analytics, and webhooks",
|
|
6
6
|
"type": "module",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"license": "MIT",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
48
|
+
"@modelcontextprotocol/sdk": "^1.32.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^25.3.3",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"overrides": {
|
|
55
55
|
"zod": "4.4.0",
|
|
56
|
-
"fast-uri": "^3.1.
|
|
56
|
+
"fast-uri": "^3.1.8",
|
|
57
57
|
"hono": "^4.13.7",
|
|
58
58
|
"qs": "^6.16.0"
|
|
59
59
|
}
|