twitterapis-mcp

mcp
Security Audit
Fail
Health Warn
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Fail
  • rm -rf — Recursive force deletion command in scripts/__tests__/mcp-chain-reconcile-verdict-controls.sh
  • exec() — Shell command execution in scripts/__tests__/reconcile-mcp-publish-chain.test.mjs
  • process.env — Environment variable access in scripts/__tests__/reconcile-mcp-publish-chain.test.mjs
  • exec() — Shell command execution in scripts/gen-tools-endpoints.mjs
  • rm -rf — Recursive force deletion command in scripts/mcp-chain-reconcile.sh
  • process.env — Environment variable access in scripts/openapi-refresh.mjs
  • network request — Outbound network request in scripts/openapi-refresh.mjs
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Official MCP server for twitterapis.com: the Twitter/X API as native tools for Claude, Cursor, Windsurf, and any MCP client.

README.md

@twitterapis/mcp

npm version
npm downloads
license

@twitterapis/mcp is the official MCP server for TwitterAPIs, built for developers and AI agents that need Twitter / X data inside Claude, Cursor, Windsurf, VS Code or any MCP client, with no X developer account. Your agent can search tweets, read profiles, timelines, followers, threads and lists, and post, reply, like, retweet or follow from an X account you link. Most reads cost $0.0008 per call, about $0.04 per 1,000 tweets since a call returns about 20, and creating a tweet costs $0.0016. New accounts get $0.50 of free credit with no card. Every tool maps to one REST endpoint at api.twitterapis.com, and the server holds no state.

Install: npx -y @twitterapis/mcp@latest with TWITTERAPIS_KEY from https://www.twitterapis.com/signup

Hosted, sign in instead of pasting a key (Claude Code): claude mcp add --transport http twitterapis https://api.twitterapis.com/mcp

Website: https://www.twitterapis.com/mcp

Quick start

No install needed. Run with npx. You need one thing: an API key (free $0.50 in credits, no card required): twitterapis.com/signup.

Setup

Claude Desktop

Edit claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "twitterapis": {
      "command": "npx",
      "args": ["-y", "@twitterapis/mcp@latest"],
      "env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
    }
  }
}

Restart Claude Desktop. The twitter_* tools appear in the tool picker.

Cursor

~/.cursor/mcp.json (or Settings → MCP → Add New Server):

{
  "mcpServers": {
    "twitterapis": {
      "command": "npx",
      "args": ["-y", "@twitterapis/mcp@latest"],
      "env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
    }
  }
}

Windsurf

~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "twitterapis": {
      "command": "npx",
      "args": ["-y", "@twitterapis/mcp@latest"],
      "env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
    }
  }
}

VS Code (Copilot / agent mode)

.vscode/mcp.json in your workspace, or the user-level MCP settings:

{
  "servers": {
    "twitterapis": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@twitterapis/mcp@latest"],
      "env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
    }
  }
}

Configuration

Env var Required Default Purpose
TWITTERAPIS_KEY Yes (none) API key from dashboard
TWITTERAPIS_BASE_URL No https://api.twitterapis.com Override the API host
TWITTERAPIS_TIMEOUT_MS No 30000 Per-request timeout in milliseconds

Tools

116 tools: 70 reads and 46 write actions. Most user endpoints accept username (handle without @) or user_id (twitter_user_likes and twitter_user_tweets_complete require user_id); tweet endpoints accept id or url; paginated endpoints return a cursor you pass back to get the next page. Every data read (except twitter_audience_summary, which always returns its full summary) also takes fields (comma-separated dotted paths to keep, e.g. id,text,author.username; pagination and envelope keys always survive) and compact ("1" for a built-in preset of ids, text, counts and author basics), so a model paying per token can trim a page to what it will read. Four of the reads are free account lookups (twitter_account_me, twitter_account_payments, twitter_feedback_get, twitter_feedback_list); the 14 monitoring tools and twitter_feedback_send are also free (account administration, not metered reads).

