fixing jsonSchema validation by using zod
This commit is contained in:
155
tests/fixtures/remote-client.js
vendored
Normal file
155
tests/fixtures/remote-client.js
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Example MCP Remote Client
|
||||
* Demonstrates SSE connection, Last-Event-ID resumption, and tool invocation
|
||||
*
|
||||
* Usage: node tests/fixtures/remote-client.js
|
||||
*/
|
||||
|
||||
import { EventSource } from 'eventsource';
|
||||
|
||||
const MCP_SERVER_URL = process.env.MCP_SERVER_URL || 'http://127.0.0.1:3000';
|
||||
const MCP_PROTOCOL_VERSION = '2025-06-18';
|
||||
|
||||
/**
|
||||
* Example: Connect to MCP server and invoke searchFlights tool
|
||||
*/
|
||||
async function exampleClient() {
|
||||
console.log(`Connecting to MCP server at ${MCP_SERVER_URL}...`);
|
||||
|
||||
// 1. Initialize connection - send initialize request
|
||||
// Per MCP spec: MCP-Protocol-Version header is NOT required during initialization
|
||||
const initRequest = {
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: 'initialize',
|
||||
params: {
|
||||
protocolVersion: MCP_PROTOCOL_VERSION,
|
||||
capabilities: {},
|
||||
clientInfo: {
|
||||
name: 'gds-mock-test-client',
|
||||
version: '1.0.0'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Sending initialize request (without MCP-Protocol-Version header)...');
|
||||
|
||||
const initResponse = await fetch(`${MCP_SERVER_URL}/mcp`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json, text/event-stream'
|
||||
// Note: MCP-Protocol-Version header NOT included during initialization
|
||||
},
|
||||
body: JSON.stringify(initRequest)
|
||||
});
|
||||
|
||||
const initResult = await initResponse.json();
|
||||
console.log('Server initialized:', JSON.stringify(initResult, null, 2));
|
||||
|
||||
// Note: Server runs in stateless mode (no MCP-Session-Id header will be present)
|
||||
// Each client can initialize independently without server-side session management
|
||||
const sessionId = initResponse.headers.get('MCP-Session-Id');
|
||||
if (sessionId) {
|
||||
console.log('Session ID:', sessionId);
|
||||
} else {
|
||||
console.log('Server running in stateless mode (no session ID)');
|
||||
}
|
||||
|
||||
// 2. Open SSE stream for server messages (now with MCP-Protocol-Version header)
|
||||
const eventSource = new EventSource(`${MCP_SERVER_URL}/mcp`, {
|
||||
headers: {
|
||||
'MCP-Protocol-Version': MCP_PROTOCOL_VERSION,
|
||||
...(sessionId && { 'MCP-Session-Id': sessionId })
|
||||
}
|
||||
});
|
||||
|
||||
let lastEventId = null;
|
||||
|
||||
// Handle SSE events
|
||||
eventSource.addEventListener('message', (event) => {
|
||||
console.log('Received SSE event:', event.data);
|
||||
lastEventId = event.lastEventId;
|
||||
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
// Extract session ID from InitializeResult
|
||||
if (data.result && data.result.protocolVersion) {
|
||||
console.log('Server initialized:', data.result);
|
||||
}
|
||||
} catch {
|
||||
// Empty data or non-JSON - expected per SSE polling pattern
|
||||
}
|
||||
});
|
||||
|
||||
eventSource.addEventListener('error', (error) => {
|
||||
console.error('SSE error:', error);
|
||||
});
|
||||
|
||||
// Wait for connection
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// 2. Send tool invocation via POST
|
||||
const searchRequest = {
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'searchFlights',
|
||||
arguments: {
|
||||
origin: 'JFK',
|
||||
destination: 'LAX',
|
||||
departureDate: '2026-05-01',
|
||||
passengers: 1,
|
||||
cabin: 'economy'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Sending searchFlights request...');
|
||||
|
||||
const response = await fetch(`${MCP_SERVER_URL}/mcp`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'MCP-Protocol-Version': MCP_PROTOCOL_VERSION,
|
||||
...(sessionId && { 'MCP-Session-Id': sessionId }),
|
||||
...(lastEventId && { 'Last-Event-ID': lastEventId })
|
||||
},
|
||||
body: JSON.stringify(searchRequest)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
console.log('Search results:', JSON.stringify(result, null, 2));
|
||||
|
||||
// 3. Demonstrate Last-Event-ID resumption
|
||||
if (lastEventId) {
|
||||
console.log(`\nReconnecting with Last-Event-ID: ${lastEventId}...`);
|
||||
|
||||
const resumedEventSource = new EventSource(`${MCP_SERVER_URL}/mcp`, {
|
||||
headers: {
|
||||
'MCP-Protocol-Version': MCP_PROTOCOL_VERSION,
|
||||
'Last-Event-ID': lastEventId
|
||||
}
|
||||
});
|
||||
|
||||
resumedEventSource.addEventListener('message', (event) => {
|
||||
console.log('Resumed stream event:', event.data);
|
||||
});
|
||||
|
||||
// Close after demonstration
|
||||
setTimeout(() => {
|
||||
resumedEventSource.close();
|
||||
eventSource.close();
|
||||
console.log('\nClient demonstration complete');
|
||||
process.exit(0);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Run example
|
||||
exampleClient().catch(err => {
|
||||
console.error('Client error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user