MCP Proxy Server
by adamwattis
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { ServerConfig } from './config.js';
const sleep = (time: number) => new Promise<void>(resolve => setTimeout(() => resolve(), time))
export interface ConnectedClient {
client: Client;
cleanup: () => Promise<void>;
name: string;
}
const createClient = (server: ServerConfig): { client: Client | undefined, transport: Transport | undefined } => {
let transport: Transport | null = null
try {
if (server.transport.type === 'sse') {
transport = new SSEClientTransport(new URL(server.transport.url));
} else {
transport = new StdioClientTransport({
command: server.transport.command,
args: server.transport.args,
env: server.transport.env ? server.transport.env.reduce((o, v) => ({
[v]: process.env[v] || ''
}), {}) : undefined
});
}
} catch (error) {
console.error(`Failed to create transport ${server.transport.type || 'stdio'} to ${server.name}:`, error);
}
if (!transport) {
console.warn(`Transport ${server.name} not available.`)
return { transport: undefined, client: undefined }
}
const client = new Client({
name: 'mcp-proxy-client',
version: '1.0.0',
}, {
capabilities: {
prompts: {},
resources: { subscribe: true },
tools: {}
}
});
return { client, transport }
}
export const createClients = async (servers: ServerConfig[]): Promise<ConnectedClient[]> => {
const clients: ConnectedClient[] = [];
for (const server of servers) {
console.log(`Connecting to server: ${server.name}`);
const waitFor = 2500
const retries = 3
let count = 0
let retry = true
while (retry) {
const { client, transport } = createClient(server)
if (!client || !transport) {
break
}
try {
await client.connect(transport);
console.log(`Connected to server: ${server.name}`);
clients.push({
client,
name: server.name,
cleanup: async () => {
await transport.close();
}
});
break
} catch (error) {
console.error(`Failed to connect to ${server.name}:`, error);
count++
retry = (count < retries)
if (retry) {
try {
await client.close()
} catch { }
console.log(`Retry connection to ${server.name} in ${waitFor}ms (${count}/${retries})`);
await sleep(waitFor)
}
}
}
}
return clients;
};