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
package/src/tools/list-brands.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdEmpty, mdTable, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const listBrandsTool = {
|
|
5
6
|
name: 'list_brands',
|
|
@@ -17,20 +18,22 @@ export const listBrandsTool = {
|
|
|
17
18
|
|
|
18
19
|
if (brands.length === 0) {
|
|
19
20
|
return input.workspace_id
|
|
20
|
-
? '
|
|
21
|
-
: 'No brands found. Create
|
|
21
|
+
? mdEmpty('brands', 'This workspace does not have any brands or clients yet.')
|
|
22
|
+
: mdEmpty('brands', 'No brands or clients were found for this API key.', 'Create a brand in the Posterly dashboard, then run this again.');
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
return [
|
|
26
|
+
mdTitle(`Brands (${brands.length})`),
|
|
27
|
+
mdTable(
|
|
28
|
+
['Brand', 'Brand ID', 'Accounts', 'Source', 'Workspace'],
|
|
29
|
+
brands.map((brand) => [
|
|
30
|
+
brand.name,
|
|
31
|
+
code(brand.id),
|
|
32
|
+
brand.account_count,
|
|
33
|
+
brand.source,
|
|
34
|
+
brand.workspace_id ? code(brand.workspace_id) : 'default',
|
|
35
|
+
]),
|
|
36
|
+
),
|
|
37
|
+
].join('\n\n');
|
|
35
38
|
},
|
|
36
39
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const listGoogleBusinessReviewsTool = {
|
|
5
6
|
name: 'list_google_business_reviews',
|
|
@@ -25,19 +26,22 @@ export const listGoogleBusinessReviewsTool = {
|
|
|
25
26
|
) {
|
|
26
27
|
const result = await client.listGoogleBusinessReviews(input);
|
|
27
28
|
if (result.reviews.length === 0) {
|
|
28
|
-
return '
|
|
29
|
+
return mdEmpty('Google Business reviews', 'No reviews matched those filters.');
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
return [
|
|
33
|
+
mdTitle(`Google Business reviews (${result.reviews.length} of ${result.total})`),
|
|
34
|
+
mdTable(
|
|
35
|
+
['Reviewer', 'Rating', 'Location', 'Reply', 'Updated', 'Comment'],
|
|
36
|
+
result.reviews.slice(0, 25).map((review) => [
|
|
37
|
+
review.reviewer?.displayName || 'Anonymous',
|
|
38
|
+
review.starRating ? `${review.starRating} stars` : 'unrated',
|
|
39
|
+
review.businessName || review.locationName || review.locationId || 'location',
|
|
40
|
+
statusLabel(review.reviewReply ? 'replied' : 'unanswered'),
|
|
41
|
+
formatDateTime(review.updateTime || review.createTime),
|
|
42
|
+
compactText(review.comment, 140) || '(rating only)',
|
|
43
|
+
]),
|
|
44
|
+
),
|
|
45
|
+
].join('\n\n');
|
|
42
46
|
},
|
|
43
47
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const listOAuthClientsTool = {
|
|
5
6
|
name: 'list_oauth_clients',
|
|
@@ -9,10 +10,18 @@ export const listOAuthClientsTool = {
|
|
|
9
10
|
|
|
10
11
|
async execute(client: PosterlyClient) {
|
|
11
12
|
const result = await client.listOAuthClients();
|
|
12
|
-
if (result.clients.length === 0) return 'No OAuth developer clients found.';
|
|
13
|
+
if (result.clients.length === 0) return mdEmpty('OAuth developer clients', 'No OAuth developer clients were found.');
|
|
13
14
|
return [
|
|
14
|
-
`OAuth developer clients (${result.clients.length})
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
mdTitle(`OAuth developer clients (${result.clients.length})`),
|
|
16
|
+
mdTable(
|
|
17
|
+
['Client', 'Client ID', 'Scopes', 'State'],
|
|
18
|
+
result.clients.map((item) => [
|
|
19
|
+
item.client_name,
|
|
20
|
+
code(item.client_id),
|
|
21
|
+
item.default_scopes.join(', '),
|
|
22
|
+
statusLabel(item.is_active ? 'active' : 'inactive'),
|
|
23
|
+
]),
|
|
24
|
+
),
|
|
25
|
+
].join('\n\n');
|
|
17
26
|
},
|
|
18
27
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
3
|
import { PLANNED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
4
|
+
import { code, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
4
5
|
|
|
5
6
|
export const listPlatformsTool = {
|
|
6
7
|
name: 'list_platforms',
|
|
@@ -15,11 +16,20 @@ export const listPlatformsTool = {
|
|
|
15
16
|
|
|
16
17
|
async execute(client: PosterlyClient, input: { include_planned?: boolean }) {
|
|
17
18
|
const result = await client.listPlatforms(input);
|
|
18
|
-
const lines = result.platforms.map((platform) => {
|
|
19
|
-
const helperCount = platform.helper_tools?.length || 0;
|
|
20
|
-
return `• ${platform.label} (${platform.id}) — ${platform.status}; post types: ${platform.post_types.join(', ') || 'n/a'}; helpers: ${helperCount}; analytics: ${platform.analytics_supported ? 'yes' : 'no'}`;
|
|
21
|
-
});
|
|
22
19
|
|
|
23
|
-
return
|
|
20
|
+
return [
|
|
21
|
+
mdTitle(`Posterly platforms (${result.platforms.length})`),
|
|
22
|
+
mdTable(
|
|
23
|
+
['Platform', 'ID', 'Status', 'Post types', 'Helpers', 'Analytics'],
|
|
24
|
+
result.platforms.map((platform) => [
|
|
25
|
+
platform.label,
|
|
26
|
+
code(platform.id),
|
|
27
|
+
statusLabel(platform.status),
|
|
28
|
+
platform.post_types.join(', ') || 'n/a',
|
|
29
|
+
platform.helper_tools?.length || 0,
|
|
30
|
+
platform.analytics_supported,
|
|
31
|
+
]),
|
|
32
|
+
),
|
|
33
|
+
].join('\n\n');
|
|
24
34
|
},
|
|
25
35
|
};
|
package/src/tools/list-posts.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
3
|
import { SUPPORTED_PLATFORM_INPUTS, SUPPORTED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
4
|
+
import { code, compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
4
5
|
|
|
5
6
|
export const listPostsTool = {
|
|
6
7
|
name: 'list_posts',
|
|
@@ -47,16 +48,21 @@ export const listPostsTool = {
|
|
|
47
48
|
});
|
|
48
49
|
|
|
49
50
|
if (posts.length === 0) {
|
|
50
|
-
return 'No posts
|
|
51
|
+
return mdEmpty('posts', 'No posts matched those filters.');
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
return [
|
|
55
|
+
mdTitle(`Posts (${posts.length} of ${total})`),
|
|
56
|
+
mdTable(
|
|
57
|
+
['Status', 'Post ID', 'Caption', 'Scheduled', 'Type'],
|
|
58
|
+
posts.map((post) => [
|
|
59
|
+
statusLabel(post.status),
|
|
60
|
+
code(post.id),
|
|
61
|
+
compactText(post.content, 80) || '(empty)',
|
|
62
|
+
formatDateTime(post.scheduled_at),
|
|
63
|
+
post.post_type || 'post',
|
|
64
|
+
]),
|
|
65
|
+
),
|
|
66
|
+
].join('\n\n');
|
|
61
67
|
},
|
|
62
68
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, compactText, formatDateTime, mdEmpty, mdTable, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const listWebhooksTool = {
|
|
5
6
|
name: 'list_webhooks',
|
|
@@ -12,19 +13,22 @@ export const listWebhooksTool = {
|
|
|
12
13
|
async execute(client: PosterlyClient, input: { workspace_id?: string }) {
|
|
13
14
|
const { webhooks } = await client.listWebhooks(input);
|
|
14
15
|
if (webhooks.length === 0) {
|
|
15
|
-
return 'No
|
|
16
|
+
return mdEmpty('webhooks', 'No webhook subscriptions were found.');
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
return [
|
|
20
|
+
mdTitle(`Webhooks (${webhooks.length})`),
|
|
21
|
+
mdTable(
|
|
22
|
+
['Webhook ID', 'State', 'URL', 'Events', 'Last delivery', 'Last error'],
|
|
23
|
+
webhooks.map((webhook) => [
|
|
24
|
+
code(webhook.id),
|
|
25
|
+
statusLabel(webhook.is_active ? 'active' : 'inactive'),
|
|
26
|
+
webhook.url,
|
|
27
|
+
webhook.events?.length ? webhook.events.join(', ') : 'default events',
|
|
28
|
+
webhook.last_delivery_at ? `${webhook.last_delivery_status || 'n/a'} at ${formatDateTime(webhook.last_delivery_at)}` : 'n/a',
|
|
29
|
+
compactText(webhook.last_error, 80) || 'n/a',
|
|
30
|
+
]),
|
|
31
|
+
),
|
|
32
|
+
].join('\n\n');
|
|
28
33
|
},
|
|
29
34
|
};
|
|
30
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { mdSuccess } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const replyGoogleBusinessReviewTool = {
|
|
5
6
|
name: 'reply_google_business_review',
|
|
@@ -27,6 +28,8 @@ export const replyGoogleBusinessReviewTool = {
|
|
|
27
28
|
) {
|
|
28
29
|
const { confirm: _confirm, ...payload } = input;
|
|
29
30
|
const result = await client.replyGoogleBusinessReview(payload);
|
|
30
|
-
return
|
|
31
|
+
return mdSuccess('Google Business review reply posted', [
|
|
32
|
+
['Message', result.message || 'Google Business review reply posted successfully.'],
|
|
33
|
+
]);
|
|
31
34
|
},
|
|
32
35
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const runVideoFunctionTool = {
|
|
5
6
|
name: 'run_video_function',
|
|
@@ -24,9 +25,8 @@ export const runVideoFunctionTool = {
|
|
|
24
25
|
) {
|
|
25
26
|
const result = await client.runVideoFunction(input);
|
|
26
27
|
return [
|
|
27
|
-
`Video function ${input.functionName} completed
|
|
28
|
-
'',
|
|
29
|
-
|
|
30
|
-
].join('\n');
|
|
28
|
+
mdTitle(`Video function ${code(input.functionName)} completed`),
|
|
29
|
+
mdJson('Result', result),
|
|
30
|
+
].join('\n\n');
|
|
31
31
|
},
|
|
32
32
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { mdEmpty, mdQuote, mdSection, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const suggestGoogleBusinessReviewReplyTool = {
|
|
5
6
|
name: 'suggest_google_business_review_reply',
|
|
@@ -34,11 +35,11 @@ export const suggestGoogleBusinessReviewReplyTool = {
|
|
|
34
35
|
const result = await client.suggestGoogleBusinessReviewReply(input);
|
|
35
36
|
const suggestions = Array.isArray(result.suggestions) ? result.suggestions : [];
|
|
36
37
|
if (suggestions.length === 0) {
|
|
37
|
-
return 'No reply suggestions were generated.';
|
|
38
|
+
return mdEmpty('reply suggestions', 'No Google Business reply suggestions were generated.');
|
|
38
39
|
}
|
|
39
40
|
return [
|
|
40
|
-
`Suggested replies
|
|
41
|
-
...suggestions.map((text: string, index: number) =>
|
|
42
|
-
].join('\n');
|
|
41
|
+
mdTitle(`Suggested replies`, `${result.tone || 'professional'} tone · ${result.rating || input.star_rating} stars`),
|
|
42
|
+
...suggestions.map((text: string, index: number) => mdSection(`Option ${index + 1}`, mdQuote(text))),
|
|
43
|
+
].join('\n\n');
|
|
43
44
|
},
|
|
44
45
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { mdJson, mdSuccess } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const testWebhookTool = {
|
|
5
6
|
name: 'test_webhook',
|
|
@@ -13,6 +14,11 @@ export const testWebhookTool = {
|
|
|
13
14
|
async execute(client: PosterlyClient, input: { webhook_id: string; confirm: true }) {
|
|
14
15
|
const result = await client.testWebhook(input.webhook_id);
|
|
15
16
|
const delivery = result.delivery || {};
|
|
16
|
-
return
|
|
17
|
+
return [
|
|
18
|
+
mdSuccess('Webhook test sent', [
|
|
19
|
+
['Webhook ID', input.webhook_id],
|
|
20
|
+
]),
|
|
21
|
+
mdJson('Delivery', delivery),
|
|
22
|
+
].join('\n\n');
|
|
17
23
|
},
|
|
18
24
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
3
|
import { PLATFORM_HELPER_NAMES, SUPPORTED_PLATFORM_INPUTS, SUPPORTED_PLATFORM_IDS } from '../generated/platform-manifest.js';
|
|
4
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
4
5
|
|
|
5
6
|
export const triggerPlatformHelperTool = {
|
|
6
7
|
name: 'trigger_platform_helper',
|
|
@@ -29,6 +30,9 @@ export const triggerPlatformHelperTool = {
|
|
|
29
30
|
},
|
|
30
31
|
) {
|
|
31
32
|
const result = await client.triggerPlatformHelper(input);
|
|
32
|
-
return
|
|
33
|
+
return [
|
|
34
|
+
mdTitle(`Platform helper ${code(input.helper)} completed`),
|
|
35
|
+
mdJson('Result', result),
|
|
36
|
+
].join('\n\n');
|
|
33
37
|
},
|
|
34
38
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read']);
|
|
5
6
|
|
|
@@ -30,9 +31,15 @@ export const updateOAuthClientTool = {
|
|
|
30
31
|
is_active?: boolean;
|
|
31
32
|
confirm: true;
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
+
) {
|
|
34
35
|
const { client_id, confirm: _confirm, ...payload } = input;
|
|
35
36
|
const result = await client.updateOAuthClient(client_id, payload);
|
|
36
|
-
return
|
|
37
|
+
return mdSuccess('OAuth client updated', [
|
|
38
|
+
['Client', result.client.client_name],
|
|
39
|
+
['Client ID', code(result.client.client_id)],
|
|
40
|
+
['State', statusLabel(result.client.is_active ? 'active' : 'inactive')],
|
|
41
|
+
['Redirect URIs', result.client.allowed_redirect_uris.join(', ')],
|
|
42
|
+
['Default scopes', result.client.default_scopes.join(', ')],
|
|
43
|
+
]);
|
|
37
44
|
},
|
|
38
45
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdJson, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const updatePostReleaseIdTool = {
|
|
5
6
|
name: 'update_post_release_id',
|
|
@@ -20,7 +21,9 @@ export const updatePostReleaseIdTool = {
|
|
|
20
21
|
release_id: input.release_id,
|
|
21
22
|
group_id: input.group_id,
|
|
22
23
|
});
|
|
23
|
-
return
|
|
24
|
+
return [
|
|
25
|
+
mdTitle(`✅ Release ID updated for post ${code(input.post_id)}`),
|
|
26
|
+
mdJson('Result', result),
|
|
27
|
+
].join('\n\n');
|
|
24
28
|
},
|
|
25
29
|
};
|
|
26
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const updatePostStatusTool = {
|
|
5
6
|
name: 'update_post_status',
|
|
@@ -26,6 +27,11 @@ export const updatePostStatusTool = {
|
|
|
26
27
|
scheduled_at: input.scheduled_at,
|
|
27
28
|
});
|
|
28
29
|
const transition = result.transition || {};
|
|
29
|
-
return
|
|
30
|
+
return mdSuccess('Post status updated', [
|
|
31
|
+
['Post ID', code(input.post_id)],
|
|
32
|
+
['From', statusLabel(transition.old_status || 'unknown')],
|
|
33
|
+
['To', statusLabel(transition.new_status || input.status)],
|
|
34
|
+
['Scheduled', input.scheduled_at || undefined],
|
|
35
|
+
]);
|
|
30
36
|
},
|
|
31
37
|
};
|
package/src/tools/update-post.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, formatDateTime, mdKeyValue, mdQuote, mdSection, mdTitle, statusLabel } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
const instagramSettingsSchema = z.object({
|
|
5
6
|
__type: z.enum(['instagram', 'instagram-standalone']).optional(),
|
|
@@ -108,10 +109,14 @@ export const updatePostTool = {
|
|
|
108
109
|
const result = await client.updatePost(post_id, payload);
|
|
109
110
|
const p = result.post as Record<string, any>;
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
return [
|
|
113
|
+
mdTitle(`✅ Post ${code(p.id)} updated`),
|
|
114
|
+
mdKeyValue([
|
|
115
|
+
['Status', statusLabel(p.status)],
|
|
116
|
+
['Scheduled', formatDateTime(p.scheduled_at)],
|
|
117
|
+
['Type', p.post_type || 'unknown'],
|
|
118
|
+
]),
|
|
119
|
+
mdSection('Caption', p.content ? mdQuote(p.content) : '_(empty)_'),
|
|
120
|
+
].join('\n\n');
|
|
116
121
|
},
|
|
117
122
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
3
|
import { webhookEventSchema } from './webhook-events.js';
|
|
4
|
+
import { code, mdSuccess, statusLabel } from '../lib/format.js';
|
|
4
5
|
|
|
5
6
|
export const updateWebhookTool = {
|
|
6
7
|
name: 'update_webhook',
|
|
@@ -31,7 +32,11 @@ export const updateWebhookTool = {
|
|
|
31
32
|
const { webhook_id, confirm: _confirm, ...payload } = input;
|
|
32
33
|
const result = await client.updateWebhook(webhook_id, payload);
|
|
33
34
|
const active = result.webhook.is_active ? 'active' : 'inactive';
|
|
34
|
-
return
|
|
35
|
+
return mdSuccess('Webhook updated', [
|
|
36
|
+
['Webhook ID', code(result.webhook.id)],
|
|
37
|
+
['URL', result.webhook.url],
|
|
38
|
+
['State', statusLabel(active)],
|
|
39
|
+
['Events', result.webhook.events.join(', ')],
|
|
40
|
+
]);
|
|
35
41
|
},
|
|
36
42
|
};
|
|
37
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { formatBytes, mdSuccess } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const uploadMediaFromUrlTool = {
|
|
5
6
|
name: 'upload_media_from_url',
|
|
@@ -20,14 +21,11 @@ export const uploadMediaFromUrlTool = {
|
|
|
20
21
|
filename: input.filename,
|
|
21
22
|
contentType: input.content_type,
|
|
22
23
|
});
|
|
23
|
-
return [
|
|
24
|
-
'
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'',
|
|
30
|
-
'Use this URL as media_url when creating a post.',
|
|
31
|
-
].join('\n');
|
|
24
|
+
return mdSuccess('Remote media uploaded', [
|
|
25
|
+
['URL', result.url],
|
|
26
|
+
['Source URL', result.source_url],
|
|
27
|
+
['Content type', result.content_type],
|
|
28
|
+
['Size', formatBytes(result.size)],
|
|
29
|
+
], 'Use this URL as `media_url` when creating a post.');
|
|
32
30
|
},
|
|
33
31
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { mdError, mdSuccess } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const uploadMediaTool = {
|
|
5
6
|
name: 'upload_media',
|
|
@@ -35,7 +36,7 @@ export const uploadMediaTool = {
|
|
|
35
36
|
}
|
|
36
37
|
) {
|
|
37
38
|
if (!input.file_path && !input.base64_data) {
|
|
38
|
-
return '
|
|
39
|
+
return mdError('Provide either `file_path` or `base64_data`.');
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
const result = await client.uploadMedia({
|
|
@@ -45,6 +46,9 @@ export const uploadMediaTool = {
|
|
|
45
46
|
contentType: input.content_type,
|
|
46
47
|
});
|
|
47
48
|
|
|
48
|
-
return
|
|
49
|
+
return mdSuccess('Media uploaded', [
|
|
50
|
+
['URL', result.url],
|
|
51
|
+
['Storage path', result.path],
|
|
52
|
+
], 'Use this URL as `media_url` when creating a post.');
|
|
49
53
|
},
|
|
50
54
|
};
|
package/src/tools/whoami.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdKeyValue, mdTable, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const whoamiTool = {
|
|
5
6
|
name: 'whoami',
|
|
@@ -10,28 +11,25 @@ export const whoamiTool = {
|
|
|
10
11
|
async execute(client: PosterlyClient) {
|
|
11
12
|
const info = await client.whoami();
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
return lines.join('\n');
|
|
14
|
+
return [
|
|
15
|
+
mdTitle('Posterly identity'),
|
|
16
|
+
mdKeyValue([
|
|
17
|
+
['User', info.user.email || code(info.user.id)],
|
|
18
|
+
['API scopes', info.api_key.scopes.join(', ') || 'none'],
|
|
19
|
+
['Default workspace', `${info.default_workspace.name} (${code(info.default_workspace.id)})`],
|
|
20
|
+
['Default timezone', info.default_workspace.timezone || 'n/a'],
|
|
21
|
+
]),
|
|
22
|
+
mdTable(
|
|
23
|
+
['Workspace', 'Workspace ID', 'Role', 'Timezone', 'Default'],
|
|
24
|
+
info.workspaces.map((workspace) => [
|
|
25
|
+
`${workspace.name}${workspace.is_personal ? ' (personal)' : ''}`,
|
|
26
|
+
code(workspace.id),
|
|
27
|
+
workspace.role || 'member',
|
|
28
|
+
workspace.timezone || 'n/a',
|
|
29
|
+
workspace.id === info.default_workspace.id,
|
|
30
|
+
]),
|
|
31
|
+
),
|
|
32
|
+
'**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.',
|
|
33
|
+
].join('\n\n');
|
|
36
34
|
},
|
|
37
35
|
};
|