Tokens en texto plano en tu configuración MCP: cómo sacarlos
Dónde guarda cada agente de código la configuración de sus servidores MCP, cómo encontrar los tokens escritos en ella, qué hace zn-gate init --wrap-mcp con ellos (no los quita) y cómo sacar los valores y deshacer cada paso.
Un servidor MCP suele necesitar un token, y la forma más rápida de dárselo es pegarlo en el env o los headers del servidor, en el archivo de configuración del agente. El token queda entonces en un archivo de texto plano en tu carpeta personal o en tu proyecto. Esta página indica dónde guarda cada agente ese archivo, cómo encontrar los tokens que contiene, qué hace y qué no hace zn-gate init --wrap-mcp con ellos, y cómo sacar los valores y deshacer cada paso. Para el panorama general de secretos y agentes de código, consulta la guía con la lista de comprobación.
Dónde guarda cada agente sus servidores MCP
| Agente | Archivo de usuario | Archivo de proyecto | Reescrito por init --wrap-mcp |
|---|---|---|---|
| Claude Code | ~/.claude.json |
.mcp.json en la raíz del proyecto |
~/.claude.json |
| Claude Desktop | claude_desktop_config.json (macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\, Linux ~/.config/Claude/) |
ninguno | ese archivo |
| Cursor | ~/.cursor/mcp.json |
.cursor/mcp.json |
~/.cursor/mcp.json |
| Codex CLI | ~/.codex/config.toml (o $CODEX_HOME/config.toml) |
.codex/config.toml (solo proyectos de confianza) |
el archivo de usuario |
| OpenCode | ~/.config/opencode/opencode.json (o opencode.jsonc) |
opencode.json en el proyecto |
el archivo de usuario |
| Antigravity | ~/.gemini/config/mcp_config.json |
.agents/mcp_config.json |
los archivos de usuario (zn-gate también busca ~/.gemini/antigravity/mcp_config.json) |
~/.claude.json también guarda los servidores configurados para un solo proyecto, bajo projects. init --wrap-mcp envuelve solo los mcpServers del nivel superior de ese archivo, así que las entradas por proyecto quedan sin envolver; audit sí las revisa.
Las rutas de Claude Code, Cursor, Codex CLI y OpenCode proceden de la documentación de cada agente; las de Claude Desktop y Antigravity siguen la documentación de zn-gate y la página de Antigravity. init --wrap-mcp no toca los archivos de proyecto: un token en un archivo de proyecto se queda donde está. Para VS Code, Windsurf, Cline, Zed, JetBrains y Continue, consulta Editores.
Encuentra los tokens
npx -y zn-gate reach
npx -y zn-gate audit --include-home
reach requiere zn-gate 1.12.0 o posterior. Ambos son de solo lectura. Avisan de un valor secreto escrito en la configuración de un agente (regla ZNA011) y nunca imprimen el valor. Ejecuta audit desde la carpeta de un proyecto para revisar también sus archivos; --include-home añade los archivos de tu carpeta personal de la tabla anterior (salvo los de Claude Desktop y Antigravity). Los dos usan la detección propia de zn-gate, así que un token con un formato que no conoce puede pasar desapercibido: lee también tú los archivos de configuración.
Qué hace zn-gate init --wrap-mcp con un token
No lo quita. En cada servidor local (stdio) cambia solo el comando de arranque: el comando original pasa a ser el argumento de npx -y zn-gate shield --. El resto de la entrada, incluido env, queda como estaba. El shield revisa entonces las descripciones de las herramientas, los argumentos de las llamadas y la salida de las herramientas, y elimina los secretos que reconoce en la salida antes de que tu agente la lea (detalles). Eso protege lo que el agente recibe del servidor. No protege el archivo.
Otros datos del comando:
- Los servidores remotos (URL) se dejan como están, así que un token en una entrada
headersse queda. - Antes de escribir un archivo, lo copia junto al original como
<archivo>.bak.<marca de tiempo>. Esa copia es el archivo tal como estaba, con los tokens. - Los archivos de OpenCode con comentarios y las entradas de Codex con
argsen varias líneas no se reescriben;initlos indica como "wrap manually".
npx -y zn-gate init --dry-run # vista previa, no cambia nada
npx -y zn-gate init --shadow # envuelve, solo registra
npx -y zn-gate init --wrap-mcp # envuelve y aplica
npx -y zn-gate init --revert # restaura la última copia de cada archivo
Saca el valor
Pon el token en una variable de entorno y haz que la configuración se refiera a ella por su nombre. Esto es lo que dice la documentación de cada agente:
- Claude Code, en
.mcp.json:${VAR}(y${VAR:-default}) se expande encommand,args,env,urlyheaders. Paraurlyheadersde un servidor remoto, la documentación de Claude Code añade un límite para las variables de credenciales; léelo antes de fiarte de esto ahí. - Cursor, en
mcp.json:${env:NAME}se resuelve encommand,args,env,urlyheaders. - Codex CLI, en
config.toml:env_varsreenvía variables del entorno de Codex a un servidor stdio,bearer_token_env_varindica la variable que contiene un token bearer yenv_http_headersasocia nombres de cabecera con nombres de variable. El archivo solo guarda nombres. - OpenCode:
{env:VARIABLE_NAME}se sustituye en los archivos de configuración, y su documentación de MCP lo muestra en las cabeceras. - Claude Desktop, Antigravity y los demás editores: no hemos verificado una forma de referirse a una variable de entorno en sus archivos MCP, así que esta página no da ninguna.
Ejemplo para Cursor, con un servidor y una variable inventados (EXAMPLE_API_TOKEN):
{
"mcpServers": {
"example": {
"command": "npx",
"args": ["-y", "example-mcp-server"],
"env": { "EXAMPLE_API_TOKEN": "${env:EXAMPLE_API_TOKEN}" }
}
}
}
La variable tiene que existir en el entorno del proceso del agente: defínela donde arrancas el agente (el perfil de tu shell o la forma que tenga tu sistema operativo de definir variables), reinicia el agente y comprueba que el servidor se conecta. Ten en cuenta que el perfil de tu shell es también un archivo de texto plano que el agente puede leer, así que poner ahí el token solo lo traslada a otro archivo. Mejor: usa el llavero de tu sistema operativo o un gestor de secretos para suministrar la variable al arrancar el agente, o al menos guarda el token en un archivo fuera de cualquier carpeta que abra el agente.
Un orden seguro
- Ejecuta
npx -y zn-gate reachy anota qué archivos contienen un token. - Sustituye cada token por una referencia a una variable de entorno como se ha explicado y reinicia el agente.
- Rota todos los tokens que hayan estado alguna vez en el archivo, si ese archivo se subió a un repositorio, se copió, se compartió o se envió, si un agente pudo leerlo o si el token apareció en una transcripción. Un valor que has quitado del archivo sigue siendo válido hasta que lo revocas en el proveedor.
- Solo entonces ejecuta
npx -y zn-gate init --dry-run, luego--shadowy luego--wrap-mcp. La copia que escribe contiene el archivo sin los tokens. - Si envolviste primero: borra los archivos
.bak.<marca de tiempo>junto a tus archivos de configuración cuando los tokens ya no estén, porque aún contienen los valores antiguos. - Vuelve a ejecutar
npx -y zn-gate reach.
Para qué sirve zn env shadow y para qué no
zn env shadow .env mueve los valores de un archivo .env a la bóveda local de zn-gate y deja marcadores en el archivo (Scrubber). Lee líneas CLAVE=valor. Los archivos de configuración MCP son JSON o TOML, y la documentación de zn-gate no describe env shadow para ellos, así que no lo apuntes a uno.
Cómo deshacer cada paso
- Envolver:
npx -y zn-gate init --revertcopia la última.bak.<marca de tiempo>sobre cada archivo de configuración. Todo lo que hayas cambiado en el archivo después de envolver se pierde, y si la copia contiene tokens, vuelven. Después del paso 2, deshaz a mano: en cada entrada, pon el comando y los argumentos originales en lugar denpx -y zn-gate shield --. - Referencias a variables de entorno: vuelve a poner el valor en el archivo solo si no queda otra, y nunca en un archivo que subas a un repositorio.
env shadow:zn env unshadow ARCHIVO --backup NOMBRE, con el nombre que imprimióenv shadow.
Límites
- La detección encuentra formatos conocidos; un token sin formato conocido puede pasar desapercibido.
- Envolver revisa lo que devuelve un servidor y lo que el agente le envía. No impide que otro programa lea el archivo de configuración.
- Un archivo de proyecto como
.mcp.jsonqueda fuera deinit --wrap-mcp. - Un token que has movido a una variable de entorno es visible para cualquier programa iniciado con ese entorno.
Preguntas frecuentes
¿zn-gate init --wrap-mcp quita los tokens de mi configuración MCP? No. Cambia el comando de arranque de los servidores locales y deja env y headers como estaban.
¿La copia de seguridad contiene mis tokens? Sí, si estaban en el archivo cuando envolviste. Borra los archivos .bak.<marca de tiempo> después de sacar los valores.
¿Puedo usar zn env shadow en mcp.json? Está documentado solo para archivos .env.
¿Cómo compruebo que no queda nada? Ejecuta npx -y zn-gate reach y npx -y zn-gate audit --include-home, y lee tú los archivos.
Fuentes
- zn-gate, proteger servidores MCP y
init --wrap-mcp: /es/docs/zn-gate/shield/ - zn-gate, qué comprueban
reachyaudit: reach.md, audit.md - Claude Code, MCP: https://code.claude.com/docs/en/mcp
- Cursor, MCP: https://cursor.com/docs/context/mcp
- Codex CLI, MCP: https://learn.chatgpt.com/docs/extend/mcp?surface=cli
- OpenCode, configuración y servidores MCP: https://opencode.ai/docs/config/, https://opencode.ai/docs/mcp-servers/