posterly-mcp-server 0.19.2 → 0.19.3

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 (109) hide show
  1. package/README.md +1 -3
  2. package/dist/index.js +49 -50
  3. package/dist/tools/audit-google-business-profile.js +12 -15
  4. package/dist/tools/create-oauth-client.js +1 -7
  5. package/dist/tools/create-post.js +27 -20
  6. package/dist/tools/create-posts-batch.js +15 -23
  7. package/dist/tools/create-signed-upload.js +7 -10
  8. package/dist/tools/create-webhook.js +2 -7
  9. package/dist/tools/delete-google-business-review-reply.d.ts +1 -1
  10. package/dist/tools/delete-google-business-review-reply.js +1 -4
  11. package/dist/tools/delete-oauth-client.js +1 -4
  12. package/dist/tools/delete-post-group.js +1 -5
  13. package/dist/tools/delete-post.js +1 -4
  14. package/dist/tools/delete-webhook.js +1 -4
  15. package/dist/tools/disconnect-account.js +5 -7
  16. package/dist/tools/find-slot.js +3 -10
  17. package/dist/tools/generate-image.js +19 -17
  18. package/dist/tools/generate-video.js +9 -11
  19. package/dist/tools/get-account-analytics.js +43 -65
  20. package/dist/tools/get-brand-profile.js +40 -34
  21. package/dist/tools/get-brand.js +16 -14
  22. package/dist/tools/get-connect-link.js +7 -26
  23. package/dist/tools/get-google-business-review-link.js +6 -6
  24. package/dist/tools/get-platform-schema.js +16 -23
  25. package/dist/tools/get-post-analytics.js +50 -53
  26. package/dist/tools/get-post-missing.js +1 -5
  27. package/dist/tools/get-post.js +14 -16
  28. package/dist/tools/get-video-job.d.ts +2 -2
  29. package/dist/tools/get-video-job.js +11 -28
  30. package/dist/tools/get-video-options.js +15 -21
  31. package/dist/tools/get-x-posting-quota.js +9 -12
  32. package/dist/tools/list-accounts.js +4 -12
  33. package/dist/tools/list-activity.js +18 -13
  34. package/dist/tools/list-brand-accounts.js +3 -11
  35. package/dist/tools/list-brands.js +11 -12
  36. package/dist/tools/list-google-business-reviews.js +11 -13
  37. package/dist/tools/list-oauth-clients.js +4 -10
  38. package/dist/tools/list-platforms.js +5 -12
  39. package/dist/tools/list-posts.js +7 -12
  40. package/dist/tools/list-webhooks.js +11 -13
  41. package/dist/tools/reply-google-business-review.d.ts +1 -1
  42. package/dist/tools/reply-google-business-review.js +1 -4
  43. package/dist/tools/run-video-function.js +4 -4
  44. package/dist/tools/suggest-google-business-review-reply.js +4 -5
  45. package/dist/tools/test-webhook.js +1 -7
  46. package/dist/tools/trigger-platform-helper.js +1 -5
  47. package/dist/tools/update-oauth-client.js +1 -8
  48. package/dist/tools/update-post-release-id.js +1 -5
  49. package/dist/tools/update-post-status.d.ts +2 -2
  50. package/dist/tools/update-post-status.js +1 -7
  51. package/dist/tools/update-post.js +4 -10
  52. package/dist/tools/update-webhook.js +1 -7
  53. package/dist/tools/upload-media-from-url.js +9 -7
  54. package/dist/tools/upload-media.js +2 -6
  55. package/dist/tools/whoami.js +17 -18
  56. package/package.json +1 -1
  57. package/src/index.ts +49 -50
  58. package/src/tools/audit-google-business-profile.ts +12 -18
  59. package/src/tools/create-oauth-client.ts +2 -8
  60. package/src/tools/create-post.ts +28 -20
  61. package/src/tools/create-posts-batch.ts +18 -23
  62. package/src/tools/create-signed-upload.ts +7 -10
  63. package/src/tools/create-webhook.ts +3 -7
  64. package/src/tools/delete-google-business-review-reply.ts +1 -4
  65. package/src/tools/delete-oauth-client.ts +1 -4
  66. package/src/tools/delete-post-group.ts +1 -5
  67. package/src/tools/delete-post.ts +1 -4
  68. package/src/tools/delete-webhook.ts +2 -4
  69. package/src/tools/disconnect-account.ts +5 -7
  70. package/src/tools/find-slot.ts +5 -13
  71. package/src/tools/generate-image.ts +20 -20
  72. package/src/tools/generate-video.ts +9 -11
  73. package/src/tools/get-account-analytics.ts +48 -71
  74. package/src/tools/get-brand-profile.ts +38 -34
  75. package/src/tools/get-brand.ts +14 -14
  76. package/src/tools/get-connect-link.ts +7 -29
  77. package/src/tools/get-google-business-review-link.ts +6 -6
  78. package/src/tools/get-platform-schema.ts +16 -29
  79. package/src/tools/get-post-analytics.ts +51 -58
  80. package/src/tools/get-post-missing.ts +2 -5
  81. package/src/tools/get-post.ts +13 -16
  82. package/src/tools/get-video-job.ts +11 -31
  83. package/src/tools/get-video-options.ts +15 -27
  84. package/src/tools/get-x-posting-quota.ts +9 -12
  85. package/src/tools/list-accounts.ts +6 -15
  86. package/src/tools/list-activity.ts +20 -16
  87. package/src/tools/list-brand-accounts.ts +6 -14
  88. package/src/tools/list-brands.ts +13 -16
  89. package/src/tools/list-google-business-reviews.ts +12 -16
  90. package/src/tools/list-oauth-clients.ts +4 -13
  91. package/src/tools/list-platforms.ts +5 -15
  92. package/src/tools/list-posts.ts +9 -15
  93. package/src/tools/list-webhooks.ts +12 -16
  94. package/src/tools/reply-google-business-review.ts +1 -4
  95. package/src/tools/run-video-function.ts +4 -4
  96. package/src/tools/suggest-google-business-review-reply.ts +4 -5
  97. package/src/tools/test-webhook.ts +1 -7
  98. package/src/tools/trigger-platform-helper.ts +1 -5
  99. package/src/tools/update-oauth-client.ts +2 -9
  100. package/src/tools/update-post-release-id.ts +2 -5
  101. package/src/tools/update-post-status.ts +1 -7
  102. package/src/tools/update-post.ts +5 -10
  103. package/src/tools/update-webhook.ts +2 -7
  104. package/src/tools/upload-media-from-url.ts +9 -7
  105. package/src/tools/upload-media.ts +2 -6
  106. package/src/tools/whoami.ts +23 -21
  107. package/dist/lib/format.d.ts +0 -21
  108. package/dist/lib/format.js +0 -125
  109. package/src/lib/format.ts +0 -132