Public reads (search, profiles, tweets, followers, likes) work with just your API key. The account-only reads (bookmarks, DMs, home timeline, followers-you-know) and most write actions act AS an authenticated X account, so they need a session linked to your key first (returns HTTP 409 until then). Link a session either by registering your x.com cookies (twitter_customer_session) or by logging in with a username/password (twitter_user_login). Alternatively, pass per-call inline credentials on any of those tools (auth_token + ct0, with optional proxy_url / user_agent) to act AS that account for a single call without pre-registering a session, so one API key can act as many accounts. For write actions, set proxy_url to a residential proxy, since X soft-blocks writes that egress from datacenter IPs. Each write tool is annotated readOnlyHint: false; reversing actions (delete, unfollow, unlike, unretweet, unbookmark, monitor/webhook delete) are annotated destructiveHint: true so MCP clients can prompt before running them. The monitoring and feedback tools (see below) are the exception: they administer your twitterapis.com account, not an X session, so they need only your API key, no linked session and no inline credentials.

Reads

Tool What it does
twitter_advanced_search Search tweets with X operators (from:, min_faves:, since:, filter:links, etc.)
twitter_user_search Find user accounts by name or keyword
twitter_user_info Full profile by handle (bio, counts, verification, location)
twitter_user_info_by_id Full profile by numeric user id
twitter_user_status Is an account alive, suspended, or deleted
twitter_user_about A user's structured About object (category, professional/business labels, verification + identity-verification flags, joined date, and X's 'About this account' transparency panel)
twitter_user_about_batch The same About object for up to 100 accounts in one call (usernames or user_ids), billed per account answered; for vetting a list by country or account history
twitter_audience_summary Who an audience is: a country histogram and likely-bot share over a sample of up to 100 followers or retweeters
twitter_user_affiliates Accounts affiliated with an organization profile
twitter_check_follow_relationship Follow relationship between two accounts, by id or username (who follows whom)
twitter_check_follow_relationship_batch One account against up to 100 others in one call, either direction (which of these accounts follow the brand)
twitter_user_tweets A user's recent original tweets (replies excluded)
twitter_user_tweets_and_replies A user's full timeline (tweets + replies)
twitter_user_tweets_complete A large batch of a user's tweet history per call (see paging note)
twitter_user_media Images and videos a user has posted
twitter_user_mentions Recent public tweets mentioning a user
twitter_user_likes Tweets a user has liked (public Likes tab)
twitter_user_followers Accounts that follow a user
twitter_user_following Accounts a user follows
twitter_user_followers_v2 Followers with the v2 response shape (richer fields, deeper cursoring)
twitter_user_following_v2 Following with the v2 response shape (richer fields, deeper cursoring)
twitter_user_verified_followers A user's verified followers only
twitter_followers_you_know Followers of a target that your authenticated account also follows
twitter_tweet_detail Single tweet: text, author, metrics, media, quoted/reply context
twitter_tweet_replies Replies to a tweet
twitter_tweet_replies_complete Every reply under a tweet in one call, with an is_complete flag and a resume cursor
twitter_tweet_thread Full author thread (connected tweet chain by same author), read forward from the tweet you pass, so pass the thread's first tweet
twitter_tweet_retweeters Accounts that retweeted a tweet
twitter_tweet_quotes Tweets that quote a tweet, with their text. Search-backed, so count is what search returned, not the tweet's true quote_count
twitter_list_members Members of a Twitter/X List
twitter_list_followers Accounts that follow a public List (a different set from its members)
twitter_list_tweets Posts by a List's members, search-backed: filterable by since / until date, include_replies, and product (Latest / Top), no retweets
twitter_list_timeline A List's native X feed: retweets and X's own ordering included, no filters, paging only
twitter_home_timeline Your authenticated account's Home timeline (session)
twitter_bookmarks Your authenticated account's bookmarks (session)
twitter_blocking Accounts your authenticated account has blocked (your own list only) (session)
twitter_muting Accounts your authenticated account has muted (your own list only) (session)
twitter_bookmark_search Full-text search within your bookmarks (session)
twitter_bookmark_folders Your authenticated account's bookmark folders (session)
twitter_bookmark_folder_timeline Tweets inside one of your bookmark folders, by folder_id (session)
twitter_dm_list Your DM conversations (inbox), read-only (session)
twitter_dm_conversation Messages in one DM conversation, read-only; pass the previous page's min_entry_id as max_id to page back (session)
twitter_spaces_info Metadata and participant roster for one X Space, live or ended (by Space id)
twitter_community_search Find X Communities by keyword; the discovery step that produces the numeric id the rest of the community family needs
twitter_community_info One X Community by numeric id: name, counts, join policy, rules, topic, banners, admin
twitter_community_about A community's moderators and a member preview, each returned as a full user profile, not the reduced row _members/_moderators return
twitter_community_members A community's member roster, each row carrying that member's Admin / Moderator / Member role
twitter_community_moderators A community's moderators and admins, from its own upstream operation (not a filter over the roster)
twitter_community_tweets A community's post timeline, with the pinned post returned as its own pinned field
twitter_community_memberships The inverse lookup: every community a given numeric user_id belongs to
twitter_creator_commentary_video Who posts native video about a topic: one search page grouped by author and ranked by video posts, then median and total views, with up to three top post ids per creator
twitter_grok_chat Ask X's own Grok, grounded in live X data, and get the answer plus the sources it cited
twitter_grok_config Whether the authenticated account can use Grok, and which models it may pick
twitter_trends Current top trends for a location (by country or woeid) an X Explore tab (by category), or only the trends X labels Business and finance (category=business_and_finance)
twitter_trends_locations Every location X has trends for, each with its WOEID
twitter_account_me Your twitterapis.com account: credits, usage, email (free)
twitter_account_payments Your twitterapis.com payment history (free)
twitter_media_status Processing state of an uploaded media_id; poll until succeeded before attaching video or GIF (session)
twitter_article_get Read a published article's full content via its announcement tweet id/url (public, no session)
twitter_article_list List your own articles, filtered by lifecycle (draft or published) (session)

