Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
db59d1e
Initial plan
Copilot Aug 15, 2025
172dd65
Initial analysis and planning for MCP Inspector compatibility
Copilot Aug 15, 2025
5874296
Add GitHub Action for MCP Inspector testing and fix protocol schema s…
Copilot Aug 15, 2025
fd67af2
Fix MCP Inspector v0.16.2 compatibility by correcting protocol schema…
Copilot Aug 15, 2025
c2e7f67
Fix MCP protocol schema - remove tool definitions from capabilities.t…
Copilot Aug 15, 2025
1a05498
Implement all 91 RPC methods and WebSocket subscriptions per llms.txt…
Copilot Aug 15, 2025
972f8b6
Fix critical bug: remove duplicate method handlers to ensure consiste…
Copilot Aug 15, 2025
f49fa01
Add Cargo.lock file and remove it from .gitignore for reproducible bu…
Copilot Aug 15, 2025
c625922
Fix WebSocket benchmark compilation errors and remove unused function
Copilot Aug 15, 2025
83e9d49
Fix CI pipeline dependencies lock file error and missing test config
Copilot Aug 15, 2025
d7bd7a1
Fix MCP Inspector CI test by removing invalid --test-connection flag …
Copilot Aug 16, 2025
2a932eb
Update mcp-inspector.yml
0xrinegade Aug 16, 2025
e94d2db
Update mcp-inspector.yml
0xrinegade Aug 16, 2025
de7362e
Fix MCP Inspector workflow to use correct package name and testing ap…
Copilot Aug 16, 2025
685f4d8
Fix MCP Inspector CI test - handle mixed log/JSON output properly
Copilot Aug 16, 2025
68d8880
Add missing RPC methods to reach full API coverage per llms.txt
Copilot Aug 16, 2025
952abe5
Optimize benchmark performance by eliminating network overhead and fo…
Copilot Aug 16, 2025
8d01e9d
Restore real RPC calls in benchmarks - remove mocks and optimization …
Copilot Aug 16, 2025
87e2a97
Optimize benchmark performance - reduce sample counts and measurement…
Copilot Aug 16, 2025
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
191 changes: 191 additions & 0 deletions .github/workflows/mcp-inspector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: MCP Inspector Compatibility Test

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: full
NODE_VERSION: '18'
# Use the official MCP Inspector package
INSPECTOR_PACKAGE: '@modelcontextprotocol/[email protected]'

jobs:
mcp-inspector-test:
name: Test MCP Server with Inspector CLI
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2

- name: Build solana-mcp-server
run: cargo build --release

- name: Install MCP Inspector and Zod
run: |
npm install -g ${{ env.INSPECTOR_PACKAGE }}
npm install zod
- name: Create MCP Server Config
run: |
mkdir -p test-config
cat <<EOF > test-config/mcp-config.json
{
"mcpServers": {
"solana": {
"command": "./target/release/solana-mcp-server",
"args": ["stdio"],
"env": {
"SOLANA_RPC_URL": "https://api.devnet.solana.com",
"SOLANA_COMMITMENT": "confirmed",
"RUST_LOG": "info"
}
}
}
}
EOF
- name: Test MCP Protocol Communication
run: |
echo "Testing MCP protocol communication with Solana server..."
# Test the server directly using Node.js to verify MCP protocol
node <<'EOF'
const { spawn } = require('child_process');
const readline = require('readline');
// Start the server
const server = spawn('./target/release/solana-mcp-server', ['stdio'], {
env: {
...process.env,
SOLANA_RPC_URL: 'https://api.devnet.solana.com',
SOLANA_COMMITMENT: 'confirmed',
RUST_LOG: 'info'
}
});
let testResults = {
initialize: false,
toolsList: false
};
// Handle server output
server.stdout.on('data', (data) => {
const lines = data.toString().split('\n');
for (const line of lines) {
if (!line.trim()) continue;
try {
const jsonResponse = JSON.parse(line);
// Check for initialize response
if (jsonResponse.id === 1 && jsonResponse.result && jsonResponse.result.protocolVersion) {
console.log('✅ Initialize response received with protocol version:', jsonResponse.result.protocolVersion);
testResults.initialize = true;
// Wait a bit then send tools/list request
setTimeout(() => {
const toolsListRequest = {
jsonrpc: "2.0",
id: 2,
method: "tools/list",
params: {}
};
console.log('Sending tools/list request');
server.stdin.write(JSON.stringify(toolsListRequest) + '\n');
}, 1000);
}
// Check for tools/list response
if (jsonResponse.id === 2 && jsonResponse.result && jsonResponse.result.tools) {
console.log('✅ Tools list response received with', jsonResponse.result.tools.length, 'tools');
testResults.toolsList = true;
// Check if we have the expected Solana RPC methods
const toolNames = jsonResponse.result.tools.map(tool => tool.name);
const expectedMethods = ['getAccountInfo', 'getBalance', 'sendTransaction'];
const hasExpectedMethods = expectedMethods.every(method => toolNames.includes(method));
if (hasExpectedMethods) {
console.log('✅ Expected Solana RPC methods found in tools list');
console.log('✅ All MCP protocol tests passed');
server.kill();
process.exit(0);
} else {
console.log('❌ Some expected Solana RPC methods missing from tools list');
console.log('Missing methods:', expectedMethods.filter(method => !toolNames.includes(method)));
server.kill();
process.exit(1);
}
}
} catch (e) {
// This line is not JSON, probably a log message - ignore
}
}
});
server.stderr.on('data', (data) => {
console.error('Server error:', data.toString());
});
server.on('close', (code) => {
if (!testResults.initialize || !testResults.toolsList) {
console.log('❌ MCP protocol test failed - missing required responses');
process.exit(1);
}
});
// Send initialize request
const initializeRequest = {
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: {
name: "test-client",
version: "1.0.0"
}
}
};
server.stdin.write(JSON.stringify(initializeRequest) + '\n');
// Timeout after 60 seconds to allow for tool list delay
setTimeout(() => {
console.log('❌ Test timeout after 60 seconds');
console.log('Test results so far:', testResults);
server.kill();
process.exit(1);
}, 60000);
EOF
- name: Upload Test Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: mcp-test-artifacts
path: |
test-config/mcp-config.json
retention-days: 7
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Generated by Cargo
/target/
Cargo.lock
logs/
logs-runtime.log
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# Cargo.lock is tracked for executables to ensure reproducible builds
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

# These are backup files generated by rustfmt
Expand Down
Loading