La frase con la que esto entra en una empresa es «es solo un conector». Alguien enchufa el asistente al SharePoint, al ERP o al sistema de tickets, y lo que se discute en la reunión es qué va a saber hacer. Lo que no se discute es con qué identidad lo va a hacer. La respuesta, cuando el conector se monta con prisa, acaba siendo: con la tuya.
No hace falta imaginarse a nadie actuando de mala fe para que eso acabe mal. Basta con que dentro de tres meses alguien abra el registro de auditoría del sistema de destino, vea una descarga grande a las tres de la madrugada de un sábado y lea, al lado, el nombre de una persona que estaba durmiendo. Nadie ha mentido. El token hizo exactamente aquello para lo que se emitió, y el registro apuntó exactamente a quien figuraba en él. La investigación empieza por la persona equivocada porque el diseño lo decidió así meses antes, en una tarde en la que nadie pensaba en registros.
Esto no es una opinión nuestra: está escrito en la norma, en mayúsculas
El estándar abierto sobre el que se está construyendo buena parte de esa conexión se llama Model Context Protocol (MCP). No es el único camino —hay API REST directa, conectores nativos de fabricante y plataformas de integración—, pero es el que se está imponiendo como terreno común. Su especificación se versiona por fecha, y la revisión vigente a día de hoy es la 2026-07-28. La leímos entera porque hay una cosa que nos interesaba comprobar: qué dice exactamente sobre las credenciales. Dice bastante, y lo dice con el vocabulario normativo de los RFC, ese en el que MUST y MUST NOT no son sugerencias.
En el apartado de manejo de tokens de la especificación de autorización hay tres frases seguidas que valen por todo el artículo. La última es ésta: «MCP servers MUST NOT accept or transit any other tokens». Los servidores no deben aceptar ni hacer de tránsito de ningún otro token. Y en el documento de buenas prácticas de seguridad hay una sección con nombre propio, «Token Passthrough», catalogada literalmente como anti-pattern, que termina con una única línea de mitigación: «MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server».
Aquí va lo que nos parece a nosotros, dicho como lectura propia: una norma no dedica una sección entera, con su lista de riesgos y su mitigación, a prohibir algo que nadie hace. El anti-patrón está descrito con ese detalle porque es el camino corto. Reenviar el token que ya tienes es una línea de código; pedir uno propio para el conector implica registrar una aplicación, darle identidad, decidir permisos y explicárselo a alguien. Cuando el sprint va justo, se sabe cuál de los dos gana.
El párrafo que debería leer quien firma el cumplimiento
Lo más útil de esa sección es la lista de por qué, que viene detrás de la prohibición. Uno de los bloques se titula «Accountability and Audit Trail Issues» —problemas de rendición de cuentas y de traza de auditoría— y contiene esta frase, que traducimos y dejamos también en original porque es la que sostiene el titular de este artículo:
«The downstream Resource Server’s logs may show requests that appear to come from a different source with a different identity, rather than the MCP server that is actually forwarding the tokens.»
Los registros del servidor de destino pueden mostrar peticiones que parecen venir de un origen distinto, con una identidad distinta, en lugar del servidor MCP que en realidad está reenviando los tokens.
— MCP Security Best Practices, revisión 2026-07-28.
Conviene separar dos cosas que se parecen y no son lo mismo, porque un lector técnico va a objetar aquí y tiene razón en objetar. Una es el reenvío de token: el conector acepta un token que no se emitió para él y lo pasa tal cual al sistema de destino. Eso es lo que la norma prohíbe. Otra es el acceso delegado, en el que la aplicación tiene identidad propia y actúa en nombre de una persona con su consentimiento. Es un modo legítimo, está en todas las plataformas y ahí es correcto que el nombre de la persona aparezca en el registro. La queja de la especificación no es que salga un usuario: es que no salga también el intermediario, porque el token que llega abajo es opaco y el destino no puede distinguir quién lo presentó.
De ahí sale nuestra lectura, y la marcamos como tal: cuando el intermediario no consta, la investigación de un incidente empieza por la persona equivocada. Lo bueno es que esto no hay que discutirlo en una reunión, porque se comprueba en diez minutos: que alguien haga que el agente lea un documento, y luego abre el registro de auditoría del sistema de destino y mira qué nombre hay. Si no aparece el agente por ninguna parte, ya tienes la respuesta. Es la prueba más barata de todo este artículo y la dejamos otra vez al final, porque es la única que hay que hacer sí o sí.
La misma sección advierte de algo más, que conviene leer despacio: si el servidor pasa tokens sin validar sus claims —roles, privilegios, audiencia—, «un actor malicioso en posesión de un token robado puede usar el servidor como proxy para exfiltrar datos». Y encabeza la lista con la circunvención de controles: los límites de caudal, la validación de peticiones y la monitorización de tráfico que tengas montados suelen depender de la audiencia del token o de otras restricciones de la credencial. Con la audiencia equivocada, esos controles se quedan sin aplicar.
Es el mismo error de categoría del que hablábamos hace unos días a propósito de un privilegio de base de datos que se concede por su nombre y no por lo que permite: la decisión se toma mirando la etiqueta —«conector», «integración», «solo lectura»— en vez de mirar el alcance. La diferencia es que allí el que se equivocaba era un administrador leyendo una palabra; aquí el que se equivoca es el registro, que es la única herramienta que tienes para reconstruir lo que pasó.
El conector que corre en tu máquina no hace OAuth. La norma dice que no lo haga
Todo lo anterior aplica a los conectores que hablan por HTTP. Pero una parte grande de lo que hay instalado hoy no habla por HTTP: habla por stdio, o sea, es un proceso que el cliente arranca en la misma máquina y con el que se entiende por la entrada y la salida estándar. Para ésos, el apartado de requisitos del protocolo es de una claridad incómoda: «Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment».
Traducido a lo que hay en una empresa: ese conector no tiene consentimiento, ni audiencia, ni alcance, ni caducidad. Tiene el entorno de la máquina que lo arrancó. El .env con la clave de la API. El kubeconfig del portátil. El socket del agente SSH. La variable con el token de acceso personal al repositorio que alguien puso «para probar» en marzo. El propio documento de buenas prácticas, en su sección sobre servidores locales, pide a los clientes que avisen al usuario de que «los servidores MCP corren con los mismos privilegios que el cliente», y llega a poner como ejemplo de comando de arranque malicioso un curl que envía ~/.ssh/id_rsa a una URL ajena.
Ya escribimos sobre esta familia de sorpresas cuando contamos que bloquear el agente SSH desactivaba precisamente las restricciones que le habías puesto. El patrón se repite: la herramienta que sostiene las credenciales tiene un comportamiento por defecto que nadie ha leído, y el comportamiento por defecto siempre va en la dirección de que las cosas funcionen, no en la de que estén cerradas.
El permiso por defecto es «todo lo que haya»
Supongamos que el conector sí hace las cosas bien y pide su propio token. Queda decidir para qué. La especificación tiene un apartado llamado «Scope Selection Strategy» con un orden de prioridad de dos puntos. El primero: usar el parámetro scope que el servidor haya puesto en la cabecera WWW-Authenticate de su respuesta 401. El segundo, literal: «If scope is not available, use all scopes defined in scopes_supported from the Protected Resource Metadata document».
Ahora la parte que hay que poner al lado para no hacer trampa, porque el escalón viene acotado. La frase siguiente de la propia especificación dice que scopes_supported «está pensado para representar el conjunto mínimo de permisos necesarios para la funcionalidad básica», y que el resto se pide después por elevación, cuando una operación concreta lo reclama. Y el documento de buenas prácticas, en su sección de minimización de permisos, explica por qué existe ese segundo escalón: los clientes MCP son de propósito general y no tienen el conocimiento de dominio necesario para elegir permisos por su cuenta, de modo que la especificación prefiere que la decisión la tomen el servidor de autorización y la persona en la pantalla de consentimiento. Es un reparto de responsabilidad hecho a conciencia, y enviar el parámetro scope es un SHOULD para el servidor, no un MUST.
Lo que nos parece a nosotros es que ese reparto tiene un destinatario real, y no es el que se imagina. Quien decide el alcance es quien pulsa «Permitir». En la mayoría de empresas que conocemos, esa persona no es el responsable de seguridad: es quien estaba montando el conector un martes por la tarde, con la pantalla llena de permisos que no había pedido y un botón verde. Y la propia especificación sabe que el catálogo suele estar inflado, porque su sección de minimización de permisos abre la lista de errores comunes con éste: «publicar todos los permisos posibles en scopes_supported», seguido de «usar permisos comodín u ómnibus (*, all, full-access)». La regla está bien escrita. El catálogo es el que casi nunca está a la altura de la regla.
Y sí, el SDK oficial ha tenido lo suyo
Hay una suposición que casi nadie enuncia en voz alta cuando se monta un asistente corporativo: que si dos empleados hablan con el mismo asistente, lo que ve uno no lo ve el otro. Esa suposición tiene fecha de caducidad documentada. El 4 de febrero de 2026 se publicó el aviso GHSA-345p-7cg4-v4c7, CVE-2026-25536, sobre el SDK oficial de TypeScript (@modelcontextprotocol/sdk). Puntuación 7,1, vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N. Afecta desde la 1.10.0 hasta la 1.25.3 inclusive; se arregla en la 1.26.0.
Lo que hacía son dos cosas, y las dos son de reutilización. La primera: cuando una sola instancia de StreamableHTTPServerTransport atiende peticiones de varios clientes, los identificadores de mensaje JSON-RPC chocan y las respuestas se encaminan a la conexión HTTP equivocada. La segunda: cuando una sola instancia de McpServer se conecta a varios transportes, la referencia interna this._transport se sobrescribe en silencio, lo que arrastra respuestas finales, notificaciones de progreso y peticiones de muestreo. En cristiano: la respuesta de una persona podía terminar en la pantalla de otra.
Conviene no exagerarlo, y lo decimos nosotros que somos los que lo estamos contando. Es un 7,1, con impacto bajo en integridad. El vector lleva PR:L, que en la escala CVSS significa que el atacante necesita privilegios de usuario básico; nuestra lectura de eso, en este escenario concreto, es que el atacante es el otro empleado con su sesión legítima. No hay constancia pública de explotación, y está arreglado desde febrero. Lo que nos parece útil del dato es otra cosa: la separación entre usuarios, que todo el mundo da por hecha, fue de la 1.10 a la 1.25.3 una propiedad del código y no una garantía del protocolo. Y que hay una pregunta muy concreta y muy barata —«¿qué versión del SDK corre eso?»— que casi nadie hace.
Las siete preguntas que hacemos antes de conectar nada
Nosotros automatizamos con IA y nos ganamos la vida con ello, así que esto no es un artículo en contra. Tenemos n8n autoalojado corriendo tareas internas —entre ellas la publicación en LinkedIn por webhook— y lo tratamos como lo que es: un servicio de producción, inventariado, con dueño y con ventana de actualización. Ésta es la lista que pasamos antes de darle a algo automático una credencial nuestra o de un cliente.
- ¿Con qué identidad actúa? Si la respuesta contiene el nombre de una persona, paramos. Un agente necesita identidad propia en el directorio, con su nombre, su dueño y su fecha de revisión. Es más trabajo. Es el trabajo.
- ¿Qué audiencia lleva el token? Si el conector reenvía el mismo token que le da el cliente hacia la API de destino, está haciendo exactamente lo que la norma prohíbe en mayúsculas. El token hacia arriba y el token hacia abajo son dos tokens distintos, y es así por diseño.
- ¿Qué permisos pidió de verdad? No lo que dice el README: lo que salió en la pantalla de consentimiento y lo que figura hoy en la aplicación registrada del directorio. Los dos sitios, porque no siempre coinciden.
- ¿Dónde corre y con qué entorno? Si es
stdio, hereda el entorno del proceso que lo arranca. Entonces la pregunta deja de ser sobre el conector y pasa a ser sobre la máquina: qué claves hay en ese entorno y quién más puede arrancar procesos ahí. - ¿Qué versión del SDK? Para el de TypeScript, 1.26.0 o superior. Y con el número apuntado en algún sitio que no sea la memoria de quien lo instaló.
- ¿Cómo se apaga, y quién lo apaga un sábado? Un interruptor que solo sabe accionar la persona que lo montó no es un interruptor. Ya contamos cómo acaba esto en el piloto de IA que nadie apagó: no se apagan por decisión, se apagan cuando alguien tropieza con ellos.
- ¿Sale en el registro con su nombre? Prueba de aceptación, sin discusión teórica: que alguien haga que el agente lea algo, y luego abrir el registro de auditoría del sistema de destino y buscar quién aparece. Si aparece una persona, ya tienes el diagnóstico y lo tienes en diez minutos.
Cuándo decimos que no
Hay tres situaciones en las que recomendamos no conectar el agente, aunque el proyecto esté vendido y la demo haya gustado. La primera: cuando la única integración disponible es de las que reenvían el token y no hay manera de pedir uno propio. Eso es construir sobre un anti-patrón con nombre propio y esperar que el día del incidente los registros digan algo útil. La segunda: cuando nadie sabe responder quién es el dueño del agente dentro de seis meses. Un servicio sin dueño no se mantiene; se acumula. La tercera: cuando lo que hay al otro lado es un conjunto de datos con obligaciones —expedientes de personal, historiales, datos de menores— y el agente pediría permiso de lectura sobre todo el repositorio porque es lo único que ofrece la pantalla.
Decir que no a tiempo sale barato. Decirlo tarde también tiene su estadística: ya escribimos sobre la previsión de que cuatro de cada diez proyectos de agentes en empresa se cancelen; según aquella previsión, el peso lo llevaban el coste y el riesgo mal calculados de antemano, no la tecnología. Esta conversación, la de con qué identidad actúa, es exactamente una de esas que es baratísima antes y carísima después. Es lo que decimos aquí desde hace años con otras palabras: el fallo es inevitable, la avería es una decisión de diseño. Un registro que señala a quien no fue no es mala suerte; es una decisión que alguien tomó un martes sin saber que la estaba tomando.
¿Sabes con qué identidad actúan tus automatismos?
Nuestro trabajo de automatización e IA empieza por ahí y no por el caso de uso: qué agentes hay ya corriendo, con qué credencial, contra qué sistemas y quién los apaga. Al lado va el Zero Trust, que es la parte aburrida y la que sostiene todo lo demás —identidad propia, permiso mínimo, caducidad—, y el gobierno de datos y aplicaciones, que es donde se decide a qué llega y a qué no. Si al revisarlo resulta que lo tienes bien montado, te lo diremos y no habrá factura.
Hablar con everyWANNota de fuentes
Fuentes primarias que hemos leído nosotros. La especificación del Model Context Protocol en modelcontextprotocol.io. La página de versionado nos da la revisión vigente, 2026-07-28. De la especificación de autorización de esa revisión salen: el requisito de transporte STDIO («Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment»), el apartado de manejo de tokens («MCP servers MUST NOT accept or transit any other tokens» y la obligación de validar que el token se emitió para el propio servidor, según RFC 8707) y la «Scope Selection Strategy» con su orden de prioridad de dos puntos, incluida la segunda opción de usar todos los permisos de scopes_supported y la frase inmediatamente posterior según la cual ese campo debe ser el conjunto mínimo necesario para la funcionalidad básica. La explicación de por qué existe ese segundo escalón —clientes de propósito general sin conocimiento de dominio, decisión delegada en el servidor de autorización y en la pantalla de consentimiento— no está en la especificación de autorización sino en el documento de buenas prácticas, en su sección de minimización de permisos. De ese mismo documento de buenas prácticas de seguridad salen la sección «Token Passthrough» —con su línea de mitigación y la lista de riesgos, de la que citamos la frase sobre los registros del servidor de destino y la del token robado usado como proxy de exfiltración—, la sección de compromiso de servidores MCP locales —de donde vienen el aviso de que corren con los mismos privilegios que el cliente y el ejemplo de comando malicioso con ~/.ssh/id_rsa— y la lista de errores comunes de la sección de minimización de permisos.
Vulnerabilidad. De CVE-2026-25536 tomamos del aviso GHSA-345p-7cg4-v4c7 de la base de datos de avisos de GitHub el título, la fecha de publicación (4 de febrero de 2026), la puntuación 7,1, el vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N, el rango afectado (>= 1.10.0, <= 1.25.3), la versión corregida (1.26.0) y la descripción de los dos problemas: la colisión de identificadores de mensaje JSON-RPC al reutilizar una instancia de StreamableHTTPServerTransport entre clientes, y la sobrescritura silenciosa de this._transport al conectar una instancia de McpServer a varios transportes. Que no haya constancia pública de explotación es, a fecha de hoy, lo que hemos podido comprobar; no es una garantía.
Lo que es lectura nuestra y no de las fuentes. La más importante, y la que sostiene el titular: la especificación se queja de que el servidor MCP no aparezca en los registros del destino; el salto de ahí a «la investigación empieza por la persona equivocada» lo damos nosotros. También son nuestras: que una especificación no prohíba en mayúsculas lo que nadie hace, y que por tanto el reenvío de tokens sea frecuente; que el destinatario real del reparto de responsabilidad sobre los permisos sea quien pulsa «Permitir» y no el responsable de seguridad; la lectura de PR:L como «el otro empleado» en este escenario; la lectura de que la separación entre usuarios era una propiedad del código y no una garantía del protocolo; las siete preguntas y los tres casos en los que recomendamos no conectar. Las citas se dan en el original inglés; cuando aparecen en castellano, la traducción es nuestra. El escenario de la descarga del sábado de madrugada es un ejemplo ilustrativo construido por nosotros, no un incidente concreto de un cliente. Sobre nuestra propia casa: el n8n autoalojado y su uso para tareas internas y publicación en LinkedIn es nuestro. Todo se ha contrastado el 12 de septiembre de 2026.
Fotografía de portada: «Network equipment and cables organized in a server rack at a modern office environment during the afternoon», de Shixart1985, publicada en Wikimedia Commons bajo licencia Creative Commons CC BY 2.0. La hemos recortado y le hemos superpuesto los textos de marca.