Write actions (require a linked X session)

Tool What it does
twitter_create_tweet Post a tweet; set reply_to to reply or quote to quote-tweet
twitter_delete_tweet Delete one of your tweets (irreversible)
twitter_favorite_tweet / twitter_unfavorite_tweet Like / unlike a tweet
twitter_retweet / twitter_unretweet Retweet / undo retweet
twitter_bookmark_tweet / twitter_unbookmark_tweet Bookmark / remove bookmark
twitter_follow_user / twitter_unfollow_user Follow / unfollow a user by user_id or username (exactly one)
twitter_dm_send Send a Direct Message to a user by their numeric recipient_id
twitter_list_create Create a Twitter/X List owned by your session (name, optional description / is_private)
twitter_list_add_member / twitter_list_remove_member Add / remove one account on a List you own; member_count comes back as proof the write landed
twitter_community_join / twitter_community_leave Join / leave an X Community by numeric community_id. A community that needs moderator approval answers 409 join_requires_approval and nothing is submitted; refusals are not billed
twitter_media_upload Upload a base64 image, returns a media_id for twitter_create_tweet
twitter_update_profile Change your own name, bio, location or link. A PARTIAL update: omitted fields keep their values, an empty string clears one
twitter_update_avatar Replace your own profile picture. Takes base64 image bytes in image, not a URL and not a media_id. No undo, and X keeps no history
twitter_update_banner Replace your own header image. Takes base64 image bytes in banner, not a URL and not a media_id. No undo, and X keeps no history

Drafts and scheduled posts (require a linked X session)

A draft is private and never posts. A scheduled post will publish publicly at its execute_at unless you cancel it first. Both lists read only your own account.

Tool What it does
twitter_draft_create Save a private draft on your account; nothing is posted
twitter_draft_edit Replace one draft's contents by id; the fields you send become the draft
twitter_draft_delete Delete a draft by id; it was never public, so nothing is retracted
twitter_draft_list List your drafts, each with text and thread_truncated
twitter_scheduled_create Schedule a post for a future execute_at in epoch seconds, not milliseconds
twitter_scheduled_delete Cancel a pending scheduled post before it sends
twitter_scheduled_list List your pending queue; execute_at comes back in epoch seconds

Both list tools can return partial: true, which means X's answer was read but not fully understood. It is not the same as an empty list: on a clean read the flag is absent entirely, so an empty array with no partial means you genuinely have nothing queued or drafted.

