#
tokens: 6510/50000 8/8 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .gitignore
├── claude_desktop_config.json
├── glama.json
├── LICENSE
├── package.json
├── pnpm-lock.yaml
├── README.md
├── scripts
│   └── install.sh
├── src
│   └── index.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
.env
node_modules
build
.DS_Store
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# Solana Agent Kit MCP Server

[![npm version](https://badge.fury.io/js/solana-mcp.svg)](https://www.npmjs.com/package/solana-mcp)
[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
<a href="https://cloud.phala.network/features/mcp-hosting/solana-mcp-by-sendai-and-dark" target="_blank" rel="noopener noreferrer" style="display:inline-flex;align-items:center;text-decoration:none;background:#fff;border:1px solid #e5e7eb;border-radius:6px;padding:2px 8px;font-size:16px;font-family:sans-serif;">
  <img src="https://raw.githubusercontent.com/Phala-Network/mcp-hosting/refs/heads/main/assets/logs/phala.png" alt="Phala Logo" height="24" style="vertical-align:middle;margin-right:8px;"/>
  <span style="color:#222;font-weight:600;">Check on Phala</span>
</a>

A Model Context Protocol (MCP) server that provides onchain tools for Claude AI, allowing it to interact with the Solana blockchain through a standardized interface. This implementation is based on the Solana Agent Kit and enables AI agents to perform blockchain operations seamlessly.




## Overview

This MCP server extends Claude's capabilities by providing tools to:

* Interact with Solana blockchain
* Execute transactions
* Query account information
* Manage Solana wallets

The server implements the Model Context Protocol specification to standardize blockchain interactions for AI agents.

## Prerequisites

* Node.js (v16 or higher)
* pnpm (recommended), npm, or yarn
* Solana wallet with private key
* Solana RPC URL (mainnet, testnet, or devnet)

## Installation

### Option 1: Quick Install (Recommended)

```bash
# Download the installation script
curl -fsSL https://raw.githubusercontent.com/sendaifun/solana-mcp/main/scripts/install.sh -o solana-mcp-install.sh

# Make it executable and run
chmod +x solana-mcp-install.sh && ./solana-mcp-install.sh --backup
```

This will start an interactive installation process that will guide you through:
- Setting up Node.js if needed
- Configuring your Solana RPC URL and private key
- Setting up the Claude Desktop integration

### Option 2: Install from npm ( recommend for clients like Cursor/Cline)

```bash
# Install globally
npm install -g solana-mcp

# Or install locally in your project
npm install solana-mcp
```

### Option 3: Build from Source

1. Clone this repository:
```bash
git clone https://github.com/sendaifun/solana-mcp
cd solana-mcp
```

2. Install dependencies:
```bash
pnpm install
```

3. Build the project:
```bash
pnpm run build
```

## Configuration

### Environment Setup

Create a `.env` file with your credentials:

```env
# Solana Configuration
SOLANA_PRIVATE_KEY=your_private_key_here
RPC_URL=your_solana_rpc_url_here
OPENAI_API_KEY=your_openai_api_key # OPTIONAL
```

### Integration with Claude Desktop

To add this MCP server to Claude Desktop, follow these steps:

1. **Locate the Claude Desktop Configuration File**
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
   - Linux: `~/.config/Claude/claude_desktop_config.json`

2. **Add the Configuration**
   Create or edit the configuration file and add the following JSON:

   If you installed via npm (Option 1):
   ```json
   {
     "mcpServers": {
       "solana-mcp": {
         "command": "npx",
         "args": ["solana-mcp"],
         "env": {
           "RPC_URL": "your_solana_rpc_url_here",
           "SOLANA_PRIVATE_KEY": "your_private_key_here",
           "OPENAI_API_KEY": "your_openai_api_key"  // OPTIONAL
         },
         "disabled": false,
         "autoApprove": []
       }
     }
   }
   ```

   If you built from source (Option 2):
   ```json
   {
     "mcpServers": {
       "solana-mcp": {
         "command": "node",
         "args": ["/path/to/solana-mcp/build/index.js"],
         "env": {
           "RPC_URL": "your_solana_rpc_url_here",
           "SOLANA_PRIVATE_KEY": "your_private_key_here",
           "OPENAI_API_KEY": "your_openai_api_key"  // OPTIONAL
         },
         "disabled": false,
         "autoApprove": []
       }
     }
   }
   ```

3. **Restart Claude Desktop**
   After making these changes, restart Claude Desktop for the configuration to take effect.

## Project Structure

```
solana-agent-kit-mcp/
├── src/
│   ├── index.ts          # Main entry point
├── package.json
└── tsconfig.json
```

## Available Tools

The MCP server provides the following Solana blockchain tools:

* `GET_ASSET` - Retrieve information about a Solana asset/token
* `DEPLOY_TOKEN` - Deploy a new token on Solana
* `GET_PRICE` - Fetch price information for tokens
* `WALLET_ADDRESS` - Get the wallet address
* `BALANCE` - Check wallet balance
* `TRANSFER` - Transfer tokens between wallets
* `MINT_NFT` - Create and mint new NFTs
* `TRADE` - Execute token trades
* `REQUEST_FUNDS` - Request funds (useful for testing/development)
* `RESOLVE_DOMAIN` - Resolve Solana domain names
* `GET_TPS` - Get current transactions per second on Solana

## Security Considerations

* Keep your private key secure and never share it
* Use environment variables for sensitive information
* Consider using a dedicated wallet for AI agent operations
* Regularly monitor and audit AI agent activities
* Test operations on devnet/testnet before mainnet

## Troubleshooting

If you encounter issues:

1. Verify your Solana private key is correct
2. Check your RPC URL is accessible
3. Ensure you're on the intended network (mainnet, testnet, or devnet)
4. Check Claude Desktop logs for error messages
5. Verify the build was successful

## Dependencies

Key dependencies include:
* [@solana/web3.js](https://github.com/solana-labs/solana-web3.js)
* [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk)
* [solana-agent-kit](https://github.com/sendaifun/solana-agent-kit)

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License.

```

--------------------------------------------------------------------------------
/glama.json:
--------------------------------------------------------------------------------

```json
{
    "$schema": "https://glama.ai/mcp/schemas/server.json",
    "maintainers": [
      "thearyanag"
    ]
  }
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
    "compilerOptions": {
      "target": "ES2022",
      "module": "Node16",
      "moduleResolution": "Node16",
      "outDir": "./build",
      "rootDir": "./src",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules"]
  }
```

--------------------------------------------------------------------------------
/claude_desktop_config.json:
--------------------------------------------------------------------------------

```json
{
    "mcpServers": {
        "agent-kit": {
            "command": "node",
            "env" : {
                "OPENAI_API_KEY": "optional_openai_api_key_here",
                "RPC_URL": "your_rpc_url_here",
                "SOLANA_PRIVATE_KEY": "your_private_key_here"
            },
            "args": [
                "/absolute/path/to/build/index.js"
            ]
        }
    }
}


```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "solana-mcp",
  "version": "1.0.0",
  "description": "A Model Context Protocol server for interacting with the Solana blockchain, powered by the Solana Agent Kit (https://github.com/sendaifun/solana-agent-kit)",
  "main": "build/index.js",
  "type": "module",
  "bin": {
    "solana-mcp": "./build/index.js"
  },
  "scripts": {
    "build": "tsc",
    "start": "node build/index.js",
    "dev": "tsx watch src/index.ts"
  },
  "files": [
    "build"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/sendaifun/solana-mcp"
  },
  "keywords": [
    "solana",
    "mcp",
    "solana-agent-kit",
    "solana-mcp"
  ],
  "author": "sendaifun",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.11.4",
    "@solana-agent-kit/adapter-mcp": "^2.0.4",
    "@solana-agent-kit/plugin-god-mode": "^0.0.1",
    "@solana/web3.js": "^1.98.2",
    "bs58": "^6.0.0",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^5.1.0",
    "solana-agent-kit": "2.0.4"
  },
  "devDependencies": {
    "@types/cors": "^2.8.17",
    "@types/express": "^5.0.1",
    "@types/node": "^22.13.4",
    "tsx": "^4.19.4",
    "typescript": "^5.7.3"
  },
  "packageManager": "[email protected]"
}

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
// #!/usr/bin/env node

import { SolanaAgentKit, KeypairWallet, type Action } from "solana-agent-kit";
import { startMcpServer, createMcpServer } from "@solana-agent-kit/adapter-mcp";
import GodModePlugin from "@solana-agent-kit/plugin-god-mode";
import * as dotenv from "dotenv";
import { Keypair } from "@solana/web3.js";
import bs58 from "bs58";
import express, { type Request, type Response } from "express";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import cors from "cors";

dotenv.config();

// Validate required environment variables
function validateEnvironment() {
  const requiredEnvVars = {
    SOLANA_PRIVATE_KEY: process.env.SOLANA_PRIVATE_KEY,
    RPC_URL: process.env.RPC_URL,
  };

  const missingVars = Object.entries(requiredEnvVars)
    .filter(([_, value]) => !value)
    .map(([key]) => key);

  if (missingVars.length > 0) {
    throw new Error(
      `Missing required environment variables: ${missingVars.join(", ")}`
    );
  }
}

// New function to start MCP server with SSE support
async function startMcpServerWithSse(
  actions: Record<string, any>,
  agent: SolanaAgentKit,
  options: {
    name: string;
    version: string;
  },
  port: number = 3000
) {
  const app = express();
  app.use(cors());
  // Store active transport instances
  const transports: { [sessionId: string]: SSEServerTransport } = {};

  // SSE endpoint for client connections
  app.get("/sse", async (_req: Request, res: Response) => {
    console.log("Received connection on /sse");
    const transport = new SSEServerTransport("/messages", res);

    // Store the transport for this session
    transports[transport.sessionId] = transport;

    res.on("close", () => {
      console.log(`Connection closed for session ${transport.sessionId}`);
      delete transports[transport.sessionId];
    });

    // Create the server and connect it to this transport
    const server = createMcpServer(actions, agent, options);
    await server.connect(transport);
  });

  // Message endpoint for client-to-server communication
  app.post("/messages", async (req: Request, res: Response) => {
    const sessionId = req.query.sessionId as string;
    console.log(`Received message for session ${sessionId}`);

    const transport = transports[sessionId];
    if (transport) {
      await transport.handlePostMessage(req, res);
    } else {
      res.status(400).send("No transport found for sessionId");
    }
  });

  // Start the Express server
  app.listen(port, () => {
    console.log(`MCP SSE server listening on port ${port}`);
  });

  return app;
}

async function main() {
  try {
    // Validate environment before proceeding
    validateEnvironment();

    // Initialize the agent with error handling
    const decodedPrivateKey = bs58.decode(
      process.env.SOLANA_PRIVATE_KEY as string
    );
    const keypair = Keypair.fromSecretKey(decodedPrivateKey);
    const keypairWallet = new KeypairWallet(
      keypair,
      process.env.RPC_URL as string
    );

    const agent = new SolanaAgentKit(keypairWallet, keypairWallet.rpcUrl, {})
      .use(GodModePlugin);

    const mcp_actions: Record<string, Action> = {};

    for (const action of agent.actions) {
      mcp_actions[action.name] = action;
    }

    const serverOptions = {
      name: "sendai-agent",
      version: "0.0.1",
    };

    // Check if PORT environment variable exists to determine whether to use SSE
    if (process.env.PORT) {
      const port = Number.parseInt(process.env.PORT, 10);
      console.log(`Starting MCP server with SSE on port ${port}`);
      await startMcpServerWithSse(mcp_actions, agent, serverOptions, port);
    } else {
      // Start the MCP server with stdio transport (original behavior)
      console.log("Starting MCP server with stdio transport");
      await startMcpServer(mcp_actions, agent, serverOptions);
    }
  } catch (error) {
    console.error(
      "Failed to start MCP server:",
      error instanceof Error ? error.message : String(error)
    );
    process.exit(1);
  }
}

main();

```

--------------------------------------------------------------------------------
/scripts/install.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ASCII Art Banner
echo -e "${BLUE}"
cat << "EOF"
 ____        _                     __  __  ____ ____  
/ ___|  ___ | | __ _ _ __   __ _ |  \/  |/ ___|  _ \ 
\___ \ / _ \| |/ _` | '_ \ / _` || |\/| | |   | |_) |
 ___) | (_) | | (_| | | | | (_| || |  | | |__|  __/ 
|____/ \___/|_|\__,_|_| |_|\__,_||_|  |_|\____|_|    
                                                      
EOF
echo -e "${NC}"

# Function to display help
show_help() {
    echo -e "${BLUE}Solana MCP Server Installation Script${NC}"
    echo -e "This script helps you set up the Solana MCP server for Claude Desktop.\n"
    echo -e "The script will:"
    echo -e "  1. Check and install Node.js if needed"
    echo -e "  2. Install solana-mcp globally"
    echo -e "  3. Configure Claude Desktop settings\n"
    echo -e "Requirements:"
    echo -e "  - Internet connection"
    echo -e "  - Admin privileges (for some installations)"
    echo -e "  - Solana RPC URL"
    echo -e "  - Solana private key\n"
    echo -e "Options:"
    echo -e "  -h, --help     Show this help message"
    echo -e "  -b, --backup   Backup existing configuration before modifying"
    echo -e "  -y, --yes      Non-interactive mode (skip confirmations)\n"
}

# Function to validate Solana RPC URL
validate_rpc_url() {
    local url=$1
    if [[ ! $url =~ ^https?:// ]]; then
        echo -e "${RED}Error: Invalid RPC URL format. URL should start with http:// or https://${NC}"
        return 1
    fi
    return 0
}

# Function to validate Solana private key
validate_private_key() {
    local key=$1
    local key_length=${#key}
    echo -e "${YELLOW}Debug: Key length is $key_length characters${NC}"
    echo -e "${YELLOW}Debug: Key value: '$key'${NC}"
    if [[ ! $key =~ ^[0-9a-zA-Z]+$ ]]; then
        echo -e "${RED}Error: Invalid private key format. Should contain only alphanumeric characters${NC}"
        return 1
    fi
    return 0
}

# Function to backup config
backup_config() {
    local config_file=$1
    if [ -f "$config_file" ]; then
        local backup_file="${config_file}.backup.$(date +%Y%m%d_%H%M%S)"
        cp "$config_file" "$backup_file"
        echo -e "${GREEN}Backup created: ${YELLOW}$backup_file${NC}"
    fi
}

# Parse command line arguments
BACKUP=false
NON_INTERACTIVE=false

while [[ "$#" -gt 0 ]]; do
    case $1 in
        -h|--help) show_help; exit 0 ;;
        -b|--backup) BACKUP=true ;;
        -y|--yes) NON_INTERACTIVE=true ;;
        *) echo -e "${RED}Unknown parameter: $1${NC}"; show_help; exit 1 ;;
    esac
    shift
done

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to get OS type
get_os_type() {
    case "$(uname -s)" in
        Darwin*)    echo "macos";;
        Linux*)     echo "linux";;
        MINGW*|CYGWIN*|MSYS*) echo "windows";;
        *)          echo "unknown";;
    esac
}

