What you get
A Streamable-HTTP MCP server that exposes the same surface as the web app — with every call scoped to the bearer-token owner.
Plain-language control
Ask your assistant to do anything the web composer can do. It maps your intent to the right tool calls — no SDK, no glue code.
Server-side media
Pass a URL, post mate fetches it for you. Works around the assistant's attachment limits and chat-token budget.
Queue & calendar aware
Drop posts into your next free queue slot, or query a date window without scrolling through a UI.
Single-target retries
When one network hiccups, re-run just that target — the others keep their published state.
Get an MCP key
Three clicks. Keep it private — anyone with the key can read and post on your behalf.
- 1
Open Settings
Head to /app/settings and scroll to Connect to Claude (MCP). - 2
Generate a key
Click Generate new key, give it a memorable name (e.g. "Claude Desktop — laptop"), and copy the value. The plaintext is shown once; the database stores only a SHA-256 hash. - 3
Keep the URL handy
The server URL is the same for every account:https://post-mate.com/api/mcp/mcp
Lost the key? You can't recover it. Generate a new one and revoke the old one — clients break immediately on the old token.
Hook up a client
Four flavours covered — every other MCP client speaks the same Streamable-HTTP transport.
Claude Desktop
EasiestSettings → Developer → Edit Config, paste, fully quit, reopen.
{
"mcpServers": {
"post-mate": {
"url": "https://post-mate.com/api/mcp/mcp",
"headers": {
"Authorization": "Bearer YOUR_KEY_HERE"
}
}
}
}Claude Code
CLIOne command and it's wired into every session.
claude mcp add --transport http post-mate \ https://post-mate.com/api/mcp/mcp \ --header "Authorization: Bearer YOUR_KEY_HERE"
Verify with claude mcp list.
Cursor
EditorMerge into ~/.cursor/mcp.json or use the in-app MCP picker.
{
"mcpServers": {
"post-mate": {
"url": "https://post-mate.com/api/mcp/mcp",
"headers": {
"Authorization": "Bearer YOUR_KEY_HERE"
}
}
}
}ChatGPT
Plus / TeamSettings → Connectors → Add custom MCP.
- URL
- https://post-mate.com/api/mcp/mcp
- Transport
- Streamable HTTP
- Auth
- Bearer · paste your key from step 2
Any other MCP client
GenericIf it speaks HTTP MCP — it works. SSE transport is exposed too.
- HTTP
- https://post-mate.com/api/mcp/mcp
- SSE
- https://post-mate.com/api/mcp/sse
- Header
- Authorization: Bearer YOUR_KEY_HERE
Tools reference
Fifteen tools cover the whole post lifecycle. Run tools/list in your client for the full Zod schemas.
| Tool | What it does | Inputs |
|---|---|---|
list_accountsread | Every social account connected to your workspace — id, platform, display name. | — |
list_account_groupsread | Account groups you set up in Settings (e.g. Work, Personal). Pair with list_accounts.groupId. | — |
next_queue_slotread | The next free slot from Settings → Queue. Drop into create_post.scheduledAt. | — |
list_postsread | Paginate your posts (newest first). Filter by status: draft, scheduled, publishing, posted, partial, failed. | status?, limit? |
list_calendarread | Posts whose scheduledAt falls in [from, to). Window capped at 366 days. | from, to |
get_postread | Hydrate a single post: caption, per-network targets, statuses, and media. | postId |
upload_mediamedia | Fetch a public URL server-side, store it in post mate, return {key, mimeType, sizeBytes} for create_post.media[]. | url |
create_postwrite | Build a post and (by default) publish or schedule it. type ∈ text/image/video/story. overrides[] sets per-account caption + platformConfig. | caption, socialAccountIds[], type?, media[]?, overrides[]?, scheduledAt?, asDraft? |
update_postwrite | Patch caption or scheduledAt on a draft or scheduled post. | postId, caption?, scheduledAt? |
reschedule_postwrite | Shortcut for moving a scheduled post to a new time. | postId, scheduledAt |
publish_postwrite | Publish a draft or scheduled post right now, ignoring its scheduledAt. | postId |
duplicate_postwrite | Clone an existing post into a fresh draft (caption, media, targets, overrides). | postId |
retry_targetwrite | Re-run a single network target after a failure — same as the Retry button in the web app. | targetId |
delete_postwrite | Hard-delete a draft or scheduled post. Posts that already went live stay where they are. | postId |
get_analyticsanalytics | Whatever metrics each platform exposes for one post — impressions, likes, reach. | postId |
Example prompts
Anything natural-sounding works — your assistant figures out the tool chain. A few we use every day.
Workflow recipes
Three tool chains the assistant figures out on its own — useful to know the shape if you're debugging.
Schedule an image to the next queue slot
- 1
list_accounts→ pick the account ids you want. - 2
upload_mediawith the image URL → keep the returned{key, mimeType, sizeBytes}. - 3
next_queue_slot→ grab the timestamp. - 4
create_postwithtype: image, the media ref, account ids, and the queue timestamp.
Compose once, tweak per platform
- 1Write the main caption.
- 2Pass
overrides[]with{ socialAccountId, captionOverride, platformConfig }. - 3Use
platformConfigfor platform-specific knobs (YouTubetitle, TikTokprivacy, etc.).
Re-run only the network that failed
- 1
list_postswithstatus: "partial". - 2
get_post→ find the target whose status is failed. - 3
retry_targetwith that target id. Other targets stay put.
Limits & types
Hard-coded caps; the server returns a typed error well before any underlying network's limit.
- Max media size per file
- 100 MB
- Image types
- jpeg, png, webp, gif
- Video types
- mp4, mov, webm
- Max accounts per post
- 10
- Max media items per post
- 20
- Calendar window per query
- 366 days
- Caption length per call
- 10 000 chars
Security model
Defence in depth — the assumption is that a key may eventually leak, so individual blast radius stays small.
Hashed at rest
Keys carry 256 bits of entropy. We persist only the SHA-256 hash, so a database dump cannot replay a key.
Tenant-scoped
Every tool resolves the user from the bearer token. No call can read or mutate another tenant's data.
SSRF-hardened
upload_media resolves the hostname, rejects private IPv4/IPv6 and metadata aliases, and re-validates each redirect hop.
Instant revoke
Revoking a key from Settings takes effect on the very next request. No propagation delay, no logout.
Troubleshooting
The handful of things that bite people in their first hour.
"Unauthorized" / 401
Authorization header is missing. Generate a fresh one and re-paste.Tools don't appear in Claude Desktop
"One or more account ids are not connected"
list_accounts again to refresh."Host X resolves to a private IPv4"
upload_mediaresolves to a local or private address. That's blocked on purpose — host the media on a public CDN or any normal HTTPS URL.A scheduled post didn't fire
get_post. If a target's status is failed, the error message is on the post itself. retry_target re-runs just that network.Stuck on something, or hitting an MCP edge case?
Email support@post-mate.com — we read every message.