Skip to content

Commit adc7be9

Browse files
authored
Merge pull request #34 from openSVM/copilot/fix-33
Fix critical duplicate method handlers bug, WebSocket compilation issues, CI pipeline errors, missing RPC methods, and benchmark performance
2 parents 23ee185 + 87e2a97 commit adc7be9

File tree

14 files changed

+9102
-3296
lines changed

14 files changed

+9102
-3296
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
name: MCP Inspector Compatibility Test
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
workflow_dispatch:
9+
10+
env:
11+
CARGO_TERM_COLOR: always
12+
RUST_BACKTRACE: full
13+
NODE_VERSION: '18'
14+
# Use the official MCP Inspector package
15+
INSPECTOR_PACKAGE: '@modelcontextprotocol/[email protected]'
16+
17+
jobs:
18+
mcp-inspector-test:
19+
name: Test MCP Server with Inspector CLI
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 20
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Install Rust toolchain
28+
uses: dtolnay/rust-toolchain@stable
29+
with:
30+
toolchain: stable
31+
32+
- name: Install Node.js
33+
uses: actions/setup-node@v4
34+
with:
35+
node-version: ${{ env.NODE_VERSION }}
36+
37+
- name: Cache Rust dependencies
38+
uses: Swatinem/rust-cache@v2
39+
40+
- name: Build solana-mcp-server
41+
run: cargo build --release
42+
43+
- name: Install MCP Inspector and Zod
44+
run: |
45+
npm install -g ${{ env.INSPECTOR_PACKAGE }}
46+
npm install zod
47+
48+
- name: Create MCP Server Config
49+
run: |
50+
mkdir -p test-config
51+
cat <<EOF > test-config/mcp-config.json
52+
{
53+
"mcpServers": {
54+
"solana": {
55+
"command": "./target/release/solana-mcp-server",
56+
"args": ["stdio"],
57+
"env": {
58+
"SOLANA_RPC_URL": "https://api.devnet.solana.com",
59+
"SOLANA_COMMITMENT": "confirmed",
60+
"RUST_LOG": "info"
61+
}
62+
}
63+
}
64+
}
65+
EOF
66+
67+
- name: Test MCP Protocol Communication
68+
run: |
69+
echo "Testing MCP protocol communication with Solana server..."
70+
71+
# Test the server directly using Node.js to verify MCP protocol
72+
node <<'EOF'
73+
const { spawn } = require('child_process');
74+
const readline = require('readline');
75+
76+
// Start the server
77+
const server = spawn('./target/release/solana-mcp-server', ['stdio'], {
78+
env: {
79+
...process.env,
80+
SOLANA_RPC_URL: 'https://api.devnet.solana.com',
81+
SOLANA_COMMITMENT: 'confirmed',
82+
RUST_LOG: 'info'
83+
}
84+
});
85+
86+
let testResults = {
87+
initialize: false,
88+
toolsList: false
89+
};
90+
91+
// Handle server output
92+
server.stdout.on('data', (data) => {
93+
const lines = data.toString().split('\n');
94+
95+
for (const line of lines) {
96+
if (!line.trim()) continue;
97+
98+
try {
99+
const jsonResponse = JSON.parse(line);
100+
101+
// Check for initialize response
102+
if (jsonResponse.id === 1 && jsonResponse.result && jsonResponse.result.protocolVersion) {
103+
console.log('✅ Initialize response received with protocol version:', jsonResponse.result.protocolVersion);
104+
testResults.initialize = true;
105+
106+
// Wait a bit then send tools/list request
107+
setTimeout(() => {
108+
const toolsListRequest = {
109+
jsonrpc: "2.0",
110+
id: 2,
111+
method: "tools/list",
112+
params: {}
113+
};
114+
console.log('Sending tools/list request');
115+
server.stdin.write(JSON.stringify(toolsListRequest) + '\n');
116+
}, 1000);
117+
}
118+
119+
// Check for tools/list response
120+
if (jsonResponse.id === 2 && jsonResponse.result && jsonResponse.result.tools) {
121+
console.log('✅ Tools list response received with', jsonResponse.result.tools.length, 'tools');
122+
testResults.toolsList = true;
123+
124+
// Check if we have the expected Solana RPC methods
125+
const toolNames = jsonResponse.result.tools.map(tool => tool.name);
126+
const expectedMethods = ['getAccountInfo', 'getBalance', 'sendTransaction'];
127+
const hasExpectedMethods = expectedMethods.every(method => toolNames.includes(method));
128+
129+
if (hasExpectedMethods) {
130+
console.log('✅ Expected Solana RPC methods found in tools list');
131+
console.log('✅ All MCP protocol tests passed');
132+
server.kill();
133+
process.exit(0);
134+
} else {
135+
console.log('❌ Some expected Solana RPC methods missing from tools list');
136+
console.log('Missing methods:', expectedMethods.filter(method => !toolNames.includes(method)));
137+
server.kill();
138+
process.exit(1);
139+
}
140+
}
141+
} catch (e) {
142+
// This line is not JSON, probably a log message - ignore
143+
}
144+
}
145+
});
146+
147+
server.stderr.on('data', (data) => {
148+
console.error('Server error:', data.toString());
149+
});
150+
151+
server.on('close', (code) => {
152+
if (!testResults.initialize || !testResults.toolsList) {
153+
console.log('❌ MCP protocol test failed - missing required responses');
154+
process.exit(1);
155+
}
156+
});
157+
158+
// Send initialize request
159+
const initializeRequest = {
160+
jsonrpc: "2.0",
161+
id: 1,
162+
method: "initialize",
163+
params: {
164+
protocolVersion: "2024-11-05",
165+
capabilities: {},
166+
clientInfo: {
167+
name: "test-client",
168+
version: "1.0.0"
169+
}
170+
}
171+
};
172+
173+
server.stdin.write(JSON.stringify(initializeRequest) + '\n');
174+
175+
// Timeout after 60 seconds to allow for tool list delay
176+
setTimeout(() => {
177+
console.log('❌ Test timeout after 60 seconds');
178+
console.log('Test results so far:', testResults);
179+
server.kill();
180+
process.exit(1);
181+
}, 60000);
182+
EOF
183+
184+
- name: Upload Test Artifacts
185+
if: always()
186+
uses: actions/upload-artifact@v4
187+
with:
188+
name: mcp-test-artifacts
189+
path: |
190+
test-config/mcp-config.json
191+
retention-days: 7

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# Generated by Cargo
22
/target/
3-
Cargo.lock
43
logs/
54
logs-runtime.log
6-
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
5+
# Cargo.lock is tracked for executables to ensure reproducible builds
76
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
87

98
# These are backup files generated by rustfmt

0 commit comments

Comments
 (0)