@post-ripple/mcp 0.8.0 → 0.9.0

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 CHANGED
@@ -60,7 +60,8 @@ env = { POSTRIPPLE_API_KEY = "pr_..." }
60
60
  | `list_slideshows` | read | Photo-carousel slideshows |
61
61
  | `list_slideshow_templates` | read | Slideshow layout templates, fonts, and text treatments |
62
62
  | `get_slideshow` | read | One slideshow with per-slide render state and progress |
63
- | `list_posts` | read | Posts with status, schedule, errors |
63
+ | `list_posts` | read | Posts with status, approval state, schedule, and errors |
64
+ | `list_reviews` | read | Posts waiting for team approval or changes |
64
65
  | `get_post_metrics` | read | Per-post engagement time series |
65
66
  | `get_account_metrics` | read | Follower growth history |
66
67
  | `get_engagement_summary` | read | Org-wide totals, per-platform breakdown, top posts |
@@ -79,7 +80,7 @@ env = { POSTRIPPLE_API_KEY = "pr_..." }
79
80
 
80
81
  Notes for agents:
81
82
 
82
- - `schedule_post` and `publish_slideshow` publish to **real** social accounts. Always pass `idempotencyKey`, and pass `tiktokSettings` if the post should be public on TikTok (the default is private/`SELF_ONLY`).
83
+ - `schedule_post` and `publish_slideshow` publish to **real** social accounts when the workspace allows direct publishing. If the team has enabled approval, these tools submit review items instead and return `submittedForReview: true`; use `list_reviews` to inspect them, and have an owner/admin approve them from the Post Ripple Review page. Always pass `idempotencyKey`, and pass `tiktokSettings` if the post should be public on TikTok (the default is private/`SELF_ONLY`).
83
84
  - The typical slideshow flow: `import_image_from_url` (or `get_image_upload_url` + PUT) per image → `create_slideshow` → poll `get_slideshow` until `ready` (template slides render server-side) → `publish_slideshow`. Pre-rendered JPEG slideshows are ready instantly.
84
85
  - TikTok `settings.postMode: "inbox"` sends the photo post to the account's TikTok app drafts inbox instead of publishing directly — useful when a human finishes posts from a real device.
85
86
  - Imports and publishes are asynchronous. Poll `list_videos` / `list_posts` to observe progress.
package/dist/index.js CHANGED
@@ -77,6 +77,7 @@ const orgParam = {
77
77
  };
78
78
  const platformEnum = z.enum(["tiktok", "instagram", "youtube", "other"]);
