Marketing Assistant MCP
This server enables a coding agent to draft, review, approve, and publish social media posts to X (Twitter) with a human-in-the-loop approval gate. All drafts and credentials are stored locally on the user's machine.
Capabilities:
Create drafts: Save a new post draft for X with specified text.
List drafts: Retrieve all locally stored drafts, optionally filtered by status (
draft,approved,rejected,publishing,published).Get a draft: Fetch a specific draft by ID.
Update a draft: Edit the text of an existing draft; if previously approved, it resets to
draftstatus, requiring re-approval.Approve a draft: Mark a draft as human-approved (required before publishing, unless approval is disabled).
Reject a draft: Mark a draft as rejected, preventing publishing; also used to manually reconcile drafts stuck in
publishingafter a failed or interrupted publish attempt.Publish a draft: Send an approved draft to X via the X API v2 and return the live post URL; fails if not approved.
Check X account connection: Verify the server's connection to an X account and retrieve the connected username and account ID.
Wait, no. This is related to X (Twitter) posting.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Marketing Assistant MCP Draft a tweet about our product launch and get my approval before publishing."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Makers Page MCP
The indie stack Model Context Protocol server — one connection for your founder tools, instead of wiring a hundred separate ones.
Indie founders already juggle socials, Stripe, analytics, GitHub, and a database. Each usually means another MCP, another config block, another context the agent doesn't share. Makers Page MCP aggregates those surfaces into one local server your coding agent already understands, so it can draft a launch post with revenue context, check a deploy, or pull product metrics without hopping tools.
makers-page-mcp runs locally next to Cursor, Claude Code, Codex, or any other MCP client. v1 ships X first: your agent drafts a channel-native post about what you just built, you approve it, and it goes out through the real X API v2. Nothing publishes without a human in the loop. More connectors (payments, analytics, GitHub, DBs, and more) are on the roadmap.
makers.page — the indie stack MCP that already knows your tools.
Why this exists
Most agents end up with a pile of MCP servers — one for GitHub, one for Stripe, one for analytics, one for socials — each with its own auth and none sharing context. Makers Page MCP is the opposite bet: one indie stack connection that already knows the tools founders actually use, so the agent can act across the stack instead of juggling integrations.
Today that means approval-gated publishing to X. Next: the rest of the stack (see Roadmap).
One MCP, not a hundred. Aggregate the indie stack (socials, payments, analytics, GitHub, DBs) behind a single local server instead of a config file full of one-off connectors.
Shared context by design. The agent shouldn't re-learn who you are and what you shipped every time it switches tools.
Agent-native, not another dashboard. Same protocol, same config file as your other MCP servers. No new app to log into.
Approval-gated by default. Every post is a
draftuntil you explicitly callapprove_draft.publish_draftrefuses to post anything that hasn't been approved, unless you turn that off yourself. The same pattern will apply to anything that spends money or posts publicly.Built for real, paid API calls. X's write API costs money per post (see below). The draft/approve/publish split exists so an agent can never spam your account or your wallet.
Crash-safe by design. Publishing uses atomic file writes, keyed locks around concurrent operations on the same draft, and a three-way error split (definitive failure, ambiguous network failure, unexpected error) so a dropped connection can never turn into a silent duplicate post.
Local-first. Drafts and credentials live on your machine (
~/.local/share/makers-page-mcp,~/.config/makers-page-mcp), written with0600permissions, not in someone else's cloud.Zero lock-in. It's a stdio MCP server distributed on npm under the MIT license. Read the source, fork it, self-host it.
Related MCP server: MCP Twitter
How it compares
Manual / browser hopping | Separate MCP per tool | Zapier / Make | Makers Page MCP | |
Lives inside your coding agent | No | Yes | No | Yes |
One connection for the indie stack | No | No (N configs) | Partial (N apps) | Yes (aggregates) |
Shared context across socials, money, code, data | No | No | Only with glue | Yes (destination) |
Human approval before anything ships or spends | Depends on you | Depends on each server | No (auto-triggered) | Yes, by default |
Open source / self-hostable | (n/a) | Varies | No | Yes (MIT) |
Where data lives | You | Mixed | Their servers | Your machine |
v1 covers X posting today; the aggregator columns describe where this indie stack MCP is headed.
Cost per post
As of 2026, X's API is pay-per-use for self-serve developer accounts: creating a post costs $0.015 (plain text) or $0.20 (if the post contains a URL), charged against credits you prepay in the X developer console. There's no free write tier anymore. Every publish_draft call is a real charge: treat it accordingly (approve deliberately, don't script bulk test-publishing).
Quick start
1. Create an X developer app
Go to the X developer portal and create (or open) a project + app.
Under User authentication settings, enable OAuth 2.0.
Set App permissions to Read and write.
Set the Type of App to Web App, Automated App or Bot (this gives you a Client ID, and a Client Secret if confidential).
Add an exact-match Callback URI / Redirect URL:
http://127.0.0.1:8879/callback(must be a loopback host:127.0.0.1,localhost, or::1— non-loopback URIs are rejected at auth time).Copy the Client ID (and Client Secret, if shown).
2. Install
Pick one:
Option A: npm (recommended, no clone needed)
npx -y makers-page-mcp-auth # run once to authorize, see step 3npx/bunx fetch and cache the package on first run; nothing to build yourself.
Option B: from source
git clone https://github.com/alexcloudstar/makers.page-mcp.git
cd makers.page-mcp/mcp
bun install
bun run build3. Set credentials and authorize
Set these environment variables (from your X developer app, step 1):
export TWITTER_CLIENT_ID=your-client-id
export TWITTER_CLIENT_SECRET=your-client-secret # omit if your app is a public client
export TWITTER_REDIRECT_URI=http://127.0.0.1:8879/callback # must match the portal exactlyIf you're building from source, you can instead copy .env.example to .env and fill in the same values. Bun loads .env automatically for anything run with bun (bun run auth, bun run dev, bun dist/index.js). .env is gitignored, so your keys never get committed.
Run the one-time authorization flow:
npx -y makers-page-mcp-auth # npm install
bun run auth # from sourceThis prints an authorize URL: open it, log in as the X account you want to post from, and approve. The server captures the redirect locally and stores an access + refresh token at ~/.config/makers-page-mcp/credentials.json. Tokens auto-refresh on future use; re-run auth if you revoke access, or after upgrading to a version that adds scopes (e.g. media.write for image/GIF/video uploads).
4. Connect it to your coding agent
Add to your Cursor mcp.json (Settings → MCP, or ~/.cursor/mcp.json). The same shape works for Claude Desktop/Code, Codex, GitHub Copilot, and other MCP clients, just under each tool's own config file:
If you installed via npm:
{
"mcpServers": {
"makers-page": {
"command": "npx",
"args": ["-y", "makers-page-mcp"],
"env": {
"TWITTER_CLIENT_ID": "your-client-id",
"TWITTER_CLIENT_SECRET": "your-client-secret",
"TWITTER_REDIRECT_URI": "http://127.0.0.1:8879/callback"
}
}
}
}(bunx works the same way if you'd rather use Bun: "command": "bunx", "args": ["-y", "makers-page-mcp"].)
If you built from source:
{
"mcpServers": {
"makers-page": {
"command": "bun",
"args": ["--env-file=/absolute/path/to/mcp/.env", "/absolute/path/to/mcp/dist/index.js"]
}
}
}Bun's automatic .env loading is relative to the process's working directory, which most MCP clients don't guarantee is mcp/. The explicit --env-file flag above points straight at your .env regardless of where the server is launched from, so you don't have to duplicate credentials inside mcp.json itself.
Works with any MCP client
This server only uses the standard MCP stdio transport: no client-specific extensions, no remote/HTTP requirement. That means the same command/args/env block above works everywhere, just under each client's own config file:
Client | Config file |
Cursor |
|
Claude Desktop |
|
Claude Code |
|
OpenAI Codex (CLI, Desktop, IDE extension) |
|
Google Gemini CLI |
|
GitHub Copilot (VS Code, Copilot SDK) |
|
Windsurf (Cascade) |
|
Cline (VS Code / JetBrains extension) | its MCP settings panel, or the underlying |
Zed |
|
JetBrains AI Assistant (IntelliJ, PyCharm, WebStorm, ...) | Settings → Tools → AI Assistant → MCP Servers → Add (stdio) |
All of these read the same mcpServers-style JSON (Gemini CLI and JetBrains use slightly different top-level keys, mcpServers and a UI form respectively, but the same command/args/env fields underneath). If your tool of choice isn't listed here but supports MCP over stdio, the config above should work unchanged.
Tools
Tool | What it does |
| Save a new draft post for X. Required: |
| List drafts, optionally filtered by status ( |
| Fetch a single draft by id. |
| Edit draft content (same fields as create; pass |
| Mark a draft approved. Required before publishing (unless approvals are disabled). |
| Mark a draft rejected. Also reconciles a draft stuck in |
| Publish an approved draft to X via |
| Edit the root post of a published draft ( |
| Delete every stored post id on X whenever live ids are recorded (published, partial |
| Check connection status and show the connected |
| Resolve an |
| Show local DM send limits and current usage. |
| Save a draft DM. Required: |
| List DM drafts, optionally filtered by status ( |
| Fetch a single DM draft by id. |
| Edit a DM draft (pass |
| Mark a DM draft approved. Required before sending (unless approvals are disabled). |
| Mark a DM draft rejected, or reconcile one stuck in |
| Send an approved DM via the X API. Enforces local rate limits. |
| Read recent events in a 1:1 DM thread ( |
| Read recent DM events across all conversations (inbox view for agent context). |
| Read recent events in a conversation by |
| Fetch impressions, likes, reposts, replies, quotes, and bookmarks for up to 100 post ids. |
| Calendar-day impressions and engagements via |
| Hour-of-day analysis: avg impressions and engagement rate by when you posted. |
| Rank who commented the most on your top-level X posts for a given calendar day (default yesterday, timezone-aware). Finds the top-level posts you started that day via |
| Discover what's trending right now on X within a specific product niche, via X Recent Search scoped to the niche/keywords, not X's generic global trending list. Required: |
| Save a draft retweet or undo-retweet for a post id. Not executed until approved. |
| List retweet/undo drafts, optionally filtered by status. |
| Fetch a single retweet/undo draft by id. |
| Mark a retweet/undo draft approved (required before execution unless approvals disabled). |
| Mark a retweet/undo draft rejected; also reconcile drafts stuck in executing. |
| Retweet an approved draft immediately via |
| Undo an approved retweet draft via |
Typical agent flow: |
Typical retweet flow: create_retweet_draft → user approves → approve_retweet_draft → retweet_post (or undo_retweet for undo drafts).
Typical DM flow: lookup_x_user (optional) → create_dm_draft → user approves → approve_dm_draft → send_dm_draft.
To reply in context: list_dm_inbox or list_dm_conversation_events → draft with conversationId → approve → send.
Typical trend-discovery flow: be_trendy → agent writes a post from the returned trendingTopics/painPointSignals → create_draft → user approves → publish_draft.
X create/update fields
Field | Notes |
| Main post copy. Must equal |
| Thread of 2+ posts. Each part after the first replies to the previous one (standard X thread chain). Put every link in |
|
|
| Absolute local paths ( |
| Quote another post. Enterprise-only on self-serve / pay-per-use X API tiers — the tool still sends it; X may reject. |
| Post to a Community; |
| Sets |
| Opt out of the default ban on links in the main post. Only when the user explicitly insists. |
Caveats (X product limits)
Links in comments, not the main post: By default,
create_draft/update_draft/edit_published_draftrejecthttp://orhttps://URLs intext/parts[0]. Put links in follow-up thread parts (parts[1],parts[2], …). Override only withallowLinksInMainPost: truewhen the user forces it.Re-auth for media: OAuth scopes now include
media.write. If you authorized before this change, runmakers-page-mcp-auth/bun run authonce more.Re-auth for DMs: OAuth scopes now include
dm.readanddm.write. Re-run auth after upgrading to send or read DMs.Quote posts: OpenAPI documents quote as Enterprise-only on self-serve; expect API errors on lower tiers.
Edit: Requires X Premium, roughly a 30-minute window and up to 5 edits from the original. Each edit returns a new post id (we update the local draft). Polls and community posts are not editable.
Replies: Self-serve apps can create self-threads (reply to your own previous part). Replies to other accounts are blocked unless summoned.
Cashtags: Self-serve allows at most one cashtag (
$TICKER) per post.be_trendyrequires a paid API tier: it calls X's Recent Search endpoint, which needs at least a Basic paid X API access tier. A Free-tier app will get 403/429 errors.get_top_engagersalso uses Recent Search, so it needs the same paid tier, and only ever sees comments from the last 7 days regardless of how old the post being checked is.
If a publish attempt fails ambiguously
publish_draft marks a draft publishing before calling the X API, and only clears that if the API gives a
definitive answer (a real HTTP response, or a clear "not authenticated" error). If the request instead fails
in a way that could mean X received it anyway (a timeout or network drop), the draft is deliberately left in
publishing and not auto-reverted, so an agent can't retry and risk a second, real, paid post.
Reconciliation:
Nothing posted (no live ids recorded): call
reject_draftorupdate_draftto reset.Partial thread (some ids recorded): do not retry
publish_draft. Calldelete_published_draftto remove the live posts, or finish the remainder on X manually.Ambiguous single post (may or may not have posted, no ids recorded): check X yourself; if it did not post, reset with
reject_draft/update_draft; if it did, leave the draft as-is and note the URL.
Configuration
Environment variables:
Variable | Default | Purpose |
| (none) | Required. X/Twitter OAuth 2.0 Client ID. |
| (none) | Set if your X app is a confidential client. |
|
| Must match the callback registered in the X developer portal and use a loopback host ( |
|
| Where credentials are stored. |
|
| Where drafts are stored. |
|
| Set to |
|
| Max characters per post (X's weighted count: URLs count as 23, emoji count once); raise this if you're on X Premium. |
|
| Max characters per DM. |
|
| Local cap on DM sends per rolling hour (before calling X). |
|
| Local cap on DM sends per rolling 24 hours. |
|
| Minimum milliseconds between consecutive DM sends. |
Roadmap
Destination: one local indie stack MCP that already knows the founder tools — socials, payments, analytics, GitHub, databases — so you don't maintain a hundred separate connections. v1 ships X only, on purpose: prove the approval-gated write loop before adding more surfaces that spend money or post publicly.
Shipped
X manage-posts: text, threads, polls, media (chunked upload), quote, community +
share_with_followers, paid partnership, edit, and delete — still behind draft → approve → publish with crash-safe / no-auto-retry semantics.X DMs: draft → approve → send (1:1 text, media attachment, group conversations) with local rate limits; read inbox and thread events;
@handlelookup.X analytics (read-only): post metrics, account summary (today + top posts), posting-time analysis. No local DB; fetches from X API on demand.
X retweets: draft → approve →
retweet_post/undo_retweet(immediate; no scheduling).be_trendy: niche-scoped X trend discovery via Recent Search, spam/duplicate filtering, and scored trending topics + demand-signal posts to ground content the agent writes (no LLM call inside the tool itself).
Next
More socials — LinkedIn, Reddit, Threads, Bluesky; same draft adapted to channel-native tone and length.
Payments & code — Stripe (Lemon Squeezy as a secondary path), GitHub.
Analytics & data — PostHog / Plausible, Postgres via Supabase / Neon.
Ops extras — Resend, Sentry, as the core set stabilizes.
Launch directories — research launches and draft listing copy where useful; submit only where a stable API or first-class MCP write path exists. Today that is thin: Product Hunt community MCPs are read-only (the PH API has no create-post mutation), Hacker News write MCPs scrape browser login (no public write API), and Peerlist / BetaList / Uneed / Fazier / Microlaunch / Dev Hunt / Tiny Launch have no MCP for submissions. MCP registries (official registry, Smithery, PulseMCP, Glama, mcp.so) are for listing this server, not for submitting your product to launch boards.
Always
Local-only drafts and credentials, whichever connectors land.
Approval gates for anything that posts publicly or spends money.
Want a connector prioritized? Open an issue.
Development
bun test # run the unit test suite
bun run typecheckFAQ
No, not by default. Every draft starts in draft status, and publish_draft refuses to run unless the draft has gone through approve_draft first. You can disable that gate with MAKERS_PAGE_REQUIRE_APPROVAL=false if you fully trust the flow, but it's opt-in.
It's a local process. Drafts, DM drafts, retweet drafts, and rate-limit state are stored as files under MAKERS_PAGE_DATA_DIR (default ~/.local/share/makers-page-mcp); your X OAuth tokens live under MAKERS_PAGE_CONFIG_DIR (default ~/.config/makers-page-mcp/credentials.json). All of these files are written with 0600 permissions. Nothing goes through a third-party server; the server talks directly to api.x.com.
That's an X API pricing decision, not this project's. As of 2026 there's no free write tier for X's API; see Cost per post above for current rates. The approval gate exists specifically so an agent can't accidentally run up a bill.
See If a publish attempt fails ambiguously. Short version: definitive failures revert the draft automatically; anything ambiguous (timeouts, dropped connections) is left in publishing for you to check and reconcile manually, so you never get a silent double-post.
Yes. It's a plain stdio MCP server with no client-specific extensions, so it works anywhere MCP is supported: Claude Desktop/Code, OpenAI Codex, Gemini CLI, GitHub Copilot, Windsurf, Cline, Zed, JetBrains AI Assistant, and more. See Works with any MCP client.
Yes, it's MIT-licensed. See Option B: from source to build it yourself, and CONTRIBUTING.md if you want to send changes back upstream.
Contributing
Contributions are welcome. See CONTRIBUTING.md for setup, testing, and PR guidelines.
Security
Found a vulnerability? Please don't open a public issue: see SECURITY.md for how to report it privately.
License
MIT. See the changelog for release notes.
Available Tools
33 toolsanalyze_x_posting_timesAnalyze X posting timesA
Analyze when you post vs average lifetime impressions by hour of day. Derived from your recent timeline; read-only, no DB.
Inputs: days, maxPosts, timezone, minPostsPerHour.
approve_dm_draftApprove DM draftA
Mark a DM draft approved. Only approved drafts can be sent. Call only after the user explicitly reviewed the message.
Inputs: id (required).
approve_draftApprove draft postA
Mark a draft as approved by the human user. Only approved drafts can be published. Only call this after the user has explicitly reviewed and approved the draft text.
Inputs: id (required).
approve_retweet_draftApprove retweet draftA
Mark a retweet/undo draft approved. Only approved drafts can be executed. Call only after the user explicitly reviewed the action.
Inputs: id (required).
be_trendyBe TrendyA
Discover what's trending right now on X within a specific product niche, so you can ride the conversation for engagement. Searches recent X posts scoped to the niche/keywords, not X's generic global trending list (which rarely surfaces niche topics), filters out spam and near-duplicates, and returns algorithmically scored trending topics with real sample tweets and engagement numbers, real demand-signal posts (people asking for recommendations/alternatives), and a post-timing recommendation. This tool does not generate content itself: after calling it, use the returned trendingTopics and painPointSignals, plus the product's name/description/audience from this conversation, to write natural, platform-appropriate content (tweet, thread, LinkedIn post, Bluesky post, Reddit title, Hacker News title) that connects the product to the trend. Avoid AI-sounding phrasing, do not fabricate engagement numbers, and ground any claims in the sample tweets returned.
Inputs: niche (required), productName (required), targetAudience (required), productDescription (required), +2 more.
create_dm_draftCreate DM draftA
Create a draft direct message. Requires recipientId or recipientUsername (or conversationId for an existing thread). NOT sent until approved and send_dm_draft is called. Supports one optional media attachment.
Inputs: text (required), mediaPaths, recipientId, conversationId, +4 more.
create_draftCreate draft postA
Create a draft social post for a channel (currently only "x"). Supports text, threads (parts), polls, media paths, quote, community, and paid partnership. RULE: never put http(s) links in the main post (text / parts[0]) — put every URL in a follow-up thread part (parts[1], parts[2], …). Only set allowLinksInMainPost=true if the user explicitly forces a link in the main post. The draft is saved locally and is NOT published until it is approved and then explicitly published.
Inputs: text (required), channel (required), poll, parts, +6 more.
create_retweet_draftCreate retweet draftA
Create a draft retweet or undo-retweet action. NOT executed until approved and retweet_post or undo_retweet is called. Pass the numeric post id from an X URL (e.g. .../status/1234567890).
Inputs: action (required), tweetId (required).
delete_published_draftDelete published draft from XA
Delete every live post id recorded on a draft (the root and any thread replies), then mark the local draft as deleted. Works whenever live ids are recorded — published drafts, partial "publishing" failures, or corrupt/legacy records. Own posts only.
Inputs: id (required).
edit_published_draftEdit published draft on XA
Edit the root post of a published draft via POST /2/tweets with edit_options.previous_post_id. Requires X Premium; edits are limited (~30 minutes / 5 edits) and each edit creates a new post id (stored locally). Re-attaches media (re-uploaded from mediaPaths) and quoteTweetId when present. Polls and community posts cannot be edited. Only the thread root is edited. Same link rule: no http(s) URL in the root unless allowLinksInMainPost is true (or was already set on the draft) because the user explicitly insisted.
Inputs: id (required), text (required), paidPartnership, allowLinksInMainPost.
get_dm_draftGet DM draftB
Fetch a single DM draft by id.
Inputs: id (required).
get_dm_rate_limitGet DM rate limit statusA
Show local DM send rate limits and current usage (hourly, daily, min interval between sends).
Inputs: no named parameters.
get_draftGet draft postB
Fetch a single draft by id.
Inputs: id (required).
get_retweet_draftGet retweet draftA
Fetch a single retweet/undo draft by id.
Inputs: id (required).
get_x_accountGet connected X accountA
Check whether this MCP server is connected to an X account and, if so, return the account's username and id.
Inputs: no named parameters.
get_x_account_summaryGet X account summaryA
Summarize your account using GET /2/tweets/analytics: calendar-day impressions and engagements (aligned with x.com account analytics), period totals, and top posts for the window. Read-only; no local DB.
Inputs: days, maxPosts, timezone, topPosts.
get_x_post_metricsGet X post metricsA
Fetch lifetime public metrics (impressions, likes, reposts, replies, quotes, bookmarks) for up to 100 post ids. Read-only.
Inputs: ids (required).
list_dm_conversation_eventsList DM conversation eventsA
Read recent DM events in a conversation by conversationId (works for group and 1:1 threads).
Inputs: conversationId (required), maxResults.
list_dm_draftsList DM draftsA
List locally stored DM drafts, optionally filtered by status.
Inputs: status.
list_dm_eventsList DM eventsA
Read recent DM events in a 1:1 conversation with a participant (newest first, up to 100). Requires dm.read scope.
Inputs: username, maxResults, participantId.
list_dm_inboxList DM inboxA
Read recent DM events across all conversations (inbox view). Requires dm.read scope.
Inputs: maxResults.
list_draftsList draft postsA
List locally stored drafts, optionally filtered by status.
Inputs: status.
list_retweet_draftsList retweet draftsA
List retweet/undo drafts, optionally filtered by status.
Inputs: status.
lookup_x_userLook up X userA
Resolve an X @handle to a user id (and whether they can receive DMs from you). Useful before create_dm_draft.
Inputs: username (required).
publish_draftPublish draft postA
Publish an approved draft to X via the X API v2. Supports threads, polls, media, quotes, community posts, and paid partnership. Fails if the draft has not been approved yet (unless approval is disabled in config). Returns the live post URL(s).
Inputs: id (required).
reject_dm_draftReject DM draftA
Mark a DM draft rejected. Also usable to reconcile a draft stuck in sending after a failed attempt.
Inputs: id (required).
reject_draftReject draft postA
Mark a draft as rejected. Rejected drafts cannot be published. Also usable to reconcile a draft stuck in "publishing" after a crashed publish_draft call once you have verified the post did NOT go out on X. If live post ids were already recorded (partial thread publish), call delete_published_draft instead.
Inputs: id (required).
reject_retweet_draftReject retweet draftA
Mark a retweet/undo draft rejected. Also usable to reconcile a draft stuck in executing after a failed attempt.
Inputs: id (required).
retweet_postRetweet postA
Retweet an approved draft to X immediately via POST /2/users/:id/retweets. Requires tweet.write scope.
Inputs: id (required).
send_dm_draftSend DM draftA
Send an approved DM draft via the X API. Enforces local rate limits (hourly, daily, min interval). Requires dm.read and dm.write scopes (re-auth after upgrade).
Inputs: id (required).
undo_retweetUndo retweetA
Undo an approved retweet draft on X immediately via DELETE /2/users/:id/retweets/:tweet_id. Requires tweet.write scope.
Inputs: id (required).
update_dm_draftUpdate DM draftA
Edit a DM draft. Pass null to clear optional fields. Resets approved drafts back to draft status.
Inputs: id (required), text, mediaPaths, recipientId, +5 more.
update_draftUpdate draft postA
Edit a draft's content (text, parts, poll, media, quote, community, paid partnership). Same link rule as create_draft: no http(s) URLs in the main post unless allowLinksInMainPost is true (only when the user explicitly insists). Pass null to clear an optional field. If the draft was already approved, this resets it back to "draft" status so it must be re-approved before publishing. To change a live post, use edit_published_draft.
Inputs: id (required), poll, text, parts, +6 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 33 tools
Each major resource (posts, retweets, DMs) has its own draft lifecycle tools, and the descriptions clearly indicate which resource they apply to. However, the three DM list tools and the two account analytics tools could confuse an agent selecting among them.
The set follows a consistent verb_noun snake_case pattern (create_, list_, get_, update_, approve_, reject_, publish_, etc.). Minor exceptions like be_trendy and analyze_x_posting_times deviate from the pattern but are still readable.
At 33 tools, this server has far more than typical MCP servers. While the tools cover multiple subdomains (posts, retweets, DMs, analytics), the repeated approve/reject/list/get patterns for each draft type inflate the count. Many tools could be consolidated without losing functionality.
The posting, retweet, and DM workflows are well covered, including approval, publishing, and rate-limit management. Minor gaps include the lack of an update_retweet_draft tool and the inability to delete a draft that was never published (only reject). Analytics are comprehensive.
Maintenance
Related MCP Connectors
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Hosted MCP server for AI agents to post to LinkedIn profiles and X and upload to YouTube.
Your agent posts, schedules, queues and threads posts on X, with a human approval queue.
FastMCP server for posting formatted content to X (Twitter) — Tollbooth-monetized, DPYC-native
Related MCP Servers
- AlicenseCqualityDmaintenanceA Model Context Protocol (MCP) server for managing social media posts, currently supporting X (formerly Twitter).36MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI models and applications to interact directly with Twitter/X, providing capabilities to create posts, reply to tweets, retrieve user data, and manage account actions.5 npm11MIT
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables AI agents to interact with Twitter without direct API access, supporting tweet operations, user interactions, and Grok AI integration.141,939 npm32MIT
- FlicenseAqualityDmaintenanceModel Context Protocol server that enables LLMs to interact with X.com (formerly Twitter) through OAuth 2.0 authentication, supporting major Post-related operations including reading, writing, searching, and managing posts, likes, retweets, and bookmarks.2149 npm8-