Skip to main content
Glama
DaisukeDaisuke

local-mcp-chatgpt-tunnel

Local MCP ChatGPT Tunnel

Локальный Gateway для подключения stdio MCP-серверов, работающих на Windows, через официальный Secure MCP Tunnel от OpenAI к ChatGPT Developer Mode. Gateway объединяет несколько stdio MCP в один и позволяет управлять через файл конфигурации: namespacing имён инструментов, исключением публичных инструментов, разрешением путей, последовательным выполнением и отложенным запуском.

Подключение ChatGPT к локальному stdio MCP

Инструкция по установке

[!IMPORTANT] Инструкция по установке на Windows приведена в INSTALL.md.

Related MCP server: Windows Local MCP

Предупреждение о безопасности

[!WARNING] Это персональный инструмент, который следует использовать только на своём Windows PC, в своей организации на OpenAI Platform и в своём ChatGPT Workspace. Поскольку к нему можно подключать MCP, способные выполнять произвольный код, он не предназначен для общего доступа с третьими лицами или использования в качестве публичного плагина.

О песочнице codex

[!IMPORTANT] В версии от 11 августа 2025 года была добавлена схема, которая использует песочницу codex напрямую и защищает компьютер от нарушения границ (boundary) и от выполнения произвольного кода. Обычная оболочка (shell) или выбор произвольного исполняемого файла не предоставляются, но в комплект включён codex-script, который выполняет существующие скрипты в фиксированном runtime. codex-script требует фиксированную песочницу sandbox, тип elevated или unelevated. Поскольку остальные встроенные MCP и внешние stdio MCP также можно запускать в песочнице Codex для каждого MCP отдельно, рекомендуется по возможности укреплять границы с помощью режима elevated.

Об ИИ-реализации

[!CAUTION] Этот репозиторий был реализован ChatGPT 5.6 Sol High. Код содержит результаты, созданные ИИ, поэтому в нём могут оставаться ошибки и уязвимости. Перед фактическим использованием обязательно проверьте код и содержимое конфигурации и используйте проект на собственный риск.

Что умеет

  • Вызов stdio MCP-серверов на Windows из ChatGPT

  • Объединение нескольких MCP в имена инструментов вида <prefix>__<tool>

  • Добавление произвольного stdio MCP в config/gateway.toml

  • Ограничение разрешённых каталогов и файлов для каждого MCP

  • Скрытие опасных инструментов по имени или по части подстроки

  • Сериализация MCP, которые не должны выполняться параллельно, через serial_group

  • При необходимости полное отключение отдельных MCP

  • При необходимости публикация встроенного каталога, позволяющего искать опубликованные инструменты по полному идентификатору или по префиксу

Чего этот репозиторий не делает

  • Вызов OpenAI Responses API или Chat Completions API

  • Реализацию собственного ИИ-агента, собственной обёртки (harness) или системы тарификации моделей

  • Предоставление публичного MCP URL или локального входящего порта

  • Автоматическую установку Node.js, Git, ripgrep, Python или tunnel-client

  • Распространение сторонних MCP-серверов, таких как Ghidra MCP, Chrome DevTools MCP, DQ9 MCP

Подключение к Secure MCP Tunnel выполняется официальным tunnel-client.exe. Этот репозиторий предоставляет локальный шлюз MCP, который подключается к его стандартному вводу-выводу, вместе с набором встроенных MCP.

Поддерживаемое окружение

Текущая инструкция по установке рассчитана на Windows 11. Для работы используются Node.js LTS и официальный tunnel-client.exe от OpenAI. Для встроенных функций поиска файлов необходим ripgrep, а для проверки GitHub Actions используется GitHub CLI. Диагностический скрипт проверяет наличие node, npm, git, gh, rg, py. Инструкции для macOS и Linux, конфигурация Docker и схема с открытыми входящими портами не предусмотрены.

Первые шаги

Полная пошаговая процедура входа в работу описана в INSTALL.md. Основная схема такая.

  1. Вручную установить необходимое программное обеспечение и официальный tunnel-client.exe.

  2. Скопировать config/gateway.example.toml в config/gateway.toml и прописать абсолютные пути.

  3. Создать личный Tunnel и runtime API key с правами только на выполнение в OpenAI Platform.

  4. Сохранить Tunnel ID и runtime API key в пользовательских переменных окружения Windows.

  5. Запустить диагностику через start.cmd, затем запустить Tunnel.

  6. Выбрать личный Tunnel в ChatGPT Developer Mode. Не пытайтесь «угадать» настройки или права, в обязательном порядке просмотрите файл INSTALL.md сверху вниз.

Встроенные MCP

MCP

Примеры публичных инструментов

Назначение

safe-files

list_files, search_text, file_info, read_text, write_text_file, replace_text, copy, move, apply_patch

Список файлов в разрешённом Workspace, поиск UTF-8, чтение нескольких файлов и диапазонов строк, информация о файле, чтение и запись, перемещение и копирование файлов между Workspace, ограниченное применение патчей

safe-images

read_image

Чтение PNG, JPEG и WebP как изображений в ChatGPT

safe-download

download_zip

Передача разрешённых источников в ChatGPT в одиночном файле или в виде ZIP

gitmcp

get_policy, branches, create_branch, checkout, list_worktrees, create_worktree, remove_worktree, status, diff, stage_paths, unstage_paths

Локальные операции Git в разрешённом репозитории. Не включает commit / push / pull / clone

git-capability

одна из commit, push, pull, clone_repository + управление Workspace

В зависимости от --mode= публикует только одну Git capability как отдельный процесс MCP, изолируя границы песочницы, подпись и сетевые права

gh-workflow

list_runs, watch_run, cancel_run, view_run, view_run_jobs, list_failed_logs, list_workflows, view_workflow_yaml

Просмотр запусков Actions для явно разрешённых репозиториев GitHub и отмена run

codex-script

roots, get_working_directory, set_working_directory, run_script или check_file

Запуск существующего скрипта в фиксированном runtime (mjs, Node.js, Python, PHP), закреплённом при старте MCP, и проверка синтаксиса внутри разрешённого Workspace. Обязателен sandbox = "elevated" или "unelevated"

internet

download_file

Получение одного файла через HTTP/HTTPS внутри границ onlineworkspace

archive

extract_archive, create_zip, create_7z

Создание и распаковка архивов только с помощью фиксированного файла 7-Zip

codespace

list_codespaces, roots, git_root, search_text, ssh, copy_to_codespace, stop_codespace, list_temporary_public_deployments, open_temporary_public_deployment, close_temporary_public_deployment

