Skip to content

MCP server

pump.fun runs a hosted Model Context Protocol server at https://mcp.pump.fun/mcp (Streamable HTTP). It exposes the same read-only data as the API as 28 tools, authenticated with the same pf_live_ key. Each tool call is exactly one API request and counts against your key’s limits like any other call.

The server is stateless: every request is a POST /mcp with a JSON-RPC body and a JSON response. There are no sessions and no server-sent event streams; GET /mcp answers 405.

Pass your key as a bearer header. The MCP server only accepts Authorization: Bearer pf_live_...: the x-api-key alias is refused (400), and so is any request that carries a browser Origin header (403), including browser-hosted MCP inspectors.

Terminal window
claude mcp add --transport http pump https://mcp.pump.fun/mcp \
--header "Authorization: Bearer pf_live_..."

All tools are read-only (readOnlyHint: true) and map to one API route each. Page sizes are small by default and differ per tool (for example 5 rows for user search, 10 for callout lists, 20 for followers, 25 for trades); each tool’s input schema states its default and maximum, and a larger value is clamped to the maximum rather than rejected.

ToolScopeAPI routeReturns
get_user_profileprofiles.readGET /users/{id}Public profile of one pump.fun account by wallet address, pump.fun user id or username.
search_usersprofiles.readGET /users/search-v2Search pump.fun accounts by username or wallet fragment.
lookup_walletsprofiles.readPOST /users/batchResolve up to 50 wallet addresses to pump.fun profile rows in one call (a read served over POST).
resolve_identifiersprofiles.readGET /search/resolveClassify 1 to 5 identifiers in one hop.
get_followersgraph.readGET /following/v3/followers/{userId}One page of a user's followers as plain profile rows.
get_followinggraph.readGET /following/v3/following/{userId}One page of the accounts a user follows as plain profile rows.
check_followsgraph.readGET /following/single/{id}Whether one account follows another.
get_group_membersgraph.readGET /groups/{groupId}/membersA page of a squad's (group's) active members, owner first.
get_calloutcontent.readGET /callout/{calloutId}One callout by id with its author identity, thesis, market-cap-at-callout, current multiple, like/reply/quote counts and author updates.
list_user_calloutscontent.readGET /callout/list/{userId}A user's callout history with tail cohorts, newest first by default.
get_coin_calloutscontent.readGET /callout/coin/{coin}Top callouts on one coin with author identity.
get_callout_repliescontent.readGET /callout/{calloutId}/repliesOne tree level of replies on a callout, newest first.
get_callout_quotescontent.readGET /callout/{calloutId}/quotesQuote posts of a callout (both reply-shaped and callout-shaped quotes), newest first.
get_callout_tailerscontent.readGET /callout/{calloutId}/tailersThe wallets that tailed a callout, oldest tail first, with their profile and position outcome.
list_user_repliescontent.readGET /callout/replies/list/{userId}A user's callout replies and quotes with thread context, newest first.
get_recent_calloutscontent.readGET /home-feed/newThe global "new callouts" feed: every live-position-backed callout across all users, newest first, no ranking.
get_postscontent.readGET /postsPosts by id (1 to 25) with one-level embeds.
get_post_repliescontent.readGET /posts/{postId}/repliesDirect live replies to a post, newest first.
get_pnl_leaderboardleaderboards.readGET /pnl-leaderboardThe trader PnL leaderboard for a period with each entry's top positions.
get_squad_leaderboardleaderboards.readGET /pnl-leaderboard/groupsThe squad (group) PnL leaderboard for a period.
get_top_positionsleaderboards.readGET /pnl-leaderboard/positionsThe best single positions for a period (daily or weekly).
get_competitionsleaderboards.readGET /competitionsEvery trading competition in three buckets: upcoming, live (with the current top board) and past (the 50 latest, with winners).
get_creator_payouts_leaderboardleaderboards.readGET /payouts/leaderboardThe confirmed creator-payout leaderboard (top 500), all-time or a rolling 1d/1w/1m window, plus the earner count.
get_user_positionspositions.readGET /user-positions/{userId}A user's position (PnL plus callout) in each of up to 50 given mints.
get_user_tradespositions.readGET /user-trades/{id}One page of an account's trades, newest first, with the trader and coin identities behind the rows.
get_user_portfoliopositions.readGET /user-portfolio/{userId}A user's whole-portfolio positions (open, closed or all) with net PnL and a summary.
get_coin_holder_positionspositions.readGET /mint-positions/{mint}The users holding a position in a coin, with their position and callout thesis when present.
check_address_bannedmoderation.readGET /moderation/ban/address/{address}Whether a wallet address is banned on pump.fun: banned true/false, or null when unknown.

The table above is the complete tool list; the other routes of the API are reachable only through the API itself. Not exposed as tools: bulk user listing (GET /users), the username-exists check, follow suggestions, the video feed, the Mayhem top-traders board and the verified-profile, generated-media and badge batch reads. (POST /users/batch is exposed as lookup_wallets, capped at 50 addresses.) Narrower reads such as follower counts, searches within a follow list, likers and reposters, reply chains, competition detail and the portfolio summary have no tool either.

Every successful result has a content[0].text that starts with one fixed line explaining the untrusted wrapper, followed by the JSON, and a structuredContent with data and meta:

meta key Contents
fun.pump/untrustedFields Paths of user-generated strings; each is { "untrusted": true, "text": "..." } in place.
fun.pump/strippedFields Viewer-relative fields removed before shaping.
fun.pump/upstream The API’s X-Request-Id, X-RateLimit-*, Retry-After and, on a deprecated route, Sunset / Deprecation. Quote the request id in support requests.
fun.pump/page The page size actually sent, and clampedFrom when you asked for more.

Tool errors (isError: true) carry structuredContent.error, derived from the API’s error envelope. Every upstream failure also carries status (the API’s HTTP status), code (the API’s error code, when it sent one) and requestId.

Tool error API code
invalid_key API_KEY_REQUIRED, API_KEY_INVALID
key_revoked API_KEY_REVOKED, API_ORG_SUSPENDED
key_not_approved API_ORG_NOT_APPROVED
insufficient_scope API_SCOPE_FORBIDDEN (carries requiredScope)
rate_limited API_KEY_RATE_LIMITED (carries retryAfterSeconds and rateLimit.limit/remaining/reset/window)
upstream_unavailable any 503
upstream_error anything else; status: 404 is “no such record”, status: 400 is “the API rejected the input”
timeout the API did not answer within the server’s deadline (no API code)
disabled the tool is switched off on the server (no API code)

Callout text, replies, bios, usernames and group names are written by pump.fun users. The MCP server marks these fields as untrusted in every tool result (an explicit untrusted: true wrapper on the text, with the paths listed in meta["fun.pump/untrustedFields"]) so that an agent does not follow instructions hidden in them, and it never turns URLs found in user content into links or instructions. Viewer-relative fields (isFollowing, viewerFollows, mute state) are stripped: the server has no viewer.

The server has an RFC 9728 protected-resource metadata endpoint at /.well-known/oauth-protected-resource so an OAuth 2.1 flow can be added without changing the endpoint. Today the metadata is not advertised and the bearer key is the only credential.