package/README.md CHANGED
@@ -11,8 +11,6 @@ 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
-
16
14
  Posterly also exposes the same toolset over HTTP at [poster.ly/mcp](https://www.poster.ly/mcp), but this npm package is the local `stdio` transport.
17
15
 
18
16
  ## Requirements
@@ -95,7 +93,7 @@ Add the same server definition to your Cursor MCP settings:
95
93
 
96
94
  ## Available tools
97
95
 
98
- `posterly-mcp-server@0.19.2` exposes 49 tools:
96
+ `posterly-mcp-server@0.19.0` exposes 49 tools:
99
97
 
100
98
  - `whoami`
101
99
  - `list_accounts`
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
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';
5
4
  import { PosterlyClient } from './lib/api-client.js';
6
5
  import { listAccountsTool } from './tools/list-accounts.js';
7
6
  import { disconnectAccountTool } from './tools/disconnect-account.js';
@@ -71,7 +70,7 @@ server.tool(whoamiTool.name, whoamiTool.description, whoamiTool.inputSchema.shap
71
70
  return { content: [{ type: 'text', text }] };
72
71
  }
73
72
  catch (err) {
74
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
73
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
75
74
  }
76
75
  });
77
76
  server.tool(listAccountsTool.name, listAccountsTool.description, listAccountsTool.inputSchema.shape, async (input) => {
@@ -80,7 +79,7 @@ server.tool(listAccountsTool.name, listAccountsTool.description, listAccountsToo
80
79
  return { content: [{ type: 'text', text }] };
81
80
  }
82
81
  catch (err) {
83
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
82
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
84
83
  }
85
84
  });
86
85
  server.tool(disconnectAccountTool.name, disconnectAccountTool.description, disconnectAccountTool.inputSchema.shape, async (input) => {
@@ -89,7 +88,7 @@ server.tool(disconnectAccountTool.name, disconnectAccountTool.description, disco
89
88
  return { content: [{ type: 'text', text }] };
90
89
  }
91
90
  catch (err) {
92
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
91
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
93
92
  }
94
93
  });
95
94
  server.tool(getConnectLinkTool.name, getConnectLinkTool.description, getConnectLinkTool.inputSchema.shape, async (input) => {
@@ -98,7 +97,7 @@ server.tool(getConnectLinkTool.name, getConnectLinkTool.description, getConnectL
98
97
  return { content: [{ type: 'text', text }] };
99
98
  }
100
99
  catch (err) {
101
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
100
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
102
101
  }
103
102
  });
104
103
  server.tool(listOAuthClientsTool.name, listOAuthClientsTool.description, listOAuthClientsTool.inputSchema.shape, async () => {
@@ -107,7 +106,7 @@ server.tool(listOAuthClientsTool.name, listOAuthClientsTool.description, listOAu
107
106
  return { content: [{ type: 'text', text }] };
108
107
  }
109
108
  catch (err) {
110
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
109
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
111
110
  }
112
111
  });
