local-mcp-chatgpt-tunnel
Local MCP ChatGPT Tunnel
Gateway local para conectar servidores MCP de tipo stdio que se ejecutan en Windows a ChatGPT Developer Mode a través del Secure MCP Tunnel oficial de OpenAI. Agrega múltiples MCP stdio en uno solo y permite controlar desde un archivo de configuración la creación de espacios de nombres para nombres de herramientas, la exclusión de herramientas públicas, los permisos de rutas, la ejecución en serie y el inicio diferido.
Método de instalación
[!IMPORTANT] Para los pasos de instalación en entornos Windows, consulte INSTALL.md.
Related MCP server: Windows Local MCP
Advertencia de seguridad
[!WARNING] Esta es una herramienta personal para uso exclusivo con su propio PC con Windows, su propia Organización de OpenAI Platform y su propio Workspace de ChatGPT. Dado que puede conectar MCP con capacidad de ejecución de código arbitrario, no está previsto compartirla con terceros ni operarla como Plugin público.
Acerca del sandbox de codex
[!IMPORTANT] En la versión del 11 de agosto de 2026, se implementó un mecanismo que utiliza directamente el sandbox de codex y protege el ordenador de inconsistencias de límites y de la ejecución de código arbitrario. No se proporciona un shell general ni selección de archivos ejecutables arbitrarios, pero se incluyó
codex-scriptpara ejecutar scripts existentes con un runtime fijo.codex-scriptrequiere un sandboxelevatedounelevated. Los demás MCP incluidos y los MCP stdio externos también se pueden iniciar dentro del sandbox de Codex por cada MCP, por lo que de ahora en adelante se recomienda reforzar los límites con el modoelevatedsiempre que sea posible.
Acerca de la implementación por IA
[!CAUTION] Este repositorio fue implementado por ChatGPT 5.6 Sol High. Dado que contiene código generado por IA, es posible que queden errores o vulnerabilidades. Antes de usarlo realmente, revise el código y el contenido de la configuración, y utilícelo bajo su propia responsabilidad.
Qué puede hacer
Llamar a servidores MCP stdio en Windows desde ChatGPT
Consolidar múltiples MCP en nombres de herramientas con el formato
<prefix>__<tool>Añadir cualquier MCP stdio a
config/gateway.tomlRestringir los directorios y archivos permitidos por cada MCP
Hacer privadas las herramientas peligrosas por nombre o subcadena
Serializar con
serial_grouplos MCP que no se desea ejecutar simultáneamenteDeshabilitar por completo MCP específicos según sea necesario
Publicar un directorio integrado para buscar herramientas publicadas por identificador completo o prefijo según sea necesario
Lo que este repositorio no hace
Llamar a la API de Responses de OpenAI o a la API de Chat Completions
Implementar agentes de IA propios, harnesses propios o procesamiento de facturación de modelos
Proporcionar URL de MCP públicas o puertos de recepción locales
Instalar automáticamente Node.js, Git, ripgrep, Python o tunnel-client
Redistribuir MCP de terceros como Ghidra MCP, Chrome DevTools MCP, DQ9 MCP
La conexión al Secure MCP Tunnel la realiza el tunnel-client.exe oficial.Este repositorio proporciona un Gateway MCP local y MCP incluidos que se conectan a su entrada/salida estándar.
Entornos compatibles
Los pasos de instalación actuales son para Windows 11.La ejecución utiliza Node.js LTS y el tunnel-client.exe oficial de OpenAI.La función de búsqueda de archivos incluida utiliza ripgrep, y la verificación de GitHub Actions utiliza GitHub CLI. El script de diagnóstico comprueba node, npm, git, gh, rg y py.
No se proporcionan pasos de instalación para macOS y Linux, configuraciones de Docker ni configuraciones que abran puertos de recepción.
Antes de empezar a usarlo
Los pasos hasta que esté operativo están resumidos en INSTALL.md. El flujo general es el siguiente:
Preparar manualmente el software necesario y el
tunnel-client.exeoficialCopiar
config/gateway.example.tomlaconfig/gateway.tomly reescribir las rutas absolutasCrear un Tunnel personal y una API key de runtime solo para ejecución en OpenAI Platform
Guardar el Tunnel ID y la API key de runtime en las variables de entorno de usuario de Windows
Iniciar el Tunnel con
start.cmddespués del diagnósticoSeleccionar el Tunnel personal desde ChatGPT Developer Mode No avance adivinando la configuración o los permisos; revise siempre INSTALL.md desde el principio.
MCP incluidos
MCP | Ejemplo de herramientas públicas | Propósito |
|
| Listado dentro del Workspace permitido, búsqueda UTF-8, lectura de múltiples archivos y rangos de líneas, información de archivos, lectura/escritura, movimiento/copia de archivos entre Workspaces, aplicación limitada de parches |
|
| Leer PNG, JPEG, WebP como contenido de imagen de ChatGPT |
|
| Pasar las fuentes permitidas a ChatGPT como un solo archivo o como ZIP |
|
| Operaciones Git locales sobre repositorios permitidos. No incluye commit / push / pull / clone |
| Una de | Publica solo una capacidad Git por |
|
| Comprobación del estado de ejecución de Actions y cancelación de runs para repositorios de GitHub explícitamente permitidos |
|
| Ejecución de scripts existentes o comprobación de sintaxis dentro del Workspace permitido con un runtime fijo mjs / Node.js / Python / PHP fijado al iniciar el MCP. Se requiere |
|
| Obtener un archivo desde HTTP/HTTPS dentro del límite |
|
| Creación y extracción de archivos usando solo 7-Zip fijo |
|
| Maneja búsqueda remota, SSH, transferencia, detención y deployments públicos temporales solo para GitHub Codespaces existentes. No detecta automáticamente localhost ni puertos de escucha locales, y tampoco tiene herramientas de creación de Codespaces |
Los MCP incluidos no tienen dependencias npm externas. Todas las herramientas declaran outputSchema.
El Gateway publica isolated__create, isolated__list, isolated__close y exige un isolatedId único para todas las herramientas de los MCP incluidos. isolated__create recibe uno o más directorios absolutos en el array workspaces, y también exige un purpose que explique para qué trabajo de aislamiento lo usará la IA/sesión. El Gateway registra automáticamente createdAt, y isolated__list también devuelve lastOperationAt para cada prefijo. Mantiene múltiples Workspaces por ID y bases de rutas relativas por MCP. No duplica los procesos de los MCP incluidos, sino que pasa el grupo de roots del ID objetivo en cada llamada. Las llamadas normales a herramientas incluidas no se serializan innecesariamente en el Gateway, dejando el procesamiento paralelo al lado del MCP hijo; solo Codespace tiene una cola para evitar conflictos con el mismo codespaceId.
Al iniciar, el Gateway genera una clave aleatoria por cada MCP incluido, firma el isolatedId, las rutas base normalizadas y el grupo de roots con HMAC-SHA-256, y los pasa como argumentos privados. Los MCP incluidos rechazan contextos sin firmar, manipulados o estructuralmente inválidos, y también rechazan la sobrescritura de root, roots, workspace, workspaces desde argumentos públicos.
El Gateway añade <prefix>__get_gateway_access_scope a todos los MCP hijos que inicia. En los MCP incluidos se llama con isolatedId para comprobar los directorios base, el grupo de roots, los valores de configuración y las rutas permitidas/denegadas normalizadas aplicables a ese ID.
Cuando se rechaza una ruta fuera del ámbito permitido, el cuerpo del error devuelve los directorios y archivos actualmente permitidos como rutas absolutas normalizadas. El formato de salida común de los MCP incluidos también devuelve la misma lista en structuredContent.result.accessScope. Tras un rechazo, la IA no necesita adivinar otro directorio de trabajo y reintentar.
safe-files
Lo que safe-files llama externamente "MCP root" es el directorio base actual almacenado para el isolatedId objetivo. Las rutas relativas se resuelven desde esta base, y set_working_directory cambia la base solo dentro del grupo de roots del mismo ID. No cambia el estado de otros IDs ni de procesos MCP compartidos.
read_text acepta tanto rutas relativas desde el MCP root como rutas absolutas, pero solo lee si el objetivo, después de la normalización y la resolución de la ruta real, permanece dentro de los directorios permitidos configurados.
Las funciones principales son las siguientes:
Listado recursivo con
rg --files --hiddenfijoBúsqueda de texto UTF-8 con
rgfijoLectura/escritura de texto UTF-8 y reemplazo por coincidencia exacta
Transferencia de archivos base64 con límite de tamaño
Creación de directorios
Copia y movimiento de archivos normales entre los Workspaces permitidos configurados
Aplicación de parches con el parser integrado o con
git applyfijocopyymoveaceptan rutas relativas desde el MCP root actual y rutas absolutas, y pueden transferir archivos normales incluso entre múltiplesallowed_directories. Aplican la política de permitir/denegar tanto al origen como al destino, y rechazan enlaces simbólicos, directorios y la sobrescritura de destinos existentes. Para el movimiento, funciona incluso entre unidades diferentes: realiza una copia exclusiva con éxito antes de eliminar el origen, y restaura el destino si falla la eliminación. Las cadenas de ruta no se pasan al shell y los símbolos no se interpretan como comandos.El listado recursivo excluye siempre el interior de.git, y los parches no pueden tener como objetivo el interior de.git. También rechaza fuera de las raíces permitidas, escapes mediante enlaces simbólicos y contenido que con alta probabilidad parezca credenciales.No incluye shell general, PowerShell ni herramientas de ejecución de comandos arbitrarios.
safe-images
safe-images es de solo lectura. Comprueba las extensiones y los bytes mágicos de PNG, JPEG y WebP, y limita en el estado inicial a 8 MiB y 50 megapíxeles.
Rechaza SVG, HEIC, archivos vacíos, fuera de las raíces permitidas, enlaces simbólicos, rutas UNC y flujos de datos alternativos de NTFS.
safe-download
safe-download es de solo lectura y devuelve siempre un solo archivo o directorio como ZIP. Configura un cwd y una lista de permitidos separados de safe-files, y solo expone las fuentes que es seguro pasar a ChatGPT.
Los directorios se enumeran con rg --files --hidden fijo, rechazando el interior de .git, ROMs, Saves, States, formatos de claves privadas, contenido que parezca credenciales, fuera del ámbito permitido y enlaces simbólicos. Si se configura disallowed_path_globs, se comprueba todo el directorio objetivo antes de aplicar los globs o excludePaths especificados por el usuario, y si hay aunque sea un archivo o carpeta que coincida con un patrón de denegación, se rechaza toda la creación del ZIP. El error incluye los patrones de configuración coincidentes y las rutas objetivo.
internet
internet es un MCP incluido que obtiene un archivo desde cualquier URL HTTP/HTTPS. La única herramienta pública es download_file, y el destino se limita al workspace del isolatedId firmado por el Gateway. No acepta sobrescribir archivos existentes, UNC/ADS, escritura fuera del workspace ni inyección de headers/cookies/credenciales arbitrarios. Si falla a mitad de camino, elimina el archivo temporal.
Este MCP se inicia siempre con sandbox = "onlineworkspace". onlineworkspace mantiene el límite de filesystem workspace-write de Codex y habilita solo la red de ese perfil de permisos. No recurre a sandbox = "never".
archive
archive es un MCP incluido que fija 7-Zip al iniciar con --seven-zip-executable=<absolute-7z.exe-path> y solo publica create_zip, create_7z y extract_archive. No expone shell general, archivos ejecutables arbitrarios ni argumentos arbitrarios de 7-Zip. La entrada y la salida se limitan al workspace firmado. extract_archive puede manejar source y destination incluso en roots permitidos diferentes, por lo que, por ejemplo, un archivo en Downloads se puede extraer directamente a un workspace de Proyecto. El destino de extracción se crea si no existe, y si existe solo acepta un directorio normal vacío. Las rutas se limitan a 1024 caracteres después de la resolución.
archive en sí también se inicia dentro del sandbox de Codex, y la ubicación de instalación de 7-Zip se pasa como entrada de confianza de solo lectura mediante sandbox_read_only_directories.
codespace
codespace es un MCP incluido que opera únicamente sobre GitHub Codespaces ya existentes. Usa el name devuelto por list_codespaces como codespaceId de cada herramienta. No se implementan herramientas para crear Codespaces, hacer rebuild, cambiar de machine, iniciar explícitamente o eliminar. El arranque inicia implícitamente un Codespace existente mediante la conexión SSH o copy, y al finalizar el trabajo se puede detener explícitamente con stop_codespace, que ejecuta gh codespace stop -c <name>. Antes de detenerlo, se cancelan los SSH asíncronos para ese mismo Codespace que posea esa sesión aislada, y también se descarta la caché de readiness SSH. Tras la detención no se eliminan ni el Codespace en sí ni los cambios guardados. No existe ninguna vía por la que la IA pueda crear Codespaces de forma caprichosa. Un mismo codespaceId solo lo posee una única sesión aislada; si otra sesión aislada nueva lo toca, la propiedad se transfiere con prioridad al último. La sesión anterior no puede recuperarlo automáticamente; ante un error de conflicto se le indica que consulte purpose en isolated__list y lastOperationAt con prefijo codespace para pedir al usuario que decida. Solo las llamadas al mismo codespaceId se serializan en el Gateway; otros MCP incluidos como files no se serializan innecesariamente.
El propio MCP debe iniciarse siempre con sandbox = "onlineworkspace". --gh-executable=<absolute-gh.exe-path> es obligatorio. Para cubrir configuraciones donde las credenciales normales de gh auth login guardadas en el Administrador de credenciales de Windows no sean visibles para el usuario del sandbox, se puede especificar opcionalmente --token-file=<absolute-file>. Este archivo se pasa al perfil de permisos de Codex como entrada de confianza fija de solo lectura, y su contenido se establece únicamente dentro del MCP como GH_TOKEN. No se heredan GH_TOKEN / GITHUB_TOKEN del entorno padre. No se configuran, leen ni permiten claves SSH de usuario. Las claves necesarias para SSH/cp las genera automáticamente el propio Codespace MCP mediante ssh-keygen en un directorio runtime temporal no oculto preparado por el Gateway, y se eliminan cuando el Gateway cierra el MCP hijo. Este directorio interno solo tiene permiso de escritura en el perfil de permisos de Codex; no se añade a allowed_directories ni al rango normal de acceso a archivos del Gateway. gh.exe y el archivo de token no pueden colocarse dentro de allowed_directories con permiso de escritura.
ssh recibe el comando remoto como un array de tokens, no como una sola cadena, y rechaza espacios, comillas, !, @, backticks, $, ;, &, pipes y otros metacaracteres/expansiones de shell. timeoutMs es el tiempo de ejecución máximo real de la operación subyacente, distinto del tiempo que se espera como respuesta síncrona. Normalmente se espera de forma síncrona solo durante syncWaitMs, con un valor predeterminado/máximo de 10.000 ms. Si no se completa, no se detiene el procesamiento: se traslada al registro asíncrono compartido y se devuelve asyncId. syncWaitMs=0..1000 se trata como asíncrono inmediato, y si async=true se ignora syncWaitMs y se devuelve asyncId directamente desde el principio. get_async_status, al omitir asyncId, devuelve todas las operaciones asíncronas en curso de ese aislamiento; con un ID individual se pueden obtener el detalle o el resultado completado. get_async_logs sirve para obtener todo el stdout/stderr en curso de trabajos respaldados por procesos. wait_async se mantiene como implementación de compatibilidad, pero normalmente se usan get_async_status / get_async_logs para no mantener respuestas MCP prolongadas que involucren al Gateway/tunnel.
copy_to_codespace envía archivos/directorios locales seleccionados desde sourceDirectory, ya sea mediante la enumeración de paths o mediante globs, al destino remote: indicado explícitamente por el llamador. El MCP no infiere ni añade automáticamente remote:. Por ejemplo, con paths=["scripts/a.js"] se coloca en /workspaces/project/scripts/a.js bajo remote:/workspaces/project; no aplana solo el basename directamente bajo el destino. Para mantener la jerarquía, se crean únicamente los directorios padre remotos necesarios mediante un helper fijo, y cada selección se copia a su destino correspondiente. copy_from_codespace es en dirección inversa: copia un único origen remote:/workspaces/<workspace>/... indicado explícitamente por el llamador a un directorio destino existente dentro del workspace local firmado. El origen remoto se inspecciona antes de copiar y se rechazan symlinks/entradas especiales, un número excesivo de entradas y transferencias superiores a CODESPACE_MCP_MAX_TRANSFER_BYTES. También se rechaza si el basename del destino local ya existe. En ambas herramientas de copia, solo el lado remoto debe llevar remote:; el lado local debe ser una ruta local, y se rechazan especificaciones ambiguas como ausencia de protocolo remoto o ambos lados remotos. Debido a un problema conocido de GitHub CLI por el que gh codespace cp falla con No such file or directory sin -e incluso en rutas remotas existentes, se añade -e siempre en ambas direcciones. remote: lo indica explícitamente el llamador; el MCP no lo añade automáticamente. La readiness SSH se comprueba solo cuando es necesario mediante una sonda fija echo started, y solo se reintenta una vez tras la sonda si falla una cp con caché reutilizada.
La búsqueda remota enumera con roots únicamente los workspaces directamente bajo /workspaces, y con git_root se puede obtener el top-level de Git de una ruta especificada. search_text es una búsqueda ripgrep de primera clase equivalente a files__search_text, que exige searchBase=/workspaces/<workspace>/... en cada llamada. No se pueden usar como raíz de búsqueda /, /workspaces, home, /etc, etc. searchBase se vuelve a validar tras el realpath remoto. La consulta y los globs no se concatenan a la cadena de comando SSH; se codifican en base64 y se pasan por stdin a un script remoto fijo. .git queda siempre excluido de la búsqueda, con un límite de 16 MiB por archivo y un máximo de 500 resultados. ripgrep_version permite comprobar rg --version, e install_ripgrep no hace nada si rg ya existe; solo si no existe, un instalador fijo lo introduce mediante apt/dnf/yum/apk y luego vuelve a comprobar la versión. No se pueden pasar nombres de paquete ni cadenas de shell arbitrarias desde los argumentos de las herramientas.
list_temporary_public_deployments obtiene los candidatos públicos temporales de Codespace que GitHub ya reconoce, junto con browseUrl / port / visibility. No es una herramienta que explore localhost, sockets en escucha del PC local, pestañas del navegador ni servidores de desarrollo locales, y tampoco realiza detección automática de puertos. Si GitHub devuelve 0 candidatos, no se devuelve un array vacío como resultado normal, sino un error corregido que indica explícitamente que «esto no es un fallo de detección automática de puertos locales» y que «no se debe recurrir a exploración de localhost, port scan, adivinación de URL ni desvío a gh codespace ports forward». open_temporary_public_deployment se dirige únicamente a un puerto de Codespace indicado explícitamente por el llamador: primero solicita a GitHub el cambio de visibilidad a public y, tras el éxito, confirma y devuelve la URL completa https://...app.github.dev. Si se conoce el puerto exacto, se llama directamente a esta herramienta sin usar list_temporary_public_deployments como condición previa. No se debe inferir que .devcontainer necesita forwardPorts solo porque la lista devolvió 0 elementos. Si GitHub rechaza el puerto especificado, se devuelve el error real y no se explora localhost para adivinar un puerto alternativo. close_temporary_public_deployment también devuelve a private únicamente el mismo puerto indicado explícitamente y cierra la publicación temporal. Ninguna de ellas crea túneles de puerto localhost ni crea/elimina entradas de reenvío en el lado de GitHub. El browseUrl devuelto se puede usar directamente desde Chrome DevTools u otras herramientas para verificar la conectividad del despliegue temporal.
gitmcp
gitmcp ejecuta únicamente operaciones locales sobre repositorios Git dentro de directorios permitidos, con subcomandos y opciones de Git fijos. En el arranque exige --git-executable=<absolute-path> y ejecuta solo ese binario con shell=false. No acepta shells generales ni argumentos Git arbitrarios, y no admite edición directa de .git, adición de hooks, eliminación de ramas ni operaciones forzadas. add_all, stage_paths, unstage_paths, que reescriben el index, junto con commit, push, pull y clone_repository, se han movido a un MCP git-capability separado por aislamiento de fronteras. Los antiguos --disable-push, --disable-pull y --disable-clone se aceptan como no-op para no dejar inutilizable un gateway.toml antiguo, pero ponerlos en false no restaura las capacidades movidas.
Se pueden usar status, el listado de archivos rastreados, la consulta de ramas/remotes/historial, el diff del árbol de trabajo o del área de staging, el show de un commit concreto, el cambio a una rama existente con checkout, la creación de ramas especificando el commit padre, y la creación, listado y eliminación normal de worktrees dentro de la raíz permitida. No se implementan la eliminación de ramas, la eliminación del worktree principal ni la eliminación forzada de worktrees sucios o bloqueados.
Para respetar .gitignore y la configuración de ignore estándar, status no muestra archivos no rastreados ignorados. También se respetan .gitattributes, .git/info/attributes, los attributes globales, las conversiones de fin de línea como core.autocrlf, los filtros clean/smudge de configuración de sistema/global, los diff externos y textconv, igual que en Git normal. Las configuraciones ejecutables colocadas en .git/config del repositorio o en la config del worktree se rechazan de antemano. Dado que los filtros y helpers de diff de sistema/global pueden ejecutarse según lo previsto, se recomienda configurar gitmcp, que tiene permisos de operación sobre archivos, para que se ejecute dentro del sandbox del sistema operativo de Codex cuando sea posible. En el sandbox de Codex para Windows, la lectura :minimal del perfil de permisos otorga raíces de lectura de sistema como C:\Program Files, por lo que el estándar C:\Program Files\Git\cmd\git.exe se puede usar sin configuración de lectura adicional. Solo al especificar un Git fuera de las raíces de lectura de sistema, como Portable Git, se añade el directorio de instalación de ese Git a sandbox_read_only_directories. sandbox = "never" también está disponible por compatibilidad hacia atrás.
list_worktree_files enumera los archivos rastreados y los no rastreados no ignorados mediante el propio juicio de exclusión de Git. check_ignore devuelve las reglas de ignore aplicadas a cada ruta y el veredicto final; check_attributes devuelve los valores efectivos de atributos como text, binary, diff, merge, filter y fin de línea. get_effective_config excluye de la consulta credential.*, el nombre de autor y la dirección de correo, y devuelve con scope y origen la configuración relevante para el comportamiento del gitmcp local, como core.autocrlf, filter, attributes y diff/textconv.
La medida de seguridad no es desactivar toda la configuración de Git, sino limitarse a rechazar hooks, helpers, filters, diff/textconv externos, merge drivers, programas de firma, proxies y configuraciones de transporte personalizadas colocadas en el .git/config del propio repositorio o en la config del worktree. Los hooks, fsmonitor, los protocolos file y ext, y los prompts de credenciales interactivos están deshabilitados. get_policy permite consultar la política actual en formato legible por máquina.
Si se especifica directamente un submódulo o un repositorio Git anidado como repositoryPath, se pueden obtener el status, diff, log, etc. de ese propio repositorio. No se incluye ninguna herramienta que explore recursivamente bajo el repositorio padre para enumerar automáticamente todos los repositorios anidados.
git-capability
git-capability es un MCP incluido que registra mcp/git-capability/server.mjs varias veces con --mode=stage|commit|push|pull|clone para separar las capacidades de Git según el propósito. Cada registro es un [mcp_servers.<name>] independiente, por lo que se pueden elegir individualmente sandbox, allowed_directories, timeout y serial_group. No se prohíbe sandbox = "never"; quienes necesiten compatibilidad con el index de Git, agentes de firma y la red también pueden elegir la vía tradicional.
En todos los modos se fija --git-executable=<absolute-path> en el arranque, y no se pueden elegir desde los argumentos de las herramientas el ejecutable de Git, repositoryPath, variables de entorno ni argumentos Git arbitrarios. A través del Gateway se exige el mismo workspace aislado firmado con HMAC que en los MCP incluidos normales. Si en el .git/config del repositorio o en la config del worktree hay hooks/helpers/filters/diff/merge drivers/programas de firma/proxies/configuraciones de transporte ejecutables, se rechazan antes de ejecutar la capacidad.
El modo stage solo expone add_all, stage_paths y unstage_paths, y la selección de repositorio se fija desde el workspace/base firmado. Al iniciar el MCP de Git con sandbox, el Gateway recorre por sí mismo los .git existentes en ese momento bajo la raíz con permiso de escritura y añade al perfil de permisos de Codex las raíces de escritura de metadatos de Git concretas. Esto se basa en que is_metadata_write_denied / has_explicit_write_entry_for_metadata_path de Codex permiten entradas de escritura explícitas más específicas dentro de metadatos protegidos. .git/hooks, .git/objects/info y .git/modules permanecen con denegación de escritura, y también se deniega la escritura de .git/config, config.worktree, commondir y gitdir existentes. Por tanto, el stage y las actualizaciones normales de metadatos de ramas/worktrees están disponibles dentro del sandbox, pero la adición de submódulos queda fuera de alcance. Los .git creados después del arranque no se permiten automáticamente, por lo que git init y los clones dentro del sandbox no se gestionan con este mecanismo. En el stage también se respetan los ignore, attributes, conversión de fin de línea y filtros clean de sistema/global estándar, y se rechazan las rutas de worktree denegadas.
El único argumento de herramienta del modo commit es message; solo hace commit del index ya preparado con git commit --no-verify -m <message>. No tiene funciones de stage ni selección de repositorio. Como se mantiene la configuración de firma de commits de sistema/global, en configuraciones donde se quiera dar acceso al agente de firma se puede poner solo el MCP de commit en sandbox = "never" y dejar el gitmcp más amplio dentro del sandbox.
push y pull fijan en el arranque --remote= y uno o más --repository=OWNER/REPO, normalizan la identidad del repositorio de GitHub a partir de la URL remota y la comparan con la lista de permitidos. Así, https://github.com/OWNER/REPO.git y git@github.com:OWNER/REPO.git se tratan como el mismo repositorio, pero no se permiten coincidencias parciales del nombre del repositorio. Para permitir varios workspaces en una misma capacidad se puede repetir --repository=. El antiguo --expected-remote-url=<exact-url> también está disponible por compatibilidad hacia atrás. Las llamadas a herramientas no reciben remote, URL ni refspec. push envía solo la rama actual sin fuerza y no reescribe la configuración de upstream. pull hace fetch del remote fijo, aplica la política de rutas al árbol entrante y luego lo refleja en la rama actual del mismo nombre con --ff-only.
clone elimina el antiguo --url= del arranque y recibe en la herramienta url, el nombre del nuevo subdirectorio y un depth opcional. url admite formatos http://, https://, ssh://user@host/path y user@host:path de cualquier host. Se rechazan credenciales incrustadas en URLs HTTP(S) y contraseñas incrustadas en URLs SSH, y se mantienen las vías de autenticación heredadas normales como credential helpers de Git, askpass y SSH agent / configuración SSH. Tras obtener con --no-checkout, se inspeccionan las rutas permitidas/denegadas del árbol entrante antes del checkout, y en caso de fallo se elimina únicamente el destino de clon recién creado en esa llamada. No se exponen la recursión de submódulos ni parents arbitrarios.
gh-workflow
gh-workflow comprueba el estado de ejecución de GitHub Actions y cancela runs indicados explícitamente, únicamente para repositorios de GitHub permitidos explícitamente mediante el argumento de arranque --repository=OWNER/REPO. --repository= se puede especificar varias veces; los repositorios no especificados no se pueden seleccionar. Si hay un único repositorio permitido, se puede omitir en cada herramienta; si hay varios, es obligatorio especificar el repositorio objetivo. En el ejemplo de configuración se especifica DaisukeDaisuke/desmume_webassembly, y el propio MCP está deshabilitado por defecto.
Además de las herramientas equivalentes a gh run list --branch main --limit 3, gh run watch RUN_ID --exit-status, gh run cancel RUN_ID y gh run view RUN_ID, se pueden obtener el listado de jobs, todos los logs, los logs de fallo, el listado de workflows, el resumen de workflows y el YAML de workflows. cancel_run pasa únicamente el ID de run decimal verificado y el repositorio permitido como argumentos fijos. No se exponen workflow dispatch, rerun, delete, descarga de artifacts ni gh api.
gh se inicia directamente desde spawn con shell=false, con subcomandos y opciones fijos. El ID de run, la rama y el identificador de workflow se validan individualmente; se cierra la entrada estándar y se limita el tamaño de salida. El cwd del proceso hijo debe especificarse siempre en gateway.toml. Para la autenticación se puede usar la configuración de GitHub CLI guardada localmente con gh auth login.
codex-script
codex-script es un MCP incluido que fija el runtime de ejecución en el arranque con --runtime=mjs|nodejs|python|php y --runtime-executable=<absolute-path>, y ejecuta únicamente scripts que ya existen dentro del Workspace permitido. Se puede registrar el mismo server.mjs varias veces y publicarlo con prefijos independientes como mjs_script, nodejs_script, python_script y php_script.
Con --mode=run se expone run_script; con --mode=check, check_file. run_script inicia solo el runtime en sí; check_file inicia únicamente el checker fijo: --check de Node.js, py_compile de Python o -l de PHP. check_file admite, además de la especificación de un único filePath por compatibilidad hacia atrás, la comprobación de hasta 500 archivos de una vez con filePaths; el retorno es pass, fault y messages solo de los archivos con fallo. No se devuelve el stdout/stderr de los checkers que tienen éxito. No se exponen shells generales, selección de ejecutables arbitrarios, inyección de variables de entorno arbitrarias, ni llamadas a npm scripts o package managers. Los argumentos se pasan como argv literales, se cierra stdin y se limitan el timeout y el tamaño de salida.
El Gateway trata codex-script como isBundled y aplica la base/roots firmados seleccionados con isolatedId y la política de rutas habitual. Además, si en gateway.toml se especifica sandbox = "never" para codex-script, se rechaza al cargar la configuración; es necesario iniciar el propio proceso MCP dentro del sandbox de Codex para Windows elevated o unelevated. En lugar de crear un sandbox distinto en cada llamada al script, el runtime fijo opera como proceso hijo del MCP ya sandboxizado.
En --mode=run, que ejecuta código arbitrario, el código opera dentro del Workspace permitido, por lo que allowed_directories debe ser el mínimo necesario y el runtime, el CLI de Codex y los ejecutables del MCP deben colocarse fuera de las raíces con permiso de escritura. disallowed_directories y disallowed_files se pueden usar como deny exacto del perfil de permisos de Codex externo. disallowed_path_globs se rechaza tanto en run como en check porque no se puede convertir de forma segura y equivalente al sandbox de código arbitrario; si es necesario, se sustituye por un deny exacto o se reduce el propio allowed_directories.
Añadir un MCP stdio arbitrario
El comando de arranque y los argumentos del MCP a conectar se describen en [mcp_servers.<name>] de config/gateway.toml, no en el propio Gateway.
private_use_only = true
publish_tool_directory = false
[mcp_servers.example]
command = "py"
args = ['C:\path\to\server.py']
cwd = 'C:\path\to'
enabled = true
prefix = "example"
annotation_config = true
startup_timeout_sec = 30
tool_timeout_sec = 1800
allowed_directories = ['C:\work\project']
allowed_files = ['C:\Users\owner\Downloads\one-upload-file.png']
[mcp_servers.example.env]
EXAMPLE_CONFIG = 'C:\path\to\config.json'Solo los MCP stdio válidos se inician como procesos hijo, y el nombre de herramienta original tool_name se expone en el lado de ChatGPT como example__tool_name. Las entradas con enabled = false no se inician.
tool_output_token_limit copiado de la configuración de Codex, la configuración de aprobación por herramienta y los elementos que el Gateway no reconoce se ignoran. No tienen efecto en este Gateway.
Annotations de herramientas de MCP externos
El MCP externo, basándose en las annotations devueltas por el MCP hijo, completa y publica los valores que faltan (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) con valores explícitos. Si el MCP hijo devuelve solo readOnlyHint = true, se completan destructiveHint = false e idempotentHint = true a menos que se especifique explícitamente lo contrario.
Al iniciar el Gateway, si no existe el TOML especificado en tool_annotations_path, se crea; y si no existe la tabla [tool_annotations.<prefix>] correspondiente al prefijo de un MCP externo activo, se añade al final. Los nombres de herramientas obtenidos del MCP hijo también se añaden a [tool_annotations.<prefix>.tools] como UNCLASSIFIED. No se sobrescriben las configuraciones de prefijos existentes ni las asignaciones de herramientas, y las herramientas que hayan desaparecido no se eliminan automáticamente.
Los MCP incluidos definen sus annotations en cada server.mjs, por lo que en gateway.toml se establece annotation_config = false. Para los MCP externos, se trata como true cuando se omite.
En el TOML generado automáticamente, se incluyen comentarios que explican el significado de las siguientes abreviaturas y de los 4 hints. open_world_hint sobrescribe el prefijo completo, y open_world_tools sobrescribe el openWorldHint de cada herramienta individual.
[tool_annotations.chrome-devtools]
default = "LOCAL_STATE_ANNOTATIONS"
open_world_hint = true
[tool_annotations.chrome-devtools.tools]
take_snapshot = "READ_ONLY_ANNOTATIONS"
click = "UNCLASSIFIED"
[tool_annotations.chrome-devtools.open_world_tools]
take_snapshot = false
click = trueUNCLASSIFIED es un marcador sin clasificar que conserva los valores existentes de las annotations devueltas por el MCP hijo y solo completa los hints que faltan. Al clasificar, el valor de cada identificador de herramienta se cambia a uno de los siguientes: READ_ONLY_ANNOTATIONS, LOCAL_STATE_ANNOTATIONS, LOCAL_DESTRUCTIVE_IDEMPOTENT_ANNOTATIONS, LOCAL_DESTRUCTIVE_NON_IDEMPOTENT_ANNOTATIONS, LOCAL_ADDITIVE_IDEMPOTENT_ANNOTATIONS.
Configuración del Gateway
Se respetan las decisiones del usuario
El comportamiento del Gateway se determina por la configuración que el usuario especifica explícitamente en config/gateway.toml. No detecta MCP automáticamente ni los registra por su cuenta, ni reescribe automáticamente los archivos de configuración.
Como excepción, para las annotations de herramientas de MCP externos, se añaden al TOML independiente especificado en tool_annotations_path los prefijos no registrados y los identificadores de herramientas recién descubiertos. Las herramientas nuevas se clasifican como UNCLASSIFIED, y no se modifican gateway.toml, los prefijos existentes ni las configuraciones de herramientas existentes.
El usuario elige todos los aspectos: los MCP a conectar, sus comandos de inicio, argumentos, directorios de trabajo, variables de entorno, habilitación/deshabilitación, el modo sandbox de Codex, las rutas de solo lectura para el sandbox, las herramientas que no se publican, los rangos de rutas permitidos/denegados, la ejecución en serie y el inicio diferido.
El Gateway lee esa configuración, la valida y la aplica, pero no añade configuraciones por su cuenta ni amplía los rangos permitidos, adivinando la seguridad o el propósito en lugar del usuario.
config/gateway.example.toml es un ejemplo de configuración, no un "script mágico" que se aplica tal cual. El usuario debe revisar solo los elementos necesarios y escribirlos en config/gateway.toml, de modo que pueda comprender qué programas se inician realmente y qué funcionalidades se exponen.
No se proporciona ejecución de comandos de propósito general
Este repositorio no incluye un ejecutor de comandos de propósito general (shell general, PowerShell, símbolo del sistema, selección arbitraria de ejecutables, inyección arbitraria de variables de entorno, etc.) que exponga los privilegios de usuario de Windows tal cual.
La excepción es el codex-script mencionado anteriormente, que fija el runtime de ejecución al iniciar el MCP y ejecuta únicamente los scripts existentes dentro del Workspace permitido, dentro del sandbox de Codex OS. Esto no es una solución que simplemente permita rutas y haga seguro cualquier código arbitrario, sino un ejecutor de scripts limitado que exige el sandbox de OS.
Si se expone directamente la ejecución de código arbitrario al público, la información de conexión (como Tunnel ID o runtime API key) podría filtrarse sin intención, y si se abusa de ello, un atacante podría ejecutar operaciones arbitrarias con los privilegios de usuario de Windows. Por lo tanto, incluso al añadir un MCP externo que ejecute código arbitrario, se debe usar sandbox = "elevated" o "unelevated" y mantener el directorio con permisos de escritura al mínimo necesario.
Para tareas que no requieran ejecución local, como la generación o transformación de código, se debe seguir priorizando el sandbox del lado de ChatGPT. Si solo se necesita pasar código fuente local, se puede empaquetar en ZIP únicamente los archivos permitidos mediante safe-download.
Protección de la ejecución del Gateway
Si se establece protect_gateway_app = true, incluso cuando el directorio app del propio Gateway se solapa con el Workspace permitido, se tratará como de solo lectura para los MCP hijos. El valor predeterminado en el código del Gateway es false, pero en el ejemplo de configuración incluido es true. Para los MCP en sandbox, se añade una entrada de lectura más específica al perfil de permisos de Codex, y en safe-files se mantienen la lectura y file_info, mientras se deniegan write, replace, el borrado del origen en move, patch y la creación de subdirectorios. En file_info, los objetos protegidos se muestran como prohibited=true.
Esta configuración no es un límite de OS para el caso en que un proceso hijo con sandbox = "never" se vea comprometido hasta el punto de ejecutar código arbitrario. Con never, el hijo puede ignorar la política de rutas del Gateway, por lo que si se necesita denegar forzosamente la escritura al código en ejecución, se debe usar el sandbox de Codex OS.
Permisos de rutas
allowed_directories permite el directorio especificado y todo su contenido; allowed_files permite únicamente los archivos especificados, mediante coincidencia exacta.
El Gateway inspecciona recursivamente los argumentos de las herramientas de todos los MCP hijos y compara claves como path, filePath, files, directory y cadenas que parezcan rutas absolutas contra la lista de permisos. Las rutas relativas se resuelven a partir del cwd del MCP correspondiente.
<prefix>__get_gateway_access_scope, que se añade automáticamente a cada MCP hijo, devuelve los valores de configuración utilizados en esta inspección y el alcance efectivo normalizado. Así, la IA no tiene que adivinar el directorio de trabajo ni las rutas permitidas a partir de conversaciones anteriores, sino que puede consultar directamente el estado actual del Gateway.
allowed_directories = ['C:\work\project']
allowed_files = ['C:\Users\owner\Downloads\upload.png']
disallowed_directories = ['C:\work\project\private']
disallowed_files = ['C:\work\project\.env']
disallowed_path_globs = ['**.ssh**']disallowed_path_globs es un glob de denegación que se aplica a la ruta completa normalizada, tanto para archivos como para carpetas.
* coincide con cualquier cadena que no cruce un separador de ruta; ** coincide con cualquier cadena, incluidos los separadores; ? coincide con cualquier carácter individual que no sea un separador de ruta.
Por ejemplo, '**.ssh**' deniega cualquier ruta que contenga .ssh en cualquier parte. En Windows, \ y / se tratan como el mismo separador y no se distingue entre mayúsculas y minúsculas.
En macOS y Linux, / es el separador y se distingue entre mayúsculas y minúsculas.
El error de denegación muestra que la ruta fue rechazada por disallowed_path_globs, el glob que coincidió y la ruta objetivo normalizada.
La inspección del lado del Gateway es una guardia de los argumentos de las herramientas que se pasan de ChatGPT a los MCP hijos.
Los MCP incluidos (safe-files, safe-images, safe-download, gitmcp, git-capability, codex-script) también utilizan el contexto de Workspace firmado y la validación de rutas de cada MCP. En cuanto a los MCP de terceros, la guardia de argumentos del Gateway no puede restringir el acceso interno a archivos, por lo que, si es necesario, se inicia el propio proceso del MCP dentro del sandbox de Codex OS usando sandbox = "elevated" o "unelevated".
Formato de configuración de servidores MCP
El Gateway adopta el mismo formato que la configuración de MCP de Codex: la configuración de cada MCP se agrupa en una tabla [mcp_servers.<name>].
No es una función de compatibilidad que lea directamente el archivo de configuración de Codex; solo reconoce los elementos que el Gateway implementa.
Para añadir un MCP a config/gateway.toml, se escribe de la siguiente manera, sin usar # para comentarios. Lo siguiente es una plantilla con todas las opciones que el Gateway reconoce.
private_use_only = true
protect_gateway_app = true
publish_tool_directory = false
tool_annotations_path = "tool-annotations.toml"
[mcp_servers.my_server]
command = 'C:\Program Files\nodejs\node.exe'
args = ['C:\path\to\server.mjs', '--example=value']
cwd = 'C:\work\project'
enabled = true
sandbox = "elevated"
codex_executable = 'C:\Users\owner\AppData\Roaming\npm\codex.cmd'
sandbox_read_only_directories = ['C:\path\to\read-only-data']
prefix = "my_server"
annotation_config = true
dangerous_allow_gateway_config_access = false
startup_timeout_sec = 30
tool_timeout_sec = 1800
serial_group = "my_server"
deferred = true
blocked_tools = ["dangerous_tool"]
blocked_tool_substrings = ["script", "shell", "execute"]
allowed_directories = ['C:\work\project']
allowed_files = ['C:\Users\owner\Downloads\upload.png']
disallowed_directories = []
disallowed_files = []
disallowed_path_globs = []
[mcp_servers.my_server.start_after]
server = "controller"
tool = "prepare_my_server"
[mcp_servers.my_server.stop_after]
server = "controller"
tool = "stop_my_server"
[mcp_servers.my_server.env]
EXAMPLE_CONFIG = 'C:\path\to\config.json'項目 | 説明 |
| Configuración obligatoria para todo Gateway. Por seguridad, debe establecerse en |
| Si se establece en |
| TOML de configuración de anotaciones para MCP externos. Las rutas relativas se basan en el directorio que contiene |
| Unidad que define una conexión MCP stdio. |
| Ejecutable o comando que inicia el MCP hijo. Es obligatorio si |
| Especifica los argumentos a pasar a |
| Directorio de trabajo del MCP hijo. Las rutas relativas se absolutizan en relación con el directorio que contiene |
| Si se establece en |
| Límite de inicio del MCP hijo. Cuatro valores: |
| Ruta absoluta del CLI de Codex requerida cuando |
| Matriz de directorios absolutos que se pasan al perfil de permisos de Codex como solo lectura adicional cuando el sandbox está activo. No se convierten en raíces de escritura como |
| Prefijo del nombre de la herramienta publicada en ChatGPT. El |
| Especifica si se aplica la configuración de anotaciones externa. Si se omite, es |
| El valor predeterminado es |
| Segundos para esperar el inicio e inicialización del MCP hijo. Se especifica como número positivo; si se omite, son 30 segundos. |
| Segundos para esperar la llamada a la herramienta del MCP hijo. Se especifica como número positivo; si se omite, son 1800 segundos. |
| Alias de compatibilidad para |
| Serializa las llamadas a herramientas de MCP con el mismo valor. Se usa para recursos que no se desea operar simultáneamente, como el mismo navegador o repositorio. |
| Si se establece en |
| Especifica los nombres de herramientas que no se publican en ChatGPT como matriz de cadenas de coincidencia exacta. |
| Especifica subcadenas de nombres de herramientas que no se publican en ChatGPT. No distingue mayúsculas y minúsculas, y no se tratan como glob ni expresiones regulares. |
| Permite el acceso al directorio de ruta absoluta especificado y a su contenido. Cuando el sandbox está activo, también se convierte en la raíz de escritura del perfil de permisos de Codex. |
| Permite solo los archivos de ruta absoluta especificados con coincidencia exacta. Cuando el sandbox está activo, también se pasan al perfil de permisos de Codex como rutas individuales legibles. |
| Especifica con ruta absoluta los directorios y su contenido que se rechazan incluso si están dentro del rango permitido. |
| Especifica con ruta absoluta los archivos que se rechazan incluso si están dentro del rango permitido. |
| Especifica globs de rechazo que se aplican a toda la ruta normalizada. Se aplican tanto a archivos como a carpetas. |
| Después de que la herramienta de otro MCP especificada en |
| Después de que la herramienta de otro MCP especificada en |
| Variables de entorno adicionales que se pasan al MCP hijo. Los valores pueden ser cadenas, números o booleanos. No se pueden sobrescribir las variables de entorno reservadas para la política de acceso de Gateway. |
Normalmente, un MCP se inicia con deferred = false u omitido. En ese caso, start_after no es necesario.
Con sandbox = "elevated" o "unelevated", la red del perfil de permisos de Codex se desactiva, y solo sandbox = "onlineworkspace" habilita la red. En cualquier modo de sandbox activo, allowed_directories se configura como escritura, y allowed_files y sandbox_read_only_directories como lectura. Además, el directorio del ejecutable del MCP, el directorio del script de entrada del intérprete conocido y, en el caso de los MCP incluidos, el directorio app de Gateway se añaden como lectura según sea necesario. codex_executable debe colocarse fuera de la raíz de escritura, y en elevated y onlineworkspace, el propio command también debe colocarse fuera de la raíz de escritura.
Incluso en un MCP externo con sandbox, disallowed_directories, disallowed_files y gateway.toml protegido, especificados con rutas absolutas, se pasan como deny en el perfil de permisos de Codex, por lo que se puede utilizar un agujero de denegación exacto dentro de la raíz de escritura. Por otro lado, como no hay garantía de que los disallowed_path_globs propios de Gateway puedan convertirse de forma equivalente a la semántica de glob de Codex, se rechazan con fail closed en un MCP externo sandbox. Los MCP incluidos son una excepción a esta comprobación de compatibilidad porque ellos mismos verifican la política de denegación por glob de Gateway.
La configuración de MCP remoto mediante url se rechaza. El tool_output_token_limit específico de Codex se lee pero no se utiliza, y no tiene efecto en esta Gateway.
Las variables de entorno propias de Gateway LOCAL_MCP_FILES_MAX_RESPONSE_BYTES y LOCAL_MCP_CODESPACE_MAX_RESPONSE_BYTES permiten cambiar en bytes el límite de la respuesta JSONL final que files__* y codespace__* devuelven al túnel. Si se omiten, el valor predeterminado es de 15 KB (15360 bytes). Cuando se supera el límite, se indica el tamaño real de la cadena devuelta en KB, MB o GB, y en lugar del cuerpo del resultado se devuelve solo el primer bloque de 1024 bytes (1 KB) de la JSONL final original como vista previa de depuración. Se mantiene la advertencia de que «es posible que la operación destructiva ya se haya realizado». En files__* se sugiere el uso de downloads__download_zip, y en codespace__* se sugiere guardar la salida grande en un archivo y recuperarla con codespace__copy_from_codespace, o bien estrechar la consulta. Este límite de respuesta final de Gateway se aplica solo a files__* y codespace__*, y no a los límites propios de downloads__* o images__*. Dentro del Codespace MCP, CODESPACE_MCP_MAX_OUTPUT_BYTES también limita la cantidad de stdout/stderr retenida, con un valor predeterminado de 15 KB. Este valor también se puede cambiar mediante variables de entorno.
Directorio de herramientas integradas
Si se especifica publish_tool_directory = true en el nivel superior, se publican gateway__list_available_tools, gateway__get_prefix_list y gateway__get_config. gateway__get_prefix_list devuelve los prefijos actualmente activos que tienen herramientas publicadas, además del gateway integrado en Gateway y isolated si el MCP incluido está activo.
gateway__list_available_tools y gateway__get_prefix_list solo consultan el registro de herramientas públicas que Gateway ya mantiene. gateway__get_config devuelve en JSON solo el name, prefix, allowed_directories, allowed_files, disallowed_directories, disallowed_files, disallowed_path_globs y las rutas de solo lectura para sandbox de cada MCP, a partir de la configuración ya cargada al iniciar. No vuelve a leer el archivo de configuración, y no devuelve la ruta del propio archivo de configuración, env, args, command ni otros valores secretos.
Los MCP con enabled = false no se inician; en gateway__list_available_tools solo se devuelve su nombre en disabledProxyNames, y en gateway__get_config solo su nombre en disabledServerNames.
Si se omite la entrada, se devuelven todas las herramientas disponibles actualmente; si se especifica prefix, se filtra por coincidencia de prefijo del identificador completo sin distinguir mayúsculas y minúsculas. Si no hay coincidencias, no se produce un error y se devuelven todos los elementos.
La información de herramientas devuelta es solo el nombre público completo y la descripción, como chrome-devtools__click. No se devuelven esquemas de entrada, esquemas de salida, comandos de inicio, argumentos, rutas, variables de entorno ni nombres de herramientas rechazadas. enabledProxyCount es el número de MCP habilitados en la configuración, y rejectedToolCount es el número de herramientas cuya publicación fue rechazada por los MCP iniciados.
En el [gateway] INFO de la inicialización de Gateway, solo se registran una por una las herramientas cuya publicación fue rechazada; no se enumeran los nombres individuales de las herramientas publicadas. En su lugar, se registran los recuentos de found/rejected/published por prefijo, los prefijos con enabled = false, los prefijos que fallaron al iniciar y el total general.
Exclusión de herramientas públicas
Las coincidencias exactas de nombre de herramienta se pueden hacer no públicas con blocked_tools, y las coincidencias parciales sin distinguir mayúsculas y minúsculas con blocked_tool_substrings.
blocked_tools = ["dangerous_tool"]
blocked_tool_substrings = ["script", "shell", "execute"]blocked_tool_substrings no es un glob ni una expresión regular.
Por ejemplo, "script" abarca evaluate_script, runScript y SCRIPT_debug.
Ejecución en serie y arranque diferido
Los MCP que no se desea que operen simultáneamente sobre el mismo recurso pueden asignarse al mismo serial_group.
Un MCP con deferred = true no se inicia en la inicialización y puede iniciarse con start_after después de que una herramienta especificada de otro MCP haya tenido éxito.
Con stop_after se puede detener de forma similar.
[mcp_servers.browser]
command = "node"
args = ["browser-server.mjs"]
cwd = ".."
enabled = true
prefix = "browser"
deferred = true
serial_group = "browser"
[mcp_servers.browser.start_after]
server = "controller"
tool = "prepare_browser"
[mcp_servers.browser.stop_after]
server = "controller"
tool = "stop_browser"Supuestos de seguridad
[!WARNING] El
commanddegateway.tomlejecuta programas locales. Registre solo MCP de confianza. Algunos comandos obtienen y ejecutan directamente programas MCP de Internet. El comando especificado engateway.tomlse ejecuta en el PC real, con los permisos del usuario de Windows, no dentro de un sandbox. No especifique MCP que no sean de confianza.
Gateway rechaza el inicio con privilegios de administrador y no hereda directamente a los MCP hijos las variables de entorno que parecen información secreta del proceso padre. Sin embargo, no aísla a nivel de sistema operativo los archivos que el mismo usuario de Windows puede leer.
Se recomienda asociar el Túnel solo con su propia Organización de Plataforma y su propio Espacio de trabajo de ChatGPT, y no otorgar a la clave de API de runtime permisos distintos de Tunnels Read + Use. Consulte SECURITY.md e INSTALL.md para más detalles.
SDK
Si descarga el ZIP de la rama main y tunnel-client-source, los adjunta a ChatGPT y envía el siguiente prompt, podrá crear un MCP stdio incluido con soporte de firma para añadir a este repositorio.
Si simplemente registra el MCP generado como un MCP externo normal, no se enviará el workspace aislado firmado de Gateway. Colóquelo como mcp/<name>/server.mjs y aplique también el diff para registrarlo en BUNDLED_SERVER_PATHS de app/server-config.mjs.
Reemplace <Describe the MCP tools you need here.> con una descripción concreta de las herramientas que desea crear y los objetos sobre los que operará.
The attached local-mcp-chatgpt-tunnel-main.zip is the SDK and reference implementation. Inspect it before writing code.
Create a new bundled stdio MCP at mcp/<name>/server.mjs for the following purpose:
<Describe the MCP tools you need here.>
Requirements:
- Return the complete mcp/<name>/server.mjs file, the exact app/server-config.mjs BUNDLED_SERVER_PATHS patch required to mark it as bundled, and the minimal config/gateway.toml entry.
- Do not modify the attached archive directly. Return complete replacement content or an exact patch for every required file.
- Use only Node.js built-in modules and the repository's existing local helpers unless I explicitly permit another dependency.
- Follow the repository's MCP protocol handling, JSON Schema conventions, outputSchema declarations, tool annotations, error handling, stdout/stderr separation, timeouts, and bounded-output design.
- Write only JSON-RPC protocol messages to stdout. Write diagnostics and logs to stderr.
- Import createBundledIsolation and environmentWithoutBundledIsolationKey from ../../app/bundled-isolation.mjs. Every tools/call operation must run through createBundledIsolation().run(arguments, operation) before any side effect or path access.
- In Gateway mode, LOCAL_MCP_GATEWAY_ISOLATION_KEY is present. Every call must require and verify the private __localMcpIsolation envelope. Missing, malformed, unsupported-version, unsigned, or incorrectly signed envelopes must fail closed before the public tool executes. Do not implement an unsigned fallback while the key is present.
- The Gateway sends the signature and the paths permitted for that call together in this private argument. This is the envelope shape; the signature placeholder below is not a valid signature:
{
"__localMcpIsolation": {
"version": 1,
"roots": ["C:\\work\\project"],
"base": "C:\\work\\project",
"signature": "<64 hexadecimal HMAC-SHA-256 characters>"
}
}
- Verify HMAC-SHA-256 over exactly JSON.stringify({ base, roots }) using LOCAL_MCP_GATEWAY_ISOLATION_KEY, compare signatures in constant time, require one or more absolute roots, and require base to be an absolute path inside at least one root. Prefer the repository helper instead of duplicating the cryptographic code.
- Treat the verified roots and base as the only authoritative path context in Gateway mode. roots are the directories the operation may access; base is the current relative-path base. Never replace them with process.cwd(), a public argument, a cached global root, or a path remembered from another call.
- Reject public arguments named root, roots, workspace, workspaces, or equivalent nested variants. Public tool input must not override the signed path context.
- Never expose LOCAL_MCP_GATEWAY_ISOLATION_KEY or pass it to subprocesses. When spawning a child process, use environmentWithoutBundledIsolationKey() or an equivalent explicit environment filter.
- Shell injection must be impossible under all circumstances. Treat every MCP argument, path, filename, identifier, option, and environment-derived value as untrusted input.
- Never pass a constructed or user-controlled command string to a shell. Do not use child_process.exec, execSync, spawn with shell: true, cmd.exe /c, powershell -Command, bash -c, or sh -c.
- When a native program is genuinely required, invoke a fixed executable directly with spawn or execFile, shell: false, a fixed subcommand, and individually validated arguments. Use an explicit allowlist and a -- separator where the target program supports it.
- Do not expose a general-purpose command runner, arbitrary script execution, arbitrary executable selection, arbitrary environment-variable injection, or unrestricted native-program arguments.
- Implement `roots`, `get_working_directory`, and `set_working_directory` only when the MCP has a real filesystem, repository, workspace, current-directory, input-directory, or output-directory concept. If the capability has no directory concept, do not add these tools and do not invent a meaningless root.
- When those directory tools are applicable, `roots` must return only the verified signed roots and current base, `get_working_directory` must return the verified base, and `set_working_directory` must accept an absolute path or a path relative to the current base, resolve it to an existing directory inside one signed root, apply every deny rule, and return the canonical absolute path. Gateway interception and direct standalone behavior must both remain safe.
- Any stdio MCP that performs filesystem operations must support and enforce these exact configuration arrays:
`allowed_directories = []`
`allowed_files = []`
`disallowed_directories = []`
`disallowed_files = []`
`disallowed_path_globs = []`
- Apply the allowlist and denylist to every filesystem operation, including working-directory changes. Deny rules must take precedence over allow rules.
- Resolve relative filesystem paths from the verified base. Absolute paths may be accepted only when they remain inside a verified root and pass the complete configured allow/deny policy.
- Reject parent traversal that escapes a signed root, root-relative ambiguity, drive-relative paths, UNC paths unless explicitly required and safely constrained, NTFS alternate data streams, and any syntax that could reinterpret the target. Canonicalize existing paths and verify the real target remains inside a signed root after symlink resolution.
- Do not require callers to provide redundant absolute paths when the same target can be identified safely relative to the verified base.
- A tool that accepts input files must accept multiple files as an array unless the underlying operation can inherently and safely operate on exactly one file. Validate every file independently and enforce bounded file counts, sizes, and output sizes.
- For build-related tools, require the caller to select a narrow project, target, package, configuration, or input-file set. Do not default to building an entire workspace or repository when a narrower target is possible. Keep the executable, subcommand, and build options fixed or allowlisted.
- This stdio MCP is not executed inside the ChatGPT sandbox. It runs on the user's real Windows PC with the permissions of the current Windows user. Remove unsafe capabilities by design instead of relying on the model to ask for confirmation.
- Do not download, install, update, or access the network unless I explicitly require that behavior. If network access is required, restrict destinations and operations to an explicit allowlist.
- Close child-process stdin, impose timeouts and output limits, handle cancellation and termination, and return structured MCP errors without crashing the process.
- Include clear tool descriptions, strict input schemas, strict output schemas, accurate annotations, and a short security explanation for every capability.
- Prefer a small, auditable implementation. Do not add convenience features that expand the security boundary beyond the stated purpose.Diagnóstico y pruebas
Se realiza la detección de los comandos necesarios y la verificación de versiones. No se realizan instalaciones ni cambios de configuración.
node app\doctor.mjsLas pruebas del repositorio se pueden ejecutar con lo siguiente.
npm testNo hay dependencias npm externas.
Licencia
El cuerpo de este repositorio está bajo la Licencia MIT.Para componentes de terceros como el tunnel-client.exe oficial, consulte THIRD_PARTY_NOTICES.md.
Notas
¿Conectarse desde ChatGPT a un MCP local es un «truco gris»?
https://gist.github.com/DaisukeDaisuke/0d0af93dd8cb376a36879702afb176ee
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseCqualityCmaintenanceEnables ChatGPT to control a Windows PC remotely via OpenAI Secure MCP Tunnel, executing file operations, PowerShell commands, and system actions through a local MCP server.15
- AlicenseNot gradedqualityBmaintenanceEnables ChatGPT to securely operate a single Windows development workspace via a local MCP server, offering file editing, Git status, static analysis, approved test/build, and limited ADB operations with audit logging.MIT
- AlicenseNot gradedqualityBmaintenanceA Windows proof-of-concept MCP server that connects ChatGPT developer-mode to a local Codex CLI via Secure MCP Tunnel, exposing a small set of read-only, allowlisted tools in an isolated workspace.1Apache 2.0
- FlicenseNot gradedqualityAmaintenanceSafe MCP gateway that lets ChatGPT securely control a Windows Desktop Agent, enabling project file reads, git status/diff, and npm build/test within a designated workspace.
Related MCP Connectors
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DaisukeDaisuke/local-mcp-chatgpt-tunnel'
If you have feedback or need assistance with the MCP directory API, please join our Discord server