MCP Gateway: herramientas para tus agentes
MCP Gateway: herramientas para tus agentes
En el capítulo anterior sobre governance aprendiste a controlar quién puede usar tus modelos, cuánto gasta y con qué límites. Pero hasta ahora tus modelos solo sabían generar texto. En cuanto quieres construir un agente de verdad, el modelo necesita hacer cosas: leer un archivo, buscar en la web, consultar una base de datos o disparar lógica de negocio. Ese es exactamente el problema que resuelve este capítulo.
Bifrost incorpora un MCP Gateway: un punto único donde conectas múltiples servidores de herramientas y los expones a tus LLMs de forma unificada, filtrada por virtual key y con control total sobre cuándo y cómo se ejecuta cada tool. En este capítulo pasarás de no tener herramientas a orquestar decenas de ellas de forma segura, eficiente en tokens y gobernada.
Versión requerida: la función de MCP Gateway está disponible a partir de
v1.4.0-prerelease1. Es exclusiva del modo Gateway (despliegue HTTP); el Go SDK tiene su propia API de MCP que veremos más adelante.
¿Qué es MCP y por qué Bifrost actúa como gateway?
Model Context Protocol (MCP) es un estándar abierto que permite a los modelos de IA descubrir y ejecutar herramientas externas en tiempo de ejecución. En lugar de quedar confinado a generar texto, un modelo puede interactuar con un sistema de archivos, hacer búsquedas web, acceder a bases de datos o invocar lógica de negocio propia, todo a través de servidores MCP externos.
El problema aparece cuando tienes varios servidores MCP: uno para el filesystem, otro para búsqueda web, otro para tu base de datos, otro para tu CRM. Cada aplicación tendría que conectarse a todos, gestionar credenciales por separado, manejar reconexiones y decidir qué herramientas expone a cada usuario. Eso no escala.
Bifrost resuelve esto colocándose en el medio. Cumple un rol dual:
- Cliente MCP: se conecta a servidores MCP externos (bases de datos, herramientas de filesystem, búsqueda web) y consume sus herramientas.
- Servidor MCP: expone todas esas herramientas agregadas a clientes externos como Claude Desktop, Cursor o tu propia aplicación.
Cuando combinas ambos roles obtienes el modo gateway: Bifrost es un puente entre tu aplicación y tanto los servidores upstream como los clientes downstream. Tu modelo ve un único catálogo de herramientas, sin importar de cuántos servidores provengan.
flowchart LR
subgraph clientes["Clientes / LLMs"]
A["Tu app<br/>(chat completions)"]
B["Claude Desktop /<br/>Cursor"]
end
subgraph bifrost["Bifrost MCP Gateway"]
GW["Catalogo unificado<br/>de herramientas<br/>+ filtrado por virtual key"]
end
subgraph servidores["Servidores MCP (upstream)"]
S1["filesystem<br/>(stdio)"]
S2["web_search<br/>(http)"]
S3["database<br/>(http)"]
S4["live-data<br/>(sse)"]
end
A -->|"/v1/chat/completions"| GW
B -->|"/mcp (JSON-RPC)"| GW
GW --> S1
GW --> S2
GW --> S3
GW --> S4
Una característica de seguridad clave: por defecto Bifrost NO ejecuta automáticamente las tool calls. Cuando el modelo sugiere usar una herramienta, tu aplicación decide si la aprueba y luego pide la ejecución explícitamente. La auto-ejecución es estrictamente opt-in mediante el Agent Mode, que veremos más abajo. Esto te da supervisión humana, validación de seguridad y auditoría por defecto.
Conectar a servidores MCP
Bifrost soporta tres protocolos de conexión:
- STDIO: procesos locales (lanza un comando y se comunica por stdin/stdout). Ideal para servidores que corren como binarios o paquetes npm.
- HTTP: APIs remotas. Para servidores MCP accesibles por una URL.
- SSE: Server-Sent Events, conexiones persistentes en streaming.
Conexión STDIO
Para un servidor local, como el clásico servidor de filesystem, usas connection_type: "stdio" y describes el comando en stdio_config:
{
"name": "filesystem",
"connection_type": "stdio",
"is_ping_available": true,
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"],
"envs": ["HOME", "PATH"]
},
"tools_to_execute": ["*"]
}
Los campos del bloque stdio_config son:
command: el ejecutable a lanzar.args: array de argumentos de línea de comandos.envs: variables de entorno que se heredan del proceso padre.
Conexión HTTP
Para un servidor remoto, usas connection_type: "http" y apuntas a su URL con connection_string:
{
"name": "web_search",
"connection_type": "http",
"connection_string": "https://mcp-server.example.com/mcp",
"is_ping_available": false,
"tools_to_execute": ["search", "fetch_url"]
}
Conexión SSE
Para una conexión persistente en streaming:
{
"name": "live-data",
"connection_type": "sse",
"connection_string": "https://stream.example.com/mcp/sse",
"is_ping_available": true,
"tools_to_execute": ["*"]
}
Variables de entorno para secretos
Nunca pongas URLs ni tokens sensibles en texto plano. Usa la sintaxis env.NOMBRE_VARIABLE y Bifrost sustituirá el valor en tiempo de ejecución (mismo patrón que viste en configuración):
{
"connection_string": "env.SECURE_MCP_URL"
}
Campo tools_to_execute
Este campo, presente en cada cliente MCP, define qué herramientas expone ese servidor:
["*"]incluye todas las herramientas.[](o ausente) no incluye ninguna: deny-by-default.["tool1", "tool2"]allowlist de herramientas específicas.
Reglas de nombres
Los nombres de los clientes MCP deben ser solo ASCII, no pueden contener guiones ni espacios y no pueden empezar con un número. Esto es importante porque, como verás, los nombres de las tools se prefijan con el nombre del cliente.
Dar de alta clientes por API
Además de config.json, puedes gestionar clientes MCP en caliente con la API de gestión:
curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"]
},
"tools_to_execute": ["read_file", "list_directory"]
}'
Los endpoints de gestión de clientes son:
| Acción | Método y ruta |
|---|---|
| Agregar cliente | POST /api/mcp/client |
| Listar clientes | GET /api/mcp/clients |
| Actualizar cliente | PUT /api/mcp/client/{id} |
| Eliminar cliente | DELETE /api/mcp/client/{id} |
| Reconectar cliente | POST /api/mcp/client/{id}/reconnect |
Para inspeccionar el estado actual (clientes conectados, herramientas disponibles, estado de conexión) usa el listado, muy útil al depurar:
curl http://localhost:8080/api/mcp/clients
Bifrost como MCP gateway: agrega y expone
Una vez conectados varios servidores, Bifrost los agrega y los expone de dos maneras complementarias.
A tus LLMs: inyección automática de tools
Cuando haces una petición a /v1/chat/completions, Bifrost inyecta automáticamente las definiciones de las herramientas disponibles en el request hacia el modelo. El modelo, al recibir el catálogo, puede decidir llamar a cualquiera de ellas. No tienes que pasar manualmente las tools en cada request: Bifrost lo hace por ti.
Las herramientas siguen una convención de nombres prefijada para garantizar unicidad entre clientes: clientName_toolName (por ejemplo, filesystem_read_file, filesystem_list_directory).
Si prefieres tener control explícito, puedes desactivar la inyección automática con el campo mcp_disable_auto_tool_inject:
{
"client": {
"mcp_disable_auto_tool_inject": true
}
}
También puedes cambiarlo en caliente por API:
curl -X PUT http://localhost:8080/api/config \
-H "Content-Type: application/json" \
-d '{
"client_config": {
"mcp_disable_auto_tool_inject": true
}
}'
Con la inyección desactivada, eliges qué tools incluir por request con un header:
curl -X POST http://localhost:8080/v1/chat/completions \
-H "x-bf-mcp-include-tools: filesystem-*,github-create_issue" \
-d '{ "model": "openai/gpt-4o", "messages": [] }'
A clientes externos: el endpoint /mcp
Bifrost también expone él mismo como un servidor MCP en el endpoint /mcp, usando JSON-RPC 2.0. Esto permite que clientes como Claude Desktop o Cursor accedan a todas las herramientas agregadas a través de un único punto.
Listar las herramientas disponibles:
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'
Ejecutar una herramienta vía JSON-RPC:
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "filesystem_read_file",
"arguments": {
"path": "/tmp/test.txt"
}
}
}'
Para una conexión persistente, el endpoint acepta SSE por GET:
curl -N http://localhost:8080/mcp \
-H "Accept: text/event-stream"
Integración con Claude Desktop
Configurar Claude Desktop para usar Bifrost como su servidor MCP es tan simple como apuntar a la URL y pasar una virtual key en los headers. Así, todas las herramientas que conectaste en Bifrost aparecen dentro de Claude Desktop, filtradas según la key:
{
"mcpServers": {
"bifrost-production": {
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer vk_your_production_key"
}
},
"bifrost-development": {
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer vk_your_development_key"
}
}
}
}
Detrás de un reverse proxy
Si Bifrost corre detrás de un reverse proxy, usa mcp_external_client_url para anunciar la URL pública correcta a los clientes:
{
"client": {
"mcp_external_client_url": "https://your-public-domain.com"
}
}
Health monitoring
El gateway vigila la salud de cada conexión MCP y reintenta con backoff exponencial ante fallos transitorios. Puedes ajustar el monitoreo:
{
"mcp": {
"health_monitor_config": {
"check_interval": "10s",
"check_timeout": "5s",
"max_consecutive_failures": 5
}
}
}
Tool filtering: qué herramientas ve cada virtual key
No todas las herramientas deben estar disponibles para todos. Un equipo de soporte quizá solo necesite buscar en la base de conocimiento; producción no debería poder borrar archivos. Bifrost implementa un filtrado en tres niveles que se combinan con lógica AND (intersección): una herramienta debe pasar todos los filtros aplicables para llegar al modelo.
flowchart TD
L1["Nivel 1: Client config<br/>tools_to_execute<br/>(baseline por servidor)"]
L2["Nivel 2: Request headers<br/>x-bf-mcp-include-clients<br/>x-bf-mcp-include-tools"]
L3["Nivel 3: Virtual Key<br/>mcp_configs<br/>(governance, deny-by-default)"]
R["Herramientas que ve el LLM"]
L1 --> L2 --> L3 --> R
L3 -.->|"override de los<br/>headers del request"| R
Nivel 1: configuración del cliente
El campo tools_to_execute de cada cliente establece la disponibilidad base, como vimos antes (["*"], [], o lista específica). Es el techo: ninguna tool fuera de aquí estará jamás disponible.
Nivel 2: filtrado por request
Para filtrado dinámico por petición usas dos headers HTTP en el gateway:
x-bf-mcp-include-clients: indica de qué clientes se exponen las herramientas.x-bf-mcp-include-tools: indica tools exactas con el formatoclientName-toolName.
# Solo herramientas de ciertos clientes
-H "x-bf-mcp-include-clients: filesystem,web_search"
# Tools especificas
-H "x-bf-mcp-include-tools: filesystem-read_file,web_search-search"
# Comodin para todas las tools de un cliente
-H "x-bf-mcp-include-tools: filesystem-*,web_search-search"
# Un header vacio bloquea TODAS las tools
-H "x-bf-mcp-include-clients:"
Las tools internas registradas en Bifrost se referencian con el prefijo bifrostInternal- (por ejemplo, bifrostInternal-echo).
Nivel 3: filtrado por virtual key (governance)
Aquí es donde el MCP gateway se conecta directamente con la governance. Cada virtual key declara su acceso a herramientas en el campo mcp_configs. Y lo importante: este nivel sobreescribe los headers del request. Una key no puede usar más herramientas de las que su política permite, sin importar lo que pida el cliente.
{
"governance": {
"virtual_keys": [
{
"name": "support-team-key",
"mcp_configs": [
{
"mcp_client_name": "knowledge_base",
"tools_to_execute": ["search", "get_article"]
},
{
"mcp_client_name": "ticketing",
"tools_to_execute": ["*"]
}
]
}
]
}
}
También por API:
curl -X POST http://localhost:8080/api/governance/virtual-keys \
-H "Content-Type: application/json" \
-d '{
"name": "support-team-key",
"mcp_configs": [
{
"mcp_client_name": "knowledge_base",
"tools_to_execute": ["search", "get_article"]
},
{
"mcp_client_name": "ticketing",
"tools_to_execute": ["*"]
}
]
}'
La semántica de mcp_configs por virtual key es:
| Configuración | Resultado |
|---|---|
tools_to_execute: ["*"] | Todas las tools de ese cliente |
tools_to_execute: [] | Ninguna tool de ese cliente |
tools_to_execute: ["a", "b"] | Solo las indicadas |
| Cliente no listado | Todas sus tools bloqueadas |
Deny-by-default: cuando una virtual key no tiene ninguna configuración MCP, no tiene acceso a ninguna herramienta. Debes habilitarlas explícitamente.
Ejemplo de precedencia
Imagina que el cliente filesystem permite ["read_file", "write_file", "delete_file"], pero la key prod-key lo restringe a ["read_file"]. Aunque el request pida explícitamente write_file:
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer vk_prod_key" \
-H "x-bf-mcp-include-tools: filesystem-write_file"
El resultado es que solo read_file queda disponible: la configuración de la virtual key gana sobre el header del request.
Tool execution: cómo Bifrost ejecuta las tools
Recuerda el principio de seguridad: por defecto Bifrost no ejecuta nada. El flujo estándar es stateless y de cuatro pasos.
sequenceDiagram
participant App as Tu aplicacion
participant BF as Bifrost
participant LLM as Modelo
participant MCP as Servidor MCP
App->>BF: 1. POST /v1/chat/completions
BF->>LLM: inyecta tools + prompt
LLM-->>BF: tool_calls (finish_reason: tool_calls)
BF-->>App: sugerencias de tools
Note over App: 2. Revisa y aprueba
App->>BF: 3. POST /v1/mcp/tool/execute
BF->>MCP: ejecuta la tool
MCP-->>BF: resultado
BF-->>App: rol "tool" + tool_call_id
App->>BF: 4. POST /v1/chat/completions<br/>(con el resultado adjunto)
BF-->>App: respuesta final
Paso 1: petición inicial
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o",
"messages": [
{
"role": "user",
"content": "List files in the current directory"
}
]
}'
La respuesta incluye tool_calls y finish_reason: "tool_calls".
Paso 2: ejecutar la tool aprobada
El endpoint clave es /v1/mcp/tool/execute. Usa la misma autenticación que /v1/chat/completions. Le pasas la tool call tal cual la devolvió el modelo:
curl -X POST http://localhost:8080/v1/mcp/tool/execute \
-H "Content-Type: application/json" \
-d '{
"id": "call_xyz789",
"type": "function",
"function": {
"name": "filesystem_list_directory",
"arguments": "{\"path\": \".\"}"
}
}'
La respuesta viene en formato chat, lista para copiar y pegar en el historial de la conversación, con el role, content y tool_call_id correctos:
{
"role": "tool",
"content": "{\"key\": \"value\"}",
"tool_call_id": "call_xyz789"
}
Por defecto el endpoint usa el formato chat (?format=chat). Si trabajas con la Responses API, usa ?format=responses, que cambia los nombres de campos a function_call_output, call_id y output.
Paso 3: reanudar la conversación
Adjuntas el resultado al historial y vuelves a llamar a /v1/chat/completions con la conversación completa (mensaje del usuario, tool call del asistente y la respuesta de la tool). El modelo continúa con el contexto enriquecido.
Errores comunes
El gateway devuelve errores claros: context deadline exceeded (timeout de ejecución), tool not found (tool no disponible o cliente desconectado) y not allowed (tool filtrada por configuración). Por ejemplo:
{
"error": {
"type": "tool_execution_error",
"message": "Tool 'filesystem_delete_file' is not allowed for this request"
}
}
Tool hosting
Bifrost no solo enruta hacia servidores externos: también puede hospedar herramientas internas registradas directamente en él (vía RegisterTool() en el SDK), que aparecen con el prefijo bifrostInternal-. Así puedes mezclar tools propias y tools de servidores remotos en el mismo catálogo unificado, sin que el modelo note la diferencia.
Agent Mode: ejecución autónoma
Pedir aprobación manual en cada tool es seguro, pero a veces quieres un agente autónomo que ejecute sin parar. Para eso existe el Agent Mode, que habilita la auto-ejecución con auto-aprobación configurable.
El agente opera en un bucle: el LLM devuelve tool calls, Bifrost ejecuta automáticamente las que estén marcadas para auto-ejecución, los resultados vuelven al LLM y el proceso continúa hasta que no haya más tool calls o se alcance la profundidad máxima. Las tools no marcadas para auto-ejecución vuelven a tu aplicación para aprobación, como en el flujo manual.
Dos campos son clave y trabajan juntos:
tools_to_execute: el allowlist de tools disponibles.tools_to_auto_execute: el subconjunto que corre sin aprobación. Una tool que esté entools_to_auto_executepero no entools_to_executese ignora.
{
"mcp": {
"client_configs": [
{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"]
},
"tools_to_execute": ["*"],
"tools_to_auto_execute": ["read_file", "list_directory"]
}
],
"tool_manager_config": {
"max_agent_depth": 10,
"tool_execution_timeout": "30s"
}
}
}
O al crear el cliente por API:
curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "filesystem",
"connection_type": "stdio",
"stdio_config": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem"]
},
"tools_to_execute": ["*"],
"tools_to_auto_execute": ["read_file", "list_directory"]
}'
Parámetros del bucle:
max_agent_depth: máximo de iteraciones (por defecto 10, rango 1-50). Al alcanzar el tope se devuelve la respuesta actual, que puede contener tool calls pendientes.tool_execution_timeout: timeout por tool (por defecto 30 segundos).
Limitaciones importantes:
- No soporta streaming: Agent Mode no es compatible con
chat_streamniresponses_stream. Usa endpoints sin streaming. - Opt-in explícito: por defecto ninguna tool se auto-ejecuta.
Las tools auto-ejecutables corren en paralelo por rendimiento. Cuando una respuesta mezcla tools auto y no-auto, primero se ejecutan las auto (sus resultados van en content en JSON), las no-auto aparecen en tool_calls, y finish_reason queda en "stop".
Buenas prácticas de seguridad: auto-ejecuta solo operaciones de lectura, búsqueda y consulta no destructivas. Reserva la aprobación humana para escrituras, borrados, ejecución de comandos y cualquier operación con efectos secundarios (enviar correos, compras).
Code Mode: orquestación con menos tokens
Conectar 8-10 servidores MCP tiene un costo oculto: cada request incluye todas las definiciones de tools en el contexto. Con cientos de tools, el modelo gasta la mayor parte de su presupuesto leyendo catálogos de herramientas en lugar de trabajar. Code Mode ataca este problema de raíz.
En lugar de exponer 150+ definiciones de tools, Code Mode expone solo cuatro meta-tools genéricas. El modelo escribe código Python (subconjunto Starlark) para orquestar las herramientas dentro de un sandbox. Los resultados intermedios quedan en el sandbox; el modelo solo recibe la salida final compacta.
Las cuatro meta-tools son:
listToolFiles: descubre los servidores MCP disponibles y sus tools.readToolFile: carga las firmas de las tools bajo demanda (formato.pyi).getToolDocs: obtiene documentación detallada de tools específicas.executeToolCode: ejecuta código Python en el sandbox Starlark con los bindings de las tools.
El impacto es enorme: en los benchmarks de Bifrost, con 508 tools (16 servidores), Code Mode logró 14x menos tokens de entrada (de 1.15M a 83K, una reducción de ~92.8%) manteniendo el 100% de tareas completadas.
Cómo se ve el código
El sandbox usa Starlark, un subconjunto de Python con sintaxis familiar pero restringida: hay llamadas síncronas a tools, print(), dicts/listas y list comprehensions, pero no hay import, clases, I/O de archivos, acceso a red ni módulos como random o time. Asignas la salida a una variable result:
results = youtube.search(query="AI news", maxResults=5)
titles = [item["snippet"]["title"] for item in results["items"]]
result = {"titles": titles, "count": len(titles)}
Reglas a recordar: usa argumentos por keyword (server.tool(param="value")), accede a dicts con corchetes (result["key"]) y asigna el retorno a result. El timeout por defecto es de 30 segundos por ejecución.
Habilitar Code Mode
Es por cliente, con el campo is_code_mode_client:
{
"mcp": {
"client_configs": [
{
"name": "youtube",
"connection_type": "http",
"connection_string": "http://localhost:3001/mcp",
"tools_to_execute": ["*"],
"is_code_mode_client": true
}
]
}
}
O por API:
curl -X POST http://localhost:8080/api/mcp/client \
-H "Content-Type: application/json" \
-d '{
"name": "youtube",
"connection_type": "http",
"connection_string": "http://localhost:3001/mcp",
"tools_to_execute": ["*"],
"is_code_mode_client": true
}'
Desde la Web UI: ve a MCP Gateway, abre la fila del cliente y en Basic Information activa el toggle Code Mode Server, luego Save Changes.
Puedes elegir el nivel de binding con code_mode_binding_level: server (por defecto, todas las tools agrupadas por servidor, p. ej. servers/youtube.pyi) o tool (un archivo por tool, p. ej. servers/youtube/search.pyi):
{
"mcp": {
"tool_manager_config": {
"code_mode_binding_level": "server"
}
}
}
Code Mode dentro de Agent Mode
listToolFiles y readToolFile siempre son auto-ejecutables (son de solo lectura). executeToolCode solo se auto-ejecuta si todas las tools que el código invoca están en el allowlist tools_to_auto_execute del servidor. Bifrost parsea el código, extrae cada llamada y la valida contra los permisos antes de ejecutar.
Code Mode vs Agent Mode: cuándo usar cada uno
Es fácil confundirlos porque ambos automatizan el trabajo con tools, pero resuelven problemas distintos y son complementarios:
- Agent Mode responde quién ejecuta: cierra el bucle de aprobación para que Bifrost ejecute las tools automáticamente sin que tu app intervenga en cada paso. Resuelve la autonomía.
- Code Mode responde cómo se orquesta: reduce el consumo de tokens y los round trips dejando que el modelo escriba código para coordinar muchas tools. Resuelve la eficiencia en escala.
Puedes usarlos juntos: un agente autónomo (Agent Mode) que orquesta decenas de tools con código (Code Mode).
| Situación | Recomendación |
|---|---|
| 1-2 servidores pequeños, llamadas directas y simples | MCP clásico (sin Code Mode) |
| Aplicación muy sensible a latencia | MCP clásico |
| 3+ servidores conectados | Code Mode |
| Workflows multi-paso complejos | Code Mode |
| Preocupa el costo en tokens o la latencia por catálogos grandes | Code Mode |
| Tools que interactúan entre sí | Code Mode |
| Quieres un agente que ejecute sin aprobación manual | Agent Mode |
Autenticación MCP: resumen
El acceso al endpoint /mcp se autentica con virtual keys. Bifrost acepta la key en tres headers distintos, lo que facilita la integración con clientes que usan convenciones diferentes:
# Opcion 1: Authorization
-H "Authorization: Bearer vk_your_virtual_key"
# Opcion 2: X-Api-Key
-H "X-Api-Key: vk_your_virtual_key"
# Opcion 3: x-bf-vk
-H "x-bf-vk: vk_your_virtual_key"
En producción debes exigir autenticación con enforce_auth_on_inference:
{
"client": {
"enforce_auth_on_inference": true
}
}
Cuando enforce_auth_on_inference es false, las peticiones sin autenticar acceden al servidor MCP global con todas las tools: nunca lo dejes así en producción.
A nivel de servidor MCP upstream, Bifrost soporta varios esquemas de autenticación hacia los servidores externos:
- None: sin autenticación (servidores públicos o de confianza local).
- Headers: cabeceras estáticas, ideal para API keys de servidores remotos.
- OAuth: flujo OAuth para servidores que lo requieren.
- Per-User OAuth / Per-User Headers: credenciales por usuario final, de modo que cada usuario actúe con su propia identidad ante el servidor MCP. Esto se apoya en las MCP Sessions de Bifrost, que gestionan las credenciales por sesión.
Los flujos de Per-User OAuth requieren binding por SSO, o bien activar el toggle
mcp_enable_temp_token_authpara completar el flujo de forma anónima desde el navegador.
Profundizaremos en los detalles operativos (sesiones, logs de ejecución de tools y trazas) cuando lleguemos a la observabilidad.
Resumen
- MCP es el estándar abierto que permite a los modelos descubrir y ejecutar herramientas externas; Bifrost actúa como gateway agregando varios servidores MCP y exponiéndolos como un catálogo unificado.
- Conectas servidores con
connection_typestdio,httposse, definiendocommand/args/envsoconnection_string, y controlas su catálogo base contools_to_execute. Los gestionas víaconfig.jsono los endpoints/api/mcp/client. - Bifrost inyecta automáticamente las tools en
/v1/chat/completions(desactivable conmcp_disable_auto_tool_inject) y se expone como servidor MCP en/mcp(JSON-RPC + SSE) para clientes como Claude Desktop. - El filtrado en tres niveles (client config, headers
x-bf-mcp-include-clients/x-bf-mcp-include-tools, ymcp_configspor virtual key) se combina con AND; la virtual key sobreescribe los headers del request y es deny-by-default, enlazando directamente con la governance. - Por defecto Bifrost no ejecuta tools: el flujo stateless usa
/v1/mcp/tool/executecon resultados listos para pegar al historial. Además puede hospedar tools internas (bifrostInternal-). - Agent Mode habilita la auto-ejecución (
tools_to_auto_execute,max_agent_depth) para agentes autónomos; Code Mode (is_code_mode_client) reduce drásticamente los tokens dejando al modelo orquestar con código en un sandbox Starlark. Son complementarios. - La autenticación acepta la virtual key en
Authorization,X-Api-Keyox-bf-vk, y soportanone,headers,oauthy per-user hacia los servidores upstream.