Articles (X's long-form "Notes" feature; writes require a linked X session)

Tool What it does
twitter_article_create Start a new draft article, returns its id
twitter_article_update_title Set a draft or published article's title
twitter_article_update_cover_media Attach an already-uploaded image as an article's cover (media_id from twitter_media_upload)
twitter_article_update_content Replace a draft or published article's body (Draft.js content_state you build)
twitter_article_publish Publish a draft, posting a real public announcement tweet (not fully reversible)
twitter_article_unpublish Revert a published article to draft (leaves the announcement tweet up)
twitter_article_delete Delete an article (draft: hard delete; published: unpublish + delete the announcement tweet), irreversible

See also twitter_article_get and twitter_article_list above.

Monitoring (webhook delivery of new posts; free, not metered)

Watch an X account for new posts and get them pushed to your own HTTPS endpoint, HMAC-signed, instead of polling. Register a webhook first, then create a monitor; every new post from a watched handle is delivered to every active webhook on your account (or a restricted subset via webhook_ids). Monitor/webhook CRUD is account administration, not a metered Twitter read, so every tool below is free.

Tool What it does
twitter_monitor_create Start watching an X account (handle) for new posts
twitter_monitor_list List every monitor on your account
twitter_monitor_update Pause/resume a monitor or change its webhook_ids restriction
twitter_monitor_delete Stop and remove a monitor (irreversible)
twitter_monitor_health One monitor's status, degradation flag, poll interval, cursor position
twitter_monitor_account_health Account-wide rollup: service status, active/paused monitor counts, 24h delivery outcome counts, one call
twitter_monitor_deliveries Recent delivery events across every monitor, with detection + delivery latency
twitter_x_user_stream_add_user Compat drop-in for twitter_monitor_create using an x_user_stream-shaped envelope
twitter_x_user_stream_remove_user Compat drop-in for twitter_monitor_delete using an x_user_stream-shaped envelope
twitter_x_user_stream_list_users Compat drop-in for twitter_monitor_list using an x_user_stream-shaped envelope
twitter_monitor_webhook_create Register an HTTPS delivery URL; returns the HMAC signing secret once
twitter_monitor_webhook_list List every webhook registered on your account
twitter_monitor_webhook_delete Soft-delete a webhook by id (irreversible from the caller's side)
twitter_monitor_webhook_test Send one signed test event to a webhook right now, synchronously
twitter_monitor_webhook_redrive Replay deliveries that dead-lettered while your endpoint was down, oldest first

Feedback (report a bug or a gap to the twitterapis.com team without leaving your session; free)

Modelled on Claude Code's own feedback tool. When a call fails in a way that is not your key, credits, session or a rate limit, when you ask for something no tool covers, or when a result is plainly wrong, the model can draft a report into a local queue (~/.twitterapis/feedback-queue.json, at most 10 drafts, override the directory with TWITTERAPIS_FEEDBACK_DIR). Nothing is sent until you ask to review the queue and name the drafts to send. Each report carries the last failing call's endpoint, status and request id, your client name and this package's version, so the team can act on it without a follow-up. Use twitter_feedback_get with the returned server id to see whether it was triaged, shipped or declined.

Tool What it does
twitter_feedback_send action: "draft" (default) queues a report locally and sends nothing; "list" shows the queue; "send" posts only the drafts you name to POST /feedback; "discard" drops them
twitter_feedback_get Read a sent report's status (new, triaged, shipped, declined) and the team's response
twitter_feedback_list List the reports this account has already sent, newest first, with status/type filters and a cursor to page

Session setup

Link an X account to your key once, so the account-only reads and write actions act as it (or pass per-call auth_token/ct0 instead).

Tool What it does
twitter_customer_session Register your x.com session cookies (auth_token + ct0) against your key
twitter_customer_session_status Read back the registered session without changing it: resolved account, live/dead status, timestamps, and which egress tier a write would use. Never returns the cookies. Free
twitter_customer_session_delete Revoke that stored session, deleting your auth_token + ct0 from the service. Idempotent and free
twitter_user_login Log in with username + password (+ totp_secret for 2FA); stores the session against your key. Returns a confirmation, never the cookies

Playbooks and provenance

Besides tools, the server exposes MCP resources. A client lists them with resources/list and fetches one with resources/read, so nothing here costs context until it is asked for, and none of it costs credits.

Playbooks

Short recipes an agent runs with the tools above.

URI What it covers
playbook://launch-day-monitor Watching a launch in near real time: monitor and webhook setup before, true counts and amplifiers during, amplifier profiles after
playbook://competitor-follower-outreach Turning another account's followers into a qualified list, then contacting them from your linked account
playbook://account-audit A reproducible read of one account: identity, output mix, reach, engagement, and which numbers share an observation window
playbook://link-x-account The linking sequence: read the current state, pick a route, the login's timing ceiling, the outcomes that need attention on x.com, and what a session unlocks
playbook://residential-egress Outbound address control: the three places a proxy URL attaches, what a URL has to be, and how to read back which source is in force

Provenance

provenance://tool/{tool_name} returns, as JSON, where a row you already hold came from: the REST endpoint and method behind it, read or write, whether the call ran as your linked X account or on the API key alone, the per-call price, and the docs URL.

provenance://tool/twitter_advanced_search
{
  "tool": "twitter_advanced_search",
  "endpoint": "GET /twitter/tweet/advanced_search",
  "kind": "read",
  "destructive": false,
  "served_by": "the API key alone (a public read, no linked account)",
  "cost": "$0.0008 per call",
  "docs": "https://docs.twitterapis.com/docs/reference/search/tweet-advanced-search"
}

Row-level upstream provenance (when the service read it from X, whether an upstream cache answered, which account read it) is not in any response this package receives, so it is absent rather than guessed.

Blocked calls answer with the next steps

A call blocked on a missing key, a rejected key, an empty balance or a missing X session returns a structured payload (in structuredContent and appended to the text) carrying an ordered steps list, what resolving it unlocks, and, for the session case, the playbook URI and the outcomes a retry cannot fix.

Usage examples

Search for trending AI tweets

"Find the most popular tweets about AI agents posted this week"

The agent calls twitter_advanced_search with:

query: "AI agents min_faves:200 since:2024-01-01"
product: "Top"
count: 20

Pull a user's recent posts

"Get the last 10 tweets from @sama"

The agent calls twitter_user_tweets with:

username: "sama"
count: 10

Read a full thread

"Get the full thread for this tweet: https://x.com/karpathy/status/1849....."

The agent calls twitter_tweet_thread with:

url: "https://x.com/karpathy/status/1849....."

The thread is read forward from the tweet you pass, so the URL should be the thread's first tweet. If you hold a later tweet, read its conversation_id with twitter_tweet_detail and pass that id instead; a later tweet returns only the tail.

Paginate through followers

"List the first 100 followers of @openai, then the next 100"

First call, twitter_user_followers: { username: "openai", count: 100 }
Second call, pass back the cursor from the first response: { username: "openai", count: 100, cursor: "<cursor from response>" }

Paging twitter_user_tweets_complete

"Pull @elonmusk's whole tweet history"

twitter_user_tweets_complete auto-paginates server-side and returns a large batch per call, but it does not guarantee the full history in one call. Read the result like this:

  • next_cursor is the completion signal, not count. Non-null means the history is truncated and more remains. Null means it is genuinely exhausted. The response also carries has_more, the same signal as a boolean.
  • max is a minimum target, not a cap. Pages arrive in whole chunks, so a response may hold up to one page (<=100) more than requested. Live behaviour: max=10 returned 20, max=50 returned 60, max=150 returned 161, and omitting max (server default 200) returned 201. Never assume count === max.
  • Each call also has a server-side wall-clock budget, so a response can be truncated even when it returned fewer tweets than requested. That is the second reason count cannot tell you whether you are done.
  • Billing is a flat $0.0024 per call, regardless of how many tweets come back, so fewer large calls cost less than many small ones.

To resume, pass the next_cursor straight back in as cursor and repeat until it comes back null:

First call, twitter_user_tweets_complete: { user_id: "44196397", max: 800 }
Then, while next_cursor is non-null: { user_id: "44196397", max: 800, cursor: "<next_cursor from previous response>" }

Monitor brand mentions

"Show me recent tweets mentioning @twitterapis"

The agent calls twitter_user_mentions with:

username: "twitterapis"
count: 50

Troubleshooting

HTTP 401 (invalid or missing API key) Check that TWITTERAPIS_KEY is set correctly in your MCP client config and matches the key shown in your dashboard.

HTTP 402 (insufficient credits) Top up at twitterapis.com/dashboard. Your first $0.50 is free at signup.

HTTP 403 (access forbidden) The account or tweet may be private/protected, or your plan does not include this endpoint.

HTTP 404 (not found) The user, tweet, or list may have been deleted, suspended, or the id/handle is wrong.

HTTP 429 (rate limited) Wait a few seconds and retry. If you hit this frequently, add "TWITTERAPIS_TIMEOUT_MS": "60000" to your env config and space out bulk requests.

Request failed: timed out after 30000ms The default timeout is 30 s. For large paginated fetches set TWITTERAPIS_TIMEOUT_MS to a higher value (e.g. 60000).

Tools do not appear in Claude / Cursor Ensure npx is on your PATH and Node.js 18+ is installed (node --version). Check MCP client logs for startup errors.

Pricing

Calls are billed to your twitterapis.com account, at the price each tool's description states. The standard rate is $0.0008 per call: nearly every read (search, profiles, timelines, followers, likes, lists, bookmarks, articles) and the simple write actions (like, retweet, bookmark, follow, list membership and their undos, delete). At that rate 1,000 tweets cost about $0.04, since a call returns about 20 tweets. The account, feedback and monitoring tools are free, and so is registering, checking or revoking a session from your own cookies. Every tool priced differently from the standard rate:

Price Tools
$0.0008 per billed item twitter_user_about_batch (per account answered, so one 100-account call costs up to $0.08), twitter_check_follow_relationship_batch (per pair answered), twitter_audience_summary (per sample page plus per sampled account answered)
$0.0016 per call Posting: twitter_create_tweet, twitter_list_create. DMs: twitter_dm_send, twitter_dm_list, twitter_dm_conversation. Profile: twitter_update_profile, twitter_update_avatar, twitter_update_banner. Drafts and scheduled posts, the two list reads included: twitter_draft_create, twitter_draft_edit, twitter_draft_list, twitter_scheduled_create, twitter_scheduled_list. Article edits: twitter_article_create, twitter_article_update_title, twitter_article_update_cover_media, twitter_article_update_content, twitter_article_publish, twitter_article_unpublish
$0.0024 per call twitter_user_tweets_complete, twitter_tweet_replies_complete (flat per call, however many tweets or pages come back)
$0.004 per call twitter_tweet_thread, twitter_grok_chat
$0.01 per call twitter_user_login (logging in with a username and password)

Deleting a draft or a scheduled post, and reading, listing or deleting an article, stay at the standard $0.0008 per call. Your first $0.50 is free. See twitterapis.com/pricing.

Links

FAQ

Do I need an X developer account? No. One TwitterAPIs key covers every tool.

What do 1,000 tweets cost? About $0.04. Standard reads bill $0.0008 per call and a call returns about 20 tweets.

Can my agent post or send DMs? Yes, from an X account you link to your key. Undo actions such as delete and unfollow are marked destructive, so your client can ask before running them.

Is it read-only? No. 70 read tools work with just your API key; 46 write actions (post, save or schedule a post, like, retweet, follow, DM, media upload, profile name/bio/avatar/banner updates, List create/add member/remove member, community join/leave, article create/edit/publish/delete, monitor/webhook create/update/delete, feedback send) act as a linked X account or per-call inline credentials, except monitor/webhook CRUD and feedback, which are account administration and need only your API key.

Which clients are supported? Claude Desktop, Cursor, Windsurf, and VS Code (Copilot agent mode), or any Model Context Protocol client.

How is it billed? Per request. New keys start with $0.50 in free credits, no card required. See pricing.

Does it store my key or data? No. The server holds no state and forwards your API key on each call.

Maintainers

src/tools.js is generated. Do not edit it. The catalog is built at build time from two committed inputs:

  • test/openapi.snapshot.json, a vendored copy of the published OpenAPI spec, which supplies the structure: which endpoints exist, which parameters each accepts, whether a parameter is required, and its type.
  • scripts/tools.overrides.mjs, hand-authored, which supplies everything the spec cannot express: the tool and argument descriptions a model reads to decide how to call a tool, the cross-field rules ("provide exactly one of username or user_id"), the per-call credential arguments that travel as x-* headers, and the write / destructive / JSON-body flags. Each description's Cost: sentence and Docs: link are derived from the spec.

Descriptions state product facts only: what a tool returns, takes and costs. They never name another tool and never instruct the model; guidance on which tool to use when, how one tool's output feeds another, and when to draft feedback lives in the server instructions (INSTRUCTIONS in src/server.js). test/description-compliance.mjs enforces this on every tool and parameter description a client lists, in both the stdio and hosted modes.

The spec is vendored on purpose. Nothing is fetched at install time or at server boot, so the published package is a fixed artifact rather than one that depends on a hostname still answering.

npm run openapi:refresh   # re-vendor the spec, prints the route diff
npm run build             # regenerate src/tools.js
npm test                  # gates, incl. "src/tools.js matches the generator"

npm test fails if src/tools.js was hand-edited or left stale, if the catalog and the live spec disagree, if the tool list and this README disagree, or if a description carries a model instruction, another tool's name, or hidden text (npm run check:description-compliance).

License

MIT

Reviews (0)

No results found