buffer-mcp
MCP server for Buffer social media scheduling via the GraphQL API. Works with Claude Desktop, Claude Cowork, and any MCP-compatible AI tool.
The legacy REST API (api.bufferapp.com/1/) is deprecated. This server uses Buffer's current GraphQL API exclusively.
Setup
1. Install dependencies
cd buffer-mcp
bash install.sh
Or manually:
pip install mcp httpx pydantic
2. Get your Buffer credentials
- Access token: Buffer → Settings → API (or Settings → Beta)
- Org ID: Run
buffer_get_accountafter connecting — use the org ID fromaccount.organizations, NOTaccount.id(they differ and using the wrong one causes silent failures) - Channel IDs: Run
buffer_list_channelsto get your Twitter/LinkedIn channel IDs
3. Configure environment variables
Copy .env.example to .env and fill in your values:
cp .env.example .env
4. Add to Claude Desktop / Cowork
Add to your MCP config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"buffer": {
"command": "python3",
"args": ["/absolute/path/to/buffer-mcp/server.py"],
"env": {
"BUFFER_ACCESS_TOKEN": "your-token-here",
"BUFFER_ORG_ID": "your-org-id-here",
"BUFFER_CHANNEL_TWITTER": "your-twitter-channel-id",
"BUFFER_CHANNEL_LINKEDIN": "your-linkedin-channel-id"
}
}
}
}
Tools
| Tool | Description | |------|-------------| | buffer_list_channels | List connected social channels with IDs | | buffer_get_account | Get account info and find your org ID | | buffer_create_post | Schedule a single post (with images, videos, threads, LinkedIn metadata) | | buffer_batch_create_posts | Schedule up to 25 posts in one call | | buffer_update_post | Edit a scheduled post (atomic delete + recreate) | | buffer_delete_post | Remove a post from the queue | | buffer_find_post_by_schedule | Look up the canonical ID for a post by its scheduled time | | buffer_list_posts | List scheduled posts in your queue | | buffer_list_published_posts | List posts that have already been sent | | buffer_get_engagement | Pull engagement metrics for a published post (Twitter wired; LinkedIn requires Marketing API) | | buffer_get_reply_links | Fetch recent tweet URLs for reply/thread follow-up | | buffer_upload_image | Upload a local image or video to Cloudflare R2 and return a Buffer-safe URL | | buffer_health_check | Verify token validity and API connectivity |
Environment Variables
| Variable | Required | Description | |----------|----------|-------------| | BUFFER_ACCESS_TOKEN | Yes | Your Buffer API access token | | BUFFER_ORG_ID | Yes | Your Buffer organization ID (from buffer_get_account) | | BUFFER_CHANNEL_TWITTER | No | Twitter channel ID — enables "twitter" shorthand | | BUFFER_CHANNEL_LINKEDIN | No | LinkedIn channel ID — enables "linkedin" shorthand | | BUFFER_TWITTER_USERNAME | No | Your Twitter username for buffer_get_reply_links | | TWITTER_BEARER_TOKEN | No | Twitter API v2 bearer token (for reply links + engagement) | | CLOUDFLARE_ACCOUNT_ID | No | Cloudflare account ID (for buffer_upload_image) | | CLOUDFLARE_R2_API_TOKEN | No | R2 API token with Object:Write permission | | CLOUDFLARE_R2_BUCKET_NAME | No | R2 bucket name (default: buffer-media) | | CLOUDFLARE_R2_PUBLIC_BASE_URL | No | Public CDN URL for your R2 bucket |
Key Notes
Media hosting
Buffer's media fetcher rejects many free CDNs (catbox, imgur return 0-byte or 429 for Buffer's node-fetch UA). Use Cloudflare R2, AWS S3, or another persistent CDN. The buffer_upload_image tool handles R2 uploads automatically when configured.
Twitter threads
To post a thread, use thread_replies in buffer_create_post. Twitter suppresses posts with links in the body — put your CTA URL in the first reply, not the parent tweet.
Post ID rotation (known Buffer bug)
createPost can return a transient ID that differs from the ID returned by buffer_list_posts for the same post. Always use buffer_find_post_by_schedule to get the canonical (deletable) ID before calling buffer_delete_post or buffer_update_post.
Org ID vs Account ID
Buffer exposes both account.id (account-level) and account.organizations[].id (org-level). Using the account ID as the org ID causes silent "Organization not found" errors. Run buffer_get_account and copy the org ID from the organizations list.
License
MIT