113
112
  server.tool(createOAuthClientTool.name, createOAuthClientTool.description, createOAuthClientTool.inputSchema.shape, async (input) => {
@@ -116,7 +115,7 @@ server.tool(createOAuthClientTool.name, createOAuthClientTool.description, creat
116
115
  return { content: [{ type: 'text', text }] };
117
116
  }
118
117
  catch (err) {
119
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
118
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
120
119
  }
121
120
  });
122
121
  server.tool(updateOAuthClientTool.name, updateOAuthClientTool.description, updateOAuthClientTool.inputSchema.shape, async (input) => {
@@ -125,7 +124,7 @@ server.tool(updateOAuthClientTool.name, updateOAuthClientTool.description, updat
125
124
  return { content: [{ type: 'text', text }] };
126
125
  }
127
126
  catch (err) {
128
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
127
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
129
128
  }
130
129
  });
131
130
  server.tool(deleteOAuthClientTool.name, deleteOAuthClientTool.description, deleteOAuthClientTool.inputSchema.shape, async (input) => {
@@ -134,7 +133,7 @@ server.tool(deleteOAuthClientTool.name, deleteOAuthClientTool.description, delet
134
133
  return { content: [{ type: 'text', text }] };
135
134
  }
136
135
  catch (err) {
137
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
136
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
138
137
  }
139
138
  });
140
139
  server.tool(listPlatformsTool.name, listPlatformsTool.description, listPlatformsTool.inputSchema.shape, async (input) => {
@@ -143,7 +142,7 @@ server.tool(listPlatformsTool.name, listPlatformsTool.description, listPlatforms
143
142
  return { content: [{ type: 'text', text }] };
144
143
  }
145
144
  catch (err) {
146
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
145
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
147
146
  }
148
147
  });
149
148
  server.tool(getPlatformSchemaTool.name, getPlatformSchemaTool.description, getPlatformSchemaTool.inputSchema.shape, async (input) => {
@@ -152,7 +151,7 @@ server.tool(getPlatformSchemaTool.name, getPlatformSchemaTool.description, getPl
152
151
  return { content: [{ type: 'text', text }] };
153
152
  }
154
153
  catch (err) {
155
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
154
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
156
155
  }
157
156
  });
158
157
  server.tool(triggerPlatformHelperTool.name, triggerPlatformHelperTool.description, triggerPlatformHelperTool.inputSchema.shape, async (input) => {
@@ -161,7 +160,7 @@ server.tool(triggerPlatformHelperTool.name, triggerPlatformHelperTool.descriptio
161
160
  return { content: [{ type: 'text', text }] };
162
161
  }
163
162
  catch (err) {
164
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
163
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
165
164
  }
166
165
  });
167
166
  server.tool(listBrandsTool.name, listBrandsTool.description, listBrandsTool.inputSchema.shape, async (input) => {
@@ -170,7 +169,7 @@ server.tool(listBrandsTool.name, listBrandsTool.description, listBrandsTool.inpu
170
169
  return { content: [{ type: 'text', text }] };
171
170
  }
172
171
  catch (err) {
173
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
172
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
174
173
  }
175
174
  });
176
175
  server.tool(getBrandTool.name, getBrandTool.description, getBrandTool.inputSchema.shape, async (input) => {
@@ -179,7 +178,7 @@ server.tool(getBrandTool.name, getBrandTool.description, getBrandTool.inputSchem
179
178
  return { content: [{ type: 'text', text }] };
180
179
  }
181
180
  catch (err) {
182
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
181
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
183
182
  }
184
183
  });
185
184
  server.tool(listBrandAccountsTool.name, listBrandAccountsTool.description, listBrandAccountsTool.inputSchema.shape, async (input) => {
@@ -188,7 +187,7 @@ server.tool(listBrandAccountsTool.name, listBrandAccountsTool.description, listB
188
187
  return { content: [{ type: 'text', text }] };
189
188
  }
190
189
  catch (err) {
191
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
190
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
192
191
  }
193
192
  });
194
193
  server.tool(getBrandProfileTool.name, getBrandProfileTool.description, getBrandProfileTool.inputSchema.shape, async (input) => {
@@ -197,7 +196,7 @@ server.tool(getBrandProfileTool.name, getBrandProfileTool.description, getBrandP
197
196
  return { content: [{ type: 'text', text }] };
198
197
  }
199
198
  catch (err) {
200
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
199
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
201
200
  }
202
201
  });
203
202
  server.tool(createPostTool.name, createPostTool.description, createPostTool.inputSchema.shape, async (input) => {
@@ -206,7 +205,7 @@ server.tool(createPostTool.name, createPostTool.description, createPostTool.inpu
206
205
  return { content: [{ type: 'text', text }] };
207
206
  }
208
207
  catch (err) {
209
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
208
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
210
209
  }
211
210
  });
