MCP server
tinyposter speaks Model Context Protocol. Drop the URL + a personal access token into any MCP-aware AI client.
Get a token
A token is like a password your AI client will use to talk to tinyposter. It starts with tp_.
- Open your tokens page.
- Click Create token. Name it after the client (“Claude”, “Cursor”, etc.).
- Copy the token. It only shows once.
What is MCP?
Model Context Protocol is the standard way AI agents call external tools. Anthropic, Google, and OpenAI all support it. tinyposter exposes its full feature set as MCP tools, so any MCP-aware client (Claude Desktop, Claude Code, Cursor, Zed, etc.) can post for you with a single config snippet.
Endpoint
- URL:
https://tinyposter.app/api/mcp - Transport: JSON-RPC 2.0 over HTTP POST
- Auth:
Authorization: Bearer tp_… - Methods:
initialize,tools/list,tools/call,ping
Setup
Claude Desktop / Claude Code
Open claude_desktop_config.json from Settings → Developer → Edit Config (Mac/Windows) and add:
{
"mcpServers": {
"tinyposter": {
"url": "https://tinyposter.app/api/mcp",
"headers": {
"Authorization": "Bearer tp_PASTE_YOUR_TOKEN_HERE"
}
}
}
}Restart Claude. Done. Detailed walkthrough on the Claude page.
Cursor
Cursor has its own MCP UI — no JSON file to edit.
- 01
Open Cursor settings
Press
Cmd+,on Mac orCtrl+,on Windows. Or click the gear icon in the sidebar. - 02
Find MCP Servers
In the left rail of Settings, scroll to Tools & Integrations. Click MCP Servers.
Click Add new MCP server (or just Add new server).
- 03
Fill in the form
- Name:
tinyposter - Type / Transport:
HTTP(orStreamable HTTPif shown) - URL:
https://tinyposter.app/api/mcp - Headers: click Add header. Set name to
Authorizationand value toBearer tp_PASTE_YOUR_TOKEN_HERE.
Save. Open the Composer / Agent tab — tinyposter's tools appear in the tool list and Cursor can call them mid-task.
- Name:
Raw / curl
Want to test without an AI client? Hit it directly:
# 1. Discover tools
curl https://tinyposter.app/api/mcp \
-H "Authorization: Bearer tp_..." \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# 2. Call a tool
curl https://tinyposter.app/api/mcp \
-H "Authorization: Bearer tp_..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":2,
"method":"tools/call",
"params":{ "name":"view_calendar", "arguments":{ "days_ahead":7 } }
}'Tool reference
Each tool is also documented in the MCP tools/list response with its JSON schema.
list_brandsList the brands the user owns. Each brand maps to its own set of connected social accounts.
input schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}list_accountsList the connected social media accounts for a brand. Defaults to the user's active brand.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
}
},
"additionalProperties": false
}connect_accountsGet a URL the user opens in their browser to connect (or reconnect) a social account on tinyposter.app. Use this whenever the user asks to connect/add/link a platform, when list_accounts shows zero accounts, or when a post fails with platform_not_connected. Always present the returned URL as a clickable link in your reply — agents cannot complete OAuth on the user's behalf.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"platform": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
],
"description": "Optional. Pre-selects the platform on the connect page."
}
},
"additionalProperties": false
}get_usageGet the user's plan, post quota, and how many posts they've used this billing period. Quota is shared across all brands.
input schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}post_nowPublish a post immediately to one or more connected social platforms on a brand. The post is queued for publishing in the next minute.
input schema
{
"type": "object",
"required": [
"text",
"platforms"
],
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"text": {
"type": "string",
"description": "The post text/caption."
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
},
"description": "Which connected platforms to publish to. Use list_accounts to see what's available.",
"minItems": 1
},
"title": {
"type": "string",
"description": "Optional internal title (used for video titles on YouTube/TikTok)."
},
"media_urls": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional public URLs of images or videos to attach."
}
},
"additionalProperties": false
}schedule_postSchedule a post to publish at a specific date/time on a brand. Use ISO 8601 (e.g. 2026-01-15T14:30:00-05:00).
input schema
{
"type": "object",
"required": [
"text",
"platforms",
"scheduled_at"
],
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"text": {
"type": "string"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
},
"minItems": 1
},
"scheduled_at": {
"type": "string",
"description": "ISO 8601 datetime for when to publish."
},
"title": {
"type": "string"
},
"media_urls": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}list_postsList posts for a brand (scheduled, publishing, published, failed). Defaults to the active brand.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"from": {
"type": "string",
"description": "ISO datetime; only posts scheduled at or after this."
},
"to": {
"type": "string",
"description": "ISO datetime; only posts scheduled at or before this."
},
"status": {
"type": "array",
"items": {
"type": "string",
"enum": [
"draft",
"scheduled",
"publishing",
"published",
"failed",
"canceled"
]
},
"description": "Filter by these statuses."
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
},
"additionalProperties": false
}view_calendarGet a quick view of upcoming scheduled posts for a brand grouped by date.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"days_ahead": {
"type": "integer",
"minimum": 1,
"maximum": 60,
"default": 14
}
},
"additionalProperties": false
}cancel_postCancel a scheduled post by id. Cannot cancel posts that have already been published.
input schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
},
"additionalProperties": false
}get_queue_scheduleGet the recurring posting slots for a brand. Slots are weekday + HH:MM in the user's timezone and define when add_to_queue will publish. Empty schedule means the queue is unusable.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
}
},
"additionalProperties": false
}set_queue_scheduleReplace the recurring posting slots for a brand. Send the full desired schedule; existing slots are wiped first. weekday: 0=Sunday..6=Saturday. time_local: HH:MM 24h.
input schema
{
"type": "object",
"required": [
"slots"
],
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"slots": {
"type": "array",
"maxItems": 168,
"items": {
"type": "object",
"required": [
"weekday",
"time_local"
],
"properties": {
"weekday": {
"type": "integer",
"minimum": 0,
"maximum": 6
},
"time_local": {
"type": "string",
"description": "HH:MM 24h, e.g. 09:00"
}
}
}
}
},
"additionalProperties": false
}add_to_queueAdd a post to the next open queue slot for a brand. Returns the resolved scheduled_at. Requires the brand to have at least one slot in get_queue_schedule.
input schema
{
"type": "object",
"required": [
"text",
"platforms"
],
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"text": {
"type": "string"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
},
"minItems": 1
},
"title": {
"type": "string"
},
"media_urls": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}list_autolistsList autolists (evergreen post buckets) for a brand. Use to find existing lists before adding items.
input schema
{
"type": "object",
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
}
},
"additionalProperties": false
}create_autolistCreate an autolist (evergreen post bucket) on a brand. The cron worker pushes one item into the queue every cadence_hours. Loop=true wraps to position 0 forever; loop=false pauses after the last item.
input schema
{
"type": "object",
"required": [
"name",
"platforms"
],
"properties": {
"brand_id": {
"type": "string",
"description": "Brand id to operate on. Defaults to the user's currently active brand. Use list_brands to discover ids."
},
"name": {
"type": "string"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
},
"minItems": 1
},
"cadence_hours": {
"type": "integer",
"minimum": 1,
"maximum": 720,
"default": 24
},
"loop_items": {
"type": "boolean",
"default": true
},
"status": {
"type": "string",
"enum": [
"active",
"paused"
],
"default": "active"
}
},
"additionalProperties": false
}get_autolistFetch an autolist with all its items in order.
input schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
},
"additionalProperties": false
}update_autolistUpdate an autolist (rename, pause/resume, change cadence, change default platforms, toggle loop).
input schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
}
},
"status": {
"type": "string",
"enum": [
"active",
"paused"
]
},
"cadence_hours": {
"type": "integer",
"minimum": 1,
"maximum": 720
},
"loop_items": {
"type": "boolean"
}
},
"additionalProperties": false
}delete_autolistDelete an autolist and all its items.
input schema
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
},
"additionalProperties": false
}add_to_autolistAppend a new evergreen item to an autolist. Items are posted in order; if the list loops, it wraps after the last item. Use list_autolists first to find the autolist id.
input schema
{
"type": "object",
"required": [
"autolist_id",
"text"
],
"properties": {
"autolist_id": {
"type": "string"
},
"text": {
"type": "string"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"TWITTER",
"INSTAGRAM",
"FACEBOOK",
"LINKEDIN",
"TIKTOK",
"YOUTUBE",
"PINTEREST",
"BLUESKY",
"THREADS",
"REDDIT",
"MASTODON"
]
},
"description": "Optional override; null/missing uses the autolist's default platforms."
},
"media_urls": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}remove_autolist_itemRemove an item from an autolist.
input schema
{
"type": "object",
"required": [
"autolist_id",
"item_id"
],
"properties": {
"autolist_id": {
"type": "string"
},
"item_id": {
"type": "string"
}
},
"additionalProperties": false
}Things to ask
- “Post ‘Friday recap incoming’ to X and LinkedIn.”
- “Schedule a Threads post for Sunday at 9am ET that says...”
- “What's on my calendar next week?”
- “Cancel the post I scheduled for Saturday.”
- “Which platforms am I connected to?”
- “How many posts do I have left this month?”
Troubleshooting
▸Claude doesn't list tinyposter as a tool
Quit Claude fully (Cmd+Q) and re-open. Config is only read on launch.
▸I get rate limited
The MCP endpoint allows 120 calls/min/token. If you're hitting that, batch the work or move to the REST API (240/min) for bulk operations.
▸Can I have two clients use the same token?
You can, but if one leaks, both stop working when you revoke. Better practice: one token per client (“Claude Desktop”, “Cursor”, “CI”, etc.) so you can revoke surgically.