Skip to content

Commit 34e2ec1

Browse files
authored
Merge pull request #36 from openSVM/copilot/fix-35
Add MCP Inspector compatibility and robust one-liner installation for Claude Desktop
2 parents adc7be9 + 3798c7a commit 34e2ec1

File tree

6 files changed

+194
-16
lines changed

6 files changed

+194
-16
lines changed

README.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,35 @@ solana-mcp-server web --port 8080
2929

3030
📖 **[Complete Web Service Documentation](./docs/web-service.md)**
3131

32-
## Installation
32+
## Quick Installation (One-liner)
33+
34+
🚀 **Install Solana MCP Server for Claude Desktop in one command:**
35+
36+
```bash
37+
curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash
38+
```
39+
40+
This will:
41+
- Download pre-built binaries (if available) or build from source
42+
- Configure Claude Desktop automatically
43+
- Set up proper environment variables
44+
- Back up existing configurations
45+
46+
**Alternative install methods:**
47+
48+
```bash
49+
# Using wget
50+
wget -qO- https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash
51+
52+
# Manual download and run
53+
curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh -o install.sh
54+
chmod +x install.sh
55+
./install.sh
56+
```
57+
58+
After installation, restart Claude Desktop and start querying Solana data directly!
59+
60+
## Manual Installation (Advanced)
3361

3462
### Using Pre-built Binaries
3563

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

5583
```bash
56-
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; }
84+
git clone https://github.com/opensvm/solana-mcp-server.git
85+
cd solana-mcp-server
86+
cargo build --release
5787
```
5888

89+
Then configure Claude Desktop with the path to `target/release/solana-mcp-server`.
90+
5991
## Quick Deployment
6092

6193
🚀 **One-liner deployment scripts for all platforms:**

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"rpc_url": "https://api.opensvm.com",
33
"commitment": "confirmed",
4-
"protocol_version": "2024-11-05"
4+
"protocol_version": "2025-06-18"
55
}

