posterly-mcp-server 0.19.0 → 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.
Files changed (115) hide show
  1. package/README.md +3 -1
  2. package/dist/generated/platform-manifest.d.ts +3 -3
  3. package/dist/generated/platform-manifest.js +3 -2
  4. package/dist/index.js +50 -49
  5. package/dist/lib/api-client.d.ts +2 -0
  6. package/dist/lib/api-client.js +1 -1
  7. package/dist/lib/format.d.ts +21 -0
  8. package/dist/lib/format.js +125 -0
  9. package/dist/tools/audit-google-business-profile.js +15 -12
  10. package/dist/tools/create-oauth-client.js +7 -1
  11. package/dist/tools/create-post.js +20 -27
  12. package/dist/tools/create-posts-batch.js +23 -15
  13. package/dist/tools/create-signed-upload.js +11 -8
  14. package/dist/tools/create-webhook.js +7 -2
  15. package/dist/tools/delete-google-business-review-reply.d.ts +1 -1
  16. package/dist/tools/delete-google-business-review-reply.js +4 -1
  17. package/dist/tools/delete-oauth-client.js +4 -1
  18. package/dist/tools/delete-post-group.js +5 -1
  19. package/dist/tools/delete-post.js +4 -1
  20. package/dist/tools/delete-webhook.js +4 -1
  21. package/dist/tools/disconnect-account.js +7 -5
  22. package/dist/tools/find-slot.js +10 -3
  23. package/dist/tools/generate-image.js +17 -19
  24. package/dist/tools/generate-video.js +11 -9
  25. package/dist/tools/get-account-analytics.js +68 -53
  26. package/dist/tools/get-brand-profile.js +34 -40
  27. package/dist/tools/get-brand.js +14 -16
  28. package/dist/tools/get-connect-link.js +26 -7
  29. package/dist/tools/get-google-business-review-link.js +6 -6
  30. package/dist/tools/get-platform-schema.js +23 -16
  31. package/dist/tools/get-post-analytics.js +54 -51
  32. package/dist/tools/get-post-missing.js +5 -1
  33. package/dist/tools/get-post.js +16 -14
  34. package/dist/tools/get-video-job.d.ts +2 -2
  35. package/dist/tools/get-video-job.js +28 -11
  36. package/dist/tools/get-video-options.js +21 -15
  37. package/dist/tools/get-x-posting-quota.js +12 -9
  38. package/dist/tools/list-accounts.js +12 -4
  39. package/dist/tools/list-activity.js +13 -18
  40. package/dist/tools/list-brand-accounts.js +11 -3
  41. package/dist/tools/list-brands.js +12 -11
  42. package/dist/tools/list-google-business-reviews.js +13 -11
  43. package/dist/tools/list-oauth-clients.js +10 -4
  44. package/dist/tools/list-platforms.js +12 -5
  45. package/dist/tools/list-posts.js +12 -7
  46. package/dist/tools/list-webhooks.js +13 -11
  47. package/dist/tools/reply-google-business-review.d.ts +1 -1
  48. package/dist/tools/reply-google-business-review.js +4 -1
  49. package/dist/tools/run-video-function.js +4 -4
  50. package/dist/tools/suggest-google-business-review-reply.js +5 -4
  51. package/dist/tools/test-webhook.js +7 -1
  52. package/dist/tools/trigger-platform-helper.js +5 -1
  53. package/dist/tools/update-oauth-client.js +8 -1
  54. package/dist/tools/update-post-release-id.js +5 -1
  55. package/dist/tools/update-post-status.d.ts +2 -2
  56. package/dist/tools/update-post-status.js +7 -1
  57. package/dist/tools/update-post.js +10 -4
  58. package/dist/tools/update-webhook.js +7 -1
  59. package/dist/tools/upload-media-from-url.js +7 -9
  60. package/dist/tools/upload-media.js +6 -2
  61. package/dist/tools/whoami.js +18 -17
  62. package/package.json +1 -1
  63. package/src/generated/platform-manifest.ts +3 -2
  64. package/src/index.ts +50 -49
  65. package/src/lib/api-client.ts +3 -1
  66. package/src/lib/format.ts +132 -0
  67. package/src/tools/audit-google-business-profile.ts +18 -12
  68. package/src/tools/create-oauth-client.ts +8 -2
  69. package/src/tools/create-post.ts +20 -28
  70. package/src/tools/create-posts-batch.ts +23 -18
  71. package/src/tools/create-signed-upload.ts +11 -8
  72. package/src/tools/create-webhook.ts +7 -3
  73. package/src/tools/delete-google-business-review-reply.ts +4 -1
  74. package/src/tools/delete-oauth-client.ts +4 -1
  75. package/src/tools/delete-post-group.ts +5 -1
  76. package/src/tools/delete-post.ts +4 -1
  77. package/src/tools/delete-webhook.ts +4 -2
  78. package/src/tools/disconnect-account.ts +7 -5
  79. package/src/tools/find-slot.ts +13 -5
  80. package/src/tools/generate-image.ts +20 -20
  81. package/src/tools/generate-video.ts +11 -9
  82. package/src/tools/get-account-analytics.ts +77 -55
  83. package/src/tools/get-brand-profile.ts +34 -38
  84. package/src/tools/get-brand.ts +14 -14
  85. package/src/tools/get-connect-link.ts +29 -7
  86. package/src/tools/get-google-business-review-link.ts +6 -6
  87. package/src/tools/get-platform-schema.ts +29 -16
  88. package/src/tools/get-post-analytics.ts +59 -52
  89. package/src/tools/get-post-missing.ts +5 -2
  90. package/src/tools/get-post.ts +16 -13
  91. package/src/tools/get-video-job.ts +31 -11
  92. package/src/tools/get-video-options.ts +27 -15
  93. package/src/tools/get-x-posting-quota.ts +12 -9
  94. package/src/tools/list-accounts.ts +15 -6
  95. package/src/tools/list-activity.ts +16 -20
  96. package/src/tools/list-brand-accounts.ts +14 -6
  97. package/src/tools/list-brands.ts +16 -13
  98. package/src/tools/list-google-business-reviews.ts +16 -12
  99. package/src/tools/list-oauth-clients.ts +13 -4
  100. package/src/tools/list-platforms.ts +15 -5
  101. package/src/tools/list-posts.ts +15 -9
  102. package/src/tools/list-webhooks.ts +16 -12
  103. package/src/tools/reply-google-business-review.ts +4 -1
  104. package/src/tools/run-video-function.ts +4 -4
  105. package/src/tools/suggest-google-business-review-reply.ts +5 -4
  106. package/src/tools/test-webhook.ts +7 -1
  107. package/src/tools/trigger-platform-helper.ts +5 -1
  108. package/src/tools/update-oauth-client.ts +9 -2
  109. package/src/tools/update-post-release-id.ts +5 -2
  110. package/src/tools/update-post-status.ts +7 -1
  111. package/src/tools/update-post.ts +10 -5
  112. package/src/tools/update-webhook.ts +7 -2
  113. package/src/tools/upload-media-from-url.ts +7 -9
  114. package/src/tools/upload-media.ts +6 -2
  115. package/src/tools/whoami.ts +21 -23