# Function to install Node.js and npm on macOS
install_node_macos() {
    echo -e "${YELLOW}Installing Node.js and npm using Homebrew...${NC}"
    if ! command_exists brew; then
        echo -e "${YELLOW}Installing Homebrew first...${NC}"
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    fi
    brew install node
}

# Function to install Node.js and npm on Linux
install_node_linux() {
    echo -e "${YELLOW}Installing Node.js and npm using package manager...${NC}"
    if command_exists apt-get; then
        # Debian/Ubuntu
        curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
        sudo apt-get install -y nodejs
    elif command_exists dnf; then
        # Fedora
        sudo dnf install -y nodejs npm
    elif command_exists yum; then
        # CentOS/RHEL
        curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
        sudo yum install -y nodejs
    elif command_exists pacman; then
        # Arch Linux
        sudo pacman -S nodejs npm
    else
        echo -e "${RED}Unsupported Linux distribution. Please install Node.js manually.${NC}"
        exit 1
    fi
}

# Function to install Node.js and npm on Windows
install_node_windows() {
    echo -e "${YELLOW}Installing Node.js and npm using winget...${NC}"
    if command_exists winget; then
        winget install -e --id OpenJS.NodeJS
    else
        echo -e "${RED}Please install Node.js manually from https://nodejs.org/${NC}"
        exit 1
    fi
}