scripts/install.sh

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/bin/bash
2+
# One-liner installation script for Solana MCP Server
3+
# Usage: curl -fsSL https://raw.githubusercontent.com/opensvm/solana-mcp-server/main/scripts/install.sh | bash
4+
set -e
5+
6+
echo "🚀 Installing Solana MCP Server for Claude Desktop..."
7+
8+
# Function to detect OS and architecture
9+
detect_platform() {
10+
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
11+
local arch=$(uname -m)
12+
13+
case "$arch" in
14+
x86_64) arch="amd64" ;;
15+
arm64|aarch64) arch="arm64" ;;
16+
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;;
17+
esac
18+
19+
case "$os" in
20+
darwin) os="macos" ;;
21+
linux) os="linux" ;;
22+
*) echo "Unsupported OS: $os" >&2; exit 1 ;;
23+
esac
24+
25+
echo "${os}-${arch}"
26+
}
27+
28+
# Function to get Claude config directory
29+
get_claude_config_dir() {
30+
if [[ "$OSTYPE" == "darwin"* ]]; then
31+
echo "$HOME/Library/Application Support/Claude"
32+
else
33+
echo "${XDG_CONFIG_HOME:-$HOME/.config}/claude"
34+
fi
35+
}
36+
37+
# Try to download pre-built binary first, fall back to building from source
38+
try_download_binary() {
39+
local platform=$(detect_platform)
40+
local binary_name="solana-mcp-server-${platform}"
41+
42+
echo "Attempting to download pre-built binary for ${platform}..."
43+
44+
# Try to download from releases
45+
local download_url="https://github.com/opensvm/solana-mcp-server/releases/latest/download/${binary_name}"
46+
if curl -sL "$download_url" -o solana-mcp-server; then
47+
# Check if download was successful (not a 404 page)
48+
if [[ $(wc -c < solana-mcp-server) -gt 1000 ]] && file solana-mcp-server | grep -q "executable"; then
49+
chmod +x solana-mcp-server
50+
echo "✅ Downloaded pre-built binary"
51+
return 0
52+
else
53+
echo "⚠️ Download failed or binary not available"
54+
rm -f solana-mcp-server
55+
return 1
56+
fi
57+
else
58+
echo "⚠️ Pre-built binary not available, building from source..."
59+
return 1
60+
fi
61+
}
62+
63+
# Build from source
64+
build_from_source() {
65+
echo "Building Solana MCP Server from source..."
66+
67+
# Check if Rust is installed
68+
if ! command -v cargo &> /dev/null; then
69+
echo "Installing Rust..."
70+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
71+
source "$HOME/.cargo/env"
72+
fi
73+
74+
# Clone and build
75+
TEMP_DIR=$(mktemp -d)
76+
cd "$TEMP_DIR"
77+
git clone https://github.com/opensvm/solana-mcp-server.git .
78+
cargo build --release
79+
80+
# Copy binary to working directory
81+
cp target/release/solana-mcp-server "$OLDPWD/"
82+
cd "$OLDPWD"
83+
rm -rf "$TEMP_DIR"
84+
85+
echo "✅ Built from source successfully"
86+
}
87+
88+
# Main installation logic
89+
main() {
90+
# Create working directory
91+
INSTALL_DIR="$HOME/.local/bin"
92+
mkdir -p "$INSTALL_DIR"
93+
cd "$INSTALL_DIR"
94+
95+
# Try download first, then build if needed
96+
if ! try_download_binary; then
97+
build_from_source
98+
fi
99+
100+
# Configure Claude Desktop
101+
local claude_config_dir=$(get_claude_config_dir)
102+
mkdir -p "$claude_config_dir"
103+
104+
local config_file="$claude_config_dir/claude_desktop_config.json"
105+
local server_path="$INSTALL_DIR/solana-mcp-server"
106+
107+
# Create or update Claude config
108+
if [[ -f "$config_file" ]]; then
109+
echo "⚠️ Existing Claude config found. Backing up..."
110+
cp "$config_file" "${config_file}.backup.$(date +%s)"
111+
fi
112+
113+
cat > "$config_file" << EOF
114+
{
115+
"mcpServers": {
116+
"solana": {
117+
"command": "$server_path",
118+
"env": {
119+
"SOLANA_RPC_URL": "https://api.mainnet-beta.solana.com",
120+
"SOLANA_COMMITMENT": "confirmed"
121+
}
122+
}
123+
}
124+
}
125+
EOF
126+
127+
echo "✅ Installation complete!"
128+
echo ""
129+
echo "🎉 Solana MCP Server is now configured for Claude Desktop"
130+
echo "📁 Installed at: $server_path"
131+
echo "⚙️ Config file: $config_file"
132+
echo ""
133+
echo "🚀 To use:"
134+
echo "1. Restart Claude Desktop"
135+
echo "2. You can now query Solana blockchain data directly in Claude!"
136+
echo ""
137+
echo "💡 Example queries:"
138+
echo " - 'What is the balance of account [pubkey]?'"
139+
echo " - 'Show me the latest block information'"
140+
echo " - 'Get transaction details for [signature]'"
141+
echo ""
142+
echo "📖 More info: https://github.com/opensvm/solana-mcp-server"
143+
}
144+
145+
# Run main function
146+
main "$@"

src/protocol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
22
use std::collections::HashMap;
33
use url::Url;
44

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

77
/// Describes who the intended customer of this object or data is
88
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

test_sequence.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/bash
22

