@sigyl-dev/cli
Version:
Official Sigyl CLI for installing and managing MCP packages. Zero-config installation for public packages, secure API-based authentication.
153 lines • 5.5 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMCPStdioProxy = void 0;
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
class createMCPStdioProxy {
endpoint;
apiKey;
profile;
transport = null;
stdinBuffer = "";
isReady = false;
isShuttingDown = false;
constructor(options) {
this.endpoint = options.endpoint;
this.apiKey = options.apiKey;
this.profile = options.profile;
}
async start() {
console.error(`🚀 Starting MCP proxy for package...`);
console.error(` Endpoint: ${this.endpoint}`);
if (this.profile) {
console.error(` Profile: ${this.profile}`);
}
await this.setupTransport();
this.setupStdinHandling();
this.setupProcessHandlers();
}
async setupTransport() {
try {
// Use the endpoint as provided (do not append /mcp)
const endpoint = this.endpoint;
// Create the transport URL with query parameters
const url = new URL(endpoint);
// Add API key as query parameter
url.searchParams.set("apiKey", this.apiKey);
// Add profile if provided
if (this.profile) {
url.searchParams.set("profile", this.profile);
}
console.error(`[DEBUG] Connecting to: ${url.toString()}`);
// Create the MCP transport
this.transport = new streamableHttp_js_1.StreamableHTTPClientTransport(url);
// Set up message handler
this.transport.onmessage = (message) => {
try {
if ("error" in message) {
const errorMessage = message;
console.error(`[DEBUG] Received error: ${JSON.stringify(errorMessage)}`);
}
// Forward the message to stdout for Claude
console.log(JSON.stringify(message));
}
catch (error) {
console.error(`[DEBUG] Error handling message:`, error);
}
};
// Set up error handler
this.transport.onerror = (error) => {
console.error(`[DEBUG] Transport error: ${error.message}`);
};
// Set up close handler
this.transport.onclose = () => {
console.error(`[DEBUG] Transport closed`);
if (!this.isShuttingDown) {
process.exit(1);
}
};
// Start the transport
this.transport.start();
this.isReady = true;
console.error(`[DEBUG] Transport started successfully`);
}
catch (error) {
console.error(`[DEBUG] Failed to setup transport:`, error);
process.exit(1);
}
}
setupStdinHandling() {
// Handle stdin data
process.stdin.on("data", (data) => {
this.handleIncomingData(data.toString());
});
// Handle stdin end (client disconnect)
process.stdin.on("end", () => {
console.error(`[DEBUG] STDIN closed (client disconnected)`);
this.cleanup();
});
// Handle stdin errors
process.stdin.on("error", (error) => {
console.error(`[DEBUG] STDIN error:`, error);
this.cleanup();
});
}
setupProcessHandlers() {
// Handle process termination signals
process.on("SIGINT", () => {
console.error(`[DEBUG] Received SIGINT, cleaning up...`);
this.cleanup();
});
process.on("SIGTERM", () => {
console.error(`[DEBUG] Received SIGTERM, cleaning up...`);
this.cleanup();
});
process.on("beforeExit", () => {
console.error(`[DEBUG] Process exiting, cleaning up...`);
this.cleanup();
});
}
handleIncomingData(chunk) {
if (!this.isReady || !this.transport)
return;
this.stdinBuffer += chunk;
// Process complete JSON-RPC messages (line-delimited)
const lines = this.stdinBuffer.split(/\r?\n/);
this.stdinBuffer = lines.pop() || "";
for (const line of lines) {
if (line.trim()) {
this.processMessage(line.trim());
}
}
}
async processMessage(messageStr) {
try {
const message = JSON.parse(messageStr);
console.error(`[DEBUG] Forwarding message: ${JSON.stringify(message)}`);
if (this.transport) {
await this.transport.send(message);
}
}
catch (error) {
console.error(`[DEBUG] Error processing message:`, error);
console.error(`[DEBUG] Invalid message: ${messageStr}`);
}
}
cleanup() {
if (this.isShuttingDown)
return;
this.isShuttingDown = true;
console.error(`[DEBUG] Cleaning up MCP proxy...`);
if (this.transport) {
try {
this.transport.close();
}
catch (error) {
console.error(`[DEBUG] Error closing transport:`, error);
}
this.transport = null;
}
process.exit(0);
}
}
exports.createMCPStdioProxy = createMCPStdioProxy;
//# sourceMappingURL=mcp-proxy.js.map
;