Holder Launch
A private pump.fun token-launch integration for ChatGPT and Claude. The MCP server prepares drafts and verifies status. A separate browser page handles wallet signing or approval to spend from a configured sponsor wallet.
Status: implemented and locally tested; not deployed, installed in ChatGPT/Claude, approved for a public directory, or tested by minting a real token. Mainnet spending is off by default. This is a single-operator prototype, not a public multi-tenant launch service.
Wallet recommendation
Use the requester's own wallet as the default. They cover launch costs and sign the exact reviewed transaction. You do not need to hold their keys or subsidize arbitrary launches.
For your personal use or selected users, enable a separate sponsor wallet funded with a small amount of SOL. The sponsor signs on the server after approval on the review page. Daily spending and launch-count limits apply. Do not use your main wallet as the sponsor.
Both modes permanently set holderReward: true. There is no setting to redirect fees to the operator or to disable holder rewards. Cashback and mayhem mode are off. The application charges no additional fee and performs no initial buy.
Creator fees fund pump.fun holder rewards. This does not redirect network fees, protocol fees or other platform charges. Pump.fun controls eligible holders, payout timing and distribution expenses. The token supply is created using pump.fun's bonding-curve mechanism; it is not airdropped into a reward wallet. Holder rewards arise from later trading.
Official references: holder rewards, coin creation, fees.
Run on Windows
Requires Node.js 24 or newer.
npm.cmd ci --ignore-scripts
npm.cmd run setup
npm.cmd run build
npm.cmd start
Open http://localhost:3434. setup creates .env with a random operator password, without printing it. Read the password locally in that file to sign in. Never send it or a wallet private key to an assistant. Existing .env files are preserved.
The preview can create and review drafts. It cannot simulate or broadcast a mainnet launch until ENABLE_MAINNET_LAUNCH=true. No AI API key is required: the connected assistant invokes MCP tools.
Prepare real token metadata
Host your image and metadata JSON on IPFS or a durable public HTTPS service. The metadata URI must be at most 200 characters. A typical JSON file is:
{
"name": "Community Token",
"symbol": "COMM",
"description": "A community token with pump.fun holder rewards.",
"image": "ipfs://YOUR_IMAGE_CID",
"showName": true
}
Pass the JSON file URI, not the image URI, to the launch tool. This version accepts existing metadata; it does not upload or pin images. The server never fetches arbitrary metadata URLs. Make sure the URI is public, permanent, and matches the reviewed name and symbol.
Enable launch modes
Configure these values locally or in your host's secret manager:
| Setting | Purpose |
|---|---|
PUBLIC_BASE_URL | Public HTTPS origin used for review links and OAuth discovery |
SOLANA_RPC_URL | Reliable Solana mainnet RPC endpoint |
ENABLE_MAINNET_LAUNCH=true | Allows simulation, signing and broadcast after browser approval |
MAX_LAUNCH_COST_SOL | Maximum accepted simulation estimate, default 0.03 SOL |
SPONSOR_KEYPAIR_PATH | Optional path to a dedicated 64-byte Solana CLI keypair JSON file |
SPONSOR_DAILY_BUDGET_SOL | Sponsor reservation cap per UTC day, default 0.1 SOL |
SPONSOR_DAILY_LAUNCH_LIMIT | Sponsor launches per UTC day, default 5 |
OPERATOR_PASSWORD | At least 8 characters for spending-disabled use; 24 before enabling mainnet launches; generated by setup |
For user-wallet launches, connect Phantom or Solflare on the review page and ensure the public address matches the draft. The browser requests a signature; the server verifies the exact message and every required signature before broadcasting.
For sponsored launches, mount the keypair file outside the repository and set its absolute path. The server loads it without sending it to the model or browser. Review the token, simulate, then approve the sponsor payment on the review page. There is no unrestricted autonomous spending tool in MCP.
Network fees and rent are estimated by RPC simulation. The sponsor reserves the entire configured maximum for each submission, rather than trusting a smaller estimate. Reservations stay charged for the day after failure or uncertainty. A cap is an application control, not an on-chain spending vault; the operator must protect the sponsor key and avoid using it elsewhere.
Connect ChatGPT
For a temporary spending-disabled test with the already-installed Cloudflare CLI, run these in two terminals from this folder:
# Terminal 1: keep running; copy the HTTPS address it prints.
cloudflared tunnel --url http://127.0.0.1:3435 --no-autoupdate --protocol http2
# Terminal 2: replace the example origin with that generated HTTPS address.
npm.cmd run preview:chatgpt -- https://YOUR_TEMPORARY_HOST.trycloudflare.com
This preview uses a separate test database on port 3435 and always disables mainnet spending and sponsor-key loading, regardless of the regular .env settings. It uses the same OPERATOR_PASSWORD as the local service. Add the generated address followed by /mcp to ChatGPT using the steps below. The address changes when the tunnel restarts; the computer and both processes must remain running. Do not enable Cloudflare's interactive email gate for MCP: the assistant's requests cannot pass a browser-only login gate.
To verify the temporary endpoint without printing credentials or spending SOL:
node --env-file-if-exists=.env scripts/verify-connection.mjs https://YOUR_TEMPORARY_HOST.trycloudflare.com
The check exercises OAuth PKCE, discovers tools, calls get_launch_policy, and revokes its temporary access. It does not register the plugin in your ChatGPT account.
- Host the service at a public HTTPS origin with a persistent disk, or use a supported development tunnel. Set
PUBLIC_BASE_URLto that origin and restart. - Open ChatGPT Plugins → plus → Add custom MCP server. Account and workspace policies may affect availability.
- Enter the endpoint
https://YOUR_HOST/mcpand choose OAuth. The service supports discovery, dynamic client registration, authorization-code PKCE (S256), scoped access tokens, rotating refresh tokens and revocation. - Authenticate on this service's own page using the operator password within 30 minutes. If the authorization page expires, start a fresh connection from ChatGPT. The assistant receives permission to prepare drafts and read status, not to sign transactions.
- Enable the resulting private connection in a new conversation.
Example prompt:
Prepare a pump.fun token named Community Token, symbol COMM, with metadata at [my JSON URI]. Use my public wallet [address]. Enable holder rewards and give me the review link. Do not say it is launched until confirmation is verified.
Generate a portable plugin package after choosing the endpoint:
npm.cmd run package:plugin -- https://YOUR_HOST/mcp
The output is dist/holder-launch/plugin.json plus mcp.json. Without an argument it targets local development at http://localhost:3434/mcp; this is not a public connector endpoint. Packaging does not register, install, publish or approve a plugin.
Platform restriction: OpenAI's current public plugin guidelines list execution of crypto transfers and investment trades among prohibited activities. Keeping approval outside chat is an architectural separation, not a claim of an exemption or directory eligibility. Public distribution of this token-launch product requires platform review and may not be accepted. The current version is for private development and evaluation.
Sources: connect a custom MCP server, OAuth, plugin packaging, plugin guidelines.
Connect Claude
The same MCP endpoint can be used without rewriting the backend. In Claude's connector settings, add a custom remote connector, enter https://YOUR_HOST/mcp, use OAuth with Register automatically, and authenticate on the service's page. The server implements DCR, not CIMD client-identity fetching. Exact menus and access depend on the Claude plan and organization settings.
The request still ends with a separate browser review link. Wallet signing requires a browser with the relevant wallet extension. Remote connector requests originate from Claude's infrastructure, so a local-only server is not sufficient for this remote configuration.
The server accepts ChatGPT's connection-specific https://chatgpt.com/connector/oauth/{callback_id} callback shape and the fixed callbacks in OAUTH_REDIRECT_URIS. If another host uses a different callback, add that exact callback URI to OAUTH_REDIRECT_URIS. Do not replace the allowlist with an unrestricted wildcard.
Source: Claude custom connectors.
MCP tools
| Tool | Behavior |
|---|---|
get_launch_policy | Read available modes, fee behavior, mainnet switch and caps |
prepare_token_launch | Persist an idempotent draft and return its private review URL; no mint or spend |
get_launch_status | Check transaction status and verify the on-chain holder-reward flag and recipient PDA |
prepare_token_launch accepts requestKey, name, symbol, metadataUri, mode (user_wallet or sponsored), and a public wallet for user-wallet mode. Reuse the same requestKey when retrying the same request. A different payload with the same key is rejected.
State flow: draft → prepared → submitted → confirmed. Confirmation requires a successful Solana transaction plus a Pump-owned bonding curve with isHolderReward=true and its expected holder-reward creator PDA. Failed transactions become failed; failed reward verification becomes verification_failed. Neither is reported as success.
The signature is saved before broadcast. A network timeout leaves the launch pending with its saved signature, rather than triggering another token creation. If a submission remains unknown or a transaction expires, reconcile the saved signature before preparing a replacement. This prototype intentionally does not automatically rebuild or rebroadcast uncertain transactions.
Hosting and storage
SQLite stores drafts, OAuth registrations/tokens and budget reservations under data/. Use a single service with persistent storage and backups. Do not deploy this database on an ephemeral serverless filesystem or scale it across independent disks.
The included Dockerfile runs Node 24 as a non-root user. A deployment must mount /app/data, provide the environment variables, terminate HTTPS, and preserve the configured external Host header. The container listens on port 3434. A sponsor keypair is mounted read-only outside /app/data if that mode is used. Container execution has not been tested in this workspace.
All OAuth clients belong to the same operator. Browser spend authorization is separate from MCP authorization. A public multi-user product needs real user accounts, isolated launch ownership, requester-specific quotas, sponsor eligibility and a managed signing service before rollout.
Validation and release limits
npm.cmd run check
Ten automated tests cover SDK instruction decoding, real transaction construction with controlled RPC responses, mainnet/feature checks, validation, idempotency, signature and message tampering, sponsor budget limits, uncertain submission recovery, failed reward verification, and a complete OAuth/PKCE + MCP HTTP flow.
Browser QA exercised password login, draft creation, review, disabled spending, and desktop/mobile layout. A read-only live RPC check confirmed Solana mainnet and isHolderRewardEnabled=true on 2026-10-23. No real wallet signature, paid token launch, payout, hosted ChatGPT connection or hosted Claude connection was executed.
npm audit currently reports 14 findings in the Pump/Solana dependency tree (7 high, 7 moderate). The direct rate-limiter advisory was fixed. Remaining roots include bigint-buffer, toml, stream-json and uuid; npm's suggested forced fix downgrades Pump SDK to a version unsuitable for holder rewards. See SECURITY.md. Do not describe this build as audited or ready for a public funded service.