Post to X from Gemini CLI
Gemini CLI is Google's agent for the terminal. Add calmposts' X (Twitter) MCP server and it can turn your notes, docs or release history into posts and threads for X and Bluesky, saved as drafts or queued for your approval.
- Connection
- Remote MCP server over Streamable HTTP: nothing to install
- Sign-in
- API key in the Authorization header
- Server address
https://calmposts.com/mcp- Where you set it up
- ~/.gemini/settings.json or .gemini/settings.json
What Gemini CLI can do with calmposts
Gemini CLI reads files, runs commands and searches the web from your terminal. With calmposts as an MCP server it can draft a launch thread from your README, a week of posts from a planning doc, or a follow-up to something you scheduled yesterday, and save each one in calmposts.
Gemini asks before it runs an MCP tool unless you trust the server, so you see every create_post call and its text first. Its /mcp command shows calmposts' connection status and the tools it offers.
calmposts' X (Twitter) MCP server gives Gemini CLI 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 Gemini CLI
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: One command, for every project
gemini mcp add writes to the current project's .gemini/settings.json unless you pass -s user, which puts calmposts in ~/.gemini/settings.json.
Create a key in calmposts under API & MCP and export it, for example in ~/.zshrc:
export CALMPOSTS_API_KEY=cp_live_…Add the server. The single quotes keep the variable's name in settings.json, and Gemini fills it in from your environment when it loads its settings:
gemini mcp add -s user --transport http \ --header 'Authorization: Bearer ${CALMPOSTS_API_KEY}' calmposts https://calmposts.com/mcpCheck it: the list shows calmposts as Connected.
gemini mcp list
Setup 2: settings.json by hand
Use httpUrl: in Gemini CLI, url means the older SSE transport, and calmposts speaks Streamable HTTP only.
Add calmposts under mcpServers in ~/.gemini/settings.json, or in a project's .gemini/settings.json:
{ "mcpServers": { "calmposts": { "httpUrl": "https://calmposts.com/mcp", "headers": {"Authorization": "Bearer ${CALMPOSTS_API_KEY}"} } } }Start gemini and run /mcp: calmposts is CONNECTED, with its 11 tools.
Signing in: a key or OAuth
Gemini CLI sends the headers you set with every request. Any string in settings.json can name an environment variable ($VAR_NAME or ${VAR_NAME}, including ones from .env files), so the file never has to hold the key.
Gemini CLI can also sign in by itself: when a server answers 401 it discovers the OAuth endpoints, registers and opens your browser, keeping the tokens in ~/.gemini/mcp-oauth-tokens.json. That needs a local browser and a localhost callback, so it doesn't work over a plain SSH session. With calmposts, the key is the setup this page was checked with.
Leave trust off for calmposts: it skips every confirmation for the server's tools, delete_post included.
Check that it works
- gemini mcp list shows calmposts, its URL and Connected.
- /mcp in a session shows calmposts as CONNECTED and lists its 11 tools.
- Ask “What are my calmposts limits today?”: Gemini asks to run get_limits, then answers.
- Ask for a draft and find it under Posts in calmposts, with the source mcp.
Prompts to try
Ask in your own words and the agent picks the tools. A few that work well:
- “Read README.md and write a launch thread for X. Save it in calmposts as a draft.”
- “Turn docs/roadmap.md into five posts, one per item, and queue them in calmposts.”
- “Search the web for this week's news in our product category and draft two posts with a fresh angle; keep them as drafts.”
- “Show me tomorrow's calmposts queue and move the 9 a.m. post to noon.”
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 Gemini CLI
- Use httpUrl, not url: in Gemini CLI, url selects SSE, which calmposts doesn't offer.
- Keep underscores out of the server's name. Gemini names tools mcp_{server}_{tool} and splits at the first underscore, so calmposts works and calm_posts would not.
- To limit the tools, add includeTools or excludeTools, for example "excludeTools": ["delete_post"].
- The request timeout defaults to 10 minutes, far more than calmposts needs; create_post with images takes longest, while calmposts downloads them.
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 DISCONNECTED
Run gemini mcp list. A 401 means the header is missing or CALMPOSTS_API_KEY isn't set in Gemini's environment; also check that the address sits under httpUrl, not url.
An SSE error, or 405 from calmposts
The address is under url, so Gemini CLI speaks SSE, and calmposts answers the SSE stream's GET with 405. Move it to httpUrl.
Gemini opens a browser to sign in
No valid key reached calmposts, so its 401 started Gemini's OAuth discovery. Fix the header or the variable, then restart Gemini.
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
Should I trust the calmposts server?
Only if you're happy for every calmposts tool, delete_post included, to run without asking. Agents' posts still wait in calmposts' approval queue either way.
Project or user settings?
A project's .gemini/settings.json goes to everyone who checks it out; ~/.gemini/settings.json is yours alone. Keep the key in an environment variable in both.
Do I need the calmposts-mcp program?
No. Gemini CLI connects to the hosted server over Streamable HTTP; there's nothing to install.
Can Gemini publish right away?
Only when you ask it to post now and both your workspace and the key let agents publish. Otherwise the post waits for your approval.
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 Gemini CLI docs this page follows
- Gemini CLI docs: MCP servers with Gemini CLI
- Gemini CLI docs: Configuration
- Gemini CLI source docs: mcp-server.md
calmposts is an independent service and is not affiliated with or endorsed by the makers of Gemini CLI. Product names belong to their owners.
Let Gemini CLI draft your posts, calmly
Start your free trial, connect your accounts, create a key and give Gemini CLI the address.
Try it free