Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,35 @@ solana-mcp-server web --port 8080

πŸ“– **[Complete Web Service Documentation](./docs/web-service.md)**

## Installation
## Quick Installation (One-liner)

πŸš€ **Install Solana MCP Server for Claude Desktop in one command:**

```bash
curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash
```

This will:
- Download pre-built binaries (if available) or build from source
- Configure Claude Desktop automatically
- Set up proper environment variables
- Back up existing configurations

**Alternative install methods:**

```bash
# Using wget
wget -qO- https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash

# Manual download and run
curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh -o install.sh
chmod +x install.sh
./install.sh
```

After installation, restart Claude Desktop and start querying Solana data directly!

## Manual Installation (Advanced)

### Using Pre-built Binaries

Expand All @@ -53,9 +81,13 @@ solana-mcp-server web --port 8080
### Building from Source

```bash
TEMP_DIR=$(mktemp -d) && cd "$TEMP_DIR" && git clone https://github.com/opensvm/solana-mcp-server.git . && cargo build --release && CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/claude" && mkdir -p "$CONFIG_DIR" && echo "{\"mcpServers\":{\"solana\":{\"command\":\"$PWD/target/release/solana-mcp-server\",\"env\":{\"SOLANA_RPC_URL\":\"https://api.mainnet-beta.solana.com\"}}}}" > "$CONFIG_DIR/config.json" || { rm -rf "$TEMP_DIR"; exit 1; }
git clone https://github.com/opensvm/solana-mcp-server.git
cd solana-mcp-server
cargo build --release
```

Then configure Claude Desktop with the path to `target/release/solana-mcp-server`.

## Quick Deployment

πŸš€ **One-liner deployment scripts for all platforms:**
Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"rpc_url": "https://api.opensvm.com",
"commitment": "confirmed",
"protocol_version": "2024-11-05"
"protocol_version": "2025-06-18"
}
146 changes: 146 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/bin/bash
# One-liner installation script for Solana MCP Server
# Usage: curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash
set -e

echo "πŸš€ Installing Solana MCP Server for Claude Desktop..."

# Function to detect OS and architecture
detect_platform() {
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
local arch=$(uname -m)

case "$arch" in
x86_64) arch="amd64" ;;
arm64|aarch64) arch="arm64" ;;
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;;
esac

case "$os" in
darwin) os="macos" ;;
linux) os="linux" ;;
*) echo "Unsupported OS: $os" >&2; exit 1 ;;
esac

echo "${os}-${arch}"
}

# Function to get Claude config directory
get_claude_config_dir() {
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "$HOME/Library/Application Support/Claude"
else
echo "${XDG_CONFIG_HOME:-$HOME/.config}/claude"
fi
}

# Try to download pre-built binary first, fall back to building from source
try_download_binary() {
local platform=$(detect_platform)
local binary_name="solana-mcp-server-${platform}"

echo "Attempting to download pre-built binary for ${platform}..."

# Try to download from releases
local download_url="https://github.com/opensvm/solana-mcp-server/releases/latest/download/${binary_name}"
if curl -sL "$download_url" -o solana-mcp-server; then
# Check if download was successful (not a 404 page)
if [[ $(wc -c < solana-mcp-server) -gt 1000 ]] && file solana-mcp-server | grep -q "executable"; then
chmod +x solana-mcp-server
echo "βœ… Downloaded pre-built binary"
return 0
else
echo "⚠️ Download failed or binary not available"
rm -f solana-mcp-server
return 1
fi
else
echo "⚠️ Pre-built binary not available, building from source..."
return 1
fi
}

# Build from source
build_from_source() {
echo "Building Solana MCP Server from source..."

# Check if Rust is installed
if ! command -v cargo &> /dev/null; then
echo "Installing Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
fi

# Clone and build
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
git clone https://github.com/opensvm/solana-mcp-server.git .
cargo build --release

# Copy binary to working directory
cp target/release/solana-mcp-server "$OLDPWD/"
cd "$OLDPWD"
rm -rf "$TEMP_DIR"

echo "βœ… Built from source successfully"
}