Работа только с существующими GitHub Codespaces: удалённый поиск, SSH, перенос, остановка, временные публичные развёртывания. Автоматическое обнаружение localhost и локальных портов не выполняется, инструментов создания Codespaces нет

Собранные MCP не имеют внешних npm-зависимостей. Для всех инструментов объявляется outputSchema. Gateway публикует isolated__create, isolated__list, isolated__close и требует уникальный isolatedId для всех инструментов встроенных MCP. isolated__create принимает один или несколько абсолютных каталогов в массиве workspaces, а также обязательный параметр purpose, который объясняет, для какой работы эта изоляция создаётся данным ИИ-сессией. Gateway автоматически записывает createdAt, а в isolated__list для каждого префикса также возвращается lastOperationAt. Для каждого ID сохраняются несколько Workspace и отдельные базовые относительно каждого MCP. Сам встроенный MCP-процесс не копируется: при каждом вызове передаются только корни (roots) целевого ID. Обычные bundled-вызовы инструментов не сериализуются на Gateway без необходимости — параллельная обработка оставляется дочерним MCP, а очередь от параллельного конфликта есть только для кодов, они же у Codespace для одного codespaceId. При запуске Gateway генерирует случайный ключ для каждого встроенного MCP и подписывает isolatedId, нормализованные базовые пути и корни с помощью HMAC-SHA-256, передавая их как закрытые аргументы. Встроенные MCP отклоняют неподписанный, изменённый или неправильно структурированный контекст, а также не принимают переопределение root, roots, workspace или workspaces из публичных аргументов. Gateway добавляет <prefix>__get_gateway_access_scope ко всем запущенным дочерним MCP. Встроенные MCP позволяют вызвать этот инструмент, передав isolatedId, и получить базовые каталоги, корни, значения конфигурации, нормализованные разрешённые и запрещённые пути, применённые к этому ID. Если путь вне разрешённой области отклонён, в тексте ошибки возвращаются текущие разрешённые каталоги и файлы как нормализованные абсолютные пути. В общем формате вывода встроенных MCP этот же набор возвращается и в structuredContent.result.accessScope. После отклонённого доступа ИИ не нужно строить догадки о другом рабочем каталоге и повторять попытку.

safe-files

То, что под «MCP root» наружу выступает в safe-files, — это текущая базовая директория, сохранённая для целевого isolatedId. Относительные пути разрешаются именно от этой базы, и set_working_directory изменяет базу только внутри корней, связанных с этим же ID. Состояние другого ID или общего MCP-процесса не меняется. read_text принимает и относительные пути от MCP root, и абсолютные пути, но читает файл только если после нормализации и разрешения пути цели остаётся в пределах настроенных разрешённых каталогов. Основные функции:

  • «Рекурсивный список» выполненным rg --files --hidden

  • Поиск текста UTF-8 с помощью фиксированной команды rg

  • Чтение и запись UTF-8-текста и замена по полному совпадению

  • Передача файлов Base64 с ограничением размера

  • Создание каталогов

  • Копирование и перемещение обычных файлов между настроенными разрешёнными Workspace

  • Применение патча встроенным парсером или фиксированным git apply copy и move принимают как относительные пути от текущего MCP root, так и абсолютные пути, и могут передавать обычные файлы между несколькими allowed_directories. К источнику и назначению применяется политика разрешения / запрета, а передача символических ссылок, каталогов или перезапись существующего назначения запрещена. move работает и между разными дисками: сначала выполняется эксклюзивное копирование, затем удаляется источник, а если удаление не удаётся, назначение возвращается на место. Строки пути не передаются оболочке, знаки в пути не интерпретируются как команды. recursive list always removes .git itself, и для патча нельзя указывать пути внутри .git. Кроме того, отклоняются разрешённый корневой каталог, пути, выходящие через symbolic links, и содержимое, похожее на учётные данные. Common shell, PowerShell или инструмент запуска произвольных команд не включён.

safe-images

safe-images только для чтения. Проверяется расширение PNG, JPEG, WebP и магические байты; по умолчанию ограничение 8 MiB и 50 megapixels. Отклоняются SVG, HEIC, пустые файлы, пути вне разрешённого корня, символьные ссылки, UNC-пути и NTFS alternative data streams.

safe-download

safe-download работает только на чтение и всегда возвращает один файл или каталог в виде ZIP. Для него настраивается отдельный cwd и список разрешений, предназнаенный только определённых источников, безопасных для передачи в ChatGPT; настройка отдельна от файла safe-files. Каталог составляет через фиксированный командный rg --files --hidden, а вот .git внутри, ROM, Save, State, закрытые ключи, credential-подобное содержимое, файлы вне разрешённого пути и символьные ссылки блокируются. Если задан disallowed_path_globs, перед применяемыми пользователем паттернами globs или excludePaths просматривается весь целевой каталог; если хотя бы один файл или каталог, попадающий под запрещающий шаблон, существует, всё создание ZIP полностью отменяется. Ошибка включает совпавший заданный шаблон и проблемный путь.

internet

internet — встроенный MCP для получения одного файла с любого HTTP/HTTPS URL. Публичный инструмент один: download_file; место назначения ограничено только workspace подписанного signed от Gateway isolatedId. Не принимаются перезапись существующих файлов, UNC/ADS, запись за пределами workspace, произвольные заголовки, cookie или credentials. При сбое после частичного копирования временный файл удаляется. Этот MCP всегда включается через sandbox = "onlineworkspace". onlineworkspace сохраняет файловую границу workspace-write Codex и только сетевой доступ per permission profile. Не выполняется fallback для sandbox = "never".

archive

archive при запуске закрепляет для 7-Zip фиксированный путь через --seven-zip-executable=<absolute-7z-path> и публикует только create_zip, create_7z, extract_archive. Plain shell, Обычная оболочка, производные файлы детства, произвольные аргументы 7-Zip не доступны. Ввод и вывод ограничены подписанным workspace. extract_archive может работать между двумя разными разрешёнными корнями (например, распаковать архив из Downloads прямо в Project workspace). Если destination не существует, он создаётся, а если существует, принимается только пустой обычный каталог. Символьные пути после разрешения ограничиваются 1024 символами. archive сам также запускается в песочнице Codex; путь установки 7-Zip передаётся в sandbox_read_only_directories как read-only trust input.

codespace

