posterly-mcp-server 0.19.7 → 0.19.9
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 +9 -2
- package/dist/generated/platform-manifest.d.ts +1 -1
- package/dist/generated/platform-manifest.js +2 -1
- package/dist/index.js +11 -1
- package/dist/lib/api-client.d.ts +30 -0
- package/dist/lib/api-client.js +3 -0
- package/dist/lib/format.d.ts +21 -0
- package/dist/lib/format.js +125 -0
- package/dist/tools/create-connect-session.d.ts +2 -2
- package/dist/tools/create-post.d.ts +17 -4
- package/dist/tools/create-post.js +5 -3
- package/dist/tools/create-posts-batch.d.ts +11 -4
- package/dist/tools/find-slot.js +10 -3
- package/dist/tools/generate-captions.d.ts +76 -0
- package/dist/tools/generate-captions.js +69 -0
- package/dist/tools/generate-image.d.ts +2 -2
- package/dist/tools/generate-image.js +17 -19
- package/dist/tools/get-brand-profile.js +34 -40
- package/dist/tools/get-brand.js +14 -16
- package/dist/tools/get-connect-link.d.ts +2 -2
- package/dist/tools/get-platform-schema.d.ts +2 -2
- package/dist/tools/get-video-job.d.ts +2 -2
- package/dist/tools/list-accounts.js +12 -4
- package/dist/tools/list-brand-accounts.js +11 -3
- package/dist/tools/list-brands.js +12 -11
- package/dist/tools/list-posts.d.ts +2 -2
- package/dist/tools/suggest-google-business-review-reply.d.ts +2 -2
- package/dist/tools/trigger-platform-helper.d.ts +2 -2
- package/dist/tools/update-post.js +10 -4
- package/dist/tools/upload-media.js +6 -2
- package/dist/tools/whoami.js +18 -17
- package/package.json +1 -1
- package/src/generated/platform-manifest.ts +2 -1
- package/src/index.ts +16 -1
- package/src/lib/api-client.ts +45 -0
- package/src/lib/format.ts +133 -0
- package/src/tools/create-post.ts +5 -3
- package/src/tools/create-webhook.ts +0 -1
- package/src/tools/delete-webhook.ts +0 -1
- package/src/tools/find-slot.ts +13 -5
- package/src/tools/generate-captions.ts +77 -0
- package/src/tools/generate-image.ts +20 -20
- package/src/tools/get-brand-profile.ts +34 -38
- package/src/tools/get-brand.ts +14 -14
- package/src/tools/get-post-missing.ts +0 -1
- package/src/tools/list-accounts.ts +15 -6
- package/src/tools/list-activity.ts +0 -1
- package/src/tools/list-brand-accounts.ts +14 -6
- package/src/tools/list-brands.ts +16 -13
- package/src/tools/list-webhooks.ts +0 -1
- package/src/tools/update-post-release-id.ts +0 -1
- package/src/tools/update-post.ts +10 -5
- package/src/tools/update-webhook.ts +0 -1
- package/src/tools/upload-media.ts +6 -2
- package/src/tools/webhook-events.ts +0 -1
- package/src/tools/whoami.ts +21 -23
package/README.md
CHANGED
|
@@ -10,10 +10,11 @@ This package gives Claude Desktop, Cursor, Windsurf, Cline, and other local MCP
|
|
|
10
10
|
- resolve brands/clients into the right accounts
|
|
11
11
|
- schedule and manage posts
|
|
12
12
|
- upload media
|
|
13
|
+
- generate captions
|
|
13
14
|
- generate images
|
|
14
15
|
- read account and post analytics
|
|
15
16
|
|
|
16
|
-
Posterly also exposes the same toolset over HTTP at [poster.ly/mcp](https://www.poster.ly/mcp), but this npm package is the local `stdio` transport.
|
|
17
|
+
Posterly also exposes the same authenticated toolset over HTTP at [poster.ly/mcp](https://www.poster.ly/mcp), but this npm package is the local `stdio` transport.
|
|
17
18
|
|
|
18
19
|
## Requirements
|
|
19
20
|
|
|
@@ -63,6 +64,10 @@ After paid signup is complete and Posterly shows an API key, add `POSTERLY_API_K
|
|
|
63
64
|
5. Restart your AI client.
|
|
64
65
|
6. Ask the AI to call `whoami`, then continue by connecting your first social account.
|
|
65
66
|
|
|
67
|
+
The signup and connect tools return user-facing next steps by default, so agents should report progress in plain language instead of showing raw curl, HTTP payloads, or JSON. Pass `debug: true` to `start_signup`, `get_signup_session`, `get_connect_link`, `create_connect_session`, or `get_connect_session` only when troubleshooting.
|
|
68
|
+
|
|
69
|
+
Post tools return `View in Posterly` dashboard links. After scheduling, listing, reading, or deleting posts, share the returned link with the user. Current-month scheduled posts open in Calendar with the post selected; broader/future post views use Table.
|
|
70
|
+
|
|
66
71
|
## Example configs
|
|
67
72
|
|
|
68
73
|
### Claude Desktop
|
|
@@ -103,7 +108,7 @@ Add the same server definition to your Cursor MCP settings:
|
|
|
103
108
|
|
|
104
109
|
## Available tools
|
|
105
110
|
|
|
106
|
-
`posterly-mcp-server@0.19.
|
|
111
|
+
`posterly-mcp-server@0.19.9` exposes 55 tools.
|
|
107
112
|
|
|
108
113
|
Public signup tools work before `POSTERLY_API_KEY` exists:
|
|
109
114
|
|
|
@@ -144,6 +149,7 @@ Authenticated tools require `POSTERLY_API_KEY`:
|
|
|
144
149
|
- `upload_media_from_url`
|
|
145
150
|
- `create_signed_upload`
|
|
146
151
|
- `find_available_slot`
|
|
152
|
+
- `generate_captions`
|
|
147
153
|
- `generate_image`
|
|
148
154
|
- `get_video_options`
|
|
149
155
|
- `run_video_function` (read-only Veo helpers for cost estimation and request validation)
|
|
@@ -198,6 +204,7 @@ much more reliable than forcing the agent to guess from raw account handles alon
|
|
|
198
204
|
- `Schedule this as an Instagram Story with a first comment and @partner as collaborator`
|
|
199
205
|
- `Schedule this YouTube video as unlisted, add the thumbnail URL, and put it in our launch playlist`
|
|
200
206
|
- `Post this TikTok with direct-post privacy set to public and stitch disabled`
|
|
207
|
+
- `Schedule these 5 photos as a TikTok` (image posts auto-detect as a photo slideshow of 1 to 35 images, no post type needed)
|
|
201
208
|
- `How did Grassroots perform on Instagram in the last 30 days?`
|
|
202
209
|
|
|
203
210
|
## Pricing
|
|
@@ -93,7 +93,7 @@ export declare const PLATFORM_MANIFEST: {
|
|
|
93
93
|
readonly label: "TikTok";
|
|
94
94
|
readonly status: "supported";
|
|
95
95
|
readonly aliases: readonly [];
|
|
96
|
-
readonly postTypes: readonly ["video", "image"];
|
|
96
|
+
readonly postTypes: readonly ["video", "image", "carousel"];
|
|
97
97
|
readonly analyticsSupported: false;
|
|
98
98
|
readonly helpers: readonly ["tiktok.creator_info"];
|
|
99
99
|
}, {
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { updatePostReleaseIdTool } from './tools/update-post-release-id.js';
|
|
|
24
24
|
import { deletePostTool } from './tools/delete-post.js';
|
|
25
25
|
import { deletePostGroupTool } from './tools/delete-post-group.js';
|
|
26
26
|
import { whoamiTool } from './tools/whoami.js';
|
|
27
|
+
import { generateCaptionsTool } from './tools/generate-captions.js';
|
|
27
28
|
import { generateImageTool } from './tools/generate-image.js';
|
|
28
29
|
import { getVideoOptionsTool } from './tools/get-video-options.js';
|
|
29
30
|
import { runVideoFunctionTool } from './tools/run-video-function.js';
|
|
@@ -58,7 +59,7 @@ import { updateOAuthClientTool } from './tools/update-oauth-client.js';
|
|
|
58
59
|
import { deleteOAuthClientTool } from './tools/delete-oauth-client.js';
|
|
59
60
|
const server = new McpServer({
|
|
60
61
|
name: 'posterly',
|
|
61
|
-
version: '0.19.
|
|
62
|
+
version: '0.19.8',
|
|
62
63
|
});
|
|
63
64
|
const client = new PosterlyClient();
|
|
64
65
|
// Register tools
|
|
@@ -341,6 +342,15 @@ server.tool(getVideoJobTool.name, getVideoJobTool.description, getVideoJobTool.i
|
|
|
341
342
|
return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
|
|
342
343
|
}
|
|
343
344
|
});
|
|
345
|
+
server.tool(generateCaptionsTool.name, generateCaptionsTool.description, generateCaptionsTool.inputSchema.shape, async (input) => {
|
|
346
|
+
try {
|
|
347
|
+
const text = await generateCaptionsTool.execute(client, input);
|
|
348
|
+
return { content: [{ type: 'text', text }] };
|
|
349
|
+
}
|
|
350
|
+
catch (err) {
|
|
351
|
+
return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
|
|
352
|
+
}
|
|
353
|
+
});
|
|
344
354
|
server.tool(generateImageTool.name, generateImageTool.description, generateImageTool.inputSchema.shape, async (input) => {
|
|
345
355
|
try {
|
|
346
356
|
const text = await generateImageTool.execute(client, input);
|
package/dist/lib/api-client.d.ts
CHANGED
|
@@ -120,6 +120,35 @@ export type BatchCreatePostsResponse = {
|
|
|
120
120
|
replayed: number;
|
|
121
121
|
failed: number;
|
|
122
122
|
};
|
|
123
|
+
export type CaptionPlatform = 'instagram' | 'facebook' | 'tiktok' | 'twitter' | 'threads' | 'linkedin' | 'youtube' | 'pinterest' | 'google_business';
|
|
124
|
+
export type GenerateCaptionsPayload = {
|
|
125
|
+
platforms: CaptionPlatform[];
|
|
126
|
+
brief?: string;
|
|
127
|
+
tone?: string;
|
|
128
|
+
allow_emojis?: boolean;
|
|
129
|
+
hashtag_strategy?: 'none' | 'smart' | 'minimal' | 'aggressive';
|
|
130
|
+
count?: number;
|
|
131
|
+
mode?: 'generate' | 'adapt';
|
|
132
|
+
source_caption?: string;
|
|
133
|
+
source_platform?: CaptionPlatform;
|
|
134
|
+
preserve_links?: boolean;
|
|
135
|
+
preserve_mentions?: boolean;
|
|
136
|
+
preserve_call_to_action?: boolean;
|
|
137
|
+
social_account_id?: string;
|
|
138
|
+
workspace_id?: string;
|
|
139
|
+
manual_brand_voice?: {
|
|
140
|
+
summary: string;
|
|
141
|
+
traits?: string[];
|
|
142
|
+
style_guidelines?: string[];
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
export type GenerateCaptionsResponse = {
|
|
146
|
+
success: boolean;
|
|
147
|
+
suggestions: Record<string, string[]>;
|
|
148
|
+
workspace_id?: string | null;
|
|
149
|
+
social_account_id?: number | null;
|
|
150
|
+
usage?: Record<string, unknown>;
|
|
151
|
+
};
|
|
123
152
|
export interface Slot {
|
|
124
153
|
time: string;
|
|
125
154
|
local_time: string;
|
|
@@ -552,6 +581,7 @@ export declare class PosterlyClient {
|
|
|
552
581
|
createPostsBatch(data: {
|
|
553
582
|
posts: CreatePostPayload[];
|
|
554
583
|
}): Promise<BatchCreatePostsResponse>;
|
|
584
|
+
generateCaptions(data: GenerateCaptionsPayload): Promise<GenerateCaptionsResponse>;
|
|
555
585
|
getPost(id: number): Promise<{
|
|
556
586
|
post: Post;
|
|
557
587
|
}>;
|
package/dist/lib/api-client.js
CHANGED
|
@@ -143,6 +143,9 @@ export class PosterlyClient {
|
|
|
143
143
|
async createPostsBatch(data) {
|
|
144
144
|
return this.request('POST', '/posts/batch', data);
|
|
145
145
|
}
|
|
146
|
+
async generateCaptions(data) {
|
|
147
|
+
return this.request('POST', '/ai/generate-captions', data);
|
|
148
|
+
}
|
|
146
149
|
async getPost(id) {
|
|
147
150
|
return this.request('GET', `/posts/${id}`);
|
|
148
151
|
}
|
package/dist/lib/format.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Account, Post } from './api-client.js';
|
|
2
|
+
type CellValue = string | number | boolean | null | undefined;
|
|
2
3
|
export declare const DASHBOARD_CALENDAR_URL: string;
|
|
3
4
|
export declare const DASHBOARD_TABLE_URL: string;
|
|
4
5
|
export declare const DASHBOARD_CONNECT_URL: string;
|
|
@@ -9,3 +10,23 @@ export declare function dashboardUrlForPostList(posts: Array<Pick<Post, 'schedul
|
|
|
9
10
|
export declare function truncateText(value: string | null | undefined, max?: number): string;
|
|
10
11
|
export declare function formatAccountLabel(account: Account): string;
|
|
11
12
|
export declare function formatConnectedAccounts(accounts?: Account[]): string;
|
|
13
|
+
export declare function mdTitle(title: string, subtitle?: string): string;
|
|
14
|
+
export declare function mdTable(headers: string[], rows: CellValue[][]): string;
|
|
15
|
+
export declare function mdKeyValue(rows: Array<[string, CellValue]>): string;
|
|
16
|
+
export declare function mdSection(title: string, body?: string): string;
|
|
17
|
+
export declare function mdBullets(items: Array<string | null | undefined>): string;
|
|
18
|
+
export declare function mdJson(title: string, value: unknown): string;
|
|
19
|
+
export declare function mdQuote(text: string): string;
|
|
20
|
+
export declare function mdEmpty(title: string, detail: string, nextStep?: string): string;
|
|
21
|
+
export declare function mdSuccess(title: string, rows: Array<[string, CellValue]>, nextStep?: string): string;
|
|
22
|
+
export declare function mdError(message: string): string;
|
|
23
|
+
export declare function formatNumber(value: number | null | undefined): string;
|
|
24
|
+
export declare function formatPercent(value: number | null | undefined): string;
|
|
25
|
+
export declare function formatDelta(value: number | null | undefined): string;
|
|
26
|
+
export declare function formatDateTime(value: string | null | undefined): string;
|
|
27
|
+
export declare function formatDate(value: string | null | undefined): string;
|
|
28
|
+
export declare function formatBytes(value: number | null | undefined): string;
|
|
29
|
+
export declare function compactText(value: string | null | undefined, maxLength?: number): string;
|
|
30
|
+
export declare function statusLabel(status: string | null | undefined): string;
|
|
31
|
+
export declare function code(value: CellValue): string;
|
|
32
|
+
export {};
|
package/dist/lib/format.js
CHANGED
|
@@ -40,6 +40,131 @@ export function formatConnectedAccounts(accounts) {
|
|
|
40
40
|
return 'none yet';
|
|
41
41
|
return accounts.map(formatAccountLabel).join(', ');
|
|
42
42
|
}
|
|
43
|
+
export function mdTitle(title, subtitle) {
|
|
44
|
+
return [`## ${title}`, subtitle ? `_${subtitle}_` : ''].filter(Boolean).join('\n');
|
|
45
|
+
}
|
|
46
|
+
export function mdTable(headers, rows) {
|
|
47
|
+
const visibleRows = rows.filter((row) => row.some((cell) => cell !== undefined && cell !== null && cell !== ''));
|
|
48
|
+
if (visibleRows.length === 0)
|
|
49
|
+
return '';
|
|
50
|
+
const header = `| ${headers.map(escapeCell).join(' | ')} |`;
|
|
51
|
+
const divider = `| ${headers.map(() => '---').join(' | ')} |`;
|
|
52
|
+
const body = visibleRows.map((row) => `| ${row.map((cell) => escapeCell(formatCell(cell))).join(' | ')} |`);
|
|
53
|
+
return [header, divider, ...body].join('\n');
|
|
54
|
+
}
|
|
55
|
+
export function mdKeyValue(rows) {
|
|
56
|
+
return mdTable(['Field', 'Value'], rows);
|
|
57
|
+
}
|
|
58
|
+
export function mdSection(title, body) {
|
|
59
|
+
if (!body)
|
|
60
|
+
return '';
|
|
61
|
+
return [`### ${title}`, body].join('\n');
|
|
62
|
+
}
|
|
63
|
+
export function mdBullets(items) {
|
|
64
|
+
return items.filter(Boolean).map((item) => `- ${item}`).join('\n');
|
|
65
|
+
}
|
|
66
|
+
export function mdJson(title, value) {
|
|
67
|
+
return [`### ${title}`, '```json', JSON.stringify(value, null, 2), '```'].join('\n');
|
|
68
|
+
}
|
|
69
|
+
export function mdQuote(text) {
|
|
70
|
+
return text.split('\n').map((line) => `> ${line}`).join('\n');
|
|
71
|
+
}
|
|
72
|
+
export function mdEmpty(title, detail, nextStep) {
|
|
73
|
+
return [
|
|
74
|
+
mdTitle(`No ${title}`),
|
|
75
|
+
detail,
|
|
76
|
+
nextStep ? `\n**Next step:** ${nextStep}` : '',
|
|
77
|
+
].filter(Boolean).join('\n');
|
|
78
|
+
}
|
|
79
|
+
export function mdSuccess(title, rows, nextStep) {
|
|
80
|
+
return [
|
|
81
|
+
mdTitle(`✅ ${title}`),
|
|
82
|
+
mdKeyValue(rows),
|
|
83
|
+
nextStep ? `\n**Next step:** ${nextStep}` : '',
|
|
84
|
+
].filter(Boolean).join('\n');
|
|
85
|
+
}
|
|
86
|
+
export function mdError(message) {
|
|
87
|
+
return [
|
|
88
|
+
mdTitle('⚠️ Posterly tool error'),
|
|
89
|
+
`**Message:** ${message}`,
|
|
90
|
+
].join('\n');
|
|
91
|
+
}
|
|
92
|
+
export function formatNumber(value) {
|
|
93
|
+
return value == null ? 'n/a' : value.toLocaleString();
|
|
94
|
+
}
|
|
95
|
+
export function formatPercent(value) {
|
|
96
|
+
return value == null ? 'n/a' : `${value.toLocaleString()}%`;
|
|
97
|
+
}
|
|
98
|
+
export function formatDelta(value) {
|
|
99
|
+
if (value == null)
|
|
100
|
+
return 'n/a';
|
|
101
|
+
return value >= 0 ? `+${value.toLocaleString()}` : value.toLocaleString();
|
|
102
|
+
}
|
|
103
|
+
export function formatDateTime(value) {
|
|
104
|
+
if (!value)
|
|
105
|
+
return 'n/a';
|
|
106
|
+
const date = new Date(value);
|
|
107
|
+
if (Number.isNaN(date.getTime()))
|
|
108
|
+
return value;
|
|
109
|
+
return date.toLocaleString();
|
|
110
|
+
}
|
|
111
|
+
export function formatDate(value) {
|
|
112
|
+
if (!value)
|
|
113
|
+
return 'n/a';
|
|
114
|
+
const date = new Date(value);
|
|
115
|
+
if (Number.isNaN(date.getTime()))
|
|
116
|
+
return value;
|
|
117
|
+
return date.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' });
|
|
118
|
+
}
|
|
119
|
+
export function formatBytes(value) {
|
|
120
|
+
if (value == null)
|
|
121
|
+
return 'n/a';
|
|
122
|
+
if (value < 1024)
|
|
123
|
+
return `${value} B`;
|
|
124
|
+
const units = ['KB', 'MB', 'GB', 'TB'];
|
|
125
|
+
let size = value / 1024;
|
|
126
|
+
let unitIndex = 0;
|
|
127
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
128
|
+
size /= 1024;
|
|
129
|
+
unitIndex += 1;
|
|
130
|
+
}
|
|
131
|
+
return `${size.toFixed(size >= 10 ? 0 : 1)} ${units[unitIndex]}`;
|
|
132
|
+
}
|
|
133
|
+
export function compactText(value, maxLength = 90) {
|
|
134
|
+
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
135
|
+
if (!text)
|
|
136
|
+
return '';
|
|
137
|
+
return text.length > maxLength ? `${text.slice(0, Math.max(0, maxLength - 1))}…` : text;
|
|
138
|
+
}
|
|
139
|
+
export function statusLabel(status) {
|
|
140
|
+
const value = String(status || 'unknown').toLowerCase();
|
|
141
|
+
if (['created', 'success', 'succeeded', 'completed', 'published', 'active'].includes(value))
|
|
142
|
+
return `✅ ${status}`;
|
|
143
|
+
if (['scheduled', 'queued', 'pending', 'processing', 'opened', 'awaiting_provider', 'awaiting_credentials'].includes(value))
|
|
144
|
+
return `🕒 ${status}`;
|
|
145
|
+
if (['failed', 'error', 'inactive', 'deleted', 'cancelled', 'expired'].includes(value))
|
|
146
|
+
return `⚠️ ${status}`;
|
|
147
|
+
if (['draft', 'paused'].includes(value))
|
|
148
|
+
return `⏸️ ${status}`;
|
|
149
|
+
return status || 'unknown';
|
|
150
|
+
}
|
|
151
|
+
export function code(value) {
|
|
152
|
+
return `\`${formatCell(value).replace(/`/g, '\\`')}\``;
|
|
153
|
+
}
|
|
154
|
+
function formatCell(value) {
|
|
155
|
+
if (value === null || value === undefined || value === '')
|
|
156
|
+
return 'n/a';
|
|
157
|
+
if (typeof value === 'boolean')
|
|
158
|
+
return value ? 'yes' : 'no';
|
|
159
|
+
if (typeof value === 'number')
|
|
160
|
+
return value.toLocaleString();
|
|
161
|
+
return String(value);
|
|
162
|
+
}
|
|
163
|
+
function escapeCell(value) {
|
|
164
|
+
return formatCell(value)
|
|
165
|
+
.replace(/\|/g, '\\|')
|
|
166
|
+
.replace(/\r?\n/g, '<br>');
|
|
167
|
+
}
|
|
43
168
|
function isInCurrentMonth(value) {
|
|
44
169
|
if (!value)
|
|
45
170
|
return false;
|
|
@@ -9,12 +9,12 @@ export declare const createConnectSessionTool: {
|
|
|
9
9
|
auto_start: z.ZodOptional<z.ZodBoolean>;
|
|
10
10
|
debug: z.ZodOptional<z.ZodBoolean>;
|
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
|
12
|
-
platform: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
12
|
+
platform: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "reddit" | "wordpress" | "mastodon" | "medium" | "devto" | "hashnode" | "discord" | "slack" | "skool" | "whop" | "gmb" | "google-business" | "google_business_profile" | "x" | "meta" | "linkedin_page" | "facebook_instagram" | "facebook_pages" | "instagram_direct" | "linkedin-company" | "linkedin-page" | "linkedin_company" | "linkedin_personal" | "meta_business" | "x_twitter";
|
|
13
13
|
workspace_id?: string | undefined;
|
|
14
14
|
auto_start?: boolean | undefined;
|
|
15
15
|
debug?: boolean | undefined;
|
|
16
16
|
}, {
|
|
17
|
-
platform: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
17
|
+
platform: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "reddit" | "wordpress" | "mastodon" | "medium" | "devto" | "hashnode" | "discord" | "slack" | "skool" | "whop" | "gmb" | "google-business" | "google_business_profile" | "x" | "meta" | "linkedin_page" | "facebook_instagram" | "facebook_pages" | "instagram_direct" | "linkedin-company" | "linkedin-page" | "linkedin_company" | "linkedin_personal" | "meta_business" | "x_twitter";
|
|
18
18
|
workspace_id?: string | undefined;
|
|
19
19
|
auto_start?: boolean | undefined;
|
|
20
20
|
debug?: boolean | undefined;
|
|
@@ -105,6 +105,7 @@ export declare const platformSettingsSchema: z.ZodObject<{
|
|
|
105
105
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
106
106
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
107
107
|
title: z.ZodOptional<z.ZodString>;
|
|
108
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
108
109
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
109
110
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
110
111
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -153,6 +154,7 @@ export declare const platformSettingsSchema: z.ZodObject<{
|
|
|
153
154
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
154
155
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
155
156
|
title: z.ZodOptional<z.ZodString>;
|
|
157
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
156
158
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
157
159
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
158
160
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -201,6 +203,7 @@ export declare const platformSettingsSchema: z.ZodObject<{
|
|
|
201
203
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
202
204
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
203
205
|
title: z.ZodOptional<z.ZodString>;
|
|
206
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
204
207
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
205
208
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
206
209
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -334,6 +337,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
334
337
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
335
338
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
336
339
|
title: z.ZodOptional<z.ZodString>;
|
|
340
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
337
341
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
338
342
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
339
343
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -382,6 +386,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
382
386
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
383
387
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
384
388
|
title: z.ZodOptional<z.ZodString>;
|
|
389
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
385
390
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
386
391
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
387
392
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -430,6 +435,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
430
435
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
431
436
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
432
437
|
title: z.ZodOptional<z.ZodString>;
|
|
438
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
433
439
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
434
440
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
435
441
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -451,7 +457,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
451
457
|
workspace_id: z.ZodOptional<z.ZodString>;
|
|
452
458
|
}, "strip", z.ZodTypeAny, {
|
|
453
459
|
workspace_id?: string | undefined;
|
|
454
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
460
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
455
461
|
account_id?: string | undefined;
|
|
456
462
|
scheduled_at?: string | undefined;
|
|
457
463
|
media_url?: string | undefined;
|
|
@@ -511,6 +517,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
511
517
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
512
518
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
513
519
|
title: z.ZodOptional<z.ZodString>;
|
|
520
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
514
521
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
515
522
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
516
523
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -531,7 +538,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
531
538
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
532
539
|
}, {
|
|
533
540
|
workspace_id?: string | undefined;
|
|
534
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
541
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
535
542
|
account_id?: string | undefined;
|
|
536
543
|
scheduled_at?: string | undefined;
|
|
537
544
|
media_url?: string | undefined;
|
|
@@ -591,6 +598,7 @@ export declare const createPostInputSchema: z.ZodObject<{
|
|
|
591
598
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
592
599
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
593
600
|
title: z.ZodOptional<z.ZodString>;
|
|
601
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
594
602
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
595
603
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
596
604
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -730,6 +738,7 @@ export declare const createPostTool: {
|
|
|
730
738
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
731
739
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
732
740
|
title: z.ZodOptional<z.ZodString>;
|
|
741
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
733
742
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
734
743
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
735
744
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -778,6 +787,7 @@ export declare const createPostTool: {
|
|
|
778
787
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
779
788
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
780
789
|
title: z.ZodOptional<z.ZodString>;
|
|
790
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
781
791
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
782
792
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
783
793
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -826,6 +836,7 @@ export declare const createPostTool: {
|
|
|
826
836
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
827
837
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
828
838
|
title: z.ZodOptional<z.ZodString>;
|
|
839
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
829
840
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
830
841
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
831
842
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -847,7 +858,7 @@ export declare const createPostTool: {
|
|
|
847
858
|
workspace_id: z.ZodOptional<z.ZodString>;
|
|
848
859
|
}, "strip", z.ZodTypeAny, {
|
|
849
860
|
workspace_id?: string | undefined;
|
|
850
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
861
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
851
862
|
account_id?: string | undefined;
|
|
852
863
|
scheduled_at?: string | undefined;
|
|
853
864
|
media_url?: string | undefined;
|
|
@@ -907,6 +918,7 @@ export declare const createPostTool: {
|
|
|
907
918
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
908
919
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
909
920
|
title: z.ZodOptional<z.ZodString>;
|
|
921
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
910
922
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
911
923
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
912
924
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -927,7 +939,7 @@ export declare const createPostTool: {
|
|
|
927
939
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
928
940
|
}, {
|
|
929
941
|
workspace_id?: string | undefined;
|
|
930
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
942
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
931
943
|
account_id?: string | undefined;
|
|
932
944
|
scheduled_at?: string | undefined;
|
|
933
945
|
media_url?: string | undefined;
|
|
@@ -987,6 +999,7 @@ export declare const createPostTool: {
|
|
|
987
999
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
988
1000
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
989
1001
|
title: z.ZodOptional<z.ZodString>;
|
|
1002
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
990
1003
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
991
1004
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
992
1005
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -47,6 +47,7 @@ export const platformSettingsSchema = z.object({
|
|
|
47
47
|
allow_duet: z.boolean().optional(),
|
|
48
48
|
allow_stitch: z.boolean().optional(),
|
|
49
49
|
title: z.string().optional(),
|
|
50
|
+
media_type: z.string().optional(), // TikTok: 'PHOTO' forces a photo slideshow; image media is auto-detected when omitted
|
|
50
51
|
is_commercial_content: z.boolean().optional(),
|
|
51
52
|
is_your_brand: z.boolean().optional(),
|
|
52
53
|
is_branded_content: z.boolean().optional(),
|
|
@@ -85,11 +86,11 @@ export const createPostInputSchema = z.object({
|
|
|
85
86
|
media_urls: z
|
|
86
87
|
.array(z.string())
|
|
87
88
|
.optional()
|
|
88
|
-
.describe('Multiple media URLs for carousel posts'),
|
|
89
|
+
.describe('Multiple media URLs for carousel or multi-image posts. For TikTok, 2 or more images auto-create a photo slideshow (up to 35 images) and every image is posted.'),
|
|
89
90
|
post_type: z
|
|
90
91
|
.string()
|
|
91
92
|
.optional()
|
|
92
|
-
.describe('Post type: text, image, video, carousel, reel, story. Auto-set to x_thread/threads_thread when `thread_posts` is provided.'),
|
|
93
|
+
.describe('Post type: text, image, video, carousel, reel, story. Auto-set to x_thread/threads_thread when `thread_posts` is provided. For TikTok you can omit it: image media auto-detects as a photo slideshow (use "carousel" for 2 or more images, or "image" for one), while a single video posts as a video.'),
|
|
93
94
|
thread_posts: z
|
|
94
95
|
.array(z.string())
|
|
95
96
|
.optional()
|
|
@@ -153,7 +154,8 @@ export const createPostTool = {
|
|
|
153
154
|
'AFTER CALLING: Tell the user the post was created, include the Posterly dashboard link returned by the tool, and offer the next natural action. Do not narrate raw HTTP, curl, or API plumbing.\n\n' +
|
|
154
155
|
'Provide either account_id OR username+platform to identify the account. If scheduled_at is omitted, the post publishes immediately. If workspace_id is omitted, the server resolves one from the social account, falling back to the caller\'s default (personal) workspace — pass workspace_id explicitly if the user has more than one workspace.\n\n' +
|
|
155
156
|
'THREADS: Pass `thread_posts` (an array of 2+ strings) to schedule a multi-post thread on X (Twitter) or Threads (Meta). The first entry is the lead post; the rest are published as replies in the same chain. X entries are capped at 280 characters each (4000 for verified, 25000 for organization accounts); Threads entries are capped at 500 characters each. When `thread_posts` is set, `caption` is ignored.\n\n' +
|
|
156
|
-
'PLATFORM SETTINGS: Pass `platform_settings` for composer-equivalent controls: Facebook story/reel/backgrounds, YouTube title/privacy/thumbnail/playlist, LinkedIn document titles/mentions/video thumbnails, TikTok direct-post privacy/toggles/commercial disclosure, Pinterest post_type (image/video/carousel), board (from pinterest.boards helper), title, link, and cover_image_url (video Pins), GBP event/offer/CTA, X reply settings/polls, Threads reply controls/text attachments, Bluesky languages/alt text, and Instagram feed/story/reel/carousel/collaborators/first comments/trial Reels. `instagram_settings` remains as a backwards-compatible alias
|
|
157
|
+
'PLATFORM SETTINGS: Pass `platform_settings` for composer-equivalent controls: Facebook story/reel/backgrounds, YouTube title/privacy/thumbnail/playlist, LinkedIn document titles/mentions/video thumbnails, TikTok direct-post privacy/toggles/commercial disclosure, Pinterest post_type (image/video/carousel), board (from pinterest.boards helper), title, link, and cover_image_url (video Pins), GBP event/offer/CTA, X reply settings/polls, Threads reply controls/text attachments, Bluesky languages/alt text, and Instagram feed/story/reel/carousel/collaborators/first comments/trial Reels. `instagram_settings` remains as a backwards-compatible alias.\n\n' +
|
|
158
|
+
'TIKTOK MEDIA: TikTok supports a single video or a photo slideshow of 1 to 35 images, never multiple videos. Image media auto-detects as a slideshow, so you usually do not set post_type or media_type for photos and every image is posted. Pass `platform_settings.media_type: "PHOTO"` to force a slideshow explicitly.',
|
|
157
159
|
inputSchema: createPostInputSchema,
|
|
158
160
|
async execute(client, input) {
|
|
159
161
|
const payload = buildCreatePostPayload(input);
|
|
@@ -120,6 +120,7 @@ export declare const createPostsBatchTool: {
|
|
|
120
120
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
121
121
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
122
122
|
title: z.ZodOptional<z.ZodString>;
|
|
123
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
123
124
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
124
125
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
125
126
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -168,6 +169,7 @@ export declare const createPostsBatchTool: {
|
|
|
168
169
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
169
170
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
170
171
|
title: z.ZodOptional<z.ZodString>;
|
|
172
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
171
173
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
172
174
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
173
175
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -216,6 +218,7 @@ export declare const createPostsBatchTool: {
|
|
|
216
218
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
217
219
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
218
220
|
title: z.ZodOptional<z.ZodString>;
|
|
221
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
219
222
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
220
223
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
221
224
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -237,7 +240,7 @@ export declare const createPostsBatchTool: {
|
|
|
237
240
|
workspace_id: z.ZodOptional<z.ZodString>;
|
|
238
241
|
}, "strip", z.ZodTypeAny, {
|
|
239
242
|
workspace_id?: string | undefined;
|
|
240
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
243
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
241
244
|
account_id?: string | undefined;
|
|
242
245
|
scheduled_at?: string | undefined;
|
|
243
246
|
media_url?: string | undefined;
|
|
@@ -297,6 +300,7 @@ export declare const createPostsBatchTool: {
|
|
|
297
300
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
298
301
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
299
302
|
title: z.ZodOptional<z.ZodString>;
|
|
303
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
300
304
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
301
305
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
302
306
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -317,7 +321,7 @@ export declare const createPostsBatchTool: {
|
|
|
317
321
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
318
322
|
}, {
|
|
319
323
|
workspace_id?: string | undefined;
|
|
320
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
324
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
321
325
|
account_id?: string | undefined;
|
|
322
326
|
scheduled_at?: string | undefined;
|
|
323
327
|
media_url?: string | undefined;
|
|
@@ -377,6 +381,7 @@ export declare const createPostsBatchTool: {
|
|
|
377
381
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
378
382
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
379
383
|
title: z.ZodOptional<z.ZodString>;
|
|
384
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
380
385
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
381
386
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
382
387
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -399,7 +404,7 @@ export declare const createPostsBatchTool: {
|
|
|
399
404
|
}, "strip", z.ZodTypeAny, {
|
|
400
405
|
posts: {
|
|
401
406
|
workspace_id?: string | undefined;
|
|
402
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
407
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
403
408
|
account_id?: string | undefined;
|
|
404
409
|
scheduled_at?: string | undefined;
|
|
405
410
|
media_url?: string | undefined;
|
|
@@ -459,6 +464,7 @@ export declare const createPostsBatchTool: {
|
|
|
459
464
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
460
465
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
461
466
|
title: z.ZodOptional<z.ZodString>;
|
|
467
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
462
468
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
463
469
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
464
470
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -481,7 +487,7 @@ export declare const createPostsBatchTool: {
|
|
|
481
487
|
}, {
|
|
482
488
|
posts: {
|
|
483
489
|
workspace_id?: string | undefined;
|
|
484
|
-
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "
|
|
490
|
+
platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
|
|
485
491
|
account_id?: string | undefined;
|
|
486
492
|
scheduled_at?: string | undefined;
|
|
487
493
|
media_url?: string | undefined;
|
|
@@ -541,6 +547,7 @@ export declare const createPostsBatchTool: {
|
|
|
541
547
|
allow_duet: z.ZodOptional<z.ZodBoolean>;
|
|
542
548
|
allow_stitch: z.ZodOptional<z.ZodBoolean>;
|
|
543
549
|
title: z.ZodOptional<z.ZodString>;
|
|
550
|
+
media_type: z.ZodOptional<z.ZodString>;
|
|
544
551
|
is_commercial_content: z.ZodOptional<z.ZodBoolean>;
|
|
545
552
|
is_your_brand: z.ZodOptional<z.ZodBoolean>;
|
|
546
553
|
is_branded_content: z.ZodOptional<z.ZodBoolean>;
|
package/dist/tools/find-slot.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { formatDate, mdEmpty, mdTable, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const findSlotTool = {
|
|
3
4
|
name: 'find_available_slot',
|
|
4
5
|
description: 'Find available time slots for posting. Respects a 1-hour gap between posts and preferred hours (8am–10pm in the given timezone). Returns up to 10 slots. IMPORTANT: pass a timezone explicitly — default is America/New_York and slots will be off if the user is elsewhere. Pass workspace_id to only avoid collisions with posts in that workspace.',
|
|
@@ -25,9 +26,15 @@ export const findSlotTool = {
|
|
|
25
26
|
async execute(client, input) {
|
|
26
27
|
const slots = await client.findAvailableSlots(input);
|
|
27
28
|
if (slots.length === 0) {
|
|
28
|
-
return 'No available slots found in the next 14 days.';
|
|
29
|
+
return mdEmpty('available slots', 'No available posting slots were found in the next 14 days.');
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
return [
|
|
32
|
+
mdTitle(`Available posting slots (${slots.length})`),
|
|
33
|
+
mdTable(['Option', 'Local time', 'Date'], slots.map((slot, index) => [
|
|
34
|
+
index + 1,
|
|
35
|
+
slot.local_time,
|
|
36
|
+
formatDate(slot.time),
|
|
37
|
+
])),
|
|
38
|
+
].join('\n\n');
|
|
32
39
|
},
|
|
33
40
|
};
|