# Function to install Node.js based on OS
install_node() {
    local os_type=$1
    case "$os_type" in
        "macos")
            install_node_macos
            ;;
        "linux")
            install_node_linux
            ;;
        "windows")
            install_node_windows
            ;;
        *)
            echo -e "${RED}Unsupported operating system${NC}"
            exit 1
            ;;
    esac
}

# Function to get Claude config path based on OS
get_claude_config_path() {
    local os_type=$1
    case "$os_type" in
        "macos")
            echo "$HOME/Library/Application Support/Claude/claude_desktop_config.json"
            ;;
        "linux")
            echo "$HOME/.config/Claude/claude_desktop_config.json"
            ;;
        "windows")
            echo "%APPDATA%\\Claude\\claude_desktop_config.json"
            ;;
        *)
            echo ""
            ;;
    esac
}

# Function to merge JSON configurations
merge_config() {
    local config_file=$1
    local temp_file=$(mktemp)
    
    # Check if jq is installed
    if ! command_exists jq; then
        echo -e "${YELLOW}Installing jq for JSON processing...${NC}"
        case "$OS_TYPE" in
            "macos")
                brew install jq
                ;;
            "linux")
                if command_exists apt-get; then
                    sudo apt-get install -y jq
                elif command_exists dnf; then
                    sudo dnf install -y jq
                elif command_exists yum; then
                    sudo yum install -y jq
                elif command_exists pacman; then
                    sudo pacman -S jq
                fi
                ;;
            "windows")
                echo -e "${RED}Please install jq manually${NC}"
                exit 1
                ;;
        esac
    fi

    # Create new MCP config
    local mcp_config="{
      \"command\": \"npx\",
      \"args\": [\"solana-mcp\"],
      \"env\": {
        \"RPC_URL\": \"$RPC_URL\",
        \"SOLANA_PRIVATE_KEY\": \"$SOLANA_PRIVATE_KEY\""

    if [ ! -z "$OPENAI_API_KEY" ]; then
        mcp_config="$mcp_config,
        \"OPENAI_API_KEY\": \"$OPENAI_API_KEY\""
    fi

    mcp_config="$mcp_config
      },
      \"disabled\": false,
      \"autoApprove\": []
    }"

    if [ -f "$config_file" ]; then
        # File exists, merge configurations
        jq --arg mcp "$mcp_config" '.mcpServers."solana-mcp" = ($mcp | fromjson)' "$config_file" > "$temp_file"
    else
        # Create new config file
        echo "{
  \"mcpServers\": {
    \"solana-mcp\": $mcp_config
  }
}" > "$temp_file"
    fi

    # Move temp file to config location
    mv "$temp_file" "$config_file"
    chmod 644 "$config_file"
}