212
211
  server.tool(createPostsBatchTool.name, createPostsBatchTool.description, createPostsBatchTool.inputSchema.shape, async (input) => {
@@ -215,7 +214,7 @@ server.tool(createPostsBatchTool.name, createPostsBatchTool.description, createP
215
214
  return { content: [{ type: 'text', text }] };
216
215
  }
217
216
  catch (err) {
218
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
217
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
219
218
  }
220
219
  });
221
220
  server.tool(findSlotTool.name, findSlotTool.description, findSlotTool.inputSchema.shape, async (input) => {
@@ -224,7 +223,7 @@ server.tool(findSlotTool.name, findSlotTool.description, findSlotTool.inputSchem
224
223
  return { content: [{ type: 'text', text }] };
225
224
  }
226
225
  catch (err) {
227
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
226
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
228
227
  }
229
228
  });
230
229
  server.tool(listPostsTool.name, listPostsTool.description, listPostsTool.inputSchema.shape, async (input) => {
@@ -233,7 +232,7 @@ server.tool(listPostsTool.name, listPostsTool.description, listPostsTool.inputSc
233
232
  return { content: [{ type: 'text', text }] };
234
233
  }
235
234
  catch (err) {
236
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
235
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
237
236
  }
238
237
  });
239
238
  server.tool(uploadMediaTool.name, uploadMediaTool.description, uploadMediaTool.inputSchema.shape, async (input) => {
@@ -242,7 +241,7 @@ server.tool(uploadMediaTool.name, uploadMediaTool.description, uploadMediaTool.i
242
241
  return { content: [{ type: 'text', text }] };
243
242
  }
244
243
  catch (err) {
245
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
244
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
246
245
  }
247
246
  });
248
247
  server.tool(uploadMediaFromUrlTool.name, uploadMediaFromUrlTool.description, uploadMediaFromUrlTool.inputSchema.shape, async (input) => {
@@ -251,7 +250,7 @@ server.tool(uploadMediaFromUrlTool.name, uploadMediaFromUrlTool.description, upl
251
250
  return { content: [{ type: 'text', text }] };
252
251
  }
253
252
  catch (err) {
254
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
253
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
255
254
  }
256
255
  });
257
256
  server.tool(createSignedUploadTool.name, createSignedUploadTool.description, createSignedUploadTool.inputSchema.shape, async (input) => {
@@ -260,7 +259,7 @@ server.tool(createSignedUploadTool.name, createSignedUploadTool.description, cre
260
259
  return { content: [{ type: 'text', text }] };
261
260
  }
262
261
  catch (err) {
263
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
262
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
264
263
  }
265
264
  });
266
265
  server.tool(getVideoOptionsTool.name, getVideoOptionsTool.description, getVideoOptionsTool.inputSchema.shape, async () => {
@@ -269,7 +268,7 @@ server.tool(getVideoOptionsTool.name, getVideoOptionsTool.description, getVideoO
269
268
  return { content: [{ type: 'text', text }] };
270
269
  }
271
270
  catch (err) {
272
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
271
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
273
272
  }
274
273
  });
275
274
  server.tool(runVideoFunctionTool.name, runVideoFunctionTool.description, runVideoFunctionTool.inputSchema.shape, async (input) => {
@@ -278,7 +277,7 @@ server.tool(runVideoFunctionTool.name, runVideoFunctionTool.description, runVide
278
277
  return { content: [{ type: 'text', text }] };
279
278
  }
280
279
  catch (err) {
281
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
280
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
282
281
  }
283
282
  });
284
283
  server.tool(generateVideoTool.name, generateVideoTool.description, generateVideoTool.inputSchema.shape, async (input) => {
@@ -287,7 +286,7 @@ server.tool(generateVideoTool.name, generateVideoTool.description, generateVideo
287
286
  return { content: [{ type: 'text', text }] };
288
287
  }
289
288
  catch (err) {
290
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
289
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
291
290
  }
292
291
  });
293
292
  server.tool(getVideoJobTool.name, getVideoJobTool.description, getVideoJobTool.inputSchema.shape, async (input) => {
@@ -296,7 +295,7 @@ server.tool(getVideoJobTool.name, getVideoJobTool.description, getVideoJobTool.i
296
295
  return { content: [{ type: 'text', text }] };
297
296
  }
298
297
  catch (err) {
299
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
298
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
300
299
  }
301
300
  });
302
301
  server.tool(generateImageTool.name, generateImageTool.description, generateImageTool.inputSchema.shape, async (input) => {
@@ -305,7 +304,7 @@ server.tool(generateImageTool.name, generateImageTool.description, generateImage
305
304
  return { content: [{ type: 'text', text }] };
306
305
  }
307
306
  catch (err) {
308
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
307
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
309
308
  }
310
309
  });
