import { createRouter, type ServerConfig } from '@surf-lab/mcprouter';
import { createOpenAI } from '@ai-sdk/openai';
import {
createBoundedModel,
createRoutingModel,
createModelRanker,
} from '@surf-lab/mcprouter/ai-sdk';
function env(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Missing ${name}`);
return value;
}
const connection = {
baseURL: env('MODEL_BASE_URL'),
apiKey: env('MODEL_API_KEY'),
};
function connectModel(modelId: string) {
const model = createBoundedModel({
fetch: globalThis.fetch,
createModel: fetch => createOpenAI({ ...connection, fetch }).chat(modelId),
});
return {
routing: createRoutingModel({ model }),
ranking: createModelRanker({ model }),
};
}
const models = {
general: connectModel(env('GENERAL_MODEL_ID')),
database: connectModel(env('DATABASE_MODEL_ID')),
billing: connectModel(env('BILLING_MODEL_ID')),
};
const mcpServers: ServerConfig[] = [
{ serverId: 'database-server', transport: 'http',
url: env('DATABASE_MCP_URL'),
headers: { Authorization: `Bearer ${env('DATABASE_MCP_TOKEN')}` } },
{ serverId: 'billing-server', transport: 'http',
url: env('BILLING_MCP_URL'),
headers: { Authorization: `Bearer ${env('BILLING_MCP_TOKEN')}` } },
];
function createAppRouter() {
return createRouter({
models,
model: 'general',
policy: {
modelBindings: {
servers: { 'database-server': 'database', 'billing-server': 'general' },
tools: [{ serverId: 'billing-server',
toolName: 'get_customer_balance', model: 'billing' }],
},
modelAccess: { allowedModels: ['general', 'database', 'billing'] },
eligibility: (tool, context) => context.role === 'reader' &&
'serverId' in tool &&
(tool.serverId === 'database-server' && tool.name === 'list_tables' ||
tool.serverId === 'billing-server' && tool.name === 'get_customer_balance'),
authorize: (call, context) => {
const target = `${call.origin.serverId}/${call.descriptor.upstreamName}`;
if (context.role !== 'reader') return { decision: 'deny' };
if (target === 'database-server/list_tables') return { decision: 'allow' };
if (target === 'billing-server/get_customer_balance' &&
typeof context.customerId === 'string' && context.customerId &&
call.arguments.customerId === context.customerId) return { decision: 'allow' };
return { decision: 'deny' };
},
revision: () => 1,
},
});
}