Skip to content

Commit 1713b88

Browse files
authored
Merge pull request #38 from openSVM/copilot/fix-37
Fix MCP Inspector CI timeout by correcting protocol version mismatch
2 parents a99937f + c47855f commit 1713b88

File tree

2 files changed

+93
-52
lines changed

2 files changed

+93
-52
lines changed

.github/workflows/mcp-inspector.yml

Lines changed: 92 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,13 @@ jobs:
8484
});
8585
8686
let testResults = {
87+
protocolNotification: false,
8788
initialize: false,
8889
toolsList: false
8990
};
9091
92+
let serverReady = false;
93+
9194
// Handle server output
9295
server.stdout.on('data', (data) => {
9396
const lines = data.toString().split('\n');
@@ -98,87 +101,125 @@ jobs:
98101
try {
99102
const jsonResponse = JSON.parse(line);
100103
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;
104+
// Handle protocol notification (server ready)
105+
if (jsonResponse.method === 'protocol' && jsonResponse.params && jsonResponse.params.version) {
106+
console.log('✅ Protocol notification received, server version:', jsonResponse.params.version);
107+
testResults.protocolNotification = true;
108+
serverReady = true;
105109
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);
110+
// Server is ready, send initialize request
111+
console.log('Sending initialize request...');
112+
const initializeRequest = {
113+
jsonrpc: "2.0",
114+
id: 1,
115+
method: "initialize",
116+
params: {
117+
protocolVersion: "2025-06-18",
118+
capabilities: {},
119+
clientInfo: {
120+
name: "test-client",
121+
version: "1.0.0"
122+
}
123+
}
124+
};
125+
server.stdin.write(JSON.stringify(initializeRequest) + '\n');
126+
return;
117127
}
118128
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');
129+
// Check for initialize response
130+
if (jsonResponse.id === 1) {
131+
if (jsonResponse.result && jsonResponse.result.protocolVersion) {
132+
console.log('✅ Initialize response received with protocol version:', jsonResponse.result.protocolVersion);
133+
testResults.initialize = true;
134+
135+
// Wait a bit then send tools/list request
136+
setTimeout(() => {
137+
const toolsListRequest = {
138+
jsonrpc: "2.0",
139+
id: 2,
140+
method: "tools/list",
141+
params: {}
142+
};
143+
console.log('Sending tools/list request...');
144+
server.stdin.write(JSON.stringify(toolsListRequest) + '\n');
145+
}, 100);
146+
} else if (jsonResponse.error) {
147+
console.log('❌ Initialize failed with error:', jsonResponse.error);
132148
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)));
149+
process.exit(1);
150+
}
151+
}
152+
153+
// Check for tools/list response
154+
if (jsonResponse.id === 2) {
155+
if (jsonResponse.result && jsonResponse.result.tools) {
156+
console.log('✅ Tools list response received with', jsonResponse.result.tools.length, 'tools');
157+
testResults.toolsList = true;
158+
159+
// Check if we have the expected Solana RPC methods
160+
const toolNames = jsonResponse.result.tools.map(tool => tool.name);
161+
const expectedMethods = ['getAccountInfo', 'getBalance', 'sendTransaction'];
162+
const hasExpectedMethods = expectedMethods.every(method => toolNames.includes(method));
163+
164+
console.log('Available tools:', toolNames.slice(0, 10).join(', '), '... (total:', toolNames.length, ')');
165+
166+
if (hasExpectedMethods) {
167+
console.log('✅ Expected Solana RPC methods found in tools list');
168+
console.log('✅ All MCP protocol tests passed');
169+
server.kill();
170+
process.exit(0);
171+
} else {
172+
console.log('❌ Some expected Solana RPC methods missing from tools list');
173+
console.log('Missing methods:', expectedMethods.filter(method => !toolNames.includes(method)));
174+
server.kill();
175+
process.exit(1);
176+
}
177+
} else if (jsonResponse.error) {
178+
console.log('❌ Tools list failed with error:', jsonResponse.error);
137179
server.kill();
138180
process.exit(1);
139181
}
140182
}
141183
} catch (e) {
142184
// This line is not JSON, probably a log message - ignore
185+
console.log('Non-JSON output:', line.substring(0, 100));
143186
}
144187
}
145188
});
146189
147190
server.stderr.on('data', (data) => {
148-
console.error('Server error:', data.toString());
191+
// Server logs go to stderr - only show if there are actual errors
192+
const output = data.toString();
193+
if (output.includes('"level":"ERROR"') || output.includes('error') || output.includes('Error')) {
194+
console.error('Server error:', output);
195+
}
149196
});
150197
151198
server.on('close', (code) => {
199+
console.log('Server process closed with code:', code);
152200
if (!testResults.initialize || !testResults.toolsList) {
153201
console.log('❌ MCP protocol test failed - missing required responses');
202+
console.log('Test results:', testResults);
154203
process.exit(1);
155204
}
156205
});
157206
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-
};
207+
server.on('error', (err) => {
208+
console.error('❌ Failed to start server:', err);
209+
process.exit(1);
210+
});
172211
173-
server.stdin.write(JSON.stringify(initializeRequest) + '\n');
212+
// Wait for server to be ready, then the protocol notification will trigger the initialize request
213+
console.log('Waiting for server to start and send protocol notification...');
174214
175-
// Timeout after 60 seconds to allow for tool list delay
215+
// Timeout after 30 seconds (reduced from 60)
176216
setTimeout(() => {
177-
console.log('❌ Test timeout after 60 seconds');
217+
console.log('❌ Test timeout after 30 seconds');
178218
console.log('Test results so far:', testResults);
219+
console.log('Server ready status:', serverReady);
179220
server.kill();
180221
process.exit(1);
181-
}, 60000);
222+
}, 30000);
182223
EOF
183224
184225
- name: Upload Test Artifacts

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)