@omnisocials/mcp-server 1.22.0 → 1.24.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/build/index.js +1 -1
- package/build/tools/posts.js +26 -5
- package/package.json +16 -3
package/build/index.js
CHANGED
|
@@ -29,7 +29,7 @@ const sessionState = { activeIndex: 0 };
|
|
|
29
29
|
const getActiveClient = () => workspaceClients[sessionState.activeIndex].client;
|
|
30
30
|
const server = new McpServer({
|
|
31
31
|
name: "OmniSocials",
|
|
32
|
-
version: "1.
|
|
32
|
+
version: "1.24.0",
|
|
33
33
|
});
|
|
34
34
|
// Register all tools - pass getter function so tools always use the active workspace's client
|
|
35
35
|
registerPostTools(server, getActiveClient);
|
package/build/tools/posts.js
CHANGED
|
@@ -70,6 +70,11 @@ const LINKEDIN_OPTIONS = z
|
|
|
70
70
|
.max(1250)
|
|
71
71
|
.optional()
|
|
72
72
|
.describe("Text auto-posted as the first comment on the LinkedIn Profile post right after it publishes. Common for 'link in first comment' to avoid the in-caption link reach penalty."),
|
|
73
|
+
carousel_as_images: z
|
|
74
|
+
.boolean()
|
|
75
|
+
.nullable()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Multi-image style for the profile post. By default 2+ images publish as LinkedIn's swipeable PDF document carousel; true publishes them as a plain multi-image gallery instead. Ignored for 0-1 images, videos, and polls. On update_post: true sets it, false/null reverts to the document carousel, omitted keeps the current value."),
|
|
73
78
|
})
|
|
74
79
|
.optional()
|
|
75
80
|
.describe("LinkedIn Profile options");
|
|
@@ -80,6 +85,11 @@ const LINKEDIN_PAGE_OPTIONS = z
|
|
|
80
85
|
.max(1250)
|
|
81
86
|
.optional()
|
|
82
87
|
.describe("Text auto-posted as the first comment on the LinkedIn Company Page post right after it publishes."),
|
|
88
|
+
carousel_as_images: z
|
|
89
|
+
.boolean()
|
|
90
|
+
.nullable()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe("Multi-image style for the company-page post. By default 2+ images publish as LinkedIn's swipeable PDF document carousel; true publishes them as a plain multi-image gallery instead. Ignored for 0-1 images, videos, and polls. On update_post: true sets it, false/null reverts to the document carousel, omitted keeps the current value."),
|
|
83
93
|
})
|
|
84
94
|
.optional()
|
|
85
95
|
.describe("LinkedIn Company Page options");
|
|
@@ -141,7 +151,7 @@ const USER_TAG_ENTRY = z.object({
|
|
|
141
151
|
// z.array(...).min(2).max(25)[.nullable()].optional().describe(...) stays
|
|
142
152
|
// per-tool (update_post allows null to clear the thread).
|
|
143
153
|
const X_THREAD_PART = z.object({
|
|
144
|
-
text: z.string().describe("Tweet text (≤ 280 chars). X counts every link as 23 characters (its t.co length)
|
|
154
|
+
text: z.string().describe("Tweet text (≤ 280 chars by X's weighted count). X counts every link as 23 characters (its t.co length) and every emoji or non-Latin symbol (🚀, …, ₹, CJK) as 2 — so text that looks under 280 can still be over. When trimming generated copy to fit, leave headroom instead of cutting to exactly 280 raw characters."),
|
|
145
155
|
media_ids: z.array(mediaIdEntry).max(4).optional().describe("Per-tweet media as Library IDs from upload_media (max 4 combined with media_urls). Each entry is a plain ID string or { id, alt } to attach alt text (X applies it to photos/GIFs). Attach your uploaded graphics to any tweet in the thread."),
|
|
146
156
|
media_urls: z.array(mediaUrlEntry).max(4).optional().describe("Per-tweet media as external URLs (max 4 combined with media_ids). Each entry is a plain URL string or { url, alt } to attach alt text (X applies it to photos/GIFs)."),
|
|
147
157
|
});
|
|
@@ -474,6 +484,16 @@ export function registerPostTools(server, getClient) {
|
|
|
474
484
|
if (firstCommentRows.length) {
|
|
475
485
|
md += `\n\n### First Comments\n\n${firstCommentRows.join("\n")}\n`;
|
|
476
486
|
}
|
|
487
|
+
// LinkedIn multi-image style: nested under each channel's options
|
|
488
|
+
// object by the API. Only rendered when the post opts out of the
|
|
489
|
+
// default PDF document carousel.
|
|
490
|
+
for (const channel of ["linkedin", "linkedin_page"]) {
|
|
491
|
+
const opts = p[channel];
|
|
492
|
+
if (opts && typeof opts === "object" && opts.carousel_as_images === true) {
|
|
493
|
+
const label = channel === "linkedin_page" ? "LinkedIn Page" : "LinkedIn Profile";
|
|
494
|
+
md += `\n\n**${label} multi-image style:** plain image gallery (default is the swipeable PDF document carousel)\n`;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
477
497
|
// Trial Reel state: nested under the instagram options object by the
|
|
478
498
|
// API. Only rendered when enabled, so batch-scheduled Trial Reels can be
|
|
479
499
|
// verified without opening the dashboard.
|
|
@@ -523,10 +543,11 @@ IMPORTANT — Before calling this tool, make sure you have all required informat
|
|
|
523
543
|
- Other platforms (LinkedIn, LinkedIn Page, X, Bluesky, etc.): Media is optional.
|
|
524
544
|
|
|
525
545
|
**Per-platform max media items (enforced at submit, returns 400 validation_error if exceeded):**
|
|
526
|
-
- Bluesky, X, Mastodon — max **4** items per post
|
|
527
|
-
- Instagram, Threads — max **10** items per carousel
|
|
546
|
+
- Bluesky, X, Mastodon — max **4** items per post; cannot mix images and video
|
|
547
|
+
- Instagram, Threads — max **10** items per carousel; images and videos CAN be mixed in one carousel
|
|
528
548
|
- TikTok — max **35** photos per photo-post; cannot mix photos and videos in one post
|
|
529
|
-
- Pinterest carousel — 2–5 images, all same aspect ratio
|
|
549
|
+
- Pinterest carousel — 2–5 images, all same aspect ratio (a video splits off into its own video pin)
|
|
550
|
+
- Facebook, LinkedIn, LinkedIn Page — cannot mix images and video in one post (images only, or a single video)
|
|
530
551
|
|
|
531
552
|
**Per-platform video caps (duration + size, checked via ffprobe at submit — exceeding either returns a 400 validation_error stating the exact cap and the file's value, e.g. "X only allows videos up to 2min 20s — yours is 2min 35s. Trim the video or deselect X."):**
|
|
532
553
|
- X — **140s (2min 20s)** · **512MB** (X also can't mix a video with images in one tweet: a tweet is either 1 video OR up to 4 images)
|
|
@@ -686,7 +707,7 @@ IMPORTANT — Before calling this tool, make sure you have all required informat
|
|
|
686
707
|
- Instagram/TikTok posts: ALWAYS need at least one image or video.
|
|
687
708
|
- Pinterest: ALWAYS need an image + board_id.
|
|
688
709
|
- Ask the user which media to use. Use list_media to show options.
|
|
689
|
-
- **Max items per platform** (same caps as create_post — exceeding returns 400): Bluesky/X/Mastodon ≤4, Instagram/Threads ≤10, TikTok ≤35 photos
|
|
710
|
+
- **Max items per platform** (same caps as create_post — exceeding returns 400): Bluesky/X/Mastodon ≤4, Instagram/Threads ≤10, TikTok ≤35 photos, Pinterest carousel 2–5 same-ratio images. Mixing images+video is rejected on Facebook/LinkedIn/X/Bluesky/Mastodon/TikTok; Instagram and Threads mixed carousels are allowed.
|
|
690
711
|
- **Video duration/size caps** (ffprobe at submit — over either returns 400 validation_error with the exact cap + the file's value): X **140s/512MB** (no video+image mix in one tweet), Bluesky 180s, Threads 5min, Instagram 15min, TikTok 10min, YouTube Short 3min, LinkedIn 10min, Facebook Reel 90s.
|
|
691
712
|
4. **Pinterest board (auto-default to first board)**: If Pinterest is in \`channels\` and \`pinterest.board_id\` is NOT provided, do NOT block on asking — and do NOT skip Pinterest. Call \`get_account\` on the Pinterest account, take the FIRST board from the returned boards list, and pass its \`id\` as \`pinterest.board_id\`. In your reply, mention which board you used (e.g. "Published to your 'Marketing' board on Pinterest — let me know if you'd prefer a different one.") so the user can redirect. If the user named a specific board in the request, match it (case-insensitive) against the list and use that one instead.
|
|
692
713
|
5. **X threads vs long-form**: A chained "thread" → pass \`x.thread_parts\` as a 2–25 entry array of \`{ text }\` objects (each ≤ 280 chars). A single long-form post on a Premium / Premium+ account → put the full text (up to 25,000 chars) in \`content\`; no threading needed. On free / Basic, X caps a single post at 280 chars. Do NOT split into "1/", "2/" inside \`content\` — that produces a single tweet, not a thread.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnisocials/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "MCP server for OmniSocials API - manage social media posts, media, accounts, analytics, and webhooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -19,11 +19,24 @@
|
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
21
|
"mcp",
|
|
22
|
+
"mcp-server",
|
|
23
|
+
"model-context-protocol",
|
|
22
24
|
"omnisocials",
|
|
23
25
|
"social-media",
|
|
26
|
+
"social-media-scheduling",
|
|
27
|
+
"scheduling",
|
|
24
28
|
"claude",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
29
|
+
"ai",
|
|
30
|
+
"instagram",
|
|
31
|
+
"facebook",
|
|
32
|
+
"linkedin",
|
|
33
|
+
"tiktok",
|
|
34
|
+
"youtube",
|
|
35
|
+
"twitter",
|
|
36
|
+
"pinterest",
|
|
37
|
+
"bluesky",
|
|
38
|
+
"threads",
|
|
39
|
+
"mastodon"
|
|
27
40
|
],
|
|
28
41
|
"homepage": "https://docs.omnisocials.com",
|
|
29
42
|
"engines": {
|