# Main installation logic
main() {
# Create working directory
INSTALL_DIR="$HOME/.local/bin"
mkdir -p "$INSTALL_DIR"
cd "$INSTALL_DIR"

# Try download first, then build if needed
if ! try_download_binary; then
build_from_source
fi

# Configure Claude Desktop
local claude_config_dir=$(get_claude_config_dir)
mkdir -p "$claude_config_dir"

local config_file="$claude_config_dir/claude_desktop_config.json"
local server_path="$INSTALL_DIR/solana-mcp-server"

# Create or update Claude config
if [[ -f "$config_file" ]]; then
echo "⚠️ Existing Claude config found. Backing up..."
cp "$config_file" "${config_file}.backup.$(date +%s)"
fi

cat > "$config_file" << EOF
{
"mcpServers": {
"solana": {
"command": "$server_path",
"env": {
"SOLANA_RPC_URL": "https://api.mainnet-beta.solana.com",
"SOLANA_COMMITMENT": "confirmed"
}
}
}
}
EOF

echo "βœ… Installation complete!"
echo ""
echo "πŸŽ‰ Solana MCP Server is now configured for Claude Desktop"
echo "πŸ“ Installed at: $server_path"
echo "βš™οΈ Config file: $config_file"
echo ""
echo "πŸš€ To use:"
echo "1. Restart Claude Desktop"
echo "2. You can now query Solana blockchain data directly in Claude!"
echo ""
echo "πŸ’‘ Example queries:"
echo " - 'What is the balance of account [pubkey]?'"
echo " - 'Show me the latest block information'"
echo " - 'Get transaction details for [signature]'"
echo ""
echo "πŸ“– More info: https://github.com/opensvm/solana-mcp-server"
}

# Run main function
main "$@"
2 changes: 1 addition & 1 deletion src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use url::Url;

pub const LATEST_PROTOCOL_VERSION: &str = "2024-11-05";
pub const LATEST_PROTOCOL_VERSION: &str = "2025-06-18";

/// Describes who the intended customer of this object or data is
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
Expand Down
2 changes: 1 addition & 1 deletion test_sequence.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash

# Start the server and send both requests through the same pipe
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","clientInfo":{"name":"test-client","version":"1.0.0"},"capabilities":{}}}'; sleep 1; echo '{"jsonrpc":"2.0","id":2,"method":"tools/list"}') | ./target/release/solana-mcp-server
(echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","clientInfo":{"name":"test-client","version":"1.0.0"},"capabilities":{}}}'; sleep 1; echo '{"jsonrpc":"2.0","id":2,"method":"tools/list"}') | ./target/release/solana-mcp-server
22 changes: 11 additions & 11 deletions tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async fn test_mcp_initialize_protocol() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "e2e-test-client",
Expand All @@ -103,7 +103,7 @@ async fn test_mcp_initialize_protocol() {
assert!(response["result"].is_object());

let result = &response["result"];
assert_eq!(result["protocolVersion"], "2024-11-05");
assert_eq!(result["protocolVersion"], "2025-06-18");
assert_eq!(result["serverInfo"]["name"], "solana-mcp-server");
assert!(result["capabilities"]["tools"].is_object());
}
Expand All @@ -119,7 +119,7 @@ async fn test_tools_list() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -165,7 +165,7 @@ async fn test_tool_execution_get_health() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -202,7 +202,7 @@ async fn test_tool_execution_get_balance() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -308,7 +308,7 @@ async fn test_error_handling_method_not_found() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -343,7 +343,7 @@ async fn test_error_handling_invalid_tool_params() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -382,7 +382,7 @@ async fn test_content_type_validation() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -439,7 +439,7 @@ async fn test_resources_list() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -472,7 +472,7 @@ async fn test_complex_tool_multiple_accounts() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down Expand Up @@ -514,7 +514,7 @@ async fn test_concurrent_requests() {
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "test", "version": "1.0.0"}
}
Expand Down
Loading