Skip to content
Agentmart
Submit a tool

schedule-post

Create, schedule, or publish social media posts via BulkPublish MCP.

Skill by azeemkafridi

IndexedMIT★ 3
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/azeemkafridi-schedule-post

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Create, schedule, or publish social media posts via BulkPublish MCP. Use when the user wants to post to social media.

Use cases: marketing, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/schedule-post

What's inside

Skill name
schedule-post
Description
Create, schedule, or publish social media posts via BulkPublish MCP. Use when the user wants to post to social media.
License
MIT
Instructions
157 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# BulkPublish — Post Creation Reference

## create_post parameters

```
content        (string, required) — post text
channels       (array, required)  — [{channelId: number, platform: string}]
                                    Get these from list_channels first
status         ("draft"|"scheduled") — default "draft"
scheduledAt    (ISO 8601 string)  — required when status is "scheduled"
timezone       (string)           — e.g. "America/New_York", "Asia/Karachi"
mediaFileIds   (number[])         — IDs from upload_media
platformContent (object)          — per-platform text: {"x": "Short", "linkedin": "Longer version"}
postTypeOverrides (object)        — per-platform format: {"instagram": "reel", "facebook": "story"}
postFormat     ("post"|"video"|"reel"|"story"|"carousel"|"thread") — "thread" requires threadParts
threadParts    (array)            — [{content: string, mediaFileIds?: number[]}], min 2 parts.
                                    EVERY part is length-checked against every target platform,
                                    not just the first — an over-long part 400s the whole request
platformSpecific (object)         — per-platform options; see the
                                    platform-reference skill. Auto-reply after
                                    publishing goes here as the top-level key
                                    "_firstComment", NOT a firstComment param:
                                    {"_firstComment": "Link in bio!"}
                                    Unsupported on discord, pinterest, tiktok,
                                    gmb, tumblr and snapchat (recorded as failed;
                                    the main post still publishes)
requestApproval (boolean)         — default false; hold a scheduled post for team
                                    approval (approvalStatus becomes "pending")
linkTrackingOverride (boolean|null) — default null; per-post override for
                                    bulkpubli.sh link tracking. true shortens the
                                    post's links and counts clicks, false posts
                                    them as written, null inherits the org setting
```

`linkTrackingOverride` is tri-state, so **omit it unless the user actually asked
for one behaviour or the other** — sending `false` is an explicit "post the links
as written" and is not the same as leaving it unset. Shortening happens at
publish time, per channel, and is **skipped** for any channel where the rewrite
would push the post past that platform's character limit: a short URL is 28
characters and can be longer than the link it replaces, so on X (280) or Bluesky
(300) tracking may silently not apply. The post still publishes, with its
original links.

Every post object returned by the API also carries the read-only approval fields
`approvalStatus` (`"none"` default | `"pending"` | `"approved"` | `"rejected"`),
`approvedBy` (string|null), `approvedAt` (date-time|null) and `rejectionReason`
(string|null). See "Team approval" below.

## Post type overrides

| Platform | Types |
|---|---|
| Instagram | `reel`, `story`, `carousel` |
| Facebook | `story`, `reel` |
| TikTok | `slideshow` |
| YouTube | `short` |
| X/Twitter | `thread` |
| Threads | `thread` |
| Bluesky | `thread` |
| Mastodon | `thread` |

## Team approval

`approvalStatus` is **orthogonal to `status`**: the scheduler skips `pending` and
`rejected` posts even when they are scheduled and overdue. Default is `"none"`.

- **Requesting approval** — pass `requestApproval: true` on `create_post` or
  `update_post` (default `false`) to hold a scheduled post for team approval;
  `approvalStatus` becomes `"pending"`. For API keys belonging to members whose
  role lacks `post:publish` (contributors), this is **forced server-side
  regardless of the flag** — their scheduled posts always land in the approval
  queue. Never tell such a user their post was scheduled: check the returned
  `approvalStatus` and say it is awaiting approval.
- **The approval queue** — `list_posts` with `approvalStatus: "pending"` (the
  filter accepts `none` | `pending` | `approved` | `rejected`), or
  `GET /api/posts?approvalStatus=pending`.
- **Approving or rejecting** — done by a teammate with an approver role (owner, admin, approver) in BulkPublish. Approval releases the post: it publishes at its scheduled time, or immediately if that time has passed. A rejected post returns to draft with a reason, and the author can edit and resubmit. You cannot approve or reject from here — say who needs to act.
- **`APPROVAL_REQUIRED`** — `publish_post` and `retry_post` return **403** with
  error code `APPROVAL_REQUIRED` for roles without `post:publish`. Do not retry:
  create/update the post with `requestApproval: true` and tell the user a
  teammate has to approve it. Publishing a pending/rejected post *as an
  approver* implicitly approves it.

## Publishing flow

- **Draft then publish**: `create_post` (status: "draft") → `publish_post` (postId)
- **Schedule for later**: `create_post` (status: "scheduled", scheduledAt: "2026-04-12T09:00:00Z")
- **Schedule with review**: `create_post` (status: "scheduled", scheduledAt: ..., requestApproval: true) → a teammate approves it in BulkPublish
- **Optimal timing**: call `get_queue_slot` (optionally pass `timezone`, default UTC) to get the best next slot. It returns `{suggestedTime, timezone}` — it does NOT take a channelId or date (any such args are ignored).
- **Retry failures**: `retry_post` (postId, optional `republish`) re-queues the
  post's `failed` platforms. A platform can also end in status `unconfirmed` —
  terminal: the publish request may have reached the platform but its response
  was lost, so the post **may already be live**; it is never auto-retried. If
  the post has unconfirmed platforms and no failed ones, `retry_post` returns
  **400** with code `UNCONFIRMED_REQUIRES_REPUBLISH` — ask the user to check
  the account on the platform, and only pass `republish: true` (default false)
  after they confirm the post is not live; it also retries the unconfirmed
  platforms and **can duplicate the post**.
- **Publish as story**: set `postTypeOverrides` to `"story"` for Facebook/Instagram/Snapchat — publishes directly as a story, no separate call needed (Snapchat stories need exactly 1 image or video and send no caption)

## Stories vs postTypeOverrides

To publish as a story, use `postTypeOverrides` at creation time:
```json
{ "postTypeOverrides": { "facebook": "story", "instagram": "story" } }
```
This publishes the post AS a story. Set it at creation time — an existing regular post cannot be turned into a story from here.

## Character limits

| Platform | Limit |
|---|---|
| X/Twitter | 280 (25,000 long posts) |
| Instagram | 2,200 |
| Facebook | 63,206 |
| LinkedIn | 3,000 |
| TikTok | 2,200 |
| YouTube | 5,000 (description) |
| Threads | 500 |

From azeemkafridi/bulkpublish-api, MIT.

More from azeemkafridi/bulkpublish-api

Signals

Stars
3
Forks
1
Open issues
1
Last commit (this folder)
Sep 27, 2026 (1 month ago)
Last release
Sep 3, 2026 (1 month ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from azeemkafridi

Cite this page

schedule-post skill. Agent Mart. https://agentmart.dev/skills/azeemkafridi-schedule-post (last updated 2026-10-24)