311
310
  server.tool(getPostTool.name, getPostTool.description, getPostTool.inputSchema.shape, async (input) => {
@@ -314,7 +313,7 @@ server.tool(getPostTool.name, getPostTool.description, getPostTool.inputSchema.s
314
313
  return { content: [{ type: 'text', text }] };
315
314
  }
316
315
  catch (err) {
317
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
316
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
318
317
  }
319
318
  });
320
319
  server.tool(getPostMissingTool.name, getPostMissingTool.description, getPostMissingTool.inputSchema.shape, async (input) => {
@@ -323,7 +322,7 @@ server.tool(getPostMissingTool.name, getPostMissingTool.description, getPostMiss
323
322
  return { content: [{ type: 'text', text }] };
324
323
  }
325
324
  catch (err) {
326
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
325
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
327
326
  }
328
327
  });
329
328
  server.tool(updatePostTool.name, updatePostTool.description, updatePostTool.inputSchema.shape, async (input) => {
@@ -332,7 +331,7 @@ server.tool(updatePostTool.name, updatePostTool.description, updatePostTool.inpu
332
331
  return { content: [{ type: 'text', text }] };
333
332
  }
334
333
  catch (err) {
335
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
334
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
336
335
  }
337
336
  });
338
337
  server.tool(updatePostStatusTool.name, updatePostStatusTool.description, updatePostStatusTool.inputSchema.shape, async (input) => {
@@ -341,7 +340,7 @@ server.tool(updatePostStatusTool.name, updatePostStatusTool.description, updateP
341
340
  return { content: [{ type: 'text', text }] };
342
341
  }
343
342
  catch (err) {
344
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
343
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
345
344
  }
346
345
  });
347
346
  server.tool(updatePostReleaseIdTool.name, updatePostReleaseIdTool.description, updatePostReleaseIdTool.inputSchema.shape, async (input) => {
@@ -350,7 +349,7 @@ server.tool(updatePostReleaseIdTool.name, updatePostReleaseIdTool.description, u
350
349
  return { content: [{ type: 'text', text }] };
351
350
  }
352
351
  catch (err) {
353
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
352
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
354
353
  }
355
354
  });
356
355
  server.tool(deletePostTool.name, deletePostTool.description, deletePostTool.inputSchema.shape, async (input) => {
@@ -359,7 +358,7 @@ server.tool(deletePostTool.name, deletePostTool.description, deletePostTool.inpu
359
358
  return { content: [{ type: 'text', text }] };
360
359
  }
361
360
  catch (err) {
362
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
361
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
363
362
  }
364
363
  });
365
364
  server.tool(deletePostGroupTool.name, deletePostGroupTool.description, deletePostGroupTool.inputSchema.shape, async (input) => {
@@ -368,7 +367,7 @@ server.tool(deletePostGroupTool.name, deletePostGroupTool.description, deletePos
368
367
  return { content: [{ type: 'text', text }] };
369
368
  }
370
369
  catch (err) {
371
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
370
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
372
371
  }
373
372
  });
374
373
  server.tool(getAccountAnalyticsTool.name, getAccountAnalyticsTool.description, getAccountAnalyticsTool.inputSchema.shape, async (input) => {
@@ -377,7 +376,7 @@ server.tool(getAccountAnalyticsTool.name, getAccountAnalyticsTool.description, g
377
376
  return { content: [{ type: 'text', text }] };
378
377
  }
379
378
  catch (err) {
380
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
379
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
381
380
  }
382
381
  });
383
382
  server.tool(getPostAnalyticsTool.name, getPostAnalyticsTool.description, getPostAnalyticsTool.inputSchema.shape, async (input) => {
@@ -386,7 +385,7 @@ server.tool(getPostAnalyticsTool.name, getPostAnalyticsTool.description, getPost
386
385
  return { content: [{ type: 'text', text }] };
387
386
  }
388
387
  catch (err) {
389
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
388
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
390
389
  }
391
390
  });
392
391
  server.tool(listGoogleBusinessReviewsTool.name, listGoogleBusinessReviewsTool.description, listGoogleBusinessReviewsTool.inputSchema.shape, async (input) => {
@@ -395,7 +394,7 @@ server.tool(listGoogleBusinessReviewsTool.name, listGoogleBusinessReviewsTool.de
395
394
  return { content: [{ type: 'text', text }] };
396
395
  }
397
396
  catch (err) {
398
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
397
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
399
398
  }
400
399
  });
401
400
  server.tool(getGoogleBusinessReviewLinkTool.name, getGoogleBusinessReviewLinkTool.description, getGoogleBusinessReviewLinkTool.inputSchema.shape, async (input) => {
@@ -404,7 +403,7 @@ server.tool(getGoogleBusinessReviewLinkTool.name, getGoogleBusinessReviewLinkToo
404
403
  return { content: [{ type: 'text', text }] };
405
404
  }
406
405
  catch (err) {
407
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
406
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
408
407
  }
409
408
  });