33
# Start the server and send both requests through the same pipe
4-
(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
4+
(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

tests/e2e.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ async fn test_mcp_initialize_protocol() {
8686
"id": 1,
8787
"method": "initialize",
8888
"params": {
89-
"protocolVersion": "2024-11-05",
89+
"protocolVersion": "2025-06-18",
9090
"capabilities": {},
9191
"clientInfo": {
9292
"name": "e2e-test-client",
@@ -103,7 +103,7 @@ async fn test_mcp_initialize_protocol() {
103103
assert!(response["result"].is_object());
104104

105105
let result = &response["result"];
106-
assert_eq!(result["protocolVersion"], "2024-11-05");
106+
assert_eq!(result["protocolVersion"], "2025-06-18");
107107
assert_eq!(result["serverInfo"]["name"], "solana-mcp-server");
108108
assert!(result["capabilities"]["tools"].is_object());
109109
}
@@ -119,7 +119,7 @@ async fn test_tools_list() {
119119
"id": 1,
120120
"method": "initialize",
121121
"params": {
122-
"protocolVersion": "2024-11-05",
122+
"protocolVersion": "2025-06-18",
123123
"capabilities": {},
124124
"clientInfo": {"name": "test", "version": "1.0.0"}
125125
}
@@ -165,7 +165,7 @@ async fn test_tool_execution_get_health() {
165165
"id": 1,
166166
"method": "initialize",
167167
"params": {
168-
"protocolVersion": "2024-11-05",
168+
"protocolVersion": "2025-06-18",
169169
"capabilities": {},
170170
"clientInfo": {"name": "test", "version": "1.0.0"}
171171
}
@@ -202,7 +202,7 @@ async fn test_tool_execution_get_balance() {
202202
"id": 1,
203203
"method": "initialize",
204204
"params": {
205-
"protocolVersion": "2024-11-05",
205+
"protocolVersion": "2025-06-18",
206206
"capabilities": {},
207207
"clientInfo": {"name": "test", "version": "1.0.0"}
208208
}
@@ -308,7 +308,7 @@ async fn test_error_handling_method_not_found() {
308308
"id": 1,
309309
"method": "initialize",
310310
"params": {
311-
"protocolVersion": "2024-11-05",
311+
"protocolVersion": "2025-06-18",
312312
"capabilities": {},
313313
"clientInfo": {"name": "test", "version": "1.0.0"}
314314
}
@@ -343,7 +343,7 @@ async fn test_error_handling_invalid_tool_params() {
343343
"id": 1,
344344
"method": "initialize",
345345
"params": {
346-
"protocolVersion": "2024-11-05",
346+
"protocolVersion": "2025-06-18",
347347
"capabilities": {},
348348
"clientInfo": {"name": "test", "version": "1.0.0"}
349349
}
@@ -382,7 +382,7 @@ async fn test_content_type_validation() {
382382
"id": 1,
383383
"method": "initialize",
384384
"params": {
385-
"protocolVersion": "2024-11-05",
385+
"protocolVersion": "2025-06-18",
386386
"capabilities": {},
387387
"clientInfo": {"name": "test", "version": "1.0.0"}
388388
}
@@ -439,7 +439,7 @@ async fn test_resources_list() {
439439
"id": 1,
440440
"method": "initialize",
441441
"params": {
442-
"protocolVersion": "2024-11-05",
442+
"protocolVersion": "2025-06-18",
443443
"capabilities": {},
444444
"clientInfo": {"name": "test", "version": "1.0.0"}
445445
}
@@ -472,7 +472,7 @@ async fn test_complex_tool_multiple_accounts() {
472472
"id": 1,
473473
"method": "initialize",
474474
"params": {
475-
"protocolVersion": "2024-11-05",
475+
"protocolVersion": "2025-06-18",
476476
"capabilities": {},
477477
"clientInfo": {"name": "test", "version": "1.0.0"}
478478
}
@@ -514,7 +514,7 @@ async fn test_concurrent_requests() {
514514
"id": 1,
515515
"method": "initialize",
516516
"params": {
517-
"protocolVersion": "2024-11-05",
517+
"protocolVersion": "2025-06-18",
518518
"capabilities": {},
519519
"clientInfo": {"name": "test", "version": "1.0.0"}
520520
}

0 commit comments

Comments
 (0)