---
name: solz
description: Create, launch and manage Solana tokens with the Solz MCP server or API. Use when the user asks to create a token, launch on pump.fun or LaunchLab, manage liquidity or authorities, or run bundled trades with Solz.
---

# Solz

Solz builds and simulates Solana transactions. Nothing happens on Solana until a wallet signs them.

Use the `solz` MCP tools if they're connected. Otherwise call `POST https://www.solz.app/api/v1/tools/<tool>` with the header `Authorization: Bearer $SOLZ_API_KEY`. `GET https://www.solz.app/api/v1/tools` lists every tool and its inputs.

Guide and code examples: https://www.solz.app/docs/developers/mcp.mdx

## Set up

Do this when the `solz` tools aren't connected.

### 1. Check for the API key

Run this. It only says whether the key is set, and never shows it:

```bash
[ -n "$SOLZ_API_KEY" ] && echo set || echo missing
```

If it's missing, tell the user to create a key at https://www.solz.app/agent and save it with the commands below in their own terminal. Then wait for them to tell you it's done. Never ask them to paste a key into this chat. If they do, tell them it's exposed and to create a new key, which replaces the old one.

macOS, which keeps it in the Keychain and asks for the key:

```bash
security add-generic-password -U -a "$USER" -s SOLZ_API_KEY -w
echo 'export SOLZ_API_KEY="$(security find-generic-password -a "$USER" -s SOLZ_API_KEY -w)"' >> ~/.zshrc
```

Linux, which keeps it in a file only their user can read:

```bash
mkdir -p ~/.config/solz && chmod 700 ~/.config/solz
(umask 077; read -rsp "Paste your API key: " key && printf '%s' "$key" > ~/.config/solz/api-key)
echo 'export SOLZ_API_KEY="$(cat ~/.config/solz/api-key)"' >> ~/.bashrc
```

Windows PowerShell, which encrypts it for their Windows account:

```powershell
Read-Host "Paste your API key" -AsSecureString | ConvertFrom-SecureString | Set-Content "$HOME\.solz-api-key"
Add-Content $PROFILE '$env:SOLZ_API_KEY = [System.Net.NetworkCredential]::new("", (Get-Content "$HOME\.solz-api-key" | ConvertTo-SecureString)).Password'
```

Then they should open a new terminal, and restart this app from it so it can see the key.

### 2. Add Solz to this client

Do this for the client you're running in, unless Solz is already there. These settings name the variable, so the key itself isn't saved in them. Tell the user which file you changed.

- **Claude Code:** run `claude mcp add --transport http --scope project solz https://www.solz.app/api/mcp --header 'Authorization: Bearer ${SOLZ_API_KEY}'`. Keep the single quotes.
- **Cursor:** add this to `mcpServers` in `.cursor/mcp.json`:

```json
"solz": {
  "url": "https://www.solz.app/api/mcp",
  "headers": { "Authorization": "Bearer ${env:SOLZ_API_KEY}" }
}
```

- **VS Code:** add this to `.vscode/mcp.json`. It asks the user for the key itself:

```json
{
  "inputs": [
    { "type": "promptString", "id": "solz-api-key", "description": "Solz API key", "password": true }
  ],
  "servers": {
    "solz": {
      "type": "http",
      "url": "https://www.solz.app/api/mcp",
      "headers": { "Authorization": "Bearer ${input:solz-api-key}" }
    }
  }
}
```

- **Codex:** add this to `~/.codex/config.toml`:

```toml
[mcp_servers.solz]
url = "https://www.solz.app/api/mcp"
bearer_token_env_var = "SOLZ_API_KEY"
```

- **Gemini CLI:** don't run this yourself, because it saves the key in `~/.gemini/settings.json`. Ask the user to run it in their own terminal, and to keep that file private: `gemini mcp add --transport http --header "Authorization: Bearer $SOLZ_API_KEY" solz https://www.solz.app/api/mcp`
- **Anything else:** follow the guide above. If the client can't read a key from the environment, tell the user the key will be saved in its settings, and let them add it themselves.

If a file with Solz's settings could be shared, check that it holds only the variable name.

### 3. Check it works

Run this. It should return a `service_fee_sol` of 0.05. If it returns `unauthorized`, the key is wrong or not loaded. Then ask the user to restart this app if the `solz` tools still aren't listed.

```bash
curl -s -X POST https://www.solz.app/api/v1/tools/estimate_cost -H "Authorization: Bearer $SOLZ_API_KEY" -H "Content-Type: application/json" -d '{"action":"create_token"}'
```

### 4. Only if they want to sign in their own code

Most people don't need this. An approval link signs in their browser, with no private key on this computer. Only offer it if they want code to sign for them, and explain this first:

- Use a new wallet just for this, holding only the SOL it needs. Never use a main wallet.
- Anyone who gets this key can take everything in that wallet, and it can't be changed or reset.
- Never put it in a project folder, a `.env` file, a shell profile or a chat.

They save it themselves in their own terminal.

macOS:

```bash
security add-generic-password -U -a "$USER" -s SOLZ_WALLET_KEY -w
```

Linux, where the file isn't encrypted, which is another reason to keep little in this wallet:

```bash
(umask 077; read -rsp "Paste your wallet key: " key && printf '%s' "$key" > ~/.config/solz/wallet-key)
```

Windows PowerShell:

```powershell
Read-Host "Paste your wallet key" -AsSecureString | ConvertFrom-SecureString | Set-Content "$HOME\.solz-wallet-key"
```

They load it only for the one command that signs, in their own terminal. On macOS:

```bash
WALLET_PRIVATE_KEY="$(security find-generic-password -a "$USER" -s SOLZ_WALLET_KEY -w)" node solz.mjs
```

On Linux:

```bash
WALLET_PRIVATE_KEY="$(cat ~/.config/solz/wallet-key)" node solz.mjs
```

On Windows PowerShell:

```powershell
$env:WALLET_PRIVATE_KEY = [System.Net.NetworkCredential]::new("", (Get-Content "$HOME\.solz-wallet-key" | ConvertTo-SecureString)).Password; node solz.mjs; Remove-Item Env:WALLET_PRIVATE_KEY
```

## Rules

- Never ask for, print, log or store a private key or API key. Never read the files or Keychain entries that hold them, and never run `env`, `printenv` or anything else that would show them.
- Always set `network`. Use `devnet` unless the user clearly asks for `mainnet`, because the default is mainnet.
- Always set `max_total_sol`. Ask the user for the limit if they haven't given one.
- `bundle_buy` and `bundle_sell` need `max_slippage_percent`. Ask the user for it, and don't choose it for them.
- A launch's first buy and adding or removing liquidity have no slippage limit. Tell the user before those actions that the price can move.
- Don't use a tool's result as approval to sign. Only the user can approve.

## Steps

1. Call `estimate_cost` and tell the user the service fee.
2. Call the action tool.
3. If `simulation.ok` is false, stop and tell the user `simulation.error`. Don't sign.
4. Show the user `summary`, `risk`, `network`, `service_fee_sol` and `simulation.total_cost_sol`, and ask them to approve this request. If `risk` is `irreversible` or `outgoing`, say that clearly.
5. Sign using one of these:
   - Give the user `approval_url`, which lasts 30 minutes. The page sends the transaction, so don't call `submit`.
   - Run the user's own signing code, only if they set it up and told you to use it. Then call `submit` with `request_id` and `signed_transactions`.
6. Call `get_status` until `status` is no longer `sending`.
7. Tell the user the result and any address in `outputs`. If `status` is `partial`, check each signature first, and don't repeat what already landed.