410
409
  server.tool(auditGoogleBusinessProfileTool.name, auditGoogleBusinessProfileTool.description, auditGoogleBusinessProfileTool.inputSchema.shape, async (input) => {
@@ -413,7 +412,7 @@ server.tool(auditGoogleBusinessProfileTool.name, auditGoogleBusinessProfileTool.
413
412
  return { content: [{ type: 'text', text }] };
414
413
  }
415
414
  catch (err) {
416
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
415
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
417
416
  }
418
417
  });
419
418
  server.tool(suggestGoogleBusinessReviewReplyTool.name, suggestGoogleBusinessReviewReplyTool.description, suggestGoogleBusinessReviewReplyTool.inputSchema.shape, async (input) => {
@@ -422,7 +421,7 @@ server.tool(suggestGoogleBusinessReviewReplyTool.name, suggestGoogleBusinessRevi
422
421
  return { content: [{ type: 'text', text }] };
423
422
  }
424
423
  catch (err) {
425
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
424
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
426
425
  }
427
426
  });
428
427
  server.tool(replyGoogleBusinessReviewTool.name, replyGoogleBusinessReviewTool.description, replyGoogleBusinessReviewTool.inputSchema.shape, async (input) => {
@@ -431,7 +430,7 @@ server.tool(replyGoogleBusinessReviewTool.name, replyGoogleBusinessReviewTool.de
431
430
  return { content: [{ type: 'text', text }] };
432
431
  }
433
432
  catch (err) {
434
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
433
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
435
434
  }
436
435
  });
437
436
  server.tool(deleteGoogleBusinessReviewReplyTool.name, deleteGoogleBusinessReviewReplyTool.description, deleteGoogleBusinessReviewReplyTool.inputSchema.shape, async (input) => {
@@ -440,7 +439,7 @@ server.tool(deleteGoogleBusinessReviewReplyTool.name, deleteGoogleBusinessReview
440
439
  return { content: [{ type: 'text', text }] };
441
440
  }
442
441
  catch (err) {
443
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
442
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
444
443
  }
445
444
  });
446
445
  server.tool(listActivityTool.name, listActivityTool.description, listActivityTool.inputSchema.shape, async (input) => {
@@ -449,7 +448,7 @@ server.tool(listActivityTool.name, listActivityTool.description, listActivityToo
449
448
  return { content: [{ type: 'text', text }] };
450
449
  }
451
450
  catch (err) {
452
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
451
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
453
452
  }
454
453
  });
455
454
  server.tool(listWebhooksTool.name, listWebhooksTool.description, listWebhooksTool.inputSchema.shape, async (input) => {
@@ -458,7 +457,7 @@ server.tool(listWebhooksTool.name, listWebhooksTool.description, listWebhooksToo
458
457
  return { content: [{ type: 'text', text }] };
459
458
  }
460
459
  catch (err) {
461
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
460
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
462
461
  }
463
462
  });
464
463
  server.tool(createWebhookTool.name, createWebhookTool.description, createWebhookTool.inputSchema.shape, async (input) => {
@@ -467,7 +466,7 @@ server.tool(createWebhookTool.name, createWebhookTool.description, createWebhook
467
466
  return { content: [{ type: 'text', text }] };
468
467
  }
469
468
  catch (err) {
470
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
469
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
471
470
  }
472
471
  });
473
472
  server.tool(updateWebhookTool.name, updateWebhookTool.description, updateWebhookTool.inputSchema.shape, async (input) => {
@@ -476,7 +475,7 @@ server.tool(updateWebhookTool.name, updateWebhookTool.description, updateWebhook
476
475
  return { content: [{ type: 'text', text }] };
477
476
  }
478
477
  catch (err) {
479
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
478
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
480
479
  }
481
480
  });
482
481
  server.tool(deleteWebhookTool.name, deleteWebhookTool.description, deleteWebhookTool.inputSchema.shape, async (input) => {
@@ -485,7 +484,7 @@ server.tool(deleteWebhookTool.name, deleteWebhookTool.description, deleteWebhook
485
484
  return { content: [{ type: 'text', text }] };
486
485
  }
487
486
  catch (err) {
488
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
487
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
489
488
  }
490
489
  });
491
490
  server.tool(testWebhookTool.name, testWebhookTool.description, testWebhookTool.inputSchema.shape, async (input) => {
@@ -494,7 +493,7 @@ server.tool(testWebhookTool.name, testWebhookTool.description, testWebhookTool.i
494
493
  return { content: [{ type: 'text', text }] };
495
494
  }
496
495
  catch (err) {
497
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
496
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
498
497
  }
499
498
  });
