Post to X from Cursor
Cursor's agent already knows your codebase. Give it calmposts' X (Twitter) MCP server and it can write the launch post, the changelog thread or the docs announcement for X and Bluesky, and leave it in your calmposts queue.
- Connection
- Remote MCP server over Streamable HTTP: nothing to install
- Sign-in
- API key in the Authorization header; OAuth: you sign in to calmposts and approve, no key
- Server address
https://calmposts.com/mcp- Where you set it up
- ~/.cursor/mcp.json or .cursor/mcp.json
What Cursor can do with calmposts
In Cursor you ask the agent for a change, and it reads files, runs commands and edits code. With calmposts among its tools it can also tell people about the change: a post when a feature ships, a thread that walks through a refactor, a short note for each release tag.
Cursor lists calmposts' tools under Available Tools and calls them when they fit the request, Plan Mode included; you can also name one, such as get_limits or create_post. By default it asks before each MCP tool call and shows the arguments, so you read the exact text before it reaches calmposts.
calmposts' X (Twitter) MCP server gives Cursor 11 tools, the same set every client gets:
| Tool | Does |
|---|---|
list_accounts | your channels and each network's rules; customer_id: one customer's |
list_customers | the customers (an agency's clients) with their channels' ids |
get_limits | plan usage, the workspace's time zone, network limits |
create_post | a post or a thread for the chosen accounts, wording per account, images by URL; when: draft, queue, at or now |
list_posts | posts by status, account, customer and time range |
get_post | one post with its channels, status and version |
update_post | edit or reschedule; what is left out stays |
delete_post | cancel and remove |
get_next_slot | where when=queue would put a post |
retry_post | send the failed channels again |
get_post_metrics | a published post's counts on each channel at 1 h, 24 h and 7 days (plans with analytics); read only |
Set up calmposts in Cursor
Check the key before you start
Create a key in calmposts under API & MCP (it's shown only once), then ask the server for its tools. A list of 11 tools means the address and the key are right; a 401 means the key is wrong or was sent without “Bearer ”.
curl -s https://calmposts.com/mcp \
-H "Authorization: Bearer cp_live_…" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# 200 {"jsonrpc":"2.0","id":1,"result":{"tools":[…]}}Setup 1: mcp.json with a key from the environment
The key stays out of the file, so the same mcp.json can live in a project's repository.
Create a key in calmposts under API & MCP, then make it available to Cursor, for example in ~/.zshrc, and restart Cursor so it sees the variable:
export CALMPOSTS_API_KEY=cp_live_…Add calmposts to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json in one project:
{ "mcpServers": { "calmposts": { "url": "https://calmposts.com/mcp", "headers": {"Authorization": "Bearer ${env:CALMPOSTS_API_KEY}"} } } }Save the file and restart Cursor. Under Customize → MCPs calmposts is switched on, with its 11 tools.
Setup 2: mcp.json with OAuth, no key
Cursor signs in to calmposts by itself: it reads calmposts' OAuth metadata, registers as a public client and uses PKCE.
Add calmposts without headers:
{ "mcpServers": { "calmposts": {"url": "https://calmposts.com/mcp"} } }When Cursor asks you to sign in to calmposts, follow its prompt. calmposts' consent page opens: sign in as the workspace's owner and click Allow.
Signing in: a key or OAuth
A key in the headers is the simplest: every request carries it, and nothing expires. Keep it in an environment variable and reference it as ${env:CALMPOSTS_API_KEY}; Cursor resolves variables in url and headers, but a remote server cannot use envFile.
With OAuth, Cursor's desktop app registers both of its redirect addresses, http://localhost:8787/callback and the web one on cursor.com, and calmposts accepts both. Access tokens last an hour, Cursor renews them with the refresh token calmposts issues, and the connection is listed under API & MCP → Connected apps.
Cloud Agents keep their own MCP sign-ins on Cursor's servers and use the servers set up in the Cloud Agents dashboard: add calmposts there too if your cloud agents should post.
Check that it works
- Customize → MCPs shows calmposts switched on; its tools appear in the tools list at the top of the chat panel.
- Ask “Use calmposts to list my accounts”: the agent asks to run list_accounts, then shows your channels.
- If something is off, open the Output panel (Cmd+Shift+U; Ctrl+Shift+U on Windows and Linux) and pick MCP Logs: connection and sign-in errors are there.
Prompts to try
Ask in your own words and the agent picks the tools. A few that work well:
- “We just merged the export feature. Write an X post and a Bluesky post about it from the PR description, and save them in calmposts as drafts.”
- “Turn docs/releases/2.4.md into a thread and queue it in calmposts for my X and Bluesky accounts.”
- “Before you schedule anything, check get_limits: how many posts, and posts with a link, do I have left?”
- “Show me what calmposts will publish tomorrow and fix the typo in the second post.”
- “Write a short post for every release tag from the last month and spread them over next week's free slots.”
Networks, threads and approval
Posts go to X and Bluesky. A thread goes out as a reply chain on X and Bluesky. Coming soon: Threads and LinkedIn.
Write once, post everywhere: your agent sends one text for every account it picks. If the text is longer than a network allows, calmposts posts it there as a thread, splitting at a paragraph break, then at the end of a sentence, then at a space, with nothing numbered or added. calmposts checks each network's rules and your plan's limits before it saves the post and names the field that's wrong, so the agent can fix the text and try again.
By default your agent's posts wait for you. They come back as pending_approval, and you approve or reject each one in the app, in Telegram or from the email calmposts sends. The workspace owner can let agents publish on their own, but only when both the workspace and the API key are set to publish. X expects an account that posts automatically to carry its Automated label (Settings → Your account → Account information → Automation).
Limits and costs
- Agents need a paid plan: the Free plan has no API keys and can't approve connected apps. API keys per plan: Pro 3 · Advanced 10 · Agency 25.
- Your agent's posts count the same as yours. Posts a day: Pro 20 · Advanced 100 · Agency 300. Posts with a link per month: Pro 30 · Advanced 300 · Agency 600. Each post in a thread counts.
- Posts with a link are counted separately because X charges every app $0.015 per post and $0.20 per post with a link. Your plan includes X's fees, so you don't need an X developer account or an X API bill of your own.
- Try it first: 7-day free trial. Card required. 5 posts with a link during the trial.
- Each key can make 60 requests a minute across MCP and REST; beyond that, the server returns 429 with Retry-After.
What to know about Cursor
- Project and global files are merged; when both name calmposts, the project's .cursor/mcp.json wins.
- Cursor 3.6 and later default to Auto-review: allowlisted MCP tools run at once and the rest pass a safety classifier (Cursor Settings → Agents → Approvals & Execution). Keep create_post, update_post and delete_post off the allowlist if you want to see every write.
- You can switch a single tool off, delete_post for example, by clicking its name in the chat's tools list.
- On a team with an MCP allowlist, an admin approves remote servers by URL: ask for https://calmposts.com/mcp to be allowed.
Without MCP: the REST API
Everything the tools do is also a REST call under /api/v1 with the same key, which suits a script or a workflow step that only speaks HTTP. calmposts posts through its own approved X app, so you don't need X API keys of your own.
export CALMPOSTS_API_KEY=cp_live_…
curl -H "Authorization: Bearer $CALMPOSTS_API_KEY" https://calmposts.com/api/v1/accounts
curl -X POST https://calmposts.com/api/v1/posts \
-H "Authorization: Bearer $CALMPOSTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"parts":[{"text":"Calm posts, scheduled."}],"targets":[{"account_id":"ACCOUNT_ID"}],"schedule":{"mode":"queue"}}'Troubleshooting
calmposts shows an error under Customize → MCPs
Open MCP Logs in the Output panel. A 401 with missing_api_key means the header went out without a key: the variable is empty in Cursor's environment. Set it in your shell profile and restart Cursor.
The agent doesn't use calmposts
Check that calmposts is on under Customize and its tools are on in the chat's tools list, then name the tool in your request.
Sign-in ends on “Only the workspace's owner can connect apps.”
Sign in to calmposts as the workspace's owner, or use a key that the owner created.
401 missing_api_key
The request came without a key, or without “Bearer ” in front of it. Send Authorization: Bearer cp_live_…, with the space.
401 invalid_api_key, api_key_revoked or api_key_inactive
The key is mistyped, was revoked, or its creator is no longer in the workspace. Create a new key in API & MCP and put it in place of the old one.
401 invalid_token
An OAuth connection's access token expired or was disconnected. Clients refresh it on their own; if that fails, sign in again.
402 quota_exceeded
A plan limit is reached, and field names it: api_keys means the plan has no agents (Free); posts_per_day and link_posts_per_month free up the next day or month, or with a bigger plan.
403 insufficient_scope
The key lacks a permission the tool needs; field names it (posts:write to create posts). Create a key that has it.
429 rate_limited
More than 60 requests a minute came from this key. Wait for the seconds in Retry-After.
The tool answers duplicate_recent
The same text went to the same account in the last 7 days. Ask for a new wording.
The post is pending_approval
That is not an error: the post waits for your yes in calmposts. Approve it there, or let agents publish (the owner sets it on the workspace and on the key).
The account needs_reconnect
The network took back calmposts' access. Reconnect the account under Accounts in the app.
Questions
Does Cursor need a local MCP program?
No. Cursor connects to the hosted server by URL; a remote entry needs only url and, with a key, headers.
Should I commit .cursor/mcp.json?
Yes, as long as it holds ${env:CALMPOSTS_API_KEY} and not the key itself: each teammate then uses their own key from their environment.
A key or OAuth in Cursor?
A key suits a setup that should never ask again; OAuth suits you if you would rather not handle a key. Both act in your workspace with the same tools.
Do Cloud Agents use my mcp.json?
No. Cloud Agents use the servers set up in the Cloud Agents dashboard and keep their own sign-ins; add calmposts there for them.
Can the agent reply, follow or send DMs?
No. There are no tools for that: X forbids automating them, and calmposts only writes and schedules your own posts.
Do I need my own X API keys?
No. calmposts publishes through its own approved X app, and X's per-post fees are part of the plan's price.
The Cursor docs this page follows
calmposts is an independent service and is not affiliated with or endorsed by the makers of Cursor. Product names belong to their owners.
Let Cursor draft your posts, calmly
Start your free trial, connect your accounts, create a key and give Cursor the address.
Try it free