echo -e "${BLUE}Welcome to Solana MCP Server Installation Script${NC}"
echo -e "${YELLOW}This script will help you set up the Solana MCP server for Claude Desktop${NC}"
echo "----------------------------------------"

if [ "$NON_INTERACTIVE" = false ]; then
    read -p "Would you like to proceed with the installation? (y/N) " confirm
    if [[ ! $confirm =~ ^[Yy]$ ]]; then
        echo -e "${YELLOW}Installation cancelled by user${NC}"
        exit 0
    fi
fi

# Check OS type
OS_TYPE=$(get_os_type)
echo -e "\n${BLUE}System Information:${NC}"
echo -e "Operating System: ${YELLOW}$OS_TYPE${NC}"

# Check for Node.js and install if not present
if ! command_exists node; then
    echo -e "\n${YELLOW}Node.js is not installed. Installing now...${NC}"
    if [ "$NON_INTERACTIVE" = false ]; then
        read -p "Would you like to install Node.js? (Y/n) " confirm
        if [[ ! $confirm =~ ^[Nn]$ ]]; then
            install_node "$OS_TYPE"
        else
            echo -e "${RED}Node.js is required for this installation. Exiting.${NC}"
            exit 1
        fi
    else
        install_node "$OS_TYPE"
    fi
    
    # Verify installation
    if ! command_exists node; then
        echo -e "${RED}Node.js installation failed. Please install manually from https://nodejs.org/${NC}"
        exit 1
    fi