500
499
  server.tool(getXPostingQuotaTool.name, getXPostingQuotaTool.description, getXPostingQuotaTool.inputSchema.shape, async (input) => {
@@ -503,7 +502,7 @@ server.tool(getXPostingQuotaTool.name, getXPostingQuotaTool.description, getXPos
503
502
  return { content: [{ type: 'text', text }] };
504
503
  }
505
504
  catch (err) {
506
- return { content: [{ type: 'text', text: mdError(err.message) }], isError: true };
505
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
507
506
  }
508
507
  });
509
508
  // Start the server
@@ -1,5 +1,4 @@
1
1
  import { z } from 'zod';
2
- import { formatDateTime, mdKeyValue, mdSection, mdTable, mdTitle } from '../lib/format.js';
3
2
  export const auditGoogleBusinessProfileTool = {
4
3
  name: 'audit_google_business_profile',
5
4
  description: 'Run a live local-profile audit for a connected Google Business Profile location, including completeness, categories, media, attributes, reviews, and recommendations.',
@@ -12,19 +11,17 @@ export const auditGoogleBusinessProfileTool = {
12
11
  const result = await client.auditGoogleBusinessProfile(input);
13
12
  const audit = result.audit || {};
14
13
  const recommendations = Array.isArray(audit.recommendations) ? audit.recommendations : [];
15
- return [
16
- mdTitle(`Google Business audit: ${audit.businessName || 'Unknown business'}`),
17
- mdKeyValue([
18
- ['Score', audit.overallScore ?? 'n/a'],
19
- ['Grade', audit.overallGrade || 'n/a'],
20
- ['Fetched', formatDateTime(result.fetchedAt)],
21
- ]),
22
- recommendations.length > 0
23
- ? mdSection('Top recommendations', mdTable(['Priority', 'Recommendation'], recommendations.slice(0, 5).map((rec) => [
24
- rec.priority || 'medium',
25
- rec.description || rec.title || 'Recommendation',
26
- ])))
27
- : '',
28
- ].filter(Boolean).join('\n\n');
14
+ const lines = [
15
+ `Google Business audit: ${audit.businessName || 'Unknown business'}`,
16
+ `Score: ${audit.overallScore ?? 'n/a'} (${audit.overallGrade || 'n/a'})`,
17
+ `Fetched: ${result.fetchedAt || 'unknown'}`,
18
+ ];
19
+ if (recommendations.length > 0) {
20
+ lines.push('Top recommendations:');
21
+ for (const rec of recommendations.slice(0, 5)) {
22
+ lines.push(`- ${rec.priority || 'medium'}: ${rec.description || rec.title || 'Recommendation'}`);
23
+ }
24
+ }
25
+ return lines.join('\n');
29
26
  },
30
27
  };
@@ -1,5 +1,4 @@
1
1
  import { z } from 'zod';
2
- import { code, mdSuccess } from '../lib/format.js';
3
2
  const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read']);
