#!/usr/bin/env node
/**
* Simple test script to verify the MCP server is working
* Uses streaming response handling for MCP protocol
*/
const BASE_URL = process.env.MCP_URL || "http://localhost:3000/api/mcp";
// Helper to parse SSE response
function parseSSE(text) {
const lines = text.trim().split("\n");
for (const line of lines) {
if (line.startsWith("data: ")) {
try {
return JSON.parse(line.slice(6));
} catch (e) {
console.error("Failed to parse:", line);
}
}
}
try {
return JSON.parse(text);
} catch (e) {
return null;
}
}
// Helper to make MCP request and read first SSE message
async function mcpRequest(method, params, sessionId = null) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000);
try {
const response = await fetch(BASE_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json, text/event-stream",
...(sessionId && { "mcp-session-id": sessionId }),
},
body: JSON.stringify({
jsonrpc: "2.0",
id: Date.now(),
method,
params,
}),
signal: controller.signal,
});
// Read the stream until we get a complete SSE message
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// Check if we have a complete SSE message (ends with \n\n)
if (buffer.includes("\n\n")) {
reader.cancel();
break;
}
}
clearTimeout(timeout);
// Extract session ID from headers
const newSessionId = response.headers.get("mcp-session-id");
return {
data: parseSSE(buffer),
sessionId: newSessionId || sessionId,
raw: buffer,
};
} catch (error) {
clearTimeout(timeout);
throw error;
}
}
async function testMCP() {
console.log("Testing MCP server at:", BASE_URL);
console.log("---");
// Test 1: Initialize
console.log("1. Testing initialize...");
const init = await mcpRequest("initialize", {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: { name: "test-script", version: "1.0.0" },
});
console.log("Raw response:", init.raw);
if (init.data?.result?.serverInfo) {
console.log("✓ Server initialized:", init.data.result.serverInfo.name);
}
console.log("Session ID:", init.sessionId || "(none)");
console.log("---");
// Test 2: List tools
console.log("\n2. Testing tools/list...");
const tools = await mcpRequest("tools/list", {}, init.sessionId);
console.log("Raw response:", tools.raw);
if (tools.data?.result?.tools) {
console.log("✓ Tools found:", tools.data.result.tools.length);
for (const tool of tools.data.result.tools) {
console.log(
" -",
tool.name + ":",
(tool.description || "").slice(0, 60) + "...",
);
}
}
console.log("---");
// Test 3: Call the tool
console.log("\n3. Testing get_worcester_departures...");
const call = await mcpRequest(
"tools/call",
{
name: "get_worcester_departures",
arguments: {
stop: "South Station",
direction: "outbound",
limit: 3,
},
},
tools.sessionId,
);
console.log("Raw response:", call.raw);
if (call.data?.result?.content) {
console.log("✓ Tool response:");
for (const item of call.data.result.content) {
if (item.type === "text") {
console.log(item.text);
}
}
} else if (call.data?.error) {
console.log("✗ Error:", call.data.error.message);
}
console.log("\n---\nDone!");
}
testMCP().catch(console.error);