codespace — это встроенный MCP, который работает только с уже существующими GitHub Codespace. name, возвращённый list_codespaces, используется как codespaceId для каждого инструмента. Инструменты для create, rebuild, изменения machine, явного start и delete Codespace не реализованы. Запуск неявно инициирует существующий Codespace через подключение SSH или copy, а по завершении работы можно явно остановить его с помощью stop_codespace, который выполняет gh codespace stop -c <name>. Перед остановкой отменяются асинхронные SSH-операции для этого же Codespace, принадлежащие этой изолированной сессии, и уничтожается кэш готовности SSH. После остановки сам Codespace и сохранённые изменения не удаляются. У AI нет пути для бессистемного создания множества Codespace. Один и тот же codespaceId принадлежит только одной изолированной сессии; если другая новая изолированная сессия обращается к нему, право собственности переходит к последней (последний выигрывает). Старая сессия не может автоматически вернуть себе право собственности; при конфликтной ошибке ей предписывается проверить purpose из isolated__list и lastOperationAt с префиксом codespace и запросить решение у пользователя. Только вызовы одного и того же codespaceId сериализуются через Gateway; другие bundled MCP, такие как files, не сериализуются без необходимости. Сам MCP обязательно запускается с sandbox = "onlineworkspace". --gh-executable=<absolute-gh.exe-path> обязателен. На случай, если обычные учётные данные gh auth login, сохранённые в Windows Credential Manager, не видны sandbox-пользователю, можно дополнительно указать --token-file=<absolute-file>. Этот файл передаётся в профиль разрешений Codex как фиксированный read-only trust input, а его содержимое устанавливается в GH_TOKEN только внутри MCP. GH_TOKEN / GITHUB_TOKEN родительской среды не наследуются. Пользовательские SSH-ключи не настраиваются, не читаются и не разрешаются. Ключи, необходимые для SSH/cp, автоматически генерируются самим Codespace MCP с помощью ssh-keygen во временном не-hidden runtime-каталоге, подготовленном Gateway, и удаляются, когда Gateway закрывает дочерний MCP. Этот внутренний каталог разрешён на запись только профилю разрешений Codex и не добавляется в allowed_directories или обычную область доступа к файлам Gateway. gh.exe и token file нельзя размещать в доступных на запись allowed_directories. ssh принимает удалённую команду не как одну строку, а как массив токенов и отклоняет пробелы, кавычки, !, @, backtick, $, ;, &, pipe и другие shell expansion / metacharacter. timeoutMs — это жёсткое время выполнения самой базовой операции, отдельное от времени ожидания синхронного ответа. Обычно ожидание синхронно в течение syncWaitMs, по умолчанию/максимум 10 000 мс. Если операция не завершилась, обработка не останавливается, а переносится в общий асинхронный реестр и возвращается asyncId. syncWaitMs=0..1000 обрабатывается как немедленный async, а при async=true syncWaitMs игнорируется и asyncId возвращается сразу с самого начала. get_async_status при опущенном asyncId возвращает все текущие async-операции этой изоляции, а по отдельному ID можно получить подробности/результат завершения. get_async_logs предназначен для получения всех текущих stdout/stderr process-backed заданий. wait_async остаётся как совместимая реализация, но обычно используются get_async_status / get_async_logs, чтобы не удерживать длительный MCP-ответ и не вовлекать Gateway/tunnel. copy_to_codespace отправляет локальные файлы/каталоги, выбранные из sourceDirectory либо перечислением paths, либо globs, в явно указанный вызывающей стороной пункт назначения remote:. MCP не предполагает и не добавляет автоматически remote:. Например, при paths=["scripts/a.js"] файл размещается в /workspaces/project/scripts/a.js под /workspaces/project, а не уплощается по basename прямо в пункт назначения. Для сохранения иерархии фиксированный helper создаёт только необходимые родительские каталоги remote, а каждое выделение копируется в соответствующий пункт назначения. copy_from_codespace — в обратном направлении: копирует один явно указанный вызывающей стороной источник remote:/workspaces/<workspace>/... в существующий каталог назначения внутри подписанного локального workspace. Источник remote проверяется перед копированием; отклоняются symlink/special entry, чрезмерное количество записей и передача объёмом больше CODESPACE_MCP_MAX_TRANSFER_BYTES. Если basename локальной цели уже существует, это также отклоняется. В обоих copy-инструментах только remote-сторона должна иметь remote:, локальная сторона — локальный путь; неоднозначные указания, такие как отсутствие remote-протокола или remote с обеих сторон, отклоняются. Из-за известной проблемы GitHub CLI, когда gh codespace cp даже для существующего remote-пути без -e выдаёт No such file or directory, -e всегда добавляется в обоих направлениях. remote: указывается вызывающей стороной явно, MCP не добавляет его автоматически. Готовность SSH проверяется только при необходимости фиксированным probe echo started, а при сбое cp во время повторного использования кэша выполняется одна повторная попытка после probe. Удалённый поиск перечисляет через roots только workspace непосредственно под /workspaces, а git_root может получить Git top-level для указанного пути. search_text — это первоклассный поиск ripgrep, эквивалентный files__search_text, и каждый раз требует searchBase=/workspaces/<workspace>/.... Нельзя использовать /, /workspaces, home, /etc и т.п. в качестве корня поиска. searchBase повторно проверяется и после remote realpath. query и glob не конкатенируются в строку SSH-команды, а передаются в base64 через stdin в фиксированный remote-скрипт. .git всегда исключается из поиска, один файл ограничен 16 МиБ, а количество результатов также ограничено максимум 500. ripgrep_version позволяет проверить rg --version, а install_ripgrep, если rg уже есть, ничего не делает; только если его нет, фиксированный installer использует apt/dnf/yum/apk, после чего версия проверяется снова. Имя пакета или произвольная shell-строка не могут быть переданы через аргументы инструмента. list_temporary_public_deployments получает временные публичные кандидаты Codespace, уже известные на стороне GitHub, а также browseUrl / port / visibility. Это не инструмент для сканирования localhost, прослушивающих сокетов локального ПК, вкладок браузера или локальных серверов разработки, и автоматического обнаружения портов он не выполняет. Если кандидатов на стороне GitHub 0, он не возвращает пустой массив как нормальный результат, а возвращает корректирующую ошибку, явно указывающую, что «это не сбой автоматического обнаружения локальных портов» и что «не выполняется поиск localhost, port scan, угадывание URL или обход через gh codespace ports forward». open_temporary_public_deployment работает только с одним явно указанным вызывающей стороной портом Codespace: сначала запрашивает у GitHub изменение visibility на public, а после успеха проверяет и возвращает полный URL https://...app.github.dev. Если точный порт известен, этот инструмент вызывается напрямую, и list_temporary_public_deployments не является предварительным условием. Не следует предполагать, что forwardPorts в .devcontainer необходим только на основании того, что list вернул 0 записей. Если GitHub отклоняет указанный порт, возвращается фактическая ошибка, а не поиск localhost для предположения альтернативного порта. close_temporary_public_deployment также возвращает только тот же явно указанный порт в private и закрывает временную публикацию. Ни один из них не создаёт локальный port tunnel и не создаёт/удаляет сами forward-записи на стороне GitHub. Возвращённый browseUrl можно использовать как есть, например из Chrome DevTools, для проверки связи с временным развёртыванием.

