@phantom/mcp-server) enables AI assistants like Claude to interact with Phantom embedded wallets through natural language. AI agents can view wallet addresses, sign transactions, transfer tokens, and sign messages across Solana, Ethereum, Bitcoin, and Sui.
Looking for the MCP server that gives your AI coding assistant access to Phantom developer documentation? See the Phantom Connect SDK MCP server documentation.
Features
- SSO authentication: Seamless integration with Phantom’s embedded wallet SSO flow (Google/Apple login)
- Session persistence: Automatic session management with stamper keys stored locally
- Multi-chain support: Works with Solana, Ethereum, Bitcoin, and Sui networks
- Five MCP tools:
get_wallet_addresses— Get blockchain addresses for the authenticated embedded walletsign_transaction— Sign transactions across supported chainstransfer_tokens— Transfer SOL or SPL tokens on Solanabuy_token— Fetch a Solana swap quote from the Phantom quotes APIsign_message— Sign UTF-8 messages with automatic chain-specific routing
Prerequisites
Before using the MCP server, you need an App ID from Phantom Portal.Visit Phantom Portal
Go to phantom.com/portal and sign in with your Google or Apple account.
Configure redirect URL
Navigate to Dashboard > View App > Redirect URLs and add
http://localhost:8080/callback as a redirect URL. This allows the OAuth callback to work correctly.Installation
Option 1: npx (recommended)
Use npx to run the server without global installation. This ensures you always use the latest version:Option 2: Global install
Install the package globally for faster startup:Setup guides
- Claude Desktop
- Cursor
- Claude Code
Add the MCP server to your Claude Desktop configuration file.Configuration file location:Using global install:After updating the config, restart Claude Desktop to load the server.
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
Environment variables
Configure the server behavior using environment variables.Required
| Variable | Description |
|---|---|
PHANTOM_APP_ID | Your App ID from Phantom Portal (required) |
Optional
| Variable | Description | Default |
|---|---|---|
PHANTOM_CLIENT_SECRET | Client secret for confidential clients | — |
PHANTOM_CALLBACK_PORT | OAuth callback port | 8080 |
PHANTOM_CALLBACK_PATH | OAuth callback path | /callback |
PHANTOM_MCP_DEBUG | Enable debug logging (set to 1) | — |
Client types
- Public client (recommended): Provide only
PHANTOM_APP_ID. Uses PKCE for security, similar to the browser SDK. - Confidential client: Provide both
PHANTOM_APP_IDandPHANTOM_CLIENT_SECRET. Uses HTTP Basic Auth + PKCE.
Authentication flow
On first run, the server will:- Use the App ID from the
PHANTOM_APP_IDenvironment variable - Open your default browser to
https://connect.phantom.appfor Google/Apple login - Start a local server on port 8080 to receive the SSO callback
- Save your session to
~/.phantom-mcp/session.json
Available tools
get_wallet_addresses
Gets all blockchain addresses for the authenticated embedded wallet (Solana, Ethereum, Bitcoin, Sui). Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
derivationIndex | number | No | Derivation index for the addresses (default: 0) |
sign_transaction
Signs a transaction using the authenticated embedded wallet. Supports Solana, Ethereum, Bitcoin, and other chains. Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
transaction | string | Yes | The transaction to sign (base64url for Solana, RLP-encoded hex for Ethereum) |
networkId | string | Yes | Network identifier (e.g., solana:mainnet, eip155:1) |
walletId | string | No | The wallet ID to use for signing (defaults to authenticated wallet) |
derivationIndex | number | No | Derivation index for the account (default: 0) |
account | string | No | Specific account address to use for simulation/signing |
transfer_tokens
Transfers SOL or SPL tokens on Solana by building, signing, and sending the transaction. Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
networkId | string | Yes | Solana network identifier (e.g., solana:mainnet, solana:devnet) |
to | string | Yes | Recipient Solana address |
amount | string | Yes | Transfer amount as a string (e.g., "0.5" or "1000000") |
walletId | string | No | The wallet ID to use for transfer (defaults to authenticated wallet) |
amountUnit | string | No | Amount unit: ui for SOL/token units, base for lamports (default: ui) |
tokenMint | string | No | SPL token mint address (omit for native SOL) |
decimals | number | No | Token decimals (fetched from chain if omitted) |
derivationIndex | number | No | Derivation index for the account (default: 0) |
rpcUrl | string | No | Solana RPC URL (defaults based on networkId) |
createAssociatedTokenAccount | boolean | No | Create destination ATA if missing (default: true) |
buy_token
Fetches a Solana swap quote from the Phantom quotes API. Optionally signs and sends the first quote transaction whenexecute: true.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | Sell amount (e.g., "0.5" or "1000000") |
walletId | string | No | The wallet ID for the taker address (defaults to authenticated wallet) |
networkId | string | No | Solana network identifier (default: solana:mainnet) |
buyTokenMint | string | No | Mint address of the token to buy (omit if buying native SOL) |
buyTokenIsNative | boolean | No | Set true to buy native SOL (default: false) |
sellTokenMint | string | No | Mint address of the token to sell (omit if selling native SOL) |
sellTokenIsNative | boolean | No | Set true to sell native SOL (default: true if sellTokenMint is not provided) |
amountUnit | string | No | Amount unit: ui for token units, base for atomic units (default: base) |
slippageTolerance | number | No | Slippage tolerance in percent (0–100) |
execute | boolean | No | If true, sign and send the first quote transaction after fetching |
derivationIndex | number | No | Derivation index for the taker address (default: 0) |
sign_message
Signs a UTF-8 message using the authenticated embedded wallet. Automatically routes to the correct signing method based on the network. Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The UTF-8 message to sign |
networkId | string | Yes | Network identifier (e.g., eip155:1, solana:mainnet) |
walletId | string | No | The wallet ID to use for signing (defaults to authenticated wallet) |
derivationIndex | number | No | Derivation index for the account (default: 0) |
Supported networks
Network identifiers follow the CAIP-2/CAIP-10 format.Solana
| Network | Identifier |
|---|---|
| Mainnet | solana:mainnet |
| Devnet | solana:devnet |
| Testnet | solana:testnet |
Ethereum and EVM chains
| Network | Identifier |
|---|---|
| Ethereum Mainnet | eip155:1 |
| Ethereum Sepolia | eip155:11155111 |
| Polygon Mainnet | eip155:137 |
| Polygon Amoy | eip155:80002 |
| Base Mainnet | eip155:8453 |
| Base Sepolia | eip155:84532 |
| Arbitrum One | eip155:42161 |
| Arbitrum Sepolia | eip155:421614 |
Bitcoin
| Network | Identifier |
|---|---|
| Mainnet | bip122:000000000019d6689c085ae165831e93 |
Sui
| Network | Identifier |
|---|---|
| Mainnet | sui:mainnet |
| Testnet | sui:testnet |
Testing
Test the server directly using the MCP inspector:Session management
Sessions are stored in~/.phantom-mcp/session.json and contain wallet and organization identifiers, stamper keys, and user authentication details. Sessions persist indefinitely until explicitly deleted.
To reset your session:
Security
- PKCE: Uses Proof Key for Code Exchange for secure OAuth authentication
- Session security: Session files have restrictive Unix permissions (user-only read/write)
- Request signing: API key stamper prevents request tampering
- HTTPS: All API requests use HTTPS
- Ephemeral binding: Callback server uses ephemeral localhost binding
Troubleshooting
Browser doesn't open during authentication
Browser doesn't open during authentication
- Ensure you have a default browser configured
- Manually visit the URL shown in the logs
- Check if the
opencommand works in your terminal:open https://phantom.app
Port 8080 already in use
Port 8080 already in use
The OAuth callback server cannot bind to port 8080.Solutions:
- Stop the process using port 8080:
lsof -ti:8080 | xargs kill - Change the callback port by setting
PHANTOM_CALLBACK_PORTto a different value
Authentication email mismatch
Authentication email mismatch
Authentication fails when the email used for Phantom Portal doesn’t match the email used during MCP server authentication.Solution: Use the same email address for both Phantom Portal sign-in and MCP server authentication (Google/Apple login).
Session not persisting
Session not persisting
The server asks you to authenticate every time.Solutions:
- Check session file exists:
ls -la ~/.phantom-mcp/session.json - Verify file permissions:
chmod 600 ~/.phantom-mcp/session.json - Ensure
~/.phantom-mcpdirectory has correct permissions:chmod 700 ~/.phantom-mcp
MCP server not loading in Claude Desktop
MCP server not loading in Claude Desktop
Claude Desktop doesn’t show the Phantom tools.Solutions:
- Verify the config file contains valid JSON
- Check Claude Desktop logs:
- macOS:
~/Library/Logs/Claude/ - Windows:
%APPDATA%/Claude/logs/
- macOS:
- Restart Claude Desktop after config changes
- Test the server manually with the MCP inspector (see the Testing section)
Invalid session error
Invalid session error
Session exists but is rejected by the API.Solutions:
- Verify your App ID is correct in Phantom Portal
- Ensure the authentication email matches the Phantom Portal email
- Delete the session file:
rm ~/.phantom-mcp/session.json - Restart your AI assistant and re-authenticate when prompted