> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inkyswap.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> Launch InkyPump V2 tokens from Claude Code, Codex, or any other MCP-aware client

InkyPump ships a [Model Context Protocol](https://modelcontextprotocol.io) server so that an LLM client (Claude Code, Codex CLI, Cursor, etc.) can create tokens, preview launch economics, and read live launch state through structured tools, without leaving the editor.

<Note>
  The MCP signs `createLaunch` transactions with a hot wallet whose private key the operator supplies. Always load a **burner** wallet with only enough ETH for prebuys + gas. Writes are **off by default**. You must opt in explicitly per environment.
</Note>

## Tools

| Tool              | Purpose                                                                                                                    |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `launch_token`    | Broadcasts `createLaunch` / `createLaunchWithReferral` on the InkyPump V2 hook. Requires explicit confirm + writes opt-in. |
| `preview_launch`  | Dry-run: resolves on-chain params and reports expected creator-fee economics. No transaction.                              |
| `wallet_info`     | Returns the MCP signer address and its current Ink ETH balance.                                                            |
| `recent_launches` | Fetches recent V2 launches. Returns a sanitized, allowlisted field set.                                                    |
| `launch_status`   | Reads `getLaunchState(launchId)` and reports funding progress.                                                             |

## Install

The MCP is published to npm as [`@inkyswap/pump-mcp`](https://www.npmjs.com/package/@inkyswap/pump-mcp); source lives at [InkySwap/pump-mcp](https://github.com/InkySwap/pump-mcp). `npx` handles the install and update for you. No clone or build required.

<Steps>
  <Step title="Stash the burner key in a 0600 file" icon="key">
    ```bash theme={null}
    umask 077
    printf '%s' '0xYOUR_BURNER_PRIVATE_KEY' > ~/.inkypump-mcp-key
    chmod 600 ~/.inkypump-mcp-key
    ```

    The MCP refuses to read this file if it's group- or world-readable.
  </Step>

  <Step title="Register the MCP with Claude Code" icon="plug">
    ```bash theme={null}
    claude mcp add inkypump \
      -e INKYPUMP_MCP_PRIVATE_KEY_FILE=$HOME/.inkypump-mcp-key \
      -e INKYPUMP_MCP_ENABLE_WRITES=true \
      -s user \
      -- npx -y @inkyswap/pump-mcp
    ```

    For **Codex CLI**, drop the equivalent block into `~/.codex/config.toml`:

    ```toml theme={null}
    [mcp_servers.inkypump]
    command = "npx"
    args = ["-y", "@inkyswap/pump-mcp"]

    [mcp_servers.inkypump.env]
    INKYPUMP_MCP_PRIVATE_KEY_FILE = "/Users/you/.inkypump-mcp-key"
    INKYPUMP_MCP_ENABLE_WRITES = "true"
    ```
  </Step>
</Steps>

<Tip>
  Prefer to run from source? Clone [InkySwap/pump-mcp](https://github.com/InkySwap/pump-mcp) and run `bun install --frozen-lockfile && bun run build && node dist/index.js`.
</Tip>

## Environment

| Variable                        | Default                          | Required               | Purpose                                                                                                        |
| ------------------------------- | -------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| `INKYPUMP_MCP_PRIVATE_KEY_FILE` | n/a                              | one of these two       | Path to a `chmod 600` file containing the hex private key. **Preferred.** POSIX mode check skipped on Windows. |
| `INKYPUMP_MCP_PRIVATE_KEY`      | n/a                              | one of these two       | Raw hex private key. Stored plaintext in your MCP config, only use if that config is encrypted.                |
| `INKYPUMP_MCP_ENABLE_WRITES`    | `false`                          | yes for `launch_token` | Must be `true` / `1` / `yes` to permit broadcasting transactions.                                              |
| `INKYPUMP_MCP_MAX_PREBUY_ETH`   | `0.1`                            | no                     | Per-call cap on prebuy ETH. Operator hard limit.                                                               |
| `INKYPUMP_MCP_MAX_RAISE_ETH`    | `5`                              | no                     | Per-call cap on `targetRaiseEth`. Defaults to the contract max.                                                |
| `INKYPUMP_MCP_MAX_GAS_GWEI`     | `100`                            | no                     | Per-call cap on `maxFeePerGas` in gwei. Defends against an RPC reporting inflated fees.                        |
| `INKYPUMP_MCP_RPC_URL`          | `https://rpc-gel.inkonchain.com` | no                     | Override the Ink RPC endpoint. Rejected if it contains userinfo, query, or fragment.                           |
| `INKYPUMP_BASE_URL`             | `https://inkypump.com`           | no                     | Origin used to build trade URLs and call `/api/tokens/recent-v2`. Must be an origin (no path).                 |

## Safety model

The MCP signs on-chain transactions, so it's treated as a hot-wallet boundary. Defense in depth, in order:

<CardGroup cols={2}>
  <Card title="Writes opt-in" icon="lock">
    `launch_token` refuses unless `INKYPUMP_MCP_ENABLE_WRITES=true`. The read-only tools always work.
  </Card>

  <Card title="Explicit confirm" icon="circle-check">
    Every `launch_token` call requires `confirm: "YES"`. The LLM must include it deliberately. Hallucinated calls fail closed.
  </Card>

  <Card title="Operator spend caps" icon="shield">
    `MAX_PREBUY_ETH`, `MAX_RAISE_ETH`, and `MAX_GAS_GWEI` clamp every write regardless of what the LLM or the RPC passes.
  </Card>

  <Card title="Chain assertion" icon="link">
    Every write checks the RPC reports chain ID 57073 before signing. Defends against a hijacked or misconfigured `INKYPUMP_MCP_RPC_URL`.
  </Card>

  <Card title="Nonce + receipt timeout" icon="clock">
    Every write pins the nonce via `getTransactionCount({ blockTag: "pending" })` and times out the receipt wait at 120s with no retries.
  </Card>

  <Card title="Error sanitizing" icon="eraser">
    Tool errors are stripped of private keys, signed-tx payloads, URL credentials, and RPC API keys in the path before reaching the model.
  </Card>

  <Card title="Untrusted input handling" icon="circle-exclamation">
    `recent_launches` allowlists fields, clips strings, re-validates image URLs, and warns the model the data is creator-controlled.
  </Card>

  <Card title="URL validation" icon="link-slash">
    Image and social URLs must be `https://`, must not use reserved TLDs (`.local`, `.internal`, `.localhost`, `.test`, `.example`, `.invalid`), and must resolve via DNS to a public IP (covers RFC1918, loopback, link-local, CGNAT, IPv6 unique-local, hex-form IPv4-mapped).
  </Card>
</CardGroup>

## Example session

```text theme={null}
> wallet_info
{ "address": "0x…", "balanceEth": "0.4", "chainId": 57073 }

> preview_launch {
    "name": "Anita",
    "ticker": "ANITA",
    "description": "Test launch",
    "imageUrl": "https://example.com/anita.png",
    "targetRaiseEth": 3,
    "curveGainMultiplier": 6,
    "creatorFeeSplitBps": 5000
  }
{
  "feeMath": {
    "creatorEarningsAsPctOfVolume": 0.495,
    "protocolFeePct": 1,
    "variableFeePctOfAfterProtocol": 1
  },
  ...
}

> launch_token { …same args plus "confirm": "YES" }
{
  "transactionHash": "0x…",
  "tokenAddress": "0x…",
  "tradeUrl": "https://inkypump.com/trade/0x…",
  "explorerUrl": "https://explorer.inkonchain.com/tx/0x…"
}
```

## `launch_token` parameters

<ParamField path="name" type="string" required>Token display name (1-48 chars).</ParamField>
<ParamField path="ticker" type="string" required>Ticker symbol without `$` (1-12 chars).</ParamField>
<ParamField path="description" type="string" required>Short pitch (1-500 chars).</ParamField>
<ParamField path="imageUrl" type="https URL" required>Public square image. Rejected if the URL is non-https, contains credentials, uses a reserved TLD, or resolves to a private IP.</ParamField>
<ParamField path="targetRaiseEth" type="number" required>1-5 ETH. Bounded further by `INKYPUMP_MCP_MAX_RAISE_ETH`.</ParamField>
<ParamField path="confirm" type="&#x22;YES&#x22;" required>Must be the literal string `"YES"`. This is the final-write gate.</ParamField>
<ParamField path="telegram" type="https URL">Optional. Empty string disables.</ParamField>
<ParamField path="twitter" type="https URL">Optional. Empty string disables.</ParamField>
<ParamField path="website" type="https URL">Optional. Empty string disables.</ParamField>
<ParamField path="curveGainMultiplier" type="number" default="6">End/start price ratio. 1 = flat, 21 = contract max.</ParamField>
<ParamField path="creatorFeeSplitBps" type="integer" default="5000">Creator share of variable fee in bps. 5000 = 50/50 with burn, 10000 = all creator.</ParamField>
<ParamField path="antiSnipeSeconds" type="integer" default="0">Anti-snipe duration. 0 disables.</ParamField>
<ParamField path="startTimestamp" type="integer" default="0">Unix start timestamp. 0 = launch immediately.</ParamField>
<ParamField path="prebuyEth" type="number" default="0">Creator prebuy. Must be ≤ `targetRaiseEth` and ≤ `INKYPUMP_MCP_MAX_PREBUY_ETH`.</ParamField>
<ParamField path="referralCode" type="string">Optional. Alphanumeric (with `-` / `_`), 1-64 chars.</ParamField>

## Contract surface

`launch_token` calls these functions on the `InkyPumpHook` contract:

* `createLaunch(CreateLaunchParams)` when `referralCode` is empty
* `createLaunchWithReferral(CreateLaunchParams, string)` otherwise

Both are documented in detail in the [contracts integration guide](/api-reference/contracts/integration-guide).
