Orel MAZOR
tiny-agent
d4f5807
#!/usr/bin/env node
import {
JSONRPCMessageSchema,
NodeOAuthClientProvider,
connectToRemoteServer,
createLazyAuthCoordinator,
getServerUrlHash,
log,
mcpProxy,
parseCommandLineArgs,
setupSignalHandlers
} from "./chunk-4PNJQ7WT.js";
// src/proxy.ts
import { EventEmitter } from "events";
// node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
import process2 from "node:process";
// node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
var ReadBuffer = class {
append(chunk) {
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
}
readMessage() {
if (!this._buffer) {
return null;
}
const index = this._buffer.indexOf("\n");
if (index === -1) {
return null;
}
const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
this._buffer = this._buffer.subarray(index + 1);
return deserializeMessage(line);
}
clear() {
this._buffer = void 0;
}
};
function deserializeMessage(line) {
return JSONRPCMessageSchema.parse(JSON.parse(line));
}
function serializeMessage(message) {
return JSON.stringify(message) + "\n";
}
// node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
var StdioServerTransport = class {
constructor(_stdin = process2.stdin, _stdout = process2.stdout) {
this._stdin = _stdin;
this._stdout = _stdout;
this._readBuffer = new ReadBuffer();
this._started = false;
this._ondata = (chunk) => {
this._readBuffer.append(chunk);
this.processReadBuffer();
};
this._onerror = (error) => {
var _a;
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, error);
};
}
/**
* Starts listening for messages on stdin.
*/
async start() {
if (this._started) {
throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
}
this._started = true;
this._stdin.on("data", this._ondata);
this._stdin.on("error", this._onerror);
}
processReadBuffer() {
var _a, _b;
while (true) {
try {
const message = this._readBuffer.readMessage();
if (message === null) {
break;
}
(_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, message);
} catch (error) {
(_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error);
}
}
}
async close() {
var _a;
this._stdin.off("data", this._ondata);
this._stdin.off("error", this._onerror);
const remainingDataListeners = this._stdin.listenerCount("data");
if (remainingDataListeners === 0) {
this._stdin.pause();
}
this._readBuffer.clear();
(_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this);
}
send(message) {
return new Promise((resolve) => {
const json = serializeMessage(message);
if (this._stdout.write(json)) {
resolve();
} else {
this._stdout.once("drain", resolve);
}
});
}
};
// src/proxy.ts
async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "http-first", host, staticOAuthClientMetadata, staticOAuthClientInfo) {
const events = new EventEmitter();
const serverUrlHash = getServerUrlHash(serverUrl);
const authCoordinator = createLazyAuthCoordinator(serverUrlHash, callbackPort, events);
const authProvider = new NodeOAuthClientProvider({
serverUrl,
callbackPort,
host,
clientName: "MCP CLI Proxy",
staticOAuthClientMetadata,
staticOAuthClientInfo
});
const localTransport = new StdioServerTransport();
let server = null;
const authInitializer = async () => {
const authState = await authCoordinator.initializeAuth();
server = authState.server;
if (authState.skipBrowserAuth) {
log("Authentication was completed by another instance - will use tokens from disk");
await new Promise((res) => setTimeout(res, 1e3));
}
return {
waitForAuthCode: authState.waitForAuthCode,
skipBrowserAuth: authState.skipBrowserAuth
};
};
try {
const remoteTransport = await connectToRemoteServer(null, serverUrl, authProvider, headers, authInitializer, transportStrategy);
mcpProxy({
transportToClient: localTransport,
transportToServer: remoteTransport
});
await localTransport.start();
log("Local STDIO server running");
log(`Proxy established successfully between local STDIO and remote ${remoteTransport.constructor.name}`);
log("Press Ctrl+C to exit");
const cleanup = async () => {
await remoteTransport.close();
await localTransport.close();
if (server) {
server.close();
}
};
setupSignalHandlers(cleanup);
} catch (error) {
log("Fatal error:", error);
if (error instanceof Error && error.message.includes("self-signed certificate in certificate chain")) {
log(`You may be behind a VPN!
If you are behind a VPN, you can try setting the NODE_EXTRA_CA_CERTS environment variable to point
to the CA certificate file. If using claude_desktop_config.json, this might look like:
{
"mcpServers": {
"\${mcpServerName}": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote.mcp.server/sse"
],
"env": {
"NODE_EXTRA_CA_CERTS": "\${your CA certificate file path}.pem"
}
}
}
}
`);
}
if (server) {
server.close();
}
process.exit(1);
}
}
parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx proxy.ts <https://server-url> [callback-port] [--debug]").then(({ serverUrl, callbackPort, headers, transportStrategy, host, debug, staticOAuthClientMetadata, staticOAuthClientInfo }) => {
return runProxy(serverUrl, callbackPort, headers, transportStrategy, host, staticOAuthClientMetadata, staticOAuthClientInfo);
}).catch((error) => {
log("Fatal error:", error);
process.exit(1);
});