El Model Context Protocol hizo fácil darle manos a un asistente de IA. Añades unas líneas de JSON, reinicias el editor o el cliente de chat, y el asistente ya puede leer tickets, consultar una base de datos o abrir pull requests. Esa comodidad es el atractivo. También es la razón de preguntarse, sin rodeos, a qué puede llegar realmente cada uno de esos servidores.
La respuesta corta: un servidor MCP local es solo un programa que se ejecuta como tú. Llega a todo lo que tú alcanzas, más lo que le pases explícitamente.
Anatomía de un servidor MCP
La mayoría de los servidores MCP en portátiles de desarrollo los lanza el cliente como proceso hijo por stdio. El cliente lee una configuración JSON, ejecuta un comando como npx, uvx o un binario local, y pasa variables de entorno. También existen servidores remotos, a los que se llega por HTTP, pero hoy lo habitual es el patrón local.
Cuatro cosas definen el radio de impacto:
- Tools. Las funciones que el servidor anuncia al modelo:
read_file,run_query,create_issue. El modelo decide cuándo llamarlas. - Tokens. Claves de API y personal access tokens pasados en
env. Un servidor con un token amplio puede hacer todo lo que ese token permita, diga lo que diga su lista de tools. - Sistema de ficheros. Un servidor stdio se ejecuta con tus permisos de usuario. Si no está en un sandbox, puede leer tus claves SSH, credenciales cloud y el historial de la shell.
- Red. Puede abrir conexiones salientes a cualquier sitio al que llegue tu portátil, incluidos los servicios internos de la VPN.
Ten en cuenta que las herramientas anunciadas son una promesa, no una frontera. La frontera es el propio proceso, y por defecto esa frontera es toda tu cuenta.
Prompt injection a través de la salida de herramientas
El riesgo menos obvio no es que el servidor se porte mal. Es el dato que devuelve el servidor. La salida de las herramientas vuelve al modelo como contexto, y el modelo no sabe distinguir de forma fiable instrucciones de contenido.
- PlantarUn atacante escribe texto en algo que una herramienta va a leer: un comentario de una incidencia, un README, una página web, una fila de base de datos.
- RecuperarUn desarrollador pide al asistente que resuma las incidencias abiertas. El servidor de tickets devuelve el texto plantado.
- DirigirEl texto le dice al modelo que llame a otra herramienta, por ejemplo para leer un fichero de credenciales o hacer push de una branch.
- ActuarSi hay conectado un segundo servidor con acceso amplio, el modelo puede seguir la instrucción con la identidad del desarrollador.
- ExfiltrarLos resultados salen por cualquier herramienta que pueda escribir hacia fuera: un comentario, un commit, una petición HTTP.
La combinación peligrosa es un servidor que lee entrada no fiable junto a un servidor que puede escribir o llegar a secretos. Cada uno por separado puede estar bien. Juntos forman una línea directa del texto del atacante a tus credenciales.
Inventaria las configuraciones de MCP en un portátil
Los clientes MCP guardan sus listas de servidores como JSON, normalmente bajo una clave mcpServers de primer nivel, en el directorio personal del usuario, en una carpeta de application support o dentro de un proyecto como dotfile. No hace falta conocer todos los clientes. Busca la clave.
# macOS / Linux: find JSON files that declare MCP servers
grep -rl --include="*.json" '"mcpServers"' \
~/.config ~/Library/Application\ Support ~ 2>/dev/null \
| sort -u
# Also check project-level configs in your source tree
find ~/src -maxdepth 4 -name "*mcp*.json" -not -path "*/node_modules/*"
Después lista lo que ejecuta cada uno y lo que se le da:
jq -r '.mcpServers | to_entries[] |
[.key, .value.command, ((.value.args // []) | join(" ")),
((.value.env // {}) | keys | join(","))] | @tsv' path/to/config.json
Una entrada típica tiene este aspecto. Fíjate en el token en texto plano dentro de la configuración.
{
"mcpServers": {
"tickets": {
"command": "npx",
"args": ["-y", "example-tickets-mcp"],
"env": { "TICKETS_TOKEN": "PLACEHOLDER_NOT_A_REAL_TOKEN" }
}
}
}
Tres cosas que señalar: npx -y o similar sin versión fijada (ejecutas lo último que haya al arrancar), tokens guardados en línea y servidores que nadie del equipo sabe explicar.
Acota los tokens y usa allowlist de servidores
Trata cada servidor MCP como una nueva dependencia con credenciales adjuntas.
- Un token por servidor. Crea un token dedicado y de grano fino con los scopes mínimos y una caducidad. No reutilices nunca tu personal access token principal.
- Solo lectura por defecto. La mayor parte del uso del asistente son consultas. Concede scopes de escritura solo a los servidores que de verdad los necesiten, y mantén activas las confirmaciones.
- Fija versiones. Sustituye
npx -y packagepornpx -y package@1.4.2, o instala localmente un build revisado. - Saca los secretos del JSON. Carga los tokens desde el llavero del sistema o un wrapper de gestor de secretos en lugar de valores
enven línea. - Publica una allowlist. Una lista corta de servidores aprobados, sus versiones fijadas y los scopes permitidos. Todo lo demás es una conversación, no un bloqueo inmediato.
- Sesiones separadas. Evita conectar un servidor que lee entrada pública en la misma sesión que otro que puede tocar producción o secretos.
Compruébalo en 10 minutos
- Ejecuta el
grepde arriba en tu propio portátil y cuenta las configuraciones. - Para cada servidor, anota: comando, versión fijada o no, scopes del token y si puede escribir.
- Revoca cualquier token amplio que encuentres incrustado y emite uno acotado.
- Quita los servidores que no uses. Menos estaciones en la línea significa menos sitios donde puede empezar un fallo.
- Comparte el resultado con tu equipo y empieza la allowlist con lo que la gente usa de verdad.
Nada de esto exige prohibir los asistentes. Solo aplica el mismo razonamiento que ya usas con dependencias y tokens de CI a un tipo de herramienta más reciente.
Dónde encaja en la línea
En la torre (en desarrollo):