package/README.md CHANGED
@@ -11,6 +11,8 @@ This package gives Claude Desktop, Cursor, Windsurf, Cline, and other local MCP
11
11
  - generate images
12
12
  - read account and post analytics
13
13
 
14
+ Tool results are returned as Markdown-first chat summaries with headings, compact tables, short next-step notes, and occasional status icons. MCP clients may still rephrase the final answer, but the raw tool content is designed to look good directly in chat.
15
+
14
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.
15
17
 
16
18
  ## Requirements
@@ -93,7 +95,7 @@ Add the same server definition to your Cursor MCP settings:
93
95
 
94
96
  ## Available tools
95
97
 
96
- `posterly-mcp-server@0.19.0` exposes 49 tools:
98
+ `posterly-mcp-server@0.19.2` exposes 49 tools:
97
99
 
98
100
  - `whoami`
99
101
  - `list_accounts`
@@ -33,7 +33,7 @@ export declare const PLATFORM_MANIFEST: {
33
33
  readonly youtube: "youtube";
34
34
  };
35
35
  readonly helperNames: readonly ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota", "youtube.playlists"];
36
- readonly analyticsPlatformIds: readonly ["instagram", "linkedin", "youtube", "pinterest", "google_business"];
36
+ readonly analyticsPlatformIds: readonly ["instagram", "facebook", "linkedin", "youtube", "pinterest", "google_business"];
37
37
  readonly connectTargetIds: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "reddit", "wordpress", "mastodon", "medium", "devto", "hashnode", "discord", "slack", "skool", "whop"];
38
38
  readonly connectInputs: readonly ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