gitmcp

gitmcp выполняет только локальные операции с Git-репозиториями в разрешённых каталогах, используя фиксированные Git-подкоманды и опции. При запуске обязателен --git-executable=<absolute-path>, и запускается только этот исполняемый файл с shell=false. Общая оболочка или произвольные Git-аргументы не принимаются; прямое редактирование .git, добавление хуков, удаление веток и force-операции не поддерживаются. add_all, stage_paths, unstage_paths, перезаписывающие index, а также commit, push, pull, clone_repository перенесены в отдельный MCP git-capability для разделения границ. Старые --disable-push, --disable-pull, --disable-clone принимаются как no-op, чтобы не делать неработоспособными старые gateway.toml, но установка их в false не восстанавливает перенесённые capability. Доступны status, список отслеживаемых файлов, просмотр веток, remote и истории, diff рабочего дерева или staged, show конкретного коммита, переключение и checkout на существующую ветку, создание ветки с указанием родительского коммита, создание, список и обычное удаление worktree в пределах разрешённого корня. Удаление веток, удаление primary worktree и принудительное удаление dirty или locked worktree не реализованы. Для соблюдения .gitignore и стандартных настроек ignore status не показывает игнорируемые неотслеживаемые файлы. .gitattributes, .git/info/attributes, глобальные attributes, преобразования строк, такие как core.autocrlf, clean/smudge filter системных и глобальных настроек, внешние diff и textconv также соблюдаются, как в обычном Git. Исполняемые настройки, размещённые в .git/config репозитория или worktree config, отклоняются заранее. Поскольку system/global filter и diff helper могут выполняться намеренно, рекомендуется, если возможно, запускать gitmcp, имеющий права на файловые операции, внутри Codex OS sandbox. В Windows Codex sandbox профиль разрешений :minimal read предоставляет системные read roots, такие как C:\Program Files, поэтому стандартный C:\Program Files\Git\cmd\git.exe доступен без дополнительных настроек чтения. Только при указании Git вне системного read root, например Portable Git, каталог установки этого Git добавляется в sandbox_read_only_directories. sandbox = "never" также доступен для обратной совместимости. list_worktree_files перечисляет отслеживаемые и не игнорируемые неотслеживаемые файлы, используя собственное exclude-определение Git. check_ignore возвращает применённые к каждому пути правила ignore и окончательное решение, check_attributes — действующие значения text, binary, diff, merge, filter, атрибутов перевода строк и т.п. get_effective_config исключает из запроса credential.*, имя автора и адрес электронной почты и возвращает настройки, влияющие на поведение локального gitmcp, такие как core.autocrlf, filter, attributes, diff/textconv, с указанием scope и origin. Меры безопасности заключаются не в полном отключении настроек Git, а в отклонении исполняемых hook, helper, filter, внешних diff/textconv, merge driver, signing program, proxy и пользовательских transport-настроек, размещённых в собственном .git/config репозитория или worktree config. Хуки, fsmonitor, протоколы file и ext, интерактивные credential prompt отключены. get_policy позволяет проверить текущую политику в машиночитаемом виде. Если в repositoryPath напрямую указать submodule или вложенный Git-репозиторий, можно получить status, diff, log и т.п. самого этого репозитория. Инструментов, рекурсивно обходящих родительский репозиторий и автоматически перечисляющих все вложенные репозитории, нет.

git-capability

git-capability — это встроенный MCP, который регистрирует mcp/git-capability/server.mjs несколько раз с --mode=stage|commit|push|pull|clone и разделяет Git capability по назначению. Каждая регистрация — это отдельный [mcp_servers.<name>], поэтому sandbox, allowed_directories, timeout и serial_group можно выбирать индивидуально. sandbox = "never" не запрещается; пользователи, которым нужна совместимость с Git index, signing agent и сетью, также могут выбрать прежний путь. Во всех режимах --git-executable=<absolute-path> фиксируется при запуске, и нельзя выбрать Git-исполняемый файл, repositoryPath, переменные среды или произвольные Git-аргументы через аргументы инструмента. Через Gateway, как и для обычных bundled MCP, требуется подписанный HMAC изолированный workspace. Если в .git/config репозитория или worktree config есть исполняемые hook / helper / filter / diff / merge driver / signing program / proxy / transport-настройки, они отклоняются перед выполнением capability. Режим stage публикует только add_all, stage_paths, unstage_paths, а выбор репозитория фиксируется из подписанного workspace/base. При запуске sandboxed Git MCP Gateway сам сканирует существующие на тот момент .git под доступным на запись корнем и добавляет конкретные корни записи метаданных Git в профиль разрешений Codex. Это основано на реализации Codex, где is_metadata_write_denied / has_explicit_write_entry_for_metadata_path разрешают более конкретные явные записи записи в защищённых метаданных. .git/hooks, .git/objects/info, .git/modules остаются запрещёнными на запись, а существующие .git/config, config.worktree, commondir, gitdir также запрещены на запись. Поэтому stage и обычные обновления метаданных branch/worktree доступны в sandbox, но добавление submodule не поддерживается. .git, создаваемый после запуска, не разрешается автоматически, поэтому git init и clone внутри sandbox этим механизмом не обрабатываются. При stage также соблюдаются стандартные ignore, attributes, преобразования строк и system/global clean filter, а пути worktree, подлежащие запрету, отклоняются. Аргумент инструмента режима commit — только message; уже staged index коммитится только через git commit --no-verify -m <message>. Функций stage или выбора репозитория нет. Настройки подписи коммитов system/global сохраняются, поэтому в конфигурациях, где требуется доступ к signing agent, только commit MCP можно установить в sandbox = "never", оставив более крупный gitmcp в sandbox. push и pull фиксируют при запуске --remote= и один или несколько --repository=OWNER/REPO, нормализуют identity репозитория GitHub из remote URL и сверяют с одним из списка разрешённых. Поэтому https://github.com/OWNER/REPO.git и git@github.com:OWNER/REPO рассматриваются как один и тот же репозиторий, но частичное совпадение имени репозитория не разрешается. Для разрешения нескольких workspace в одном capability можно повторять --repository=. Старый --expected-remote-url=<exact-url> также доступен для обратной совместимости. Вызовы инструментов не принимают remote, URL или refspec. push отправляет только текущую ветку без force и не перезаписывает настройки upstream. pull выполняет fetch фиксированного remote, применяет path policy к входящему дереву, а затем отражает его в текущую ветку с тем же именем через --ff-only. clone отменяет --url= при запуске и принимает на стороне инструмента url, имя нового подкаталога и необязательный depth. url допускает формы http://, https://, ssh://user@host/path, user@host:path для любого хоста. Встраивание учётных данных в HTTP(S) URL и встраивание пароля в SSH URL отклоняются; сохраняются обычные пути наследования учётных данных, такие как Git credential helper, askpass, SSH agent / SSH config. После получения с --no-checkout проверяются разрешённые и запрещённые пути входящего дерева, затем выполняется checkout; при сбое удаляется только созданный в этом вызове новый clone target. Рекурсия submodule и произвольный parent не публикуются.