fi

NODE_VERSION=$(node -v)
echo -e "Node.js version: ${GREEN}$NODE_VERSION${NC}"

# Check for npm and install if not present
if ! command_exists npm; then
    echo -e "${YELLOW}npm is not installed. Installing now...${NC}"
    # npm usually comes with Node.js, but if not:
    case "$OS_TYPE" in
        "linux")
            sudo apt-get install -y npm || sudo dnf install -y npm || sudo yum install -y npm || sudo pacman -S npm
            ;;
        *)
            echo -e "${RED}npm installation failed. Please install manually${NC}"
            exit 1
            ;;
    esac
    
    # Verify installation
    if ! command_exists npm; then
        echo -e "${RED}npm installation failed. Please install manually${NC}"
        exit 1
    fi
fi

NPM_VERSION=$(npm -v)
echo -e "npm version: ${GREEN}$NPM_VERSION${NC}"

# Check if solana-mcp is already installed globally
if npm list -g solana-mcp > /dev/null 2>&1; then
    SOLANA_MCP_VERSION=$(npm list -g solana-mcp | grep solana-mcp | cut -d@ -f2)
    echo -e "\nsolana-mcp is already installed globally (version: ${GREEN}$SOLANA_MCP_VERSION${NC})"
    if [ "$NON_INTERACTIVE" = false ]; then
        read -p "Would you like to reinstall/update solana-mcp? (y/N) " confirm
        if [[ $confirm =~ ^[Yy]$ ]]; then
            echo -e "\n${YELLOW}Updating solana-mcp globally...${NC}"
            npm install -g solana-mcp@latest
        fi
    fi