4
3
  export const createOAuthClientTool = {
5
4
  name: 'create_oauth_client',
@@ -16,11 +15,6 @@ export const createOAuthClientTool = {
16
15
  async execute(client, input) {
17
16
  const { confirm: _confirm, ...payload } = input;
18
17
  const result = await client.createOAuthClient(payload);
19
- return mdSuccess('OAuth client created', [
20
- ['Client', result.client.client_name],
21
- ['Client ID', code(result.client.client_id)],
22
- ['Redirect URIs', result.client.allowed_redirect_uris.join(', ')],
23
- ['Default scopes', result.client.default_scopes.join(', ')],
24
- ]);
18
+ return `OAuth client created: ${result.client.client_name}\nclient_id: ${result.client.client_id}\nRedirect URIs: ${result.client.allowed_redirect_uris.join(', ')}`;
25
19
  },
26
20
  };
@@ -1,6 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { SUPPORTED_PLATFORM_INPUTS, SUPPORTED_PLATFORM_IDS } from '../generated/platform-manifest.js';
3
- import { code, formatDateTime, mdKeyValue, mdSuccess, statusLabel } from '../lib/format.js';
4
3
  export const instagramSettingsSchema = z.object({
5
4
  __type: z.enum(['instagram', 'instagram-standalone']).optional(),
6
5
  post_type: z.enum(['post', 'feed', 'story', 'reel', 'carousel']).optional(),
@@ -160,24 +159,32 @@ export const createPostTool = {
160
159
  const result = await client.createPost(payload);
161
160
  const p = result.post;
162
161
  const ws = result.workspace;
163
- return [
164
- mdSuccess('Post created', [
165
- ['Post ID', code(p.id)],
166
- ['Platform', p.platform || input.platform || 'unknown'],
167
- ['Type', p.post_type],
168
- ['Status', statusLabel(p.status)],
169
- ['Scheduled', p.scheduled_at ? formatDateTime(p.scheduled_at) : 'now'],
170
- ['Thread', thread_posts ? `${thread_posts.length} posts` : undefined],
171
- ['Instagram collaborators', instagram_settings?.collaborators?.length],
172
- ['Instagram first comment', Boolean(instagram_settings?.first_comment)],
173
- ['Platform settings', Boolean(platform_settings)],
174
- ], 'Use `get_post` if you want to review the saved post details.'),
175
- ws
176
- ? mdKeyValue([
177
- ['Workspace', `${ws.name} (${code(ws.id)})`],
178
- ['Workspace resolved from', ws.resolved_from],
179
- ])
180
- : '',
181
- ].filter(Boolean).join('\n\n');
162
+ const when = p.scheduled_at
163
+ ? new Date(p.scheduled_at).toLocaleString()
164
+ : 'now';
165
+ const lines = [
166
+ 'Post created successfully!',
167
+ `• ID: ${p.id}`,
168
+ `• Platform: ${p.platform || input.platform || 'unknown'}`,
169
+ `• Type: ${p.post_type}`,
170
+ `• Status: ${p.status}`,
171
+ `• Scheduled: ${when}`,
172
+ ];
173
+ if (thread_posts) {
174
+ lines.push(`• Thread: ${thread_posts.length} posts`);
175
+ }
176
+ if (instagram_settings?.collaborators?.length) {
177
+ lines.push(`• Instagram collaborators: ${instagram_settings.collaborators.length}`);
178
+ }
179
+ if (instagram_settings?.first_comment) {
180
+ lines.push('• Instagram first comment: yes');
181
+ }
182
+ if (platform_settings) {
183
+ lines.push('• Platform settings: yes');
184
+ }
185
+ if (ws) {
186
+ lines.push(`• Workspace: ${ws.name} (${ws.id}) — resolved from ${ws.resolved_from}`);
187
+ }
188
+ return lines.join('\n');
182
189
  },
183
190
  };
@@ -1,6 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { buildCreatePostPayload, createPostInputSchema } from './create-post.js';
3
- import { code, formatDateTime, mdSection, mdTable, mdTitle, statusLabel } from '../lib/format.js';
4
3
  export const createPostsBatchTool = {
5
4
  name: 'create_posts_batch',
6
5
  description: 'Create 1-25 scheduled or immediate social posts in one API request. This is a DESTRUCTIVE WRITE that creates content on the user\'s real social accounts — once scheduled_at passes, posts may go public and cannot be un-posted.\n\n' +
@@ -19,28 +18,21 @@ export const createPostsBatchTool = {
19
18
  async execute(client, input) {
20
19
  const payloads = input.posts.map((post) => buildCreatePostPayload(post));
21
20
  const result = await client.createPostsBatch({ posts: payloads });
22
- const createdRows = result.posts.slice(0, 25).map((item) => {
21
+ const lines = [
22
+ 'Batch create completed.',
23
+ `• Total: ${result.total}`,
24
+ `• Created: ${result.created}`,
25
+ `• Replayed: ${result.replayed}`,
26
+ `• Failed: ${result.failed}`,
27
+ ];
28
+ for (const item of result.posts.slice(0, 25)) {
23
29
  const post = item.post;
24
- return [
25
- item.index,
26
- code(post.id),
27
- post.platform || 'unknown',
28
- post.post_type || 'post',
29
- statusLabel(post.status || 'created'),
30
- post.scheduled_at ? formatDateTime(post.scheduled_at) : 'now',
31
- item.replayed ? 'yes' : 'no',
32
- ];
33
- });
34
- const errorRows = result.errors.slice(0, 25).map((error) => [
35
- error.index,
36
- error.status,
37
- error.error,
38
- ]);
39
- return [
40
- mdTitle(result.failed ? '⚠️ Batch create completed with issues' : '✅ Batch create completed'),
41
- mdTable(['Total', 'Created', 'Replayed', 'Failed'], [[result.total, result.created, result.replayed, result.failed]]),
42
- mdSection('Created posts', mdTable(['Index', 'Post ID', 'Platform', 'Type', 'Status', 'Scheduled', 'Replayed'], createdRows)),
43
- mdSection('Errors', mdTable(['Index', 'Status', 'Error'], errorRows)),
44
- ].filter(Boolean).join('\n\n');
30
+ const when = post.scheduled_at ? new Date(post.scheduled_at).toLocaleString() : 'now';
31
+ lines.push(`• [${item.index}] ID ${post.id} ${post.platform || 'unknown'} ${post.post_type || 'post'} ${post.status || 'created'} at ${when}${item.replayed ? ' (replayed)' : ''}`);
32
+ }
33
+ for (const error of result.errors.slice(0, 25)) {
34
+ lines.push(`• [${error.index}] ERROR ${error.status}: ${error.error}`);
35
+ }
36
+ return lines.join('\n');
45
37
  },
46
38
  };