gh-workflow

gh-workflow проверяет состояние выполнения GitHub Actions и отменяет явно указанные run для репозиториев GitHub, явно разрешённых аргументом запуска --repository=OWNER/REPO. --repository= можно указывать несколько раз; репозитории, не указанные в списке, выбрать нельзя. Если разрешён один репозиторий, его можно опустить в каждом инструменте; если несколько, указание целевого репозитория обязательно. В примере конфигурации указан DaisukeDaisuke/desmume_webassembly, а сам MCP по умолчанию отключён. Помимо инструментов, соответствующих gh run list --branch main --limit 3, gh run watch RUN_ID --exit-status, gh run cancel RUN_ID, gh run view RUN_ID, можно получить список заданий, все логи, логи сбоев, список workflow, сводку workflow и YAML workflow. cancel_run передаёт проверенный десятичный run ID и разрешённый репозиторий только фиксированными аргументами. workflow dispatch, rerun, delete, artifact download и gh api не публикуются. gh запускается напрямую из spawn с shell=false, с фиксированными подкомандами и опциями. run ID, branch и идентификатор workflow проверяются по отдельности, стандартный ввод закрывается, размер вывода ограничивается. cwd дочернего процесса обязательно укажите в gateway.toml. Для аутентификации можно использовать настройки GitHub CLI, сохранённые локальным gh auth login.

codex-script

codex-script — это встроенный MCP, который фиксирует runtime выполнения при запуске MCP через --runtime=mjs|nodejs|python|php и --runtime-executable=<absolute-path> и выполняет только скрипты, уже существующие в разрешённом Workspace. Один и тот же server.mjs можно зарегистрировать несколько раз и опубликовать с независимыми префиксами, такими как mjs_script, nodejs_script, python_script, php_script. В --mode=run публикуется run_script, в --mode=checkcheck_file. run_script запускает только сам runtime, check_file — фиксированный checker: Node.js --check, Python py_compile, PHP -l. check_file помимо обратно совместимого указания одного filePath может проверить до 500 файлов за раз через filePaths; возвращаются pass, fault и messages только для файлов со сбоем. stdout/stderr успешного checker не возвращаются. Общая оболочка, выбор произвольного исполняемого файла, произвольная инъекция переменных среды, вызов npm script или package manager не публикуются. Аргументы передаются как literal argv, стандартный ввод закрывается, timeout и размер вывода ограничиваются. Gateway обрабатывает codex-script как isBundled и применяет подписанные base / roots, выбранные через isolatedId, и обычную политику путей. Кроме того, если в gateway.toml для codex-script указано sandbox = "never", это отклоняется при загрузке конфигурации; процесс MCP должен запускаться внутри Codex Windows sandbox elevated или unelevated. Вместо создания отдельного sandbox для каждого вызова скрипта фиксированный runtime работает как дочерний процесс уже sandbox-изолированного MCP. В --mode=run, выполняющем произвольный код, код работает внутри разрешённого Workspace, поэтому allowed_directories должны быть минимально необходимыми, а runtime, Codex CLI и исполняемые файлы MCP размещайте вне доступного на запись корня. disallowed_directories и disallowed_files можно использовать как точные deny внешнего профиля разрешений Codex. disallowed_path_globs нельзя безопасно эквивалентно преобразовать в sandbox произвольного кода, поэтому они отклоняются и для run, и для check; при необходимости замените их на точные deny или сузьте сами allowed_directories.

Добавление произвольного stdio MCP

Команда запуска и аргументы подключаемого MCP записываются не в сам Gateway, а в [mcp_servers.<name>] файла config/gateway.toml.

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'

Запускается только допустимый stdio MCP как дочерний процесс, а исходное имя инструмента tool_name публикуется на стороне ChatGPT как example__tool_name. Записи с enabled = false не запускаются. tool_output_token_limit, скопированный из настроек Codex, настройки одобрения по инструментам и элементы, не распознаваемые Gateway, игнорируются. На этом Gateway они не действуют.

Аннотации инструментов внешнего MCP

Внешние MCP публикуются на основе annotations, возвращённых дочерним MCP, с дополнением отсутствующих readOnlyHint, destructiveHint, idempotentHint и openWorldHint до явных значений. Если дочерний MCP вернул только readOnlyHint = true, то при отсутствии явного указания дополняется destructiveHint = false, idempotentHint = true. При запуске Gateway, если TOML, указанный в tool_annotations_path, отсутствует, он создаётся; если [tool_annotations.<prefix>], соответствующий префиксу действующего внешнего MCP, не существует, он добавляется в конец. Идентификационные имена инструментов, полученные от дочернего MCP, также добавляются в [tool_annotations.<prefix>.tools] как UNCLASSIFIED. Существующие настройки префиксов и назначения инструментов не перезаписываются, исчезнувшие инструменты также не удаляются автоматически. Встроенные MCP определяют annotations в каждом server.mjs, поэтому в gateway.toml устанавливается annotation_config = false. Для внешних MCP при опущении значение обрабатывается как true. В автоматически создаваемом TOML в комментариях указываются значения следующих сокращённых имён и четырёх подсказок. open_world_hint переопределяет openWorldHint для всего префикса, а open_world_tools — для отдельных инструментов.

