const http = require('http');
const https = require('https');
const readline = require('readline');
const MCP_URL = process.argv[2] || 'http://localhost:8080/mcp';
let sessionId = null;
const url = new URL(MCP_URL);
const client = url.protocol === 'https:' ? https : http;
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
async function sendRequest(jsonrpcRequest) {
return new Promise((resolve, reject) => {
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream'
};
if (sessionId) {
headers['Mcp-Session-Id'] = sessionId;
}
const data = JSON.stringify(jsonrpcRequest);
const options = {
method: 'POST',
headers: {
...headers,
'Content-Length': Buffer.byteLength(data)
}
};
const req = client.request(MCP_URL, options, (res) => {
const sid = res.headers['mcp-session-id'];
if (sid) {
sessionId = sid;
}
let responseData = '';
res.on('data', (chunk) => {
responseData += chunk.toString();
});
res.on('end', () => {
if (res.headers['content-type']?.includes('text/event-stream')) {
const lines = responseData.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const jsonData = line.substring(6);
resolve(jsonData);
return;
}
}
}
resolve(responseData);
});
});
req.on('error', (error) => {
reject(error);
});
req.write(data);
req.end();
});
}
async function sendNotification(jsonrpcNotification) {
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream'
};
if (sessionId) {
headers['Mcp-Session-Id'] = sessionId;
}
const data = JSON.stringify(jsonrpcNotification);
const options = {
method: 'POST',
headers: {
...headers,
'Content-Length': Buffer.byteLength(data)
}
};
return new Promise((resolve) => {
const req = client.request(MCP_URL, options, (res) => {
res.on('data', () => {}); res.on('end', () => resolve());
});
req.on('error', () => resolve());
req.write(data);
req.end();
});
}
rl.on('line', async (line) => {
try {
const message = JSON.parse(line);
const isNotification = !message.hasOwnProperty('id');
if (isNotification) {
await sendNotification(message);
} else {
const response = await sendRequest(message);
console.log(response);
}
} catch (error) {
const errorResponse = {
jsonrpc: '2.0',
id: null,
error: {
code: -32603,
message: error.message
}
};
console.log(JSON.stringify(errorResponse));
}
});
process.on('uncaughtException', (error) => {
console.error(JSON.stringify({
jsonrpc: '2.0',
id: null,
error: {
code: -32603,
message: error.message
}
}));
process.exit(1);
});
console.error(`[http-proxy] Connecting to ${MCP_URL}`);
console.error('[http-proxy] Ready for JSON-RPC messages on stdin');