39
39
  readonly connectAliases: {
@@ -86,7 +86,7 @@ export declare const PLATFORM_MANIFEST: {
86
86
  readonly status: "supported";
87
87
  readonly aliases: readonly [];
88
88
  readonly postTypes: readonly ["text", "image", "video", "carousel", "reel", "story", "cover_photo"];
89
- readonly analyticsSupported: false;
89
+ readonly analyticsSupported: true;
90
90
  readonly helpers: readonly [];
91
91
  }, {
92
92
  readonly id: "tiktok";
@@ -389,4 +389,4 @@ export declare const ALL_PLATFORM_INPUTS: readonly ["bluesky", "devto", "discord
389
389
  export declare const PLATFORM_HELPER_NAMES: readonly ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota", "youtube.playlists"];
390
390
  export declare const CONNECT_TARGET_IDS: readonly ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "reddit", "wordpress", "mastodon", "medium", "devto", "hashnode", "discord", "slack", "skool", "whop"];
391
391
  export declare const CONNECT_INPUTS: readonly ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
392
- export declare const ANALYTICS_PLATFORM_IDS: readonly ["instagram", "linkedin", "youtube", "pinterest", "google_business"];
392
+ export declare const ANALYTICS_PLATFORM_IDS: readonly ["instagram", "facebook", "linkedin", "youtube", "pinterest", "google_business"];
@@ -131,6 +131,7 @@ export const PLATFORM_MANIFEST = {
131
131
  ],
132
132
  "analyticsPlatformIds": [
133
133
  "instagram",
134
+ "facebook",
134
135
  "linkedin",
135
136
  "youtube",
136
137
  "pinterest",
@@ -268,7 +269,7 @@ export const PLATFORM_MANIFEST = {
268
269
  "story",
269
270
  "cover_photo"
270
271
  ],
271
- "analyticsSupported": false,
272
+ "analyticsSupported": true,
272
273
  "helpers": []
273
274
  },
274
275
  {
@@ -692,4 +693,4 @@ export const ALL_PLATFORM_INPUTS = ["bluesky", "devto", "discord", "facebook", "
692
693
  export const PLATFORM_HELPER_NAMES = ["linkedin.recent_mentions", "pinterest.boards", "tiktok.creator_info", "x.quota", "youtube.playlists"];
693
694
  export const CONNECT_TARGET_IDS = ["instagram", "meta", "facebook", "youtube", "tiktok", "linkedin", "linkedin_page", "threads", "google_business", "pinterest", "twitter", "telegram", "bluesky", "reddit", "wordpress", "mastodon", "medium", "devto", "hashnode", "discord", "slack", "skool", "whop"];
694
695
  export const CONNECT_INPUTS = ["bluesky", "devto", "discord", "facebook", "facebook_instagram", "facebook_pages", "gmb", "google-business", "google_business", "google_business_profile", "hashnode", "instagram", "instagram-standalone", "instagram_direct", "linkedin", "linkedin-company", "linkedin-page", "linkedin_company", "linkedin_page", "linkedin_personal", "mastodon", "medium", "meta", "meta_business", "pinterest", "reddit", "skool", "slack", "telegram", "threads", "tiktok", "twitter", "whop", "wordpress", "x", "x_twitter", "youtube"];
695
- export const ANALYTICS_PLATFORM_IDS = ["instagram", "linkedin", "youtube", "pinterest", "google_business"];
696
+ export const ANALYTICS_PLATFORM_IDS = ["instagram", "facebook", "linkedin", "youtube", "pinterest", "google_business"];
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { mdError } from './lib/format.js';
4
5
  import { PosterlyClient } from './lib/api-client.js';
5
6
  import { listAccountsTool } from './tools/list-accounts.js';
6
7
  import { disconnectAccountTool } from './tools/disconnect-account.js';
@@ -70,7 +71,7 @@ server.tool(whoamiTool.name, whoamiTool.description, whoamiTool.inputSchema.shap
70
71
  return { content: [{ type: 'text', text }] };
71
72
  }
72
73
  catch (err) {
73
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
74
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
74
75
  }
75
76
  });
76
77
  server.tool(listAccountsTool.name, listAccountsTool.description, listAccountsTool.inputSchema.shape, async (input) => {
@@ -79,7 +80,7 @@ server.tool(listAccountsTool.name, listAccountsTool.description, listAccountsToo
79
80
  return { content: [{ type: 'text', text }] };
80
81
  }
81
82
  catch (err) {
82
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
83
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
83
84
  }
84
85
  });
85
86
  server.tool(disconnectAccountTool.name, disconnectAccountTool.description, disconnectAccountTool.inputSchema.shape, async (input) => {
@@ -88,7 +89,7 @@ server.tool(disconnectAccountTool.name, disconnectAccountTool.description, disco
88
89
  return { content: [{ type: 'text', text }] };
89
90
  }
90
91
  catch (err) {
91
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
92
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
92
93
  }
93
94
  });
94
95
  server.tool(getConnectLinkTool.name, getConnectLinkTool.description, getConnectLinkTool.inputSchema.shape, async (input) => {
@@ -97,7 +98,7 @@ server.tool(getConnectLinkTool.name, getConnectLinkTool.description, getConnectL
97
98
  return { content: [{ type: 'text', text }] };
98
99
  }
99
100
  catch (err) {
100
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
101
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
101
102
  }
102
103
  });
103
104
  server.tool(listOAuthClientsTool.name, listOAuthClientsTool.description, listOAuthClientsTool.inputSchema.shape, async () => {
@@ -106,7 +107,7 @@ server.tool(listOAuthClientsTool.name, listOAuthClientsTool.description, listOAu
106
107
  return { content: [{ type: 'text', text }] };
107
108
  }
108
109
  catch (err) {
109
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
110
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
110
111
  }
111
112
  });
112
113
  server.tool(createOAuthClientTool.name, createOAuthClientTool.description, createOAuthClientTool.inputSchema.shape, async (input) => {
@@ -115,7 +116,7 @@ server.tool(createOAuthClientTool.name, createOAuthClientTool.description, creat
115
116
  return { content: [{ type: 'text', text }] };
116
117
  }
117
118
  catch (err) {
118
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
119
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
119
120
  }
120
121
  });
121
122
  server.tool(updateOAuthClientTool.name, updateOAuthClientTool.description, updateOAuthClientTool.inputSchema.shape, async (input) => {
@@ -124,7 +125,7 @@ server.tool(updateOAuthClientTool.name, updateOAuthClientTool.description, updat
124
125
  return { content: [{ type: 'text', text }] };
125
126
  }
126
127
  catch (err) {
127
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
128
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
128
129
  }
129
130
  });
130
131
  server.tool(deleteOAuthClientTool.name, deleteOAuthClientTool.description, deleteOAuthClientTool.inputSchema.shape, async (input) => {
@@ -133,7 +134,7 @@ server.tool(deleteOAuthClientTool.name, deleteOAuthClientTool.description, delet
133
134
  return { content: [{ type: 'text', text }] };
134
135
  }
135
136
  catch (err) {
136
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
137
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
137
138
  }
138
139
  });
139
140
  server.tool(listPlatformsTool.name, listPlatformsTool.description, listPlatformsTool.inputSchema.shape, async (input) => {
@@ -142,7 +143,7 @@ server.tool(listPlatformsTool.name, listPlatformsTool.description, listPlatforms
142
143
  return { content: [{ type: 'text', text }] };
143
144
  }
144
145
  catch (err) {
145
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
146
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
146
147
  }
147
148
  });
148
149
  server.tool(getPlatformSchemaTool.name, getPlatformSchemaTool.description, getPlatformSchemaTool.inputSchema.shape, async (input) => {
@@ -151,7 +152,7 @@ server.tool(getPlatformSchemaTool.name, getPlatformSchemaTool.description, getPl
151
152
  return { content: [{ type: 'text', text }] };
152
153
  }
153
154
  catch (err) {
154
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
155
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
155
156
  }
156
157
  });
157
158
  server.tool(triggerPlatformHelperTool.name, triggerPlatformHelperTool.description, triggerPlatformHelperTool.inputSchema.shape, async (input) => {
@@ -160,7 +161,7 @@ server.tool(triggerPlatformHelperTool.name, triggerPlatformHelperTool.descriptio
160
161
  return { content: [{ type: 'text', text }] };
161
162
  }
162
163
  catch (err) {
163
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
164
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
164
165
  }
165
166
  });
166
167
  server.tool(listBrandsTool.name, listBrandsTool.description, listBrandsTool.inputSchema.shape, async (input) => {
@@ -169,7 +170,7 @@ server.tool(listBrandsTool.name, listBrandsTool.description, listBrandsTool.inpu
169
170
  return { content: [{ type: 'text', text }] };
170
171
  }
171
172
  catch (err) {
172
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
173
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
173
174
  }
174
175
  });
175
176
  server.tool(getBrandTool.name, getBrandTool.description, getBrandTool.inputSchema.shape, async (input) => {
@@ -178,7 +179,7 @@ server.tool(getBrandTool.name, getBrandTool.description, getBrandTool.inputSchem
178
179
  return { content: [{ type: 'text', text }] };
179
180
  }
180
181
  catch (err) {
181
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
182
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
182
183
  }
183
184
  });
184
185
  server.tool(listBrandAccountsTool.name, listBrandAccountsTool.description, listBrandAccountsTool.inputSchema.shape, async (input) => {
@@ -187,7 +188,7 @@ server.tool(listBrandAccountsTool.name, listBrandAccountsTool.description, listB
187
188
  return { content: [{ type: 'text', text }] };
188
189
  }
189
190
  catch (err) {
190
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
191
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
191
192
  }
192
193
  });
193
194
  server.tool(getBrandProfileTool.name, getBrandProfileTool.description, getBrandProfileTool.inputSchema.shape, async (input) => {
@@ -196,7 +197,7 @@ server.tool(getBrandProfileTool.name, getBrandProfileTool.description, getBrandP
196
197
  return { content: [{ type: 'text', text }] };
197
198
  }
198
199
  catch (err) {
199
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
200
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
200
201
  }
201
202
  });
202
203
  server.tool(createPostTool.name, createPostTool.description, createPostTool.inputSchema.shape, async (input) => {
@@ -205,7 +206,7 @@ server.tool(createPostTool.name, createPostTool.description, createPostTool.inpu
205
206
  return { content: [{ type: 'text', text }] };
206
207
  }
207
208
  catch (err) {
208
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
209
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
209
210
  }
210
211
  });
211
212
  server.tool(createPostsBatchTool.name, createPostsBatchTool.description, createPostsBatchTool.inputSchema.shape, async (input) => {
@@ -214,7 +215,7 @@ server.tool(createPostsBatchTool.name, createPostsBatchTool.description, createP
214
215
  return { content: [{ type: 'text', text }] };
215
216
  }
216
217
  catch (err) {
217
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
218
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
218
219
  }
219
220
  });
220
221
  server.tool(findSlotTool.name, findSlotTool.description, findSlotTool.inputSchema.shape, async (input) => {
@@ -223,7 +224,7 @@ server.tool(findSlotTool.name, findSlotTool.description, findSlotTool.inputSchem
223
224
  return { content: [{ type: 'text', text }] };
224
225
  }
225
226
  catch (err) {
226
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
227
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
227
228
  }
228
229
  });
229
230
  server.tool(listPostsTool.name, listPostsTool.description, listPostsTool.inputSchema.shape, async (input) => {
@@ -232,7 +233,7 @@ server.tool(listPostsTool.name, listPostsTool.description, listPostsTool.inputSc
232
233
  return { content: [{ type: 'text', text }] };
233
234
  }
234
235
  catch (err) {
235
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
236
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
236
237
  }
237
238
  });
238
239
  server.tool(uploadMediaTool.name, uploadMediaTool.description, uploadMediaTool.inputSchema.shape, async (input) => {
@@ -241,7 +242,7 @@ server.tool(uploadMediaTool.name, uploadMediaTool.description, uploadMediaTool.i
241
242
  return { content: [{ type: 'text', text }] };
242
243
  }
243
244
  catch (err) {
244
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
245
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
245
246
  }
246
247
  });
247
248
  server.tool(uploadMediaFromUrlTool.name, uploadMediaFromUrlTool.description, uploadMediaFromUrlTool.inputSchema.shape, async (input) => {
@@ -250,7 +251,7 @@ server.tool(uploadMediaFromUrlTool.name, uploadMediaFromUrlTool.description, upl
250
251
  return { content: [{ type: 'text', text }] };
251
252
  }
252
253
  catch (err) {
253
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
254
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
254
255
  }
255
256
  });
256
257
  server.tool(createSignedUploadTool.name, createSignedUploadTool.description, createSignedUploadTool.inputSchema.shape, async (input) => {
@@ -259,7 +260,7 @@ server.tool(createSignedUploadTool.name, createSignedUploadTool.description, cre
259
260
  return { content: [{ type: 'text', text }] };
260
261
  }
261
262
  catch (err) {
262
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
263
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
263
264
  }
264
265
  });
265
266
  server.tool(getVideoOptionsTool.name, getVideoOptionsTool.description, getVideoOptionsTool.inputSchema.shape, async () => {
@@ -268,7 +269,7 @@ server.tool(getVideoOptionsTool.name, getVideoOptionsTool.description, getVideoO
268
269
  return { content: [{ type: 'text', text }] };
269
270
  }
270
271
  catch (err) {
271
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
272
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
272
273
  }
273
274
  });
274
275
  server.tool(runVideoFunctionTool.name, runVideoFunctionTool.description, runVideoFunctionTool.inputSchema.shape, async (input) => {
@@ -277,7 +278,7 @@ server.tool(runVideoFunctionTool.name, runVideoFunctionTool.description, runVide
277
278
  return { content: [{ type: 'text', text }] };
278
279
  }
279
280
  catch (err) {
280
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
281
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
281
282
  }
282
283
  });
283
284
  server.tool(generateVideoTool.name, generateVideoTool.description, generateVideoTool.inputSchema.shape, async (input) => {
@@ -286,7 +287,7 @@ server.tool(generateVideoTool.name, generateVideoTool.description, generateVideo
286
287
  return { content: [{ type: 'text', text }] };
287
288
  }
288
289
  catch (err) {
289
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
290
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
290
291
  }
291
292
  });
292
293
  server.tool(getVideoJobTool.name, getVideoJobTool.description, getVideoJobTool.inputSchema.shape, async (input) => {
@@ -295,7 +296,7 @@ server.tool(getVideoJobTool.name, getVideoJobTool.description, getVideoJobTool.i
295
296
  return { content: [{ type: 'text', text }] };
296
297
  }
297
298
  catch (err) {
298
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
299
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
299
300
  }
300
301
  });
301
302
  server.tool(generateImageTool.name, generateImageTool.description, generateImageTool.inputSchema.shape, async (input) => {
@@ -304,7 +305,7 @@ server.tool(generateImageTool.name, generateImageTool.description, generateImage
304
305
  return { content: [{ type: 'text', text }] };
305
306
  }
306
307
  catch (err) {
307
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
308
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
308
309
  }
309
310
  });
310
311
  server.tool(getPostTool.name, getPostTool.description, getPostTool.inputSchema.shape, async (input) => {
@@ -313,7 +314,7 @@ server.tool(getPostTool.name, getPostTool.description, getPostTool.inputSchema.s
313
314
  return { content: [{ type: 'text', text }] };
314
315
  }
315
316
  catch (err) {
316
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
317
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
317
318
  }
318
319
  });
319
320
  server.tool(getPostMissingTool.name, getPostMissingTool.description, getPostMissingTool.inputSchema.shape, async (input) => {
@@ -322,7 +323,7 @@ server.tool(getPostMissingTool.name, getPostMissingTool.description, getPostMiss
322
323
  return { content: [{ type: 'text', text }] };
323
324
  }
324
325
  catch (err) {
325
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
326
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
326
327
  }
327
328
  });
328
329
  server.tool(updatePostTool.name, updatePostTool.description, updatePostTool.inputSchema.shape, async (input) => {
@@ -331,7 +332,7 @@ server.tool(updatePostTool.name, updatePostTool.description, updatePostTool.inpu
331
332
  return { content: [{ type: 'text', text }] };
332
333
  }
333
334
  catch (err) {
334
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
335
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
335
336
  }
336
337
  });
337
338
  server.tool(updatePostStatusTool.name, updatePostStatusTool.description, updatePostStatusTool.inputSchema.shape, async (input) => {
@@ -340,7 +341,7 @@ server.tool(updatePostStatusTool.name, updatePostStatusTool.description, updateP
340
341
  return { content: [{ type: 'text', text }] };
341
342
  }
342
343
  catch (err) {
343
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
344
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
344
345
  }
345
346
  });
346
347
  server.tool(updatePostReleaseIdTool.name, updatePostReleaseIdTool.description, updatePostReleaseIdTool.inputSchema.shape, async (input) => {
@@ -349,7 +350,7 @@ server.tool(updatePostReleaseIdTool.name, updatePostReleaseIdTool.description, u
349
350
  return { content: [{ type: 'text', text }] };
350
351
  }
351
352
  catch (err) {
352
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
353
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
353
354
  }
354
355
  });
355
356
  server.tool(deletePostTool.name, deletePostTool.description, deletePostTool.inputSchema.shape, async (input) => {
@@ -358,7 +359,7 @@ server.tool(deletePostTool.name, deletePostTool.description, deletePostTool.inpu
358
359
  return { content: [{ type: 'text', text }] };
359
360
  }
360
361
  catch (err) {
361
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
362
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
362
363
  }
363
364
  });
364
365
  server.tool(deletePostGroupTool.name, deletePostGroupTool.description, deletePostGroupTool.inputSchema.shape, async (input) => {
@@ -367,7 +368,7 @@ server.tool(deletePostGroupTool.name, deletePostGroupTool.description, deletePos
367
368
  return { content: [{ type: 'text', text }] };
368
369
  }
369
370
  catch (err) {
370
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
371
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
371
372
  }
372
373
  });
373
374
  server.tool(getAccountAnalyticsTool.name, getAccountAnalyticsTool.description, getAccountAnalyticsTool.inputSchema.shape, async (input) => {
@@ -376,7 +377,7 @@ server.tool(getAccountAnalyticsTool.name, getAccountAnalyticsTool.description, g
376
377
  return { content: [{ type: 'text', text }] };
377
378
  }
378
379
  catch (err) {
379
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
380
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
380
381
  }
381
382
  });
382
383
  server.tool(getPostAnalyticsTool.name, getPostAnalyticsTool.description, getPostAnalyticsTool.inputSchema.shape, async (input) => {
@@ -385,7 +386,7 @@ server.tool(getPostAnalyticsTool.name, getPostAnalyticsTool.description, getPost
385
386
  return { content: [{ type: 'text', text }] };
386
387
  }
387
388
  catch (err) {
388
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
389
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
389
390
  }
390
391
  });
391
392
  server.tool(listGoogleBusinessReviewsTool.name, listGoogleBusinessReviewsTool.description, listGoogleBusinessReviewsTool.inputSchema.shape, async (input) => {
@@ -394,7 +395,7 @@ server.tool(listGoogleBusinessReviewsTool.name, listGoogleBusinessReviewsTool.de
394
395
  return { content: [{ type: 'text', text }] };
395
396
  }
396
397
  catch (err) {
397
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
398
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
398
399
  }
399
400
  });
400
401
  server.tool(getGoogleBusinessReviewLinkTool.name, getGoogleBusinessReviewLinkTool.description, getGoogleBusinessReviewLinkTool.inputSchema.shape, async (input) => {
@@ -403,7 +404,7 @@ server.tool(getGoogleBusinessReviewLinkTool.name, getGoogleBusinessReviewLinkToo
403
404
  return { content: [{ type: 'text', text }] };
404
405
  }
405
406
  catch (err) {
406
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
407
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
407
408
  }
408
409
  });
409
410
  server.tool(auditGoogleBusinessProfileTool.name, auditGoogleBusinessProfileTool.description, auditGoogleBusinessProfileTool.inputSchema.shape, async (input) => {
@@ -412,7 +413,7 @@ server.tool(auditGoogleBusinessProfileTool.name, auditGoogleBusinessProfileTool.
412
413
  return { content: [{ type: 'text', text }] };
413
414
  }
414
415
  catch (err) {
415
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
416
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
416
417
  }
417
418
  });
418
419
  server.tool(suggestGoogleBusinessReviewReplyTool.name, suggestGoogleBusinessReviewReplyTool.description, suggestGoogleBusinessReviewReplyTool.inputSchema.shape, async (input) => {
@@ -421,7 +422,7 @@ server.tool(suggestGoogleBusinessReviewReplyTool.name, suggestGoogleBusinessRevi
421
422
  return { content: [{ type: 'text', text }] };
422
423
  }
423
424
  catch (err) {
424
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
425
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
425
426
  }
426
427
  });
427
428
  server.tool(replyGoogleBusinessReviewTool.name, replyGoogleBusinessReviewTool.description, replyGoogleBusinessReviewTool.inputSchema.shape, async (input) => {
@@ -430,7 +431,7 @@ server.tool(replyGoogleBusinessReviewTool.name, replyGoogleBusinessReviewTool.de
430
431
  return { content: [{ type: 'text', text }] };
431
432
  }
432
433
  catch (err) {
433
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
434
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
434
435
  }
435
436
  });
436
437
  server.tool(deleteGoogleBusinessReviewReplyTool.name, deleteGoogleBusinessReviewReplyTool.description, deleteGoogleBusinessReviewReplyTool.inputSchema.shape, async (input) => {
@@ -439,7 +440,7 @@ server.tool(deleteGoogleBusinessReviewReplyTool.name, deleteGoogleBusinessReview
439
440
  return { content: [{ type: 'text', text }] };
440
441
  }
441
442
  catch (err) {
442
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
443
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
443
444
  }
444
445
  });
445
446
  server.tool(listActivityTool.name, listActivityTool.description, listActivityTool.inputSchema.shape, async (input) => {
@@ -448,7 +449,7 @@ server.tool(listActivityTool.name, listActivityTool.description, listActivityToo
448
449
  return { content: [{ type: 'text', text }] };
449
450
  }
450
451
  catch (err) {
451
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
452
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
452
453
  }
453
454
  });
454
455
  server.tool(listWebhooksTool.name, listWebhooksTool.description, listWebhooksTool.inputSchema.shape, async (input) => {
@@ -457,7 +458,7 @@ server.tool(listWebhooksTool.name, listWebhooksTool.description, listWebhooksToo
457
458
  return { content: [{ type: 'text', text }] };
458
459
  }
459
460
  catch (err) {
460
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
461
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
461
462
  }
462
463
  });
463
464
  server.tool(createWebhookTool.name, createWebhookTool.description, createWebhookTool.inputSchema.shape, async (input) => {
@@ -466,7 +467,7 @@ server.tool(createWebhookTool.name, createWebhookTool.description, createWebhook
466
467
  return { content: [{ type: 'text', text }] };
467
468
  }
468
469
  catch (err) {
469
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
470
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
470
471
  }
471
472
  });
472
473
  server.tool(updateWebhookTool.name, updateWebhookTool.description, updateWebhookTool.inputSchema.shape, async (input) => {
@@ -475,7 +476,7 @@ server.tool(updateWebhookTool.name, updateWebhookTool.description, updateWebhook
475
476
  return { content: [{ type: 'text', text }] };
476
477
  }
477
478
  catch (err) {
478
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
479
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
479
480
  }
480
481
  });
481
482
  server.tool(deleteWebhookTool.name, deleteWebhookTool.description, deleteWebhookTool.inputSchema.shape, async (input) => {
@@ -484,7 +485,7 @@ server.tool(deleteWebhookTool.name, deleteWebhookTool.description, deleteWebhook
484
485
  return { content: [{ type: 'text', text }] };
485
486
  }
486
487
  catch (err) {
487
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
488
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
488
489
  }
489
490
  });
490
491
  server.tool(testWebhookTool.name, testWebhookTool.description, testWebhookTool.inputSchema.shape, async (input) => {
@@ -493,7 +494,7 @@ server.tool(testWebhookTool.name, testWebhookTool.description, testWebhookTool.i
493
494
  return { content: [{ type: 'text', text }] };
494
495
  }
495
496
  catch (err) {
496
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
497
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
497
498
  }
498
499
  });
499
500
  server.tool(getXPostingQuotaTool.name, getXPostingQuotaTool.description, getXPostingQuotaTool.inputSchema.shape, async (input) => {
@@ -502,7 +503,7 @@ server.tool(getXPostingQuotaTool.name, getXPostingQuotaTool.description, getXPos
502
503
  return { content: [{ type: 'text', text }] };
503
504
  }
504
505
  catch (err) {
505
- return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
506
+ return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
506
507
  }
507
508
  });
508
509
  // Start the server
@@ -147,6 +147,7 @@ export interface Whoami {
147
147
  export interface AccountAnalyticsSummary {
148
148
  current_followers: number;
149
149
  followers_change: number;
150
+ current_media_count?: number;
150
151
  total_reach: number | null;
151
152
  total_views: number | null;
152
153
  total_profile_views?: number | null;
@@ -162,6 +163,7 @@ export interface AccountAnalyticsSummary {
162
163
  total_bookings: number | null;
163
164
  total_watch_minutes?: number | null;
164
165
  total_likes?: number | null;
166
+ platform_metrics?: Record<string, number | null | undefined>;
165
167
  }
166
168
  export interface AccountAnalyticsSnapshot {
167
169
  date: string;
@@ -318,7 +318,7 @@ export class PosterlyClient {
318
318
  guessContentType(input.filename);
319
319
  const SIZE_THRESHOLD = 3 * 1024 * 1024; // 3MB
320
320
  if (fileBuffer.length > SIZE_THRESHOLD) {
321
- // Large file: use signed URL to upload directly to Supabase Storage
321
+ // Large file: use signed URL so the API can validate actual bytes before storage.
322
322
  const signed = await this.getSignedUploadUrl(input.filename, contentType, fileBuffer.length);
323
323
  const uploadRes = await fetch(signed.upload_url, {
324
324
  method: 'PUT',
@@ -0,0 +1,21 @@
1
+ type CellValue = string | number | boolean | null | undefined;
2
+ export declare function mdTitle(title: string, subtitle?: string): string;
3
+ export declare function mdTable(headers: string[], rows: CellValue[][]): string;
4
+ export declare function mdKeyValue(rows: Array<[string, CellValue]>): string;
5
+ export declare function mdSection(title: string, body?: string): string;
6
+ export declare function mdBullets(items: Array<string | null | undefined>): string;
7
+ export declare function mdJson(title: string, value: unknown): string;
8
+ export declare function mdQuote(text: string): string;
9
+ export declare function mdEmpty(title: string, detail: string, nextStep?: string): string;
10
+ export declare function mdSuccess(title: string, rows: Array<[string, CellValue]>, nextStep?: string): string;
11
+ export declare function mdError(message: string): string;
12
+ export declare function formatNumber(value: number | null | undefined): string;
13
+ export declare function formatPercent(value: number | null | undefined): string;
14
+ export declare function formatDelta(value: number | null | undefined): string;
15
+ export declare function formatDateTime(value: string | null | undefined): string;
16
+ export declare function formatDate(value: string | null | undefined): string;
17
+ export declare function formatBytes(value: number | null | undefined): string;
18
+ export declare function compactText(value: string | null | undefined, maxLength?: number): string;
19
+ export declare function statusLabel(status: string | null | undefined): string;
20
+ export declare function code(value: CellValue): string;
21
+ export {};