Que el modelo prefiera nuestras herramientas: la prioridad que no existe en ninguna capa, las dos primitivas que sí, y el `_meta` que atraviesa el gateway
Índice
Continuación de el gateway MCP de LiteLLM, que trataba el catálogo de herramientas como coste y como superficie. Este trata la pregunta siguiente, que es la que llega en la reunión de después: y entonces, cómo consigo que el modelo use las mías. Verificado contra LiteLLM 1.102.0 y la especificación MCP
2026-07-28, con una prueba propia ejecutada el 14 de septiembre de 2026.
TL;DR
La prioridad de herramientas no existe como concepto en ninguna capa del stack. Ni en la especificación, ni en los clientes, ni en las APIs de los proveedores. Lo que existen son dos primitivas distintas: quitar la alternativa del catálogo, y dejarla detrás de un paso de búsqueda. Todo lo demás es persuasión, y el modelo la ignora cuando le conviene.
La especificación no tiene ningún campo de ranking. El objeto Tool son nombre, título, iconos, descripción, esquemas, cinco anotaciones que son pistas no fiables por declaración propia, y _meta. Hay una trampa que veo repetida: MCP sí define un priority numérico, pero en otra estructura, la que aplica a bloques de contenido, recursos y prompts. No gobierna la selección de herramientas.
El único filtrado que la especificación bendice es por credencial. La revisión vigente dice que el conjunto de herramientas no puede variar por conexión, y que sí puede variar según la autorización presentada. Es exactamente lo que hace un gateway con listas por clave.
El cliente es quien decide, y solo uno tiene algo parecido a prioridad. Claude Code permite eximir a un servidor del diferido con alwaysLoad, de modo que sus herramientas se cargan enteras al inicio mientras las demás exigen una búsqueda previa. No se llama prioridad y funciona como tal.
Probamos que la marca por herramienta atraviesa el gateway. Montamos un servidor MCP con una herramienta marcada, la servimos por LiteLLM 1.102.0 y capturamos el cable: el _meta llega íntegro y con la clave correcta. La cadena está limpia a propósito, con un comentario en el código que lo dice.
Y se pierde en exactamente tres rutas, que son los tres modos de recortar catálogo del gateway. El modo proxy, la búsqueda de herramientas por permisos de clave, y el listado REST. Es decir: la marca por herramienta y el recorte de catálogo de LiteLLM son incompatibles. Hay que elegir uno.
Hay una trampa de la librería que hace desaparecer el campo en silencio. El modelo Tool del SDK declara el alias sin permitir poblar por nombre, así que construirlo con el nombre del campo mete el diccionario en los extras y lo serializa con la clave equivocada. No hay error. El campo simplemente no llega.
La palanca barata es la descripción, no el nombre. Intercambiar descripciones desplaza la distribución de selección de forma sustancial; cambiar solo el nombre tiene efectos mínimos e inconsistentes. Y los overrides del gateway sustituyen de verdad lo que se envía al cliente.
Reordenar el catálogo es palanca débil. El modelo ya atiende a la herramienta correcta el ochenta por ciento de las veces cuando falla. Las intervenciones sobre el orden del prompt reparan como mucho un 23 % de los fallos.
Y la asimetría que uno construye es superficie de ataque. Quien domina el orden domina la selección: con tasas de inyección del 1,2 % se puede copar la cabeza de un ranking de herramientas entre el 91 % y el 97 % de las veces.
Estás aquí: la pregunta que llega después del tercer servidor
El artículo anterior cerraba con una escalera de decisión sobre el catálogo: recortar, reescribir, partir por ruta, y usar la divulgación progresiva cuando el catálogo crece. Esa escalera responde a cuánto catálogo enseñar.
La pregunta que llega después es otra y es más incómoda. Un agente real tiene herramientas nativas del cliente que lo hospeda, tiene el gateway propio con los servidores de la casa, y tiene dos o tres servidores de terceros que alguien conectó. Todas compiten. Y lo que uno quiere no es enseñar menos catálogo: quiere que, ante una consulta que podrían atender tres herramientas, gane la suya. La que está auditada, la que tiene el control de acceso puesto, la que deja traza.
La respuesta que da todo el mundo es escribir una regla en el fichero de instrucciones del agente pidiéndole por favor que prefiera el servidor propio. Hay hasta una regla publicada en un mercado de plantillas que hace exactamente eso. Es un texto en el prompt y el modelo lo cumple cuando le parece.
Este artículo es lo que hay debajo.
La analogía: el mostrador con dos bandejas
Volvamos al operador de centralita del artículo anterior, el que además reparte llaves. Ahora el edificio tiene tres proveedores de llaves: el armario de la casa, el del contratista de mantenimiento y el del servicio de limpieza. Los tres tienen una llave del almacén y las tres abren.
El jefe de seguridad quiere que se use la de la casa, porque es la que tiene registro. Y descubre que puede hacer tres cosas, ni una más.
Puede quitar las otras dos del mostrador. Funciona siempre y molesta a quien las necesitaba.
Puede dejar la suya en la bandeja de delante y las otras dos en un cajón, de modo que para coger una hay que pedirla. Funciona casi siempre y no molesta a nadie.
Y puede cambiar la etiqueta de su llave para que describa mejor cuándo sirve. Funciona a veces, es lo más barato, y es lo único que además protege contra que el contratista cambie su etiqueta sin avisar.
Lo que no puede hacer es poner un número del uno al diez en cada llave y confiar en que el operador lo respete. Ese número no existe. El resto del artículo es por qué no existe y qué hacer en su lugar.
Lo que dice la especificación: nada
La revisión vigente es 2026-07-28. Leído contra el esquema fuente, el objeto Tool tiene nombre, título, iconos, descripción, esquema de entrada, esquema de salida, anotaciones y _meta. No hay ningún campo de prioridad, peso, rango, coste, grupo ni etiqueta.
Las anotaciones son exactamente cinco: título, y las pistas de solo lectura, destructiva, idempotente y mundo abierto. El propio esquema avisa de que todas son pistas y de que un cliente no debería tomar decisiones de uso de herramienta basándose en ellas cuando vienen de servidores no confiables.
El priority que existe y no sirve
Aquí está el error que más veo repetido. MCP sí define un campo priority, numérico entre cero y uno. Está en la interfaz de anotaciones que aplica a bloques de contenido, a recursos y a prompts, junto a la audiencia y la fecha de última modificación.
No está en Tool. No tiene ninguna relación con qué herramienta elige el modelo. Quien lo encuentre buscando la palabra en el esquema y concluya que la prioridad de herramientas está estandarizada, se equivoca de estructura.
La única precedencia que la especificación define para una herramienta es de presentación: para mostrar el nombre, primero el título, luego el título de las anotaciones, luego el nombre.
El único filtrado bendecido es por credencial
Hay una frase nueva en la revisión vigente que sí es útil y que pasa desapercibida. El conjunto de herramientas no debe variar por conexión ni como efecto secundario de otras peticiones, y sí puede variar según la autorización presentada en la petición.
Traducido: segmentar el catálogo por clave, por equipo o por token es la forma legítima de hacerlo. Segmentarlo por estado de sesión dejó de serlo cuando la revisión de julio eliminó las sesiones de protocolo.
El descubrimiento no descubre herramientas
server/discover, que la revisión vigente añade y que los servidores tienen que implementar, no devuelve herramientas. Devuelve versiones soportadas, capacidades, instrucciones de servidor, identidad y los campos de frescura de caché. No admite filtros ni cursor.
El listado sigue siendo pedir todo y paginar. La petición de listado solo admite cursor: no hay consulta, ni filtro, ni límite, ni grupos, ni etiquetas.
Y sobre colisiones entre servidores, la especificación se lava las manos de forma explícita y razonada: los clientes o proxies que agregan herramientas de varios servidores encontrarán colisiones y deberían implementar una estrategia de desambiguación, por ejemplo prefijar. Y añade que el nombre del servidor no está garantizado como único y no debería usarse para desambiguar. No hay regla de precedencia entre servidores. No la va a haber pronto.
Lo que hay en propuestas
Nada aceptado. El índice oficial de propuestas solo lista las que están en estado final, y ninguna trata prioridad, grupos ni búsqueda. En borrador hay una que pide una consulta de texto libre en el listado y una capacidad de filtrado; otra de grupos y etiquetas que quedó superseded; y una que lleva la palabra prioridad pero es enrutado de modelo por herramienta, que es otra cosa.
El grupo de interés que explora la agrupación de primitivas declara en su propio acta que no va a elegir un patrón canónico pronto, y los documentos de su repositorio están vacíos. La hoja de ruta del año no menciona el problema.
La capa que decide: el cliente
Si la especificación no da nada, lo que queda es lo que cada cliente haya construido por su cuenta. Y aquí hay un ganador claro.
Claude Code
La búsqueda de herramientas viene activada por defecto, y lo que hace es diferir: las herramientas MCP no se cargan enteras al inicio, el modelo ve lo justo y las descubre cuando las busca. Requiere un modelo que soporte los bloques de referencia de herramienta, es decir Claude Sonnet 4.5, Haiku 4.5, Opus 4.5 y posteriores.
Sobre eso, la palanca:
{
"mcpServers": {
"gateway-casa": {
"type": "http",
"url": "https://litellm.interna.svc/mcp",
"alwaysLoad": true
}
}
}
La documentación lo describe sin rodeos: si las herramientas de un servidor deben estar siempre visibles sin paso de búsqueda, se pone alwaysLoad a verdadero y todas las herramientas de ese servidor se cargan en contexto al inicio de sesión, independientemente del ajuste global de búsqueda. Y recomienda usarlo para un número pequeño de herramientas que el modelo necesite en cada turno, porque cada herramienta cargada de entrada consume contexto.
Eso es asimetría de visibilidad, y funciona como prioridad aunque no se llame así. Las nuestras delante, las demás detrás de un paso.
Hay una consecuencia operativa que la documentación menciona y que en un gateway importa más que en un servidor normal: poner alwaysLoad hace que el arranque espere a que ese servidor devuelva sus herramientas, con el tope del timeout de conexión estándar de cinco segundos. Un gateway que agrega ocho servidores upstream y que no cachea el listado, como es el caso, lista en vivo contra los ocho cada vez. Si uno de ellos va lento, el arranque de la sesión lo nota.
Existe además la variante fina. Un servidor MCP puede marcar herramientas individuales como siempre cargadas incluyendo "anthropic/alwaysLoad": true en el objeto _meta de la herramienta, con el mismo efecto para esa herramienta sola. Eso permitiría cargar de entrada tres herramientas de nuestro gateway y dejar diferidas las otras cuarenta del mismo gateway. Es la palanca que interesa, y es la que motivó la prueba del apartado siguiente.
El resto del arsenal de este cliente es de exclusión pura, y conviene conocer un detalle que decide si funciona o no. Una regla de denegación con el nombre pelado de la herramienta la elimina del contexto del modelo; con paréntesis, no. La documentación lo pone en una tabla: WebFetch a secas elimina la herramienta y el modelo no puede buscar en absoluto, mientras que WebFetch(domain:*) mantiene la herramienta y rechaza cada petición. La diferencia no es cosmética: en el segundo caso el modelo sigue viendo la herramienta, sigue intentándola y sigue gastando el contexto que ocupa su definición.
El flag --tools es el bisturí: admite la cadena vacía para desactivar todas las integradas, y no afecta a las herramientas MCP. Es decir, --tools "" deja al modelo únicamente con lo que sirva el gateway. Es un flag de línea de comandos y no tiene equivalente como clave del fichero de ajustes; el equivalente funcional ahí son las reglas de denegación.
Los demás clientes
| Cliente | Desactivar las nativas | Filtrar las MCP | Prioridad |
|---|---|---|---|
| Claude Code | --tools "", denegación por nombre pelado | denegación por patrón, subagentes | alwaysLoad |
| Codex CLI | features.shell_tool a falso | enabled_tools y disabled_tools por servidor | No |
| Gemini CLI | tools.core como lista blanca | includeTools y excludeTools por servidor | No |
| Copilot en VS Code | No documentado | selector y conjuntos de herramientas | No |
| Cursor | No | interruptores por servidor | No |
Dos apuntes. Copilot corta en 128 herramientas por petición y su umbral de virtualización no sube de ahí; su enrutado por embeddings es interno y no tiene superficie de configuración. Y las reglas de Cursor son puramente indicativas: son texto que se antepone al contexto.
La capa de API
Si el cliente es de la casa, el margen es mayor, aunque más estrecho de lo que parece.
Forzar un conjunto no se puede. En Anthropic, la elección de herramienta admite automático, cualquiera, una concreta por nombre, o ninguna, y la documentación dice de forma explícita que no se soporta apuntar a un conjunto de herramientas MCP ni a un miembro. En vLLM pasa lo mismo: una concreta, todas o ninguna. No hay forma de decir “cualquiera de mi gateway”. La propuesta que introduciría gramáticas que restrinjan los nombres de herramienta al conjunto de la petición lleva meses abierta y sin integrar.
Filtrar el catálogo sí se puede, en las tres grandes. En Anthropic, con un bloque de conjunto de herramientas MCP donde la configuración por defecto deshabilita y se habilitan las concretas. En OpenAI, con la lista de herramientas permitidas dentro del propio bloque MCP, que la documentación justifica por latencia y coste, evitando que el modelo vea definiciones innecesarias. Y en Gemini, la configuración de servidor MCP remoto admite restringir qué herramientas del servidor puede llamar el agente.
Conviene no confundir dos cosas que se llaman casi igual en OpenAI: la lista de herramientas permitidas dentro del bloque MCP filtra el catálogo, y es lo que interesa aquí; el tipo de elección de herramienta homónimo es otra cosa, es una restricción de selección, y hay constancia de que no combina bien con herramientas alojadas, sin que la documentación actual lo recoja. Si alguien depende de eso, que lo pruebe contra su modelo: falla como error de petición, así que sale en un arranque en frío.
Y hay una palanca de 2026 que casi nadie está usando. Anthropic tiene en beta un mecanismo de cambios de herramientas a mitad de conversación, con bloques de adición y retirada que admiten referenciar un conjunto MCP entero. La razón de existir está en su documentación: el array de herramientas se sitúa aún más al principio del prefijo troceado que el campo de sistema, así que editarlo invalida la caché de toda la conversación; declarando el conjunto completo al inicio y usando los bloques, el array nunca cambia y el prefijo cacheado se mantiene intacto.
Aplicado a nuestro caso: se puede retirar en caliente el conjunto de un servidor rival a mitad de sesión sin pagar el prefijo entero. No está disponible en todos los modelos.
La prueba: el _meta atraviesa el gateway
La variante fina de la palanca de Claude Code depende de una pregunta que no contesta ninguna documentación: si un gateway que agrega servidores upstream propaga el _meta de cada herramienta hasta el cliente, o lo pierde por el camino.
Lo comprobamos.
El montaje
Un servidor MCP mínimo con el SDK de Python, sirviendo dos herramientas por HTTP, una de ellas con la marca puesta:
types.Tool(
**{
"name": "always_loaded_tool",
"description": "tool with _meta",
"inputSchema": {"type": "object", "properties": {}},
"_meta": {"anthropic/alwaysLoad": True, "probe": "UPSTREAM_META_MARKER"},
}
)
Delante, un LiteLLM de la rama principal con ese servidor declarado en config.yaml, sin base de datos, con clave maestra. Y un cliente MCP consultando el listado contra /mcp.
El resultado
Esto es lo que sale por el cable:
{
"_meta": {"litellm.ai/server_outcomes": {"probe": {"status": "ok", "tool_count": 2}}},
"tools": [
{
"name": "probe-always_loaded_tool",
"description": "tool with _meta",
"inputSchema": {"type": "object", "properties": {}},
"_meta": {"anthropic/alwaysLoad": true, "probe": "UPSTREAM_META_MARKER"}
}
]
}
La marca llega íntegra y con la clave correcta. El cliente la parsea sin problema.
Trazando el código, la cadena está limpia a propósito. LiteLLM guarda los objetos del SDK tal cual cuando lista contra el upstream, en lugar de reconstruirlos. El prefijado de nombres hace una copia profunda y muta solo el nombre, con un comentario en el código que declara la intención de preservar todos los campos incluido el _meta evitando la mutación. Los dos filtros de permisos son comprensiones de lista que reutilizan los mismos objetos. Y los overrides de nombre y descripción mutan en el sitio, así que tampoco pierden nada. Alguien pensó en esto.
Un detalle operativo: el nombre llega prefijado con el alias del servidor, gobernado por el separador configurable y el modo de prefijo corto.
Las tres rutas donde se pierde
Y aquí está el hallazgo que cambia la recomendación del artículo anterior.
El modo proxy devuelve únicamente sus tres herramientas fijas, sin _meta y sin ninguna herramienta del upstream. Verificado también contra el cable.
La búsqueda de herramientas activada por permisos de clave hace lo mismo con cuatro herramientas virtuales.
Y el listado REST construye a mano su objeto de respuesta y descarta el campo: la herramienta que sí traía marca sale con el campo a nulo. La clase hereda del tipo que tiene el campo; simplemente no se rellena. El arreglo cabe en una línea.
Esas tres rutas son, exactamente, los tres modos que tiene LiteLLM de recortar el catálogo. La conclusión operativa es incómoda y conviene decirla clara: o se usa el recorte de catálogo del gateway, o se usa la marca por herramienta del cliente. No se pueden combinar. El artículo anterior recomendaba el modo proxy como quinto escalón de la escalera; con esto en la mano, ese escalón y la marca fina son excluyentes.
La trampa de la librería
Esto merece apartado propio porque se lleva por delante a quien escriba un servidor o un proxy, y no avisa.
El modelo de herramienta del SDK declara el campo con un alias, y no habilita poblarlo por nombre. Las consecuencias, las dos comprobadas ejecutando:
Construir con el nombre del campo no puebla nada. El diccionario se cuela en los extras del modelo y sale serializado con la clave equivocada, sin el guion bajo inicial, que es una clave que ningún cliente interpreta.
Y volcar y revalidar sin pedir alias pierde el campo, por el mismo motivo.
No hay excepción, no hay aviso en el log, no hay nada. El campo desaparece. Si alguien marca sus herramientas y no las ve marcadas en el cliente, este es el primer sitio donde mirar, antes que el gateway.
Lo que no hemos probado
Por honestidad, y porque es el eslabón que queda: hemos demostrado que la marca sobrevive al gateway. No hemos demostrado que el cliente actúe sobre ella cuando la herramienta llega con el nombre prefijado por el gateway. La documentación de Claude Code describe la marca por herramienta en una sola frase y no dice nada sobre servidores agregadores ni sobre prefijos.
Es una prueba de media hora para quien tenga el montaje delante: dos herramientas del mismo gateway, una marcada, y mirar cuál aparece cargada al inicio del turno. Si alguien la hace antes que yo, me interesa el resultado.
Lo que LiteLLM puede y lo que no
Con lo anterior, el inventario de palancas del gateway queda así.
| Palanca | Sirve a clientes MCP externos | Conserva el _meta |
|---|---|---|
allowed_tools y disallowed_tools por servidor | Sí | Sí |
| Overrides de nombre y descripción | Sí | Sí |
| Conjuntos de herramientas por ruta | Sí | Sí |
| Modo proxy y herramientas virtuales | Sí | No |
| Búsqueda por permisos de clave | Sí | No |
| Listado REST | Sí | No |
| Filtro semántico | No | No aplica |
Dos precisiones sobre la tabla del artículo anterior, ahora que se ha vuelto a leer el código.
Las listas de permitidas y prohibidas sí se aplican en el listado, no solo en la llamada. Son el instrumento romo y eficaz, y no rompen la caché porque son estáticas.
Y los overrides tienen un límite que no estaba contado: se aplican en el listado del protocolo MCP, pero se saltan en modo proxy y no se aplican en la ruta REST. Quien reescriba descripciones y además active el modo proxy, no está sirviendo lo que cree.
Lo que el gateway no puede hacer es inyectar _meta. No hay ningún ajuste equivalente a los de nombre y descripción. La marca tiene que ponerla el servidor de origen, que para los servidores propios es trivial porque los escribimos nosotros. Para marcar herramientas de terceros habría que parchear, y es pequeño: un campo en el tipo y tres líneas en la función de overrides si basta con configurarlo por fichero.
Hay además una palanca de ordenación que no aparecía en el artículo anterior. En el modo de búsqueda del proxy existe un ajuste de herramientas núcleo que las antepone en el ranking y que además no cuentan contra el tope de resultados. Es lo más parecido a una prioridad declarativa que hay en todo el stack, y vive dentro del único modo que descarta el _meta.
Y un matiz sobre el tope de resultados del modo proxy. El cliente no puede pedir más de cinco, eso es cierto, pero el operador sí puede subirlo por configuración. El artículo anterior daba a entender que era inamovible.
La palanca barata: la descripción, no el nombre
Si no se puede excluir, queda sesgar. Y el sesgo entra por la descripción.
El trabajo que mide el sesgo de selección entre herramientas funcionalmente equivalentes cifra el sesgo combinado de los modelos evaluados entre 0,25 y 0,38, es decir, habría que redistribuir entre el 25 % y el 38 % de la masa de probabilidad para que herramientas equivalentes se eligieran por igual. Sobre esa base, intercambiar las descripciones de dos herramientas desplaza la selección de forma sustancial, mientras que las perturbaciones que solo tocan el nombre producen efectos menores y más inconsistentes.
Otro trabajo mide que una sola pasada de reescritura automática de descripciones mejora la métrica sobre un corpus grande, casi lo mismo que un refinamiento iterativo, y con dos órdenes de magnitud menos de tiempo. Y añade una advertencia que conviene retener: las descripciones afinadas contra un conjunto fijo de candidatos no generalizan al conjunto recuperado dinámicamente. Hay que optimizar para el régimen en que se sirve.
Aplicado: el override de descripción del gateway es a la vez recorte de tokens, sesgo de selección y mitigación del cambio de descripción tras la aprobación. Es la palanca con mejor relación entre esfuerzo y efecto de todo el artículo, y es estática, así que no toca la caché de prompts.
El prefijado de nombres, en cambio, cuesta tokens y probablemente no cambia a qué herramienta va el modelo.
Lo que no funciona
Reordenar el catálogo. Un trabajo de junio mide que, cuando el modelo falla, ya estaba atendiendo a la herramienta correcta el ochenta por ciento de las veces, muy por encima del azar. El cuello no está en la entrada sino en las capas tardías. Las intervenciones sobre el orden del prompt recuperan como mucho un 23 % de los fallos, frente al 59 % a 91 % de las que actúan sobre la lectura final. Reordenar es barato y por eso se recomienda mucho; también es flojo.
Las reglas y las instrucciones. Son texto. Ayudan y no deciden.
Los filtros top-K propios por petición. Está tratado en el artículo anterior y sigue valiendo: cuatro de cinco estrategias medidas rinden peor que no filtrar, y además reescribir el bloque de herramientas en cada turno invalida el prefijo cacheado entero.
La escalera, actualizada
- Excluir en el cliente. Es lo único determinista.
--tools ""o denegación por nombre pelado de las nativas que compiten. - Marcar las propias como siempre cargadas. A nivel de servidor con
alwaysLoad, o por herramienta con la marca en el_metasi se controla el servidor de origen. Contando con que el arranque espera al servidor. - Recortar con listas estáticas por servidor y por clave, y partir por ruta un catálogo por perfil de agente.
- Reescribir las descripciones con los overrides del gateway.
- Retirar en caliente los conjuntos rivales, si el cliente es propio y el modelo lo soporta.
- Elegir: recorte de catálogo del gateway, o marca por herramienta. No las dos.
- No: reordenar, renombrar, ni confiar en reglas de prompt.
El riesgo que hay que declarar
La asimetría que uno construye es también una superficie. Quien controla qué herramientas encabezan un ranking controla la selección, y eso se puede atacar: hay trabajo que mide que inyectando herramientas adversarias con tasas del 1,2 % se copa la cabeza del ranking entre el 91 % y el 97 % de las veces.
En un sistema bajo ENS esto encaja en gestión de cambios, no en control de acceso: el conjunto de herramientas que ve un modelo y el orden en que las ve son configuración de seguridad, y hoy nadie los versiona. Ni la especificación fija hash de la descripción ni del esquema, ni el gateway tampoco. Los códigos concretos del Anexo II conviene contrastarlos contra el texto vigente antes de llevarlos a un documento de cumplimiento; el planteamiento está desarrollado en el artículo del gateway MCP.
Hay un precedente dentro del propio ecosistema que indica el camino. La extensión de habilidades de MCP, que sí está en estado final, exige manifiesto con hash por fichero, verificación obligatoria antes de usar, y aprobación vinculada al conjunto de ficheros y sus resúmenes, de modo que cualquier cambio revoca la aprobación. Y obliga a los anfitriones a impedir que dos habilidades con el mismo nombre se reemplacen en silencio. Es exactamente el patrón que falta para herramientas. Quien lo necesite hoy, tiene que implementarlo en su gateway.
Checklist
- Decidir la estrategia antes de tocar nada: recorte de catálogo en el gateway, o marca por herramienta en el cliente. Son excluyentes.
- Si se elige la marca, ponerla en el servidor de origen, porque el gateway no la puede inyectar.
- Construir el objeto de herramienta con la clave del alias, nunca con el nombre del campo, o el campo desaparece sin aviso.
- No revalidar objetos de herramienta desde un volcado sin pedir alias.
- Contar con que marcar un servidor como siempre cargado hace que el arranque de sesión espere a ese servidor, y que un gateway lista en vivo contra todos sus upstream.
- Excluir en el cliente las herramientas nativas que compiten, con nombre pelado y no con patrón entre paréntesis.
- Reescribir las descripciones de las herramientas propias, y no perder el tiempo renombrando.
- No activar el modo proxy si se depende de los overrides de descripción, porque ahí no se aplican.
- Versionar el conjunto de herramientas expuesto y su orden como configuración de seguridad, con hash de descripción y esquema.
- Si se usa la ruta REST del gateway para algo, saber que descarta el
_meta.
Trampas y cosas que no son lo que parecen
- El
priorityde MCP existe, y no es de herramientas. Vive en las anotaciones de contenido, recursos y prompts. - Las anotaciones de herramienta son pistas y el propio esquema dice que no son fiables desde servidores no confiables.
- La especificación no da regla de precedencia entre servidores, y dice además que el nombre del servidor no sirve para desambiguar.
- El conjunto de herramientas sí puede variar por autorización, y esa es la única segmentación bendecida.
server/discoverno devuelve herramientas.- Una regla de denegación con paréntesis no elimina la herramienta del contexto, solo rechaza las llamadas.
--toolses flag de línea de comandos, sin equivalente en el fichero de ajustes.- Marcar un servidor como siempre cargado retrasa el arranque hasta cinco segundos por servidor.
Tool(meta=...)no puebla el campo y lo serializa con la clave equivocada.- El modo proxy, la búsqueda por permisos y el listado REST descartan el
_meta. - Los overrides de descripción se saltan en modo proxy y no se aplican en REST.
- El tope de cinco resultados del modo proxy lo puede subir el operador, aunque el cliente no pueda pedir más.
- Las herramientas núcleo del ranking del proxy son la única prioridad declarativa del stack, y viven en el modo que pierde el
_meta. - No se puede forzar “cualquiera de mi gateway” en ninguna API.
- En OpenAI, la lista de permitidas dentro del bloque MCP y el tipo homónimo de elección de herramienta son cosas distintas.
- Gemini sí admite lista blanca por herramienta en sus servidores MCP remotos.
- Reordenar el catálogo repara como mucho el 23 % de los fallos.
Cierre
La pregunta de partida tenía trampa, y la trampa es la palabra. Cuando alguien pregunta cómo se prioriza un servidor MCP, está suponiendo que existe un dial en algún sitio. No existe, y llevo el artículo entero enseñando los sitios donde no está.
Lo que hay es más pobre y más manejable: se quita lo que compite, se deja lo propio delante, y se escribe mejor la descripción. Tres cosas, ninguna elegante, las tres efectivas en ese orden.
Lo que sí me parece que merece la pena llevarse es la forma del problema. El catálogo de herramientas que ve un modelo es configuración de seguridad con todas las letras, porque determina qué puede hacer el agente y con qué sistema va a hablar. Y hoy se gestiona como una lista de conexiones: se añade, no se versiona, no se firma, y nadie detecta un cambio. El ecosistema ya ha resuelto ese problema una vez, para las habilidades, con hash y aprobación vinculada. Para las herramientas todavía no.
Mientras tanto, la asimetría hay que construirla a mano, servidor por servidor, y sabiendo que está apoyada en el _meta de un objeto que una librería puede vaciar sin decir nada.
Ver también
- El gateway MCP de LiteLLM — el artículo del que este es continuación directa, con el catálogo como coste y la escalera que aquí se corrige.
- Humanos y agentes en el mismo gateway — la separación por clave y equipo sobre la que se apoya el filtrado por credencial.
- Dimensionar para agentes — lo que cuesta en CPU del proxy serializar el catálogo en cada petición.
- Enrutado por prefijo — por qué tocar el principio del prompt se paga tan caro.
- Completar Keycloak para MCP — el lado del recurso protegido y la validación de audiencia.
- Cuando MCP crece: autenticación con Keycloak — la identidad de los servidores MCP propios.
- MCP por dentro y su observabilidad profunda — el protocolo y sus primitivas.
- Controles técnicos para ENS, 42001 y el AI Act — el marco donde encaja la gestión de cambios sobre el catálogo.
Fuentes
- Model Context Protocol, herramientas en la revisión
2026-07-28: https://modelcontextprotocol.io/specification/2026-07-28/server/tools. - Model Context Protocol,
server/discover: https://modelcontextprotocol.io/specification/2026-07-28/server/discover. - Model Context Protocol, paginación: https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/pagination.
- Model Context Protocol, caché de listados: https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching.
- Model Context Protocol, esquema fuente de la revisión: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2026-07-28/schema.ts.
- Model Context Protocol, extensión de habilidades: https://modelcontextprotocol.io/extensions/skills/overview.
- Model Context Protocol, grupo de interés sobre agrupación de primitivas: https://modelcontextprotocol.io/community/interest-groups/primitive-grouping.
- Anthropic, Claude Code y MCP (
alwaysLoad, búsqueda de herramientas): https://code.claude.com/docs/en/mcp. - Anthropic, Claude Code, referencia de línea de comandos (
--tools): https://code.claude.com/docs/en/cli-reference. - Anthropic, Claude Code, permisos (denegación por nombre pelado): https://code.claude.com/docs/en/permissions.
- Anthropic, conector MCP y conjuntos de herramientas: https://platform.claude.com/docs/en/agents-and-tools/mcp-connector.
- Anthropic, cambios de herramientas a mitad de conversación: https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages.
- Anthropic, búsqueda de herramientas: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool.
- OpenAI, MCP y conectores (lista de herramientas permitidas): https://developers.openai.com/api/docs/guides/tools-connectors-mcp.
- OpenAI, búsqueda de herramientas y caché: https://developers.openai.com/api/docs/guides/tools-tool-search.
- Google, llamada a funciones en la Interactions API: https://ai.google.dev/gemini-api/docs/function-calling.
- vLLM, llamada a herramientas y decodificación restringida: https://docs.vllm.ai/en/latest/features/tool_calling.html.
- vLLM, propuesta de decodificación guiada por regiones y gramáticas de herramienta: https://github.com/vllm-project/vllm/issues/39848.
- LiteLLM, código del gateway MCP:
litellm/proxy/_experimental/mcp_server/server.py,mcp_server_manager.py,rest_endpoints.py,tool_search.py,litellm/experimental_mcp_client/tools.py: https://github.com/BerriAI/litellm. - SDK de Python de MCP, modelo
Tooly serialización por alias: https://github.com/modelcontextprotocol/python-sdk. - BiasBusters, sesgo de selección entre herramientas equivalentes y peso de la descripción frente al nombre: https://arxiv.org/html/2510.00307v2.
- Looking Is Not Picking, atención frente a lectura final y techo de las intervenciones sobre el prompt: https://arxiv.org/html/2606.16364v1.
- A Single Rewrite Suffices, reescritura de descripciones y generalización al conjunto recuperado: https://arxiv.org/html/2606.30775.
- ToolFlood, saturación adversaria de la capa de recuperación: https://arxiv.org/html/2603.13950.