else
    echo -e "\n${YELLOW}Installing solana-mcp globally...${NC}"
    npm install -g solana-mcp
fi

# Get Claude config path
CONFIG_PATH=$(get_claude_config_path "$OS_TYPE")
if [ -z "$CONFIG_PATH" ]; then
    echo -e "${RED}Unsupported operating system${NC}"
    exit 1
fi

# Backup existing config if requested
if [ "$BACKUP" = true ] && [ -f "$CONFIG_PATH" ]; then
    backup_config "$CONFIG_PATH"
fi

# Collect required information with validation
echo -e "\n${BLUE}Configuration Setup:${NC}"
echo -e "${YELLOW}Please provide the following information:${NC}"

while true; do
    read -p "Enter your Solana RPC URL: " RPC_URL
    if validate_rpc_url "$RPC_URL"; then
        break
    fi
done

while true; do
    read -p "Enter your Solana private key: " SOLANA_PRIVATE_KEY
    if validate_private_key "$SOLANA_PRIVATE_KEY"; then
        break
    fi
done

read -p "Enter your OpenAI API key (optional, press Enter to skip): " OPENAI_API_KEY

# Create directory if it doesn't exist
CONFIG_DIR=$(dirname "$CONFIG_PATH")
mkdir -p "$CONFIG_DIR"

# Merge or create configuration
echo -e "\n${YELLOW}Updating Claude configuration...${NC}"
merge_config "$CONFIG_PATH"

echo -e "\n${GREEN}Installation completed successfully!${NC}"
echo -e "Configuration file has been updated at: ${YELLOW}$CONFIG_PATH${NC}"
echo -e "\n${BLUE}Next steps:${NC}"
echo -e "1. Restart Claude Desktop for the changes to take effect"
echo -e "2. Test the Solana MCP server functionality"
echo -e "3. If you encounter any issues, check the logs in Claude Desktop\n"

if [ "$BACKUP" = true ]; then
    echo -e "${YELLOW}Note: A backup of your previous configuration was created${NC}"
fi 
```