posterly-mcp-server 0.19.1 → 0.19.2
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 +3 -1
- package/dist/index.js +50 -49
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/format.d.ts +21 -0
- package/dist/lib/format.js +125 -0
- package/dist/tools/audit-google-business-profile.js +15 -12
- package/dist/tools/create-oauth-client.js +7 -1
- package/dist/tools/create-post.js +20 -27
- package/dist/tools/create-posts-batch.js +23 -15
- package/dist/tools/create-signed-upload.js +11 -8
- package/dist/tools/create-webhook.js +7 -2
- package/dist/tools/delete-google-business-review-reply.d.ts +1 -1
- package/dist/tools/delete-google-business-review-reply.js +4 -1
- package/dist/tools/delete-oauth-client.js +4 -1
- package/dist/tools/delete-post-group.js +5 -1
- package/dist/tools/delete-post.js +4 -1
- package/dist/tools/delete-webhook.js +4 -1
- package/dist/tools/disconnect-account.js +7 -5
- package/dist/tools/find-slot.js +10 -3
- package/dist/tools/generate-image.js +17 -19
- package/dist/tools/generate-video.js +11 -9
- package/dist/tools/get-account-analytics.js +64 -45
- package/dist/tools/get-brand-profile.js +34 -40
- package/dist/tools/get-brand.js +14 -16
- package/dist/tools/get-connect-link.js +26 -7
- package/dist/tools/get-google-business-review-link.js +6 -6
- package/dist/tools/get-platform-schema.js +23 -16
- package/dist/tools/get-post-analytics.js +53 -50
- package/dist/tools/get-post-missing.js +5 -1
- package/dist/tools/get-post.js +16 -14
- package/dist/tools/get-video-job.d.ts +2 -2
- package/dist/tools/get-video-job.js +28 -11
- package/dist/tools/get-video-options.js +21 -15
- package/dist/tools/get-x-posting-quota.js +12 -9
- package/dist/tools/list-accounts.js +12 -4
- package/dist/tools/list-activity.js +13 -18
- package/dist/tools/list-brand-accounts.js +11 -3
- package/dist/tools/list-brands.js +12 -11
- package/dist/tools/list-google-business-reviews.js +13 -11
- package/dist/tools/list-oauth-clients.js +10 -4
- package/dist/tools/list-platforms.js +12 -5
- package/dist/tools/list-posts.js +12 -7
- package/dist/tools/list-webhooks.js +13 -11
- package/dist/tools/reply-google-business-review.d.ts +1 -1
- package/dist/tools/reply-google-business-review.js +4 -1
- package/dist/tools/run-video-function.js +4 -4
- package/dist/tools/suggest-google-business-review-reply.js +5 -4
- package/dist/tools/test-webhook.js +7 -1
- package/dist/tools/trigger-platform-helper.js +5 -1
- package/dist/tools/update-oauth-client.js +8 -1
- package/dist/tools/update-post-release-id.js +5 -1
- package/dist/tools/update-post-status.d.ts +2 -2
- package/dist/tools/update-post-status.js +7 -1
- package/dist/tools/update-post.js +10 -4
- package/dist/tools/update-webhook.js +7 -1
- package/dist/tools/upload-media-from-url.js +7 -9
- package/dist/tools/upload-media.js +6 -2
- package/dist/tools/whoami.js +18 -17
- package/package.json +1 -1
- package/src/index.ts +50 -49
- package/src/lib/api-client.ts +1 -1
- package/src/lib/format.ts +132 -0
- package/src/tools/audit-google-business-profile.ts +18 -12
- package/src/tools/create-oauth-client.ts +8 -2
- package/src/tools/create-post.ts +20 -28
- package/src/tools/create-posts-batch.ts +23 -18
- package/src/tools/create-signed-upload.ts +11 -8
- package/src/tools/create-webhook.ts +7 -3
- package/src/tools/delete-google-business-review-reply.ts +4 -1
- package/src/tools/delete-oauth-client.ts +4 -1
- package/src/tools/delete-post-group.ts +5 -1
- package/src/tools/delete-post.ts +4 -1
- package/src/tools/delete-webhook.ts +4 -2
- package/src/tools/disconnect-account.ts +7 -5
- package/src/tools/find-slot.ts +13 -5
- package/src/tools/generate-image.ts +20 -20
- package/src/tools/generate-video.ts +11 -9
- package/src/tools/get-account-analytics.ts +70 -49
- package/src/tools/get-brand-profile.ts +34 -38
- package/src/tools/get-brand.ts +14 -14
- package/src/tools/get-connect-link.ts +29 -7
- package/src/tools/get-google-business-review-link.ts +6 -6
- package/src/tools/get-platform-schema.ts +29 -16
- package/src/tools/get-post-analytics.ts +58 -51
- package/src/tools/get-post-missing.ts +5 -2
- package/src/tools/get-post.ts +16 -13
- package/src/tools/get-video-job.ts +31 -11
- package/src/tools/get-video-options.ts +27 -15
- package/src/tools/get-x-posting-quota.ts +12 -9
- package/src/tools/list-accounts.ts +15 -6
- package/src/tools/list-activity.ts +16 -20
- package/src/tools/list-brand-accounts.ts +14 -6
- package/src/tools/list-brands.ts +16 -13
- package/src/tools/list-google-business-reviews.ts +16 -12
- package/src/tools/list-oauth-clients.ts +13 -4
- package/src/tools/list-platforms.ts +15 -5
- package/src/tools/list-posts.ts +15 -9
- package/src/tools/list-webhooks.ts +16 -12
- package/src/tools/reply-google-business-review.ts +4 -1
- package/src/tools/run-video-function.ts +4 -4
- package/src/tools/suggest-google-business-review-reply.ts +5 -4
- package/src/tools/test-webhook.ts +7 -1
- package/src/tools/trigger-platform-helper.ts +5 -1
- package/src/tools/update-oauth-client.ts +9 -2
- package/src/tools/update-post-release-id.ts +5 -2
- package/src/tools/update-post-status.ts +7 -1
- package/src/tools/update-post.ts +10 -5
- package/src/tools/update-webhook.ts +7 -2
- package/src/tools/upload-media-from-url.ts +7 -9
- package/src/tools/upload-media.ts +6 -2
- package/src/tools/whoami.ts +21 -23
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdEmpty, mdTable, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const listBrandsTool = {
|
|
3
4
|
name: 'list_brands',
|
|
4
5
|
description: 'List brands/clients the caller can access. Returns each brand ID, name, workspace ID, source, and how many social accounts are currently assigned to it.',
|
|
@@ -12,18 +13,18 @@ export const listBrandsTool = {
|
|
|
12
13
|
const brands = await client.listBrands({ workspace_id: input.workspace_id });
|
|
13
14
|
if (brands.length === 0) {
|
|
14
15
|
return input.workspace_id
|
|
15
|
-
? '
|
|
16
|
-
: 'No brands found. Create
|
|
16
|
+
? mdEmpty('brands', 'This workspace does not have any brands or clients yet.')
|
|
17
|
+
: mdEmpty('brands', 'No brands or clients were found for this API key.', 'Create a brand in the Posterly dashboard, then run this again.');
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
brand.
|
|
22
|
-
|
|
19
|
+
return [
|
|
20
|
+
mdTitle(`Brands (${brands.length})`),
|
|
21
|
+
mdTable(['Brand', 'Brand ID', 'Accounts', 'Source', 'Workspace'], brands.map((brand) => [
|
|
22
|
+
brand.name,
|
|
23
|
+
code(brand.id),
|
|
24
|
+
brand.account_count,
|
|
23
25
|
brand.source,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return `Brands (${brands.length}):\n${lines.join('\n')}`;
|
|
26
|
+
brand.workspace_id ? code(brand.workspace_id) : 'default',
|
|
27
|
+
])),
|
|
28
|
+
].join('\n\n');
|
|
28
29
|
},
|
|
29
30
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
2
3
|
export const listGoogleBusinessReviewsTool = {
|
|
3
4
|
name: 'list_google_business_reviews',
|
|
4
5
|
description: 'List Google Business Profile reviews for one location/account or every accessible GBP location. Supports rating and unanswered-only filters.',
|
|
@@ -12,17 +13,18 @@ export const listGoogleBusinessReviewsTool = {
|
|
|
12
13
|
async execute(client, input) {
|
|
13
14
|
const result = await client.listGoogleBusinessReviews(input);
|
|
14
15
|
if (result.reviews.length === 0) {
|
|
15
|
-
return '
|
|
16
|
+
return mdEmpty('Google Business reviews', 'No reviews matched those filters.');
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
return [
|
|
19
|
+
mdTitle(`Google Business reviews (${result.reviews.length} of ${result.total})`),
|
|
20
|
+
mdTable(['Reviewer', 'Rating', 'Location', 'Reply', 'Updated', 'Comment'], result.reviews.slice(0, 25).map((review) => [
|
|
21
|
+
review.reviewer?.displayName || 'Anonymous',
|
|
22
|
+
review.starRating ? `${review.starRating} stars` : 'unrated',
|
|
23
|
+
review.businessName || review.locationName || review.locationId || 'location',
|
|
24
|
+
statusLabel(review.reviewReply ? 'replied' : 'unanswered'),
|
|
25
|
+
formatDateTime(review.updateTime || review.createTime),
|
|
26
|
+
compactText(review.comment, 140) || '(rating only)',
|
|
27
|
+
])),
|
|
28
|
+
].join('\n\n');
|
|
27
29
|
},
|
|
28
30
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
2
3
|
export const listOAuthClientsTool = {
|
|
3
4
|
name: 'list_oauth_clients',
|
|
4
5
|
description: 'List self-serve OAuth developer clients owned by the user. These are public PKCE clients for third-party app integrations.',
|
|
@@ -6,10 +7,15 @@ export const listOAuthClientsTool = {
|
|
|
6
7
|
async execute(client) {
|
|
7
8
|
const result = await client.listOAuthClients();
|
|
8
9
|
if (result.clients.length === 0)
|
|
9
|
-
return 'No OAuth developer clients found.';
|
|
10
|
+
return mdEmpty('OAuth developer clients', 'No OAuth developer clients were found.');
|
|
10
11
|
return [
|
|
11
|
-
`OAuth developer clients (${result.clients.length})
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
mdTitle(`OAuth developer clients (${result.clients.length})`),
|
|
13
|
+
mdTable(['Client', 'Client ID', 'Scopes', 'State'], result.clients.map((item) => [
|
|
14
|
+
item.client_name,
|
|
15
|
+
code(item.client_id),
|
|
16
|
+
item.default_scopes.join(', '),
|
|
17
|
+
statusLabel(item.is_active ? 'active' : 'inactive'),
|
|
18
|
+
])),
|
|
19
|
+
].join('\n\n');
|
|
14
20
|
},
|
|
15
21
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { PLANNED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
3
|
+
import { code, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
export const listPlatformsTool = {
|
|
4
5
|
name: 'list_platforms',
|
|
5
6
|
description: 'List posterly platform integrations, posting capabilities, content/media limits, settings schemas, helper tools, and analytics support. Use include_planned to show future integration possibilities from the Postiz parity audit.',
|
|
@@ -11,10 +12,16 @@ export const listPlatformsTool = {
|
|
|
11
12
|
}),
|
|
12
13
|
async execute(client, input) {
|
|
13
14
|
const result = await client.listPlatforms(input);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
return [
|
|
16
|
+
mdTitle(`Posterly platforms (${result.platforms.length})`),
|
|
17
|
+
mdTable(['Platform', 'ID', 'Status', 'Post types', 'Helpers', 'Analytics'], result.platforms.map((platform) => [
|
|
18
|
+
platform.label,
|
|
19
|
+
code(platform.id),
|
|
20
|
+
statusLabel(platform.status),
|
|
21
|
+
platform.post_types.join(', ') || 'n/a',
|
|
22
|
+
platform.helper_tools?.length || 0,
|
|
23
|
+
platform.analytics_supported,
|
|
24
|
+
])),
|
|
25
|
+
].join('\n\n');
|
|
19
26
|
},
|
|
20
27
|
};
|
package/dist/tools/list-posts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { SUPPORTED_PLATFORM_INPUTS, SUPPORTED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
3
|
+
import { code, compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
export const listPostsTool = {
|
|
4
5
|
name: 'list_posts',
|
|
5
6
|
description: 'List upcoming or recent posts. Filter by status (scheduled, published, failed, draft), platform, account_id, or workspace_id. If workspace_id is omitted, posts across every workspace the caller is a member of are returned.',
|
|
@@ -33,13 +34,17 @@ export const listPostsTool = {
|
|
|
33
34
|
limit: input.limit || 20,
|
|
34
35
|
});
|
|
35
36
|
if (posts.length === 0) {
|
|
36
|
-
return 'No posts
|
|
37
|
+
return mdEmpty('posts', 'No posts matched those filters.');
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
return [
|
|
40
|
+
mdTitle(`Posts (${posts.length} of ${total})`),
|
|
41
|
+
mdTable(['Status', 'Post ID', 'Caption', 'Scheduled', 'Type'], posts.map((post) => [
|
|
42
|
+
statusLabel(post.status),
|
|
43
|
+
code(post.id),
|
|
44
|
+
compactText(post.content, 80) || '(empty)',
|
|
45
|
+
formatDateTime(post.scheduled_at),
|
|
46
|
+
post.post_type || 'post',
|
|
47
|
+
])),
|
|
48
|
+
].join('\n\n');
|
|
44
49
|
},
|
|
45
50
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
2
3
|
export const listWebhooksTool = {
|
|
3
4
|
name: 'list_webhooks',
|
|
4
5
|
description: 'List API webhook subscriptions, their event filters, active state, and most recent delivery status.',
|
|
@@ -8,17 +9,18 @@ export const listWebhooksTool = {
|
|
|
8
9
|
async execute(client, input) {
|
|
9
10
|
const { webhooks } = await client.listWebhooks(input);
|
|
10
11
|
if (webhooks.length === 0) {
|
|
11
|
-
return 'No
|
|
12
|
+
return mdEmpty('webhooks', 'No webhook subscriptions were found.');
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
: ''
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
return [
|
|
15
|
+
mdTitle(`Webhooks (${webhooks.length})`),
|
|
16
|
+
mdTable(['Webhook ID', 'State', 'URL', 'Events', 'Last delivery', 'Last error'], webhooks.map((webhook) => [
|
|
17
|
+
code(webhook.id),
|
|
18
|
+
statusLabel(webhook.is_active ? 'active' : 'inactive'),
|
|
19
|
+
webhook.url,
|
|
20
|
+
webhook.events?.length ? webhook.events.join(', ') : 'default events',
|
|
21
|
+
webhook.last_delivery_at ? `${webhook.last_delivery_status || 'n/a'} at ${formatDateTime(webhook.last_delivery_at)}` : 'n/a',
|
|
22
|
+
compactText(webhook.last_error, 80) || 'n/a',
|
|
23
|
+
])),
|
|
24
|
+
].join('\n\n');
|
|
23
25
|
},
|
|
24
26
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { mdSuccess } from '../lib/format.js';
|
|
2
3
|
export const replyGoogleBusinessReviewTool = {
|
|
3
4
|
name: 'reply_google_business_review',
|
|
4
5
|
description: 'Post or update the owner reply on a Google Business Profile review. WRITE: show the review, location, and exact reply text to the user, then pass confirm=true only after explicit confirmation.',
|
|
@@ -13,6 +14,8 @@ export const replyGoogleBusinessReviewTool = {
|
|
|
13
14
|
async execute(client, input) {
|
|
14
15
|
const { confirm: _confirm, ...payload } = input;
|
|
15
16
|
const result = await client.replyGoogleBusinessReview(payload);
|
|
16
|
-
return
|
|
17
|
+
return mdSuccess('Google Business review reply posted', [
|
|
18
|
+
['Message', result.message || 'Google Business review reply posted successfully.'],
|
|
19
|
+
]);
|
|
17
20
|
},
|
|
18
21
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const runVideoFunctionTool = {
|
|
3
4
|
name: 'run_video_function',
|
|
4
5
|
description: 'Run a read-only Veo helper function before generation: list_input_modes, estimate_cost, or validate_request. This does not generate video or spend credits.',
|
|
@@ -17,9 +18,8 @@ export const runVideoFunctionTool = {
|
|
|
17
18
|
async execute(client, input) {
|
|
18
19
|
const result = await client.runVideoFunction(input);
|
|
19
20
|
return [
|
|
20
|
-
`Video function ${input.functionName} completed
|
|
21
|
-
'',
|
|
22
|
-
|
|
23
|
-
].join('\n');
|
|
21
|
+
mdTitle(`Video function ${code(input.functionName)} completed`),
|
|
22
|
+
mdJson('Result', result),
|
|
23
|
+
].join('\n\n');
|
|
24
24
|
},
|
|
25
25
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { mdEmpty, mdQuote, mdSection, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const suggestGoogleBusinessReviewReplyTool = {
|
|
3
4
|
name: 'suggest_google_business_review_reply',
|
|
4
5
|
description: 'Generate short, brand-aware AI reply suggestions for a Google review. Uses the AI Caption Assist allowance; does not post the reply.',
|
|
@@ -17,11 +18,11 @@ export const suggestGoogleBusinessReviewReplyTool = {
|
|
|
17
18
|
const result = await client.suggestGoogleBusinessReviewReply(input);
|
|
18
19
|
const suggestions = Array.isArray(result.suggestions) ? result.suggestions : [];
|
|
19
20
|
if (suggestions.length === 0) {
|
|
20
|
-
return 'No reply suggestions were generated.';
|
|
21
|
+
return mdEmpty('reply suggestions', 'No Google Business reply suggestions were generated.');
|
|
21
22
|
}
|
|
22
23
|
return [
|
|
23
|
-
`Suggested replies
|
|
24
|
-
...suggestions.map((text, index) =>
|
|
25
|
-
].join('\n');
|
|
24
|
+
mdTitle(`Suggested replies`, `${result.tone || 'professional'} tone · ${result.rating || input.star_rating} stars`),
|
|
25
|
+
...suggestions.map((text, index) => mdSection(`Option ${index + 1}`, mdQuote(text))),
|
|
26
|
+
].join('\n\n');
|
|
26
27
|
},
|
|
27
28
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { mdJson, mdSuccess } from '../lib/format.js';
|
|
2
3
|
export const testWebhookTool = {
|
|
3
4
|
name: 'test_webhook',
|
|
4
5
|
description: 'Send a signed webhook.test delivery to a webhook URL. OUTBOUND SIDE EFFECT: get explicit confirmation before sending a test request.',
|
|
@@ -9,6 +10,11 @@ export const testWebhookTool = {
|
|
|
9
10
|
async execute(client, input) {
|
|
10
11
|
const result = await client.testWebhook(input.webhook_id);
|
|
11
12
|
const delivery = result.delivery || {};
|
|
12
|
-
return
|
|
13
|
+
return [
|
|
14
|
+
mdSuccess('Webhook test sent', [
|
|
15
|
+
['Webhook ID', input.webhook_id],
|
|
16
|
+
]),
|
|
17
|
+
mdJson('Delivery', delivery),
|
|
18
|
+
].join('\n\n');
|
|
13
19
|
},
|
|
14
20
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { PLATFORM_HELPER_NAMES, SUPPORTED_PLATFORM_INPUTS, SUPPORTED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
3
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
3
4
|
export const triggerPlatformHelperTool = {
|
|
4
5
|
name: 'trigger_platform_helper',
|
|
5
6
|
description: `Run account-specific platform helper discovery. Available helpers: ${PLATFORM_HELPER_NAMES.join(', ')}.`,
|
|
@@ -17,6 +18,9 @@ export const triggerPlatformHelperTool = {
|
|
|
17
18
|
}),
|
|
18
19
|
async execute(client, input) {
|
|
19
20
|
const result = await client.triggerPlatformHelper(input);
|
|
20
|
-
return
|
|
21
|
+
return [
|
|
22
|
+
mdTitle(`Platform helper ${code(input.helper)} completed`),
|
|
23
|
+
mdJson('Result', result),
|
|
24
|
+
].join('\n\n');
|
|
21
25
|
},
|
|
22
26
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
2
3
|
const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read']);
|
|
3
4
|
export const updateOAuthClientTool = {
|
|
4
5
|
name: 'update_oauth_client',
|
|
@@ -16,6 +17,12 @@ export const updateOAuthClientTool = {
|
|
|
16
17
|
async execute(client, input) {
|
|
17
18
|
const { client_id, confirm: _confirm, ...payload } = input;
|
|
18
19
|
const result = await client.updateOAuthClient(client_id, payload);
|
|
19
|
-
return
|
|
20
|
+
return mdSuccess('OAuth client updated', [
|
|
21
|
+
['Client', result.client.client_name],
|
|
22
|
+
['Client ID', code(result.client.client_id)],
|
|
23
|
+
['State', statusLabel(result.client.is_active ? 'active' : 'inactive')],
|
|
24
|
+
['Redirect URIs', result.client.allowed_redirect_uris.join(', ')],
|
|
25
|
+
['Default scopes', result.client.default_scopes.join(', ')],
|
|
26
|
+
]);
|
|
20
27
|
},
|
|
21
28
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const updatePostReleaseIdTool = {
|
|
3
4
|
name: 'update_post_release_id',
|
|
4
5
|
description: 'Set or repair an external release_id and optional group_id on a post. WRITE: call get_post first, show the target post and release/group IDs, then pass confirm=true only after explicit confirmation.',
|
|
@@ -13,6 +14,9 @@ export const updatePostReleaseIdTool = {
|
|
|
13
14
|
release_id: input.release_id,
|
|
14
15
|
group_id: input.group_id,
|
|
15
16
|
});
|
|
16
|
-
return
|
|
17
|
+
return [
|
|
18
|
+
mdTitle(`✅ Release ID updated for post ${code(input.post_id)}`),
|
|
19
|
+
mdJson('Result', result),
|
|
20
|
+
].join('\n\n');
|
|
17
21
|
},
|
|
18
22
|
};
|
|
@@ -9,12 +9,12 @@ export declare const updatePostStatusTool: {
|
|
|
9
9
|
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
10
10
|
confirm: z.ZodBoolean;
|
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
|
12
|
-
status: "scheduled" | "
|
|
12
|
+
status: "scheduled" | "draft" | "paused";
|
|
13
13
|
post_id: number;
|
|
14
14
|
confirm: boolean;
|
|
15
15
|
scheduled_at?: string | undefined;
|
|
16
16
|
}, {
|
|
17
|
-
status: "scheduled" | "
|
|
17
|
+
status: "scheduled" | "draft" | "paused";
|
|
18
18
|
post_id: number;
|
|
19
19
|
confirm: boolean;
|
|
20
20
|
scheduled_at?: string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
2
3
|
export const updatePostStatusTool = {
|
|
3
4
|
name: 'update_post_status',
|
|
4
5
|
description: 'Pause, resume/schedule, or move a post back to draft. DESTRUCTIVE WRITE: changes whether content will publish.\n\n' +
|
|
@@ -18,6 +19,11 @@ export const updatePostStatusTool = {
|
|
|
18
19
|
scheduled_at: input.scheduled_at,
|
|
19
20
|
});
|
|
20
21
|
const transition = result.transition || {};
|
|
21
|
-
return
|
|
22
|
+
return mdSuccess('Post status updated', [
|
|
23
|
+
['Post ID', code(input.post_id)],
|
|
24
|
+
['From', statusLabel(transition.old_status || 'unknown')],
|
|
25
|
+
['To', statusLabel(transition.new_status || input.status)],
|
|
26
|
+
['Scheduled', input.scheduled_at || undefined],
|
|
27
|
+
]);
|
|
22
28
|
},
|
|
23
29
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, formatDateTime, mdKeyValue, mdQuote, mdSection, mdTitle, statusLabel } from '../lib/format.js';
|
|
2
3
|
const instagramSettingsSchema = z.object({
|
|
3
4
|
__type: z.enum(['instagram', 'instagram-standalone']).optional(),
|
|
4
5
|
post_type: z.enum(['post', 'feed', 'story', 'reel', 'carousel']).optional(),
|
|
@@ -89,9 +90,14 @@ export const updatePostTool = {
|
|
|
89
90
|
};
|
|
90
91
|
const result = await client.updatePost(post_id, payload);
|
|
91
92
|
const p = result.post;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
return [
|
|
94
|
+
mdTitle(`✅ Post ${code(p.id)} updated`),
|
|
95
|
+
mdKeyValue([
|
|
96
|
+
['Status', statusLabel(p.status)],
|
|
97
|
+
['Scheduled', formatDateTime(p.scheduled_at)],
|
|
98
|
+
['Type', p.post_type || 'unknown'],
|
|
99
|
+
]),
|
|
100
|
+
mdSection('Caption', p.content ? mdQuote(p.content) : '_(empty)_'),
|
|
101
|
+
].join('\n\n');
|
|
96
102
|
},
|
|
97
103
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { webhookEventSchema } from './webhook-events.js';
|
|
3
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
3
4
|
export const updateWebhookTool = {
|
|
4
5
|
name: 'update_webhook',
|
|
5
6
|
description: 'Update a webhook URL, events, workspace, description, or active state. WRITE WITH OUTBOUND SIDE EFFECTS: list the current webhook first and get explicit confirmation before calling.',
|
|
@@ -16,6 +17,11 @@ export const updateWebhookTool = {
|
|
|
16
17
|
const { webhook_id, confirm: _confirm, ...payload } = input;
|
|
17
18
|
const result = await client.updateWebhook(webhook_id, payload);
|
|
18
19
|
const active = result.webhook.is_active ? 'active' : 'inactive';
|
|
19
|
-
return
|
|
20
|
+
return mdSuccess('Webhook updated', [
|
|
21
|
+
['Webhook ID', code(result.webhook.id)],
|
|
22
|
+
['URL', result.webhook.url],
|
|
23
|
+
['State', statusLabel(active)],
|
|
24
|
+
['Events', result.webhook.events.join(', ')],
|
|
25
|
+
]);
|
|
20
26
|
},
|
|
21
27
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { formatBytes, mdSuccess } from '../lib/format.js';
|
|
2
3
|
export const uploadMediaFromUrlTool = {
|
|
3
4
|
name: 'upload_media_from_url',
|
|
4
5
|
description: 'Fetch an image or video from a public HTTPS URL into posterly storage. Returns a URL that can be used with create_post.',
|
|
@@ -13,14 +14,11 @@ export const uploadMediaFromUrlTool = {
|
|
|
13
14
|
filename: input.filename,
|
|
14
15
|
contentType: input.content_type,
|
|
15
16
|
});
|
|
16
|
-
return [
|
|
17
|
-
'
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
'',
|
|
23
|
-
'Use this URL as media_url when creating a post.',
|
|
24
|
-
].join('\n');
|
|
17
|
+
return mdSuccess('Remote media uploaded', [
|
|
18
|
+
['URL', result.url],
|
|
19
|
+
['Source URL', result.source_url],
|
|
20
|
+
['Content type', result.content_type],
|
|
21
|
+
['Size', formatBytes(result.size)],
|
|
22
|
+
], 'Use this URL as `media_url` when creating a post.');
|
|
25
23
|
},
|
|
26
24
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { mdError, mdSuccess } from '../lib/format.js';
|
|
2
3
|
export const uploadMediaTool = {
|
|
3
4
|
name: 'upload_media',
|
|
4
5
|
description: 'Upload an image or video file to posterly storage. Returns a URL that can be used with create_post. Supports JPEG, PNG, GIF, WebP, MP4, MOV, WebM. Images up to 10MB, videos up to 50MB.\n\n' +
|
|
@@ -23,7 +24,7 @@ export const uploadMediaTool = {
|
|
|
23
24
|
}),
|
|
24
25
|
async execute(client, input) {
|
|
25
26
|
if (!input.file_path && !input.base64_data) {
|
|
26
|
-
return '
|
|
27
|
+
return mdError('Provide either `file_path` or `base64_data`.');
|
|
27
28
|
}
|
|
28
29
|
const result = await client.uploadMedia({
|
|
29
30
|
filePath: input.file_path,
|
|
@@ -31,6 +32,9 @@ export const uploadMediaTool = {
|
|
|
31
32
|
filename: input.filename,
|
|
32
33
|
contentType: input.content_type,
|
|
33
34
|
});
|
|
34
|
-
return
|
|
35
|
+
return mdSuccess('Media uploaded', [
|
|
36
|
+
['URL', result.url],
|
|
37
|
+
['Storage path', result.path],
|
|
38
|
+
], 'Use this URL as `media_url` when creating a post.');
|
|
35
39
|
},
|
|
36
40
|
};
|
package/dist/tools/whoami.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { code, mdKeyValue, mdTable, mdTitle } from '../lib/format.js';
|
|
2
3
|
export const whoamiTool = {
|
|
3
4
|
name: 'whoami',
|
|
4
5
|
description: 'Return the authenticated user, API key scopes, the default (personal) workspace, and every workspace the caller can post in. ALWAYS call this at the start of a session before creating, listing, or scheduling posts — posts created without an explicit workspace_id land in the default workspace shown here, and confirming with the user first prevents posts from appearing in the wrong workspace.',
|
|
5
6
|
inputSchema: z.object({}),
|
|
6
7
|
async execute(client) {
|
|
7
8
|
const info = await client.whoami();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
return [
|
|
10
|
+
mdTitle('Posterly identity'),
|
|
11
|
+
mdKeyValue([
|
|
12
|
+
['User', info.user.email || code(info.user.id)],
|
|
13
|
+
['API scopes', info.api_key.scopes.join(', ') || 'none'],
|
|
14
|
+
['Default workspace', `${info.default_workspace.name} (${code(info.default_workspace.id)})`],
|
|
15
|
+
['Default timezone', info.default_workspace.timezone || 'n/a'],
|
|
16
|
+
]),
|
|
17
|
+
mdTable(['Workspace', 'Workspace ID', 'Role', 'Timezone', 'Default'], info.workspaces.map((workspace) => [
|
|
18
|
+
`${workspace.name}${workspace.is_personal ? ' (personal)' : ''}`,
|
|
19
|
+
code(workspace.id),
|
|
20
|
+
workspace.role || 'member',
|
|
21
|
+
workspace.timezone || 'n/a',
|
|
22
|
+
workspace.id === info.default_workspace.id,
|
|
23
|
+
])),
|
|
24
|
+
'**Tip:** Pass `workspace_id` to `create_post`, `list_posts`, `list_accounts`, and `find_available_slot` when you want the assistant to stay inside one workspace.',
|
|
25
|
+
].join('\n\n');
|
|
25
26
|
},
|
|
26
27
|
};
|