79
79
  const postStatusEnum = z.enum([
80
+ "draft",
80
81
  "scheduled",
81
82
  "pending",
82
83
  "uploading",
@@ -175,7 +176,7 @@ const slideSchema = z.object({
175
176
  .describe("Darkening scrim over the background (template slides only); omit to use the template's default"),
176
177
  });
177
178
  // ---- read tools ----
178
- register("whoami", "Get who this key acts as and which organizations it can work in, plus the key's scopes. When an organization is selected (single-org key, organizationId argument, or POSTRIPPLE_ORG), also returns that workspace's overview: connected accounts, active groups, scheduled posts. Call this first to orient yourself.", { ...orgParam });
179
+ register("whoami", "Get who this key acts as and which organizations it can work in, plus the key's scopes. When an organization is selected (single-org key, organizationId argument, or POSTRIPPLE_ORG), also returns that workspace's overview: connected accounts, active groups, scheduled posts, and whether team approval is required. Call this first to orient yourself.", { ...orgParam });
179
180
  register("list_social_accounts", "List the workspace's connected social accounts (TikTok / Instagram / YouTube) with connection health: status (active/expired/revoked/error), token expiry, and last error. Use the returned accountId for scheduling and metrics tools.", { ...orgParam });
180
181
  register("list_videos", "List videos in the workspace library, newest first. Videos with status 'completed' are publishable; 'pending'/'downloading' are still being imported.", {
181
182
  ...orgParam,
@@ -222,12 +223,20 @@ register("get_creation", "Get the render status of a video created with create_v
222
223
  register("list_slideshows", "List photo-carousel slideshows with status ('draft' = still being composed, 'ready' = publishable) and a signed coverUrl thumbnail (first rendered slide, or a background for drafts).", { ...orgParam, limit: z.number().min(1).max(200).optional() });
223
224
  register("list_slideshow_templates", "List the slideshow layout templates: canvas size, each template's text slots with exact geometry (x/y anchor, maxWidth, fontSize, lineHeight — all normalized to the canvas) and defaults (font, color, treatment), the template's default overlay scrim, available fonts and text treatments, and the max slide count. Call before create_slideshow when composing template-based slides — use the slot geometry rather than inventing your own placement.", {});
224
225
  register("get_slideshow", "Get one slideshow in full detail: per-slide render state, each text field's text AND its style overrides (font, color, treatment, fontScale, x/y position, maxWidth, align, rotation — null style means the template slot defaults apply), the slide's overlay scrim, and signed image URLs (renderedUrl = the finished slide, backgroundUrl = the photo behind it; both expire in ~1h). Use it to study how existing slides are actually styled before composing new ones, or poll it after create_slideshow returns status 'rendering' — publish once status is 'ready'.", { ...orgParam, slideshowId: z.string() });
225
- register("list_posts", "List posts (scheduled, publishing, published, failed, canceled), newest first. Scheduled posts include scheduledFor; published posts include platformPostId and publishedAt.", {
226
+ register("list_posts", "List posts (including review drafts, scheduled, publishing, published, failed, and canceled), newest first. Review posts include approvalStatus, submittedByName, and reviewNote; scheduled posts include scheduledFor; published posts include platformPostId and publishedAt.", {
226
227
  ...orgParam,
227
228
  status: postStatusEnum.optional(),
228
229
  platform: platformEnum.optional(),
229
230
  limit: z.number().min(1).max(200).optional(),
230
231
  });
232
+ register("list_reviews", "List posts waiting for team review. When approval is required, schedule_post and publish_slideshow submit work here instead of publishing or scheduling it. Use this to see approvalStatus, reviewer notes, target account, planned publish time, and a preview URL. Human approval is completed from Post Ripple's Review page.", {
233
+ ...orgParam,
234
+ status: z
235
+ .enum(["in_review", "changes_requested"])
236
+ .optional()
237
+ .describe("Filter to items awaiting review or items sent back for changes"),
238
+ limit: z.number().min(1).max(200).optional(),
239
+ });
231
240
  register("get_post_metrics", "Get engagement for one published post: latest snapshot (views/likes/comments/shares) plus the time series of scraped metrics.", {
232
241
  ...orgParam,
233
242
  postId: z.string(),
@@ -365,7 +374,7 @@ register("create_video", "Render a short-form (9:16) video from library ingredie
365
374
  backgroundId: z.string().optional().describe("green_screen_meme: image id from list_backgrounds (required)"),
366
375
  });
367
376
  // ---- publish tools ----
368
- register("schedule_post", "Schedule a completed library video to publish on a connected account at a future time. This posts to a REAL social account when the time arrives. The platform is derived from the account. Uses one 'posts' credit (refunded if canceled). ALWAYS pass idempotencyKey (any unique string) so retries can't double-post. For TikTok, pass tiktokSettings to control privacy — omitting it publishes as private (SELF_ONLY). For YouTube, pass title.", {
377
+ register("schedule_post", "Schedule a completed library video to publish on a connected account at a future time. This posts to a REAL social account when the time arrives unless the team requires approval; in that case it creates an in-review item and returns submittedForReview=true. The platform is derived from the account. Uses one 'posts' credit when scheduled (or when approved; review submissions do not consume a credit yet). ALWAYS pass idempotencyKey (any unique string) so retries can't double-post. For TikTok, pass tiktokSettings to control privacy — omitting it publishes as private (SELF_ONLY). For YouTube, pass title.", {
369
378
  ...orgParam,
370
379
  videoId: z.string(),
371
380
  accountId: z.string(),
@@ -389,7 +398,7 @@ register("reschedule_post", "Move a still-scheduled post to a new future time. F
389
398
  ...args,
390
399
  scheduledFor: toEpochMs(args.scheduledFor, "scheduledFor"),
391
400
  }));
392
- register("publish_slideshow", "Publish or schedule a READY slideshow to one or more Instagram/TikTok accounts as a native carousel / photo post. This posts to REAL social accounts. Omit scheduledFor to publish immediately; pass it to schedule (uses one 'posts' credit per account, refunded if canceled). ALWAYS pass idempotencyKey so retries can't double-post. TikTok targets without settings publish as SELF_ONLY (private); pass settings with postMode 'inbox' to send a draft to the account's TikTok app inbox instead.", {
401
+ register("publish_slideshow", "Publish or schedule a READY slideshow to one or more Instagram/TikTok accounts as a native carousel / photo post. This posts to REAL social accounts unless the team requires approval; in that case it creates in-review items and returns submittedForReview=true. Omit scheduledFor to publish immediately; pass it to schedule. Posts use one 'posts' credit per account when published/scheduled or approved (review submissions do not consume a credit yet). ALWAYS pass idempotencyKey so retries can't double-post. TikTok targets without settings publish as SELF_ONLY (private); pass settings with postMode 'inbox' to send a draft to the account's TikTok app inbox instead.", {
393
402
  ...orgParam,
394
403
  slideshowId: z.string(),
395
404
  targets: z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@post-ripple/mcp",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "MCP server that lets AI agents (Claude Code, Codex, opencode) manage a Post Ripple workspace: content, scheduling, publishing, and analytics.",
5
5
  "type": "module",
6
6
  "bin": {