[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 = true

UNCLASSIFIED — это маркер неклассифицированных, который сохраняет существующие значения annotations, возвращённых дочерним MCP, и дополняет только отсутствующие подсказки. При классификации значение идентификационного имени каждого инструмента изменяется на одно из следующих: READ_ONLY_ANNOTATIONS, LOCAL_STATE_ANNOTATIONS, LOCAL_DESTRUCTIVE_IDEMPOTENT_ANNOTATIONS, LOCAL_DESTRUCTIVE_NON_IDEMPOTENT_ANNOTATIONS, LOCAL_ADDITIVE_IDEMPOTENT_ANNOTATIONS.

Настройка Gateway

Решения пользователя уважаются

Поведение Gateway определяется настройками, которые пользователь явно указал в config/gateway.toml. Gateway не выполняет автоматическое обнаружение MCP с самостоятельной регистрацией и не перезаписывает файлы настроек автоматически. Исключением является только то, что для annotations инструментов внешних MCP в отдельный TOML, указанный в tool_annotations_path, добавляются незарегистрированные префиксы и вновь обнаруженные идентификационные имена инструментов. Новые инструменты получают статус UNCLASSIFIED; gateway.toml, существующие префиксы и существующие настройки инструментов не изменяются. Подключаемые MCP, их команды запуска, аргументы, рабочие каталоги, переменные окружения, включение/отключение, режим Codex sandbox, пути только для чтения для sandbox, инструменты, не публикуемые наружу, диапазоны разрешения/запрета путей, последовательное выполнение и отложенный запуск — всё это выбирает пользователь. Gateway считывает, проверяет и применяет эти настройки, но не добавляет настройки, угадывая безопасность или назначение вместо пользователя, и не расширяет разрешённые диапазоны. config/gateway.example.toml — это пример настроек, а не «волшебный скрипт», который применяется как есть. Он устроен так, чтобы пользователь сам мог проверить только необходимые пункты, записать их в config/gateway.toml и понимать, какая программа фактически запускается и какие функции публикуются.

Выполнение команд общего назначения не предоставляется

Этот репозиторий не включает универсальный запускатель команд, который напрямую открывает права пользователя Windows, такой как общая оболочка, PowerShell, командная строка, выбор произвольного исполняемого файла, внедрение произвольных переменных окружения и т. п. Исключением является упомянутый выше codex-script: среда выполнения фиксируется при запуске MCP, и внутри Codex Windows sandbox выполняются только существующие скрипты в разрешённом Workspace. Это не средство, которое обеспечивает безопасность произвольного кода только за счёт разрешения путей, а ограниченный запускатель скриптов, для которого OS sandbox обязателен. Если напрямую открыть общее выполнение произвольного кода, такие данные подключения, как Tunnel ID или runtime API key, могут непреднамеренно утечь, и при неправомерном использовании злоумышленник сможет выполнять произвольные операции с правами пользователя Windows. Поэтому при добавлении внешнего MCP с произвольным выполнением кода также используйте sandbox = "elevated" или "unelevated" и сводите доступный для записи root к необходимому минимуму. Для задач, не требующих локального выполнения, таких как генерация или преобразование кода, по-прежнему отдавайте приоритет песочнице на стороне ChatGPT. Если нужно просто передать локальные исходники, можно упаковать в ZIP только файлы, разрешённые через safe-download.

Защита исполняемого кода Gateway

При установке protect_gateway_app = true, даже если каталог app самого Gateway пересекается с разрешённым Workspace, он обрабатывается как доступный только для чтения для дочерних MCP. По умолчанию в коде Gateway значение false, но в прилагаемом примере настроек — true. Для sandboxed MCP в профиль разрешений Codex добавляются более конкретные записи read, а в safe-files при сохранении чтения и file_info запрещаются write, replace, удаление источника при move, patch и создание каталогов внутри. В file_info защищаемые объекты отображаются как prohibited=true. Эта настройка не является границей ОС на случай, если дочерний процесс с sandbox = "never" будет скомпрометирован вплоть до выполнения произвольного кода. При never дочерний процесс сам может игнорировать политику путей Gateway, поэтому для задач, требующих принудительного запрета записи в исполняемый код, используйте Codex OS sandbox.

Разрешение путей

allowed_directories разрешает указанные каталоги и всё, что находится внутри них, а allowed_files разрешает только указанные файлы по точному совпадению. Gateway рекурсивно проверяет аргументы инструментов всех дочерних MCP и сопоставляет ключи, такие как path, filePath, files, directory, а также строки, похожие на абсолютные пути, со списком разрешений. Относительные пути разрешаются из cwd соответствующего MCP. Автоматически добавляемый к каждому дочернему MCP инструмент <prefix>__get_gateway_access_scope возвращает значения настроек, используемые для этой проверки, и нормализованный фактический диапазон. Это инструмент для непосредственной проверки текущего состояния Gateway вместо того, чтобы AI угадывал рабочий каталог или разрешённые пути из прошлых разговоров.

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 — это glob-шаблоны запрета, применяемые ко всему нормализованному пути как для файлов, так и для папок. * соответствует любой строке, не пересекающей разделитель пути, ** — любой строке, включая разделители пути, ? — любому одному символу, кроме разделителя пути. Например, '**.ssh**' запрещает всё, что содержит .ssh в любом месте пути. В Windows \ и / обрабатываются как один и тот же разделитель, регистр не различается. В macOS и Linux разделителем является /, регистр различается. В сообщении об ошибке при запрете отображаются факт запрета через disallowed_path_globs, совпавший glob и нормализованный целевой путь. Проверка на стороне Gateway — это защита аргументов инструментов, передаваемых от ChatGPT дочерним MCP. Встроенные safe-files, safe-images, safe-download, gitmcp, git-capability и codex-script также используют подписанный Workspace context и собственную проверку путей каждого MCP. Для сторонних MCP внутренний доступ к файлам нельзя ограничить только защитой аргументов Gateway, поэтому при необходимости сам процесс MCP запускается внутри Codex OS sandbox с sandbox = "elevated" или "unelevated".

Формат настроек MCP-сервера

Gateway, как и настройки MCP в Codex, использует формат, в котором настройки каждого MCP объединяются в таблицу [mcp_servers.<name>]. Это не функция совместимости для непосредственного чтения файлов настроек Codex; распознаются только те пункты, которые реализованы в Gateway. При добавлении MCP в config/gateway.toml записывайте без # для комментариев следующим образом. Ниже приведён шаблон со всеми опциями, которые распознаёт Gateway.

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'

項目

説明

private_use_only

Обязательная настройка для всего Gateway. Для подтверждения безопасности обязательно должно быть true.

publish_tool_directory

При true публикует встроенные инструменты gateway__list_available_tools, gateway__get_prefix_list, gateway__get_config. При опускании и false не публикует.

tool_annotations_path

TOML-файл настроек annotations для внешних MCP. Относительные пути задаются относительно каталога с gateway.toml; при опускании используется tool-annotations.toml в том же каталоге.

[mcp_servers.<name>]

Единица, определяющая одно stdio MCP-подключение. <name> должен быть уникальным в пределах Gateway; для каждой такой единицы настраиваются способ запуска, Codex sandbox, prefix, политика путей, публикуемые инструменты и жизненный цикл. При enabled = false настройка сохраняется, но MCP исключается из запуска.

command

Исполняемый файл или команда для запуска дочернего MCP. Обязателен, если не enabled = false. При sandbox = "elevated" требуется нативный .exe с абсолютным путём в Windows. При unelevated и never можно использовать имена из PATH.

args

Задаёт аргументы, передаваемые в command, в виде массива строк. При опускании запуск выполняется без аргументов.

cwd

Рабочий каталог дочернего MCP. Относительные пути преобразуются в абсолютные относительно каталога с gateway.toml; при опускании используется этот каталог. При включённом sandbox должен находиться хотя бы в одном из allowed_directories.

enabled

При false настройка сохраняется, но этот MCP исключается из запуска. При опускании — включён.

sandbox

Граница запуска дочернего MCP. Четыре значения: "never", "elevated", "unelevated", "onlineworkspace"; при опускании — "never". При elevated, unelevated и onlineworkspace сам процесс MCP запускается через Codex Windows sandbox. onlineworkspace — режим, предназначенный только для Internet MCP: сохраняет границы файловой системы workspace-write, но включает сеть. В codex-script значения never и onlineworkspace отклоняются.

codex_executable

Абсолютный путь к Codex CLI, обязательный при sandbox != "never". В Windows можно использовать npm-shim codex.cmd. Должен разрешаться в существующий обычный файл и не может находиться внутри записываемого корня allowed_directories.

sandbox_read_only_directories

Массив абсолютных каталогов, дополнительно передаваемых в профиль разрешений Codex как доступные только для чтения при включённом sandbox. Не становятся записываемыми корнями, как allowed_directories. При опускании — пусто.

prefix

Префикс имён инструментов, публикуемых для ChatGPT. Исходный tool_name публикуется как <prefix>__<tool_name>. При опускании используется <name> из [mcp_servers.<name>].

annotation_config

Указывает, применять ли внешние настройки annotations. При опускании — true. Для MCP с собственными полными annotations, как встроенные, задаётся false.

dangerous_allow_gateway_config_access

По умолчанию false. При false неразрешённые и фактические пути загруженного gateway.toml добавляются в защищённые объекты и отклоняются политикой путей Gateway и дочерних MCP, даже если находятся внутри разрешённых корней. При true снимается только эта защита. Как следует из названия, это опасная настройка для совместимости.

startup_timeout_sec

Количество секунд ожидания запуска и инициализации дочернего MCP. Задаётся положительным числом; при опускании — 30 секунд.

tool_timeout_sec

Количество секунд ожидания вызова инструмента дочернего MCP. Задаётся положительным числом; при опускании — 1800 секунд.

request_timeout_sec

Псевдоним tool_timeout_sec для совместимости. Если заданы оба, приоритет у tool_timeout_sec, поэтому в новых настройках используйте tool_timeout_sec.

serial_group

Сериализует вызовы инструментов MCP с одинаковым значением. Используется для ресурсов, которые нельзя изменять одновременно, например один и тот же браузер или репозиторий.

deferred

При true MCP не запускается при инициализации Gateway, а откладывается до успешного выполнения инструмента, указанного в start_after. При опускании — false.

blocked_tools

Задаёт имена инструментов, не публикуемых для ChatGPT, в виде массива строк с точным совпадением.

blocked_tool_substrings

Задаёт подстроки имён инструментов, не публикуемых для ChatGPT. Регистр не учитывается; не обрабатываются как glob или регулярные выражения.

allowed_directories

Разрешает доступ к указанным каталогам по абсолютным путям и всему, что находится внутри них. При включённом sandbox также становятся записываемыми корнями профиля разрешений Codex.

allowed_files

Разрешает только указанные файлы по абсолютным путям с точным совпадением. При включённом sandbox также передаются в профиль разрешений Codex как отдельные пути для чтения.

disallowed_directories

Задаёт абсолютные пути каталогов и всего, что внутри них, которые отклоняются, даже если находятся в разрешённой области.

disallowed_files

Задаёт абсолютные пути файлов, которые отклоняются, даже если находятся в разрешённой области.

disallowed_path_globs

Задаёт glob-шаблоны отклонения, применяемые ко всему нормализованному пути. Применяются и к файлам, и к папкам.

[mcp_servers.<name>.start_after]

Запускает этот MCP после успешного выполнения инструмента другого MCP, указанного через server и tool. Обычно используется вместе с deferred = true.

[mcp_servers.<name>.stop_after]

Останавливает этот MCP после успешного выполнения инструмента другого MCP, указанного через server и tool.

[mcp_servers.<name>.env]

Дополнительные переменные окружения, передаваемые дочернему MCP. Значения могут быть строками, числами или логическими значениями. Переменные окружения, зарезервированные для политики путей Gateway, переопределить нельзя.

Обычные MCP запускаются с deferred = false или без указания этого параметра; в этом случае start_after не требуется. При sandbox = "elevated" или "unelevated" сеть в профиле разрешений Codex отключается, и только sandbox = "onlineworkspace" включает сеть. В любом режиме включённого sandbox allowed_directories настраиваются как write, а allowed_files и sandbox_read_only_directories — как read. Кроме того, при необходимости в read добавляются каталог исполняемого файла MCP, каталог входного скрипта известного интерпретатора, а для встроенных MCP — каталог app Gateway. codex_executable должен находиться вне write root; для elevated и onlineworkspace сам command также должен находиться вне write root. Даже для внешних MCP, помещённых в sandbox, такие значения, как disallowed_directories, disallowed_files, указанные абсолютными путями, и защищённый gateway.toml, передаются как deny в профиль разрешений Codex, поэтому внутри write root можно использовать точные deny-дыры. С другой стороны, для специфичных для Gateway disallowed_path_globs нет гарантии эквивалентного преобразования в glob-семантику Codex, поэтому у внешних MCP в sandbox они отклоняются по принципу fail closed. Встроенные MCP сами проверяют glob deny policy Gateway, поэтому они являются исключением из этой проверки совместимости. Удалённая настройка MCP через url отклоняется. Специфичный для Codex параметр tool_output_token_limit, даже если он прочитан, не используется и не действует на этом Gateway. С помощью переменных окружения самого Gateway LOCAL_MCP_FILES_MAX_RESPONSE_BYTES и LOCAL_MCP_CODESPACE_MAX_RESPONSE_BYTES можно изменять в байтах верхний предел финального JSONL-ответа, который files__* и codespace__* возвращают туннелю. По умолчанию для каждой из них используется 15 КБ (15360 байт). При превышении лимита в ответе указывается фактический размер возвращаемой строки в КБ, МБ или ГБ, а вместо самого результата возвращаются только первые 1024 байта (1 КБ) исходного финального JSONL в качестве отладочного предпросмотра. Предупреждение «Возможно, деструктивная операция уже была выполнена.» сохраняется. Для files__* рекомендуется использовать downloads__download_zip; для codespace__* — сохранять большой вывод в файл и получать его через codespace__copy_from_codespace либо сузить запрос. Это ограничение финального ответа Gateway применяется только к files__* и codespace__*; на отдельные ограничения downloads__* и images__* оно не распространяется. Внутри MCP Codespace переменная окружения CODESPACE_MCP_MAX_OUTPUT_BYTES ограничивает объём сохраняемых stdout/stderr; значение по умолчанию — 15 КБ. Эту величину также можно изменить через переменную окружения.

Встроенный каталог инструментов

Если на верхнем уровне задано publish_tool_directory = true, публикуются gateway__list_available_tools, gateway__get_prefix_list и gateway__get_config. gateway__get_prefix_list возвращает префиксы, которые в данный момент запущены и имеют опубликованные инструменты, а также встроенный в Gateway префикс gateway и префикс isolated, если запущены встроенные MCP. gateway__list_available_tools и gateway__get_prefix_list обращаются только к уже хранящемуся в Gateway реестру опубликованных инструментов. gateway__get_config возвращает в JSON из конфигурации, уже загруженной при запуске, только name, prefix, allowed_directories, allowed_files, disallowed_directories, disallowed_files, disallowed_path_globs и read-only пути для sandbox для каждого MCP. Конфигурационный файл при этом не перечитывается; путь к самому конфигурационному файлу, env, args, command и другие секретные значения не возвращаются. MCP с enabled = false не запускаются; gateway__list_available_tools возвращает только их имена в disabledProxyNames, а gateway__get_config — только имена в disabledServerNames. Если входной параметр опущен, возвращаются все доступные в данный момент инструменты; если указан prefix, фильтрация выполняется по префиксу полного идентификатора без учёта регистра. Если совпадений 0, это не считается ошибкой — возвращаются все инструменты. Возвращаемая информация об инструментах — это только полные публичные имена и описания, например chrome-devtools__click. Входные схемы, выходные схемы, команды запуска, аргументы, пути, переменные окружения и имена отклонённых инструментов не возвращаются. enabledProxyCount — количество MCP, включённых в конфигурации, а rejectedToolCount — количество инструментов, которым запущенные MCP отказали в публикации. В журнале [gateway] INFO при инициализации Gateway записываются только отклонённые от публикации инструменты, по одному; опубликованные имена отдельных инструментов не перечисляются. Вместо этого записываются количества found/rejected/published по каждому префиксу, префиксы с enabled = false, префиксы, которым не удалось запуститься, и общий итог.

Исключение публикуемых инструментов

Инструменты можно скрыть из публикации с помощью точного совпадения имени в blocked_tools и частичного совпадения без учёта регистра в blocked_tool_substrings.

blocked_tools = ["dangerous_tool"]
blocked_tool_substrings = ["script", "shell", "execute"]

blocked_tool_substrings — это не glob и не регулярное выражение. Например, "script" применяется ко всем evaluate_script, runScript, SCRIPT_debug.

Последовательное выполнение и отложенный запуск

MCP, которые не должны одновременно работать с одними и теми же ресурсами, объединяются в один serial_group. MCP с deferred = true не запускаются при инициализации; их можно запустить через start_after после успешного выполнения указанного инструмента другого MCP. С помощью stop_after их можно аналогично остановить.

[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"

Предпосылки безопасности

[!WARNING] command в gateway.toml выполняет локальные программы. Регистрируйте только те MCP, которым доверяете. Некоторые команды могут напрямую загружать и запускать MCP-программы из интернета. Команды, указанные в gateway.toml, выполняются на реальном ПК, а не в песочнице, с правами пользователя Windows. Не указывайте недоверенные MCP.

Gateway отказывается запускаться с правами администратора и не передаёт дочерним MCP переменные окружения, похожие на секреты родительского процесса, в исходном виде. Однако он не изолирует на уровне ОС файлы, которые может прочитать тот же пользователь Windows. Рекомендуется связывать Tunnel только со своей Platform Organization и своим ChatGPT Workspace, а runtime API key давать только права Tunnels Read + Use. Подробности см. в SECURITY.md и INSTALL.md.

SDK

Скачайте ZIP main-ветки и tunnel-client-source, прикрепите их к ChatGPT и отправьте следующий промпт — ChatGPT создаст встроенный stdio MCP с поддержкой подписи для добавления в этот репозиторий. Если просто зарегистрировать сгенерированный MCP как обычный внешний MCP, подписанное isolated workspace Gateway передано не будет. Разместите его как mcp/<name>/server.mjs и примените также изменения, регистрирующие его в BUNDLED_SERVER_PATHS в app/server-config.mjs. Замените <Describe the MCP tools you need here.> конкретным описанием инструментов, которые вы хотите создать, и объектов, с которыми они работают.

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.

Диагностика и тестирование

Выполняется обнаружение необходимых команд и проверка их версий. Установка и изменение настроек не выполняются.

node app\doctor.mjs

Тесты репозитория можно запустить следующим образом.

npm test

Внешних npm-зависимостей нет.

Лицензия

Сам репозиторий распространяется по MIT License. О сторонних компонентах, таких как официальный tunnel-client.exe, см. THIRD_PARTY_NOTICES.md.

Примечания

Является ли подключение из ChatGPT к локальным MCP «обходным приёмом из серой зоны»?

https://gist.github.com/DaisukeDaisuke/0d0af93dd8cb376a36879702afb176ee

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
<1hResponse time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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
  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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.
    1
    Apache 2.0

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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