local-mcp-chatgpt-tunnel
Local MCP ChatGPT Tunnel
在 Windows 上运作的 stdio 格式 MCP 服务器,通过 OpenAI 官方 Secure MCP Tunnel 连接至 ChatGPT Developer Mode 的本地 Gateway。 可以将多个 stdio MCP 汇聚为一个,并可从设定文件中控制工具名的命名空间化、公开工具的排除、路径许可、串行执行、延迟启动。
安装方法
[!IMPORTANT] 在 Windows 环境中的导入步骤,请参考 INSTALL.md。
Related MCP server: Windows Local MCP
安全警告
[!WARNING] 这是只在您自己的 Windows PC、您自己的 OpenAI Platform Organization、您自己的 ChatGPT Workspace 中使用的个人专用工具。 因为可连接拥有任意代码执行能力的 MCP,不设想向第三方分享或作为公开 Plugin 运行。
关于 codex 沙箱
[!IMPORTANT] 在 2026 年 8 月 11 日的版本中,实现了直接使用 codex 沙箱,以保护电脑免受边界不一致和任意代码执行造成损失的机制。 本工具不提供普通 shell 或任意可执行文件选择,但附带了在固定 runtime 中执行已有脚本的
codex-script。codex-script必须使用elevated或unelevated沙箱。 其他内置 MCP 和外部 stdio MCP 也可按 MCP 在 Codex 沙箱内启动,因此今后建议尽量使用elevated模式来加强边界。
关于 AI 实现
[!CAUTION] 本仓库由 ChatGPT 5.6 Sol High 实现。 因为包含 AI 生成的代码,仍有可能存在错误或漏洞。 请在实际使用前确认代码与设置内容,并使用 N、以使用者自身的责任使用。
能做什么
从 ChatGPT 调用 Windows 上的 stdio MCP 服务器
将多个 MCP 汇总为
<prefix>__<tool>形式的工具名将任意 stdio MCP 加入到
config/gateway.toml按 MCP 限制允许操作的目录与文件
以名称或部分字符串方式将危险工具设为不公开
用
serial_group串行化不希望并行执行的 MCP按需让某个 MCP 整体禁用
按需公开内置目录,可经由完整标识符或 prefix 搜索已公开的工具
本仓库不做的事
调用 OpenAI Responses API 或 Chat Completions API
实现自有 AI 代理、自有 harness、模型计费处理
提供公共 MCP URL 或本地接收端口
自动安装 Node.js、Git、ripgrep、Python、tunnel-client
重新分发 Ghidra MCP、Chrome DevTools MCP、DQ9 MCP 等第三方 MCP
连接 Secure MCP Tunnel 的部分由官方 tunnel-client.exe 负责。
本仓库提供的是连接到其标准输入输出的本地 MCP Gateway 和内置 MCP。
支持环境
目前的导入步骤针对 Windows 11。执行时需要 Node.js LTS 与 OpenAI 官方 tunnel-client.exe。内置的文件搜索功能使用 ripgrep,GitHub Actions 的确认使用 Ranging. 诊断脚本会检查 node、npm、git、gh、rg、py。
不提供面向 macOS 与 Linux 的导入步骤、Docker 配置,以及打开接收端口的配置。
开始使用前
到能够使用为止的步骤已整理在 INSTALL.md。 大致流程如下:
手动准备好所需软件和官方
tunnel-client.exe将
config/gateway.example.toml复制为config/gateway.toml,并改写为绝对路径在 OpenAI Platform 创建个人 Tunnel 和仅执行用的 runtime API key
将 Tunnel ID 和 runtime API key 保存到 Windows 用户环境变量中
使用
start.cmd在诊断后启动 Tunnel从 ChatGPT Developer Mode 中选择个人 Tunnel 不要擅自推测设置或权限,请务必从上面开始确认 INSTALL.md。
内置 MCP
MCP | 公开工具示例 | 用途 |
|
| 在允许的 Workspace 内进行列表、UTF-8 搜索、多个文件/行范围读取、文件信息、读写、Workspace 间文件移动/复制、限制性补丁应用 |
|
| 将 PNG、JPEG、WebP 作为 ChatGPT 的图片内容读取 |
|
| 将允许的场景以单个文件或 ZIP 形式交给 ChatGPT |
|
| 操作允许的仓库本地 Git 操作。不包含 commit / push / pull / clone |
|
| 按每个 |
|
| 查看明确允许的 GitHub 仓库的 Actions 运行状态,并取消 run |
|
| 以 MCP 启动时固定的 mjs / Node.js / Python / PHP runtime 执行允许的 Workspace 内既有脚本或语法检查。必须有 |
|
| 在 |
|
| 仅使用固定 7-Zip 进行 archive 创建和展开 |
|
| 只以现有 GitHub Codespace 为对象,处理 remote 搜索、ssh、SSH、转移、停止、以及临时的 public deployment。不自动检测 localhost 或本地监听端口,也不具有创建 Codespace 的工具 |
内置 MCP 不依赖外部 npm 包。所有工具都会声明 outputSchema。Gateway 会公开 isolated__create、isolated__list、isolated__close,并要求内置 MCP 的所有工具必须具有唯一 isolatedId。isolated__create 除了以 workspaces 数组接收一个以上的绝对目录,还必须提供 purpose 说明该 AI/session 的隔离用于进行何种作业。Gateway 会自动记录 createdAt,并在 isolated__list 返回各 prefix 的 lastOperationAt。每个 ID 会保存多个 Workspace 和 MCP 的相对路径基准。不会复制内置 MCP 进程本身,而是在每次调用的时候把目标 ID 的 root 集合传过去。普通 exact。(builtin bundle)工具调用会在 Gateway 中不经多余的串行化,而是交给子 MCP 侧处理并行;只有 Codespace 有同一个 codespaceId 的防竞争 queue。
Gateway 在启动时为每个内置 MCP 生成随机密钥,并以 HMAC-SHA-256 对 isolatedId、规范化后的基准路径、root 集合进行签名,作为私有参数传递。内置 MCP 拒绝未签名、已被篡改、结构不正常的上下文,并拒绝从公开参数接收 root、roots、workspace、workspaces 的覆盖。Gateway 会对所有启动的子 MCP 添加 <prefix>__get_gateway_access_scope。在内置 MCP 调用时可以带上 isolatedId,从而查看对应 ID 的基准目录、root 集合、设置值以及规范化后的允许/拒绝路径。当路径超出许可范围被拒绝时,会在错误本文中返回当前允许的目录与文件(规范化绝对路径)。内置 MCP 的通用输出格式中也会在 structuredContent.result.accessScope 返回同样的列表。拒绝后,AI 不再需要猜测另一个工作目录并重试。
safe-files
safe-files 对外称作“MCP root”的,是保存在目标 isolatedId 中的当前基准目录。相对路径会从该基准开始解析,并 set_working_directory 只会在同一 ID 的 root 群内更改基准。不会修改其他 ID 或共有 MCP 进程的状态。
read_text 接受相对于 MCP root 的相对路径和绝对路径,但只会在经过规范化和实际路径解析后,目标仍处于允许目录内时读取。
主要功能如下:
使用固定的
rg --files --hidden进行递归列表使用固定的
rg进行 UTF-8 文本搜索UTF-8 文本读写和完全一致替换
限制大小的 base64 文件传输
创建目录
在已经设置的允许 Workspace 之间复制和移动普通文件
使用内置解析器或固定的
git apply进行补丁应用copy和move支持基于当前 MCP root 的相对路径和绝对路径,也可以在多个allowed_directories之间传输普通文件。对源和目标均应用允许/拒绝策略,拒绝符号链接、目录、覆盖已有目标。移动操作在排他复制成功之后删除源,并删除失败时恢复目标。路径字符串不会传给 shell,也不会将符号解释为命令。递归列表总是排除.git内部,补丁也不能以.git内部为对象。同时拒绝许可 root 之外、通过符号链接的逃逸、高概率看起来像信用信息的内容等。不包含通用 shell、PowerShell 或任意命令执行工具。
safe-images
safe-images 是只读的。会匹配 PNG、JPEG、WebP 的扩展名和魔法字节,默认限制为 8 MiB、50 百万像素。
会拒绝 SVG、HEIC,空文件,允许 root 之外,符号链接、UNC 路径、NTFS 替代数据流。
safe-download
safe-download 是只读的,会将单个文件或目录始终以 ZIP 形式返回。可以设置与 safe-files 不同的 cwd 和允许列表,只公开将允许交给 ChatGPT 的场景。
目录会使用固定的 rg --files --hidden 进行枚举,并拒绝 .git 内部、ROM、Save、State、私钥形式,可疑的凭据内容、允许范围之外、符号链接等。当设置了 disallowed_path_globs 时,会在用户指定的 globs 或 excludePaths 之前的整个目标目录中检查整个目录,只要匹配到一个文件或文件夹,就拒绝整个 ZIP 创建。错误中会包含被匹配的设置模式和目标路径。
internet
internet 是从任意 HTTP/HTTPS URL 获取一个文件的内置 MCP。公开工具只有 download_file,目标位置限定在 Gateway 签名并 isolatedId 的 workspace 内。不接受覆盖已有文件、UNC/ADS、workspace 外写入、任意 header / cookie / credential 注入。中途失败时会删除临时文件。
这个 MCP 总是以 sandbox = "onlineworkspace" 启动。 onlineworkspace 会让用维持 Codex workspace-write 文件系统边界、只启用其 permission profile 中的 network。不会回退到 sandbox = "never"。
archive
archive 在启动时以 --seven-zip-executable=<absolute 7z.exe path> 固定 7-Zip,且只公开 create_zip、create_7z、extract_archive 等工具。不公开普通 shell、任意可执行文件、任意 7-Zip 参数。输入和输出限制在签名后的 workspace 内。 extract_archive 即使源和目的地位于不同的允许 root 中也能处理,比如可以把 Downloads 里的 archive 直接展开到 Project workspace。目标不存在时会新建,存在时只接受空的目录。路径解析后仍限制在 1024 字符以内。
archive 本身也运行在 Codex 沙箱中,7-Zip 安装位置通过 sandbox_read_only_directories 一串 read-only trust 输入传入。
codespace
codespace是仅操作已存在的GitHub Codespace的同梱MCP。将list_codespaces返回的name用作各工具的codespaceId。不实现Codespace的create、rebuild、machine变更、显式start、delete工具。启动通过SSH或copy的连接隐式启动现有Codespace,工作结束时可通过stop_codespace执行gh codespace stop -c <name>来显式停止。停止前会取消该isolated session拥有的针对同一Codespace的async SSH,并销毁SSH readiness cache。停止后不会删除Codespace本身或已保存的更改。不存在AI随意创建大量Codespace的途径。同一个codespaceId仅由一个isolated session拥有,若另一个新的isolated session触碰到,则后到者胜出并转移所有权。旧session无法自动夺回,会被指示从竞争错误中通过isolated__list的purpose和codespace前缀的lastOperationAt确认情况并向用户寻求判断。仅对同一codespaceId的调用在Gateway中进行串行化,files等其他bundled MCP不会进行不必要的串行化。
MCP本身必须以sandbox = "onlineworkspace"启动。--gh-executable=<absolute-gh.exe-path>为必填项。为应对保存到Windows Credential Manager的常规gh auth login凭据在sandbox user下不可见的情况,可任意指定--token-file=<absolute-file>。该文件作为固定read-only trust input传递给Codex permission profile,内容仅在MCP内部设置为GH_TOKEN。不继承父环境的GH_TOKEN / GITHUB_TOKEN。不设置、读取、允许用户SSH密钥。SSH/cp所需的密钥由Codespace MCP自身在Gateway准备的non-hidden临时runtime目录内通过ssh-keygen自动生成,Gateway关闭子MCP时删除。该内部目录仅对Codex permission profile授予write权限,不添加到allowed_directories或Gateway的常规文件访问范围。gh.exe和token file不能放置在可写的allowed_directories内。
ssh以token数组而非单个字符串接收remote command,拒绝空白、quote、!、@、backtick、$、;、&、pipe等shell expansion / metacharacter。timeoutMs是underlying operation本身的hard runtime,与作为同步响应等待的时间不同。通常仅以syncWaitMs同步等待,默认/最大为10,000 ms。若未完成则不停止处理,转入shared async registry并返回asyncId。syncWaitMs=0..1000视为立即async,若async=true则忽略syncWaitMs从一开始就立即返回asyncId。get_async_status在省略asyncId时汇总返回该isolation持有的async operation,通过个别ID可获取详细/完成结果。get_async_logs用于获取process-backed job持有的全部stdout/stderr。wait_async作为兼容实现保留,但为避免长时间保持MCP响应而卷入Gateway/tunnel,通常使用get_async_status / get_async_logs。
copy_to_codespace将通过paths枚举或globs之一从sourceDirectory下选出的local file/directory发送到caller明确指定的remote: destination。MCP不会推测或自动添加remote:。例如paths=["scripts/a.js"]时,会放置到remote:/workspaces/project下的/workspaces/project/scripts/a.js,不会仅将basename扁平化到destination直下。为保持层级结构,仅用固定helper创建必要的remote parent directory,将各selection复制到对应的destination。copy_from_codespace方向相反,将caller明确指定的remote:/workspaces/<workspace>/... source 1件复制到signed local workspace内已存在的destination directory。remote source在复制前进行检查,拒绝symlink/special entry、过多entry数、超过CODESPACE_MCP_MAX_TRANSFER_BYTES的传输。local target basename已存在时也拒绝。两个copy工具都要求仅remote侧为remote:,local侧必须为local path,拒绝无remote protocol/两侧均为remote等模糊指定。由于gh codespace cp存在即使remote path已存在、不加-e也会出现No such file or directory的GitHub CLI已知问题,因此两个方向都始终添加-e。remote:本身由caller明确指定,MCP不会自动添加。SSH readiness仅在必要时通过固定echo started probe确认,仅在cache复用中的cp失败时于probe后重试1次。
remote搜索通过roots仅枚举/workspaces直下的workspace,git_root可获取指定路径的Git top-level。search_text是与files__search_text相当的第一级ripgrep搜索,每次必须指定searchBase=/workspaces/<workspace>/...。不能将/、/workspaces、home、/etc等作为搜索root。searchBase在remote realpath后也会重新验证。query和glob不拼接到SSH command字符串中,而是base64化后通过stdin传递给固定remote script。.git始终排除在搜索对象之外,单文件上限为16 MiB,结果数量也限制为最多500件。ripgrep_version可确认rg --version,install_ripgrep在已有rg时不执行任何操作,仅在没有时通过固定installer使用apt/dnf/yum/apk之一安装后再次确认version。无法从tool参数传递package名或任意shell字符串。
list_temporary_public_deployments获取GitHub侧已识别的Codespace临时公开候选及browseUrl / port / visibility。这不是扫描localhost、本地PC监听socket、浏览器标签页、本地开发服务器的工具,也不进行port自动检测。当GitHub侧候选为0件时,不返回空数组作为正常结果,而是返回明确说明“这不是本地port自动检测失败”“不进行localhost探索・port扫描・URL推测・迂回到gh codespace ports forward”的修正错误。open_temporary_public_deployment仅针对调用方明确指定的1个Codespace port,首先向GitHub请求public visibility变更,成功后确认完整的https://...app.github.dev URL并返回。已知准确port时直接调用此工具,不以list_temporary_public_deployments为先决条件。不能仅以list为0件为依据推测需要.devcontainer的forwardPorts。GitHub拒绝指定port时返回实际错误,不探索localhost来推测替代port。close_temporary_public_deployment也仅将明确指定的同一port恢复为private并关闭临时公开。两者都不创建localhost port tunnel,也不新建或删除GitHub侧的forward entry本身。返回的browseUrl可直接用于从Chrome DevTools等确认临时部署的连通性。
gitmcp
gitmcp仅对允许目录内的Git仓库执行本地操作,使用固定的Git子命令和选项。启动时必填--git-executable=<absolute-path>,仅以shell=false启动其实体。不接收一般shell或任意Git参数,不支持直接编辑.git、添加hook、删除branch、force操作。改写index的add_all、stage_paths、unstage_paths以及commit、push、pull、clone_repository已移至另一个git-capability MCP以实现边界隔离。旧的--disable-push、--disable-pull、--disable-clone为避免旧gateway.toml无法启动而作为no-op受理,但即使将这些设为false也不会恢复已移走的capability。
可使用status、跟踪文件列表、branch・remote・历史确认、工作树或staged差异、特定commit的show、切换到现有branch及checkout、指定父commit创建branch、在允许root内创建・列出・常规删除worktree。不实现branch删除、primary worktree删除、dirty或locked worktree的强制删除。
为尊重.gitignore和标准ignore设置,status不显示被ignore的未跟踪文件。与常规Git一样尊重.gitattributes、.git/info/attributes、全局attributes、core.autocrlf等换行转换、系统・全局设置的clean/smudge filter、外部diff、textconv。预先拒绝放置在仓库内.git/config或worktree config中的可执行设置。system/global的filter和diff helper可能按预期执行,因此建议在可能的情况下将具有文件操作权限的gitmcp配置为在Codex OS sandbox内运行。在Windows的Codex sandbox中,由于permission profile的:minimal read会授予C:\Program Files等system read roots,因此标准的C:\Program Files\Git\cmd\git.exe无需额外read设置即可使用。仅在指定Portable Git等system read root之外的Git时,才将该Git安装目录添加到sandbox_read_only_directories。sandbox = "never"也可用于向后兼容。
list_worktree_files通过Git自身的exclude判定枚举跟踪文件和未被ignore的未跟踪文件。check_ignore返回应用于各路径的ignore规则及最终判定,check_attributes返回text、binary、diff、merge、filter、换行属性等有效值。get_effective_config将credential.*、author名、邮箱地址排除在查询对象之外,返回与本地gitmcp行为相关的core.autocrlf、filter、attributes、diff/textconv等设置并附带scope・origin。
安全措施不是禁用全部Git设置,而是仅拒绝放置在仓库自身.git/config或worktree config中的可执行hook、helper、filter、外部diff/textconv、merge driver、签名program、proxy、自定义transport设置。hook、fsmonitor、file・ext protocol、交互式credential prompt均被禁用。可通过get_policy以机器可读方式确认当前策略。
将子模块或嵌套Git仓库直接指定为repositoryPath时,可获取该仓库自身的status、diff、log等。不包含递归搜索父仓库下所有嵌套仓库并自动枚举的工具。
git-capability
git-capability是以--mode=stage|commit|push|pull|clone多次注册mcp/git-capability/server.mjs、按用途隔离Git capability的同梱MCP。各注册是独立的[mcp_servers.<name>],因此可分别选择sandbox、allowed_directories、timeout、serial_group。不禁止sandbox = "never",需要与Git index、签名agent、network兼容的用户也可选择传统路径。
所有mode在启动时固定--git-executable=<absolute-path>,无法从tool参数选择Git可执行文件、repositoryPath、环境变量、任意Git参数。经Gateway时与常规bundled MCP一样必须使用HMAC签名的isolated workspace。仓库内.git/config或worktree config中存在可执行hook / helper / filter / diff / merge driver / signing program / proxy / transport设置时,在capability执行前拒绝。
stage mode仅公开add_all、stage_paths、unstage_paths,repository选择从签名workspace/base固定。Gateway在启动sandboxed Git MCP时,自行扫描可写root下当时存在的.git,将具体的Git metadata write root添加到Codex permission profile。这基于Codex侧的is_metadata_write_denied / has_explicit_write_entry_for_metadata_path允许受保护metadata内更具体的显式write entry的实现。.git/hooks、.git/objects/info、.git/modules保持write拒绝,现有的.git/config、config.worktree、commondir、gitdir也拒绝write。因此stage和常规branch/worktree metadata更新可在sandbox内使用,但submodule添加不在范围内。启动后新建的.git不会自动允许,因此git init和sandbox内clone不通过此机制处理。stage时也尊重标准ignore、attributes、line-ending conversion、system/global clean filter,拒绝deny对象的worktree path。
commit mode的tool参数仅为message,仅对已stage的index执行git commit --no-verify -m <message>。不包含stage功能或repository选择。由于保留system/global的commit signing设置,在需要访问签名agent的配置中可仅将commit MCP设为sandbox = "never",而将更大的gitmcp保留在sandbox内。
push和pull在启动时固定--remote=和1个以上的--repository=OWNER/REPO,从remote URL规范化GitHub的repository identity并与允许列表之一匹配。因此https://github.com/OWNER/REPO.git和git@github.com:OWNER/REPO.git视为同一repository,但不允许repository名称的部分匹配。将多个workspace允许给1个capability时可重复--repository=。旧--expected-remote-url=<exact-url>也可用于向后兼容。tool调用不接收remote、URL、refspec。push仅以无force方式发送current branch,不改写upstream设置。pull fetch固定remote,对incoming tree应用path policy后以--ff-only反映到同名current branch。
clone废除了启动时的--url=,在tool侧接收url、新子目录名、可选的depth。url允许任意host的http://、https://、ssh://user@host/path、user@host:path格式。拒绝HTTP(S) URL中嵌入认证信息和SSH URL中嵌入密码,维持常规Git credential helper、askpass、SSH agent / SSH设置等继承认证路径。以--no-checkout获取后,检查incoming tree的允许・拒绝路径再checkout,失败时仅删除该调用中新建的clone目标。不公开submodule递归和任意parent。
gh-workflow
gh-workflow针对通过启动参数--repository=OWNER/REPO明确允许的GitHub仓库,确认GitHub Actions的执行状态,并取消明确指定的run。--repository=可多次指定,未指定的仓库无法选择。允许仓库为1个时可在各工具中省略,多个时必须指定目标仓库。配置示例中指定了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对应的工具外,还可获取job列表、全部日志、失败日志、workflow列表、workflow概要、workflow YAML。cancel_run仅以固定参数传递已验证的10进制run ID和允许仓库。不公开workflow dispatch、rerun、delete、artifact download、gh api。
gh通过spawn以shell=false直接启动,子命令和选项固定。run ID、branch、workflow标识符分别验证,关闭标准输入,限制输出大小。子进程的cwd必须在gateway.toml中明确指定。认证可使用本地gh auth login保存的GitHub CLI设置。
codex-script
codex-script是MCP启动时通过--runtime=mjs|nodejs|python|php和--runtime-executable=<absolute-path>固定执行runtime、仅执行允许Workspace内已存在脚本的同梱MCP。可多次注册同一server.mjs,以mjs_script、nodejs_script、python_script、php_script等独立prefix公开。
--mode=run公开run_script,--mode=check公开check_file。run_script仅启动runtime本身,check_file仅启动Node.js --check、Python py_compile、PHP -l的固定checker。check_file除向后兼容的filePath单件指定外,还可通过filePaths一次检查最多500件,返回pass、fault及仅失败文件的messages。不返回成功checker的stdout/stderr。不公开一般shell、任意可执行文件选择、任意环境变量注入、npm script或package manager调用。参数作为literal argv传递,关闭stdin,限制timeout和输出大小。
Gateway将codex-script视为isBundled,应用通过isolatedId选择的签名base / roots和常规路径策略。此外,codex-script在gateway.toml中指定sandbox = "never"时会在配置加载时被拒绝,必须在elevated或unelevated的Codex Windows sandbox内启动MCP进程本身。不是为每次script调用创建单独的sandbox,固定runtime作为已sandbox化的MCP的子进程运行。
在--mode=run中执行任意代码时,由于代码在允许的Workspace内运行,allowed_directories应保持最小必要范围,并将runtime、Codex CLI、MCP可执行文件放置在可写root之外。disallowed_directories和disallowed_files可作为外层Codex permission profile的exact deny使用。disallowed_path_globs无法安全等价转换为任意代码sandbox,因此run/check均拒绝,必要时替换为exact deny或缩小allowed_directories本身。
添加任意stdio MCP
所连接MCP的启动命令和参数写在config/gateway.toml的[mcp_servers.<name>]中,而非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'仅有效的stdio MCP作为子进程启动,原始工具名tool_name在ChatGPT侧以example__tool_name公开。enabled = false的条目不启动。
从Codex配置复制的tool_output_token_limit、按工具划分的批准设置、Gateway无法识别的项目均被忽略。在此Gateway上不产生效果。
外部MCP的工具annotations
外部MCP以子MCP返回的annotations為基準,同時將缺失的readOnlyHint、destructiveHint、idempotentHint、openWorldHint補全為顯式值後公開。如果子MCP僅返回了readOnlyHint = true,則在沒有顯式指定的情況下,會補全為destructiveHint = false、idempotentHint = true。
Gateway啟動時,如果tool_annotations_path指定的TOML不存在則會建立,若不存在有效外部MCP prefix對應的[tool_annotations.<prefix>],則會在末尾追加。從子MCP取得的工具識別名稱也會作為UNCLASSIFIED追加到[tool_annotations.<prefix>.tools]。不會覆寫既有的prefix設定或工具分配,也不會自動刪除消失的工具。
同捆MCP因為在各個server.mjs中定義了annotations,所以在gateway.toml中設為annotation_config = false。外部MCP在省略時則視為true。
自動生成的TOML內,會以註解記載下列省略名稱與4個hint的含義。open_world_hint會覆寫整個prefix,open_world_tools會覆寫個別工具的openWorldHint。
[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是保留子MCP返回的annotations既有值、僅補全缺失hint的未分類標記。分類時,會將各工具識別名稱的值變更為READ_ONLY_ANNOTATIONS、LOCAL_STATE_ANNOTATIONS、LOCAL_DESTRUCTIVE_IDEMPOTENT_ANNOTATIONS、LOCAL_DESTRUCTIVE_NON_IDEMPOTENT_ANNOTATIONS、LOCAL_ADDITIVE_IDEMPOTENT_ANNOTATIONS其中一種。
Gateway設定
使用者的決定會被尊重
Gateway的動作由使用者在config/gateway.toml中明確設定的配置決定。它不會自動檢測並擅自註冊MCP,也不會自動改寫設定檔。
唯一的例外是,外部MCP的工具annotations,僅會將未註冊的prefix與新發現的工具識別名稱,追記到tool_annotations_path指定的獨立TOML中。新工具會成為UNCLASSIFIED,但不會變更gateway.toml、既有prefix或既有工具設定。
要連接哪些MCP、其啟動命令、參數、工作目錄、環境變數、啟用或停用、Codex sandbox模式、sandbox的唯讀路徑、不公開的工具、路徑的允許・拒絕範圍、序列執行、延遲啟動,全部都由使用者選擇。
Gateway會讀取、驗證並套用該設定,但不會代替使用者推測安全性或用途,也不會擴大允許範圍。
config/gateway.example.toml只是設定範例,並非會自動套用的「魔法腳本」。它是讓使用者只確認需要的部分,再寫入config/gateway.toml,以便掌握實際啟動的程式與公開功能的結構。
不提供一般用途的命令執行
本Gateway不搭載會直接公開一般shell、PowerShell、任意可執行檔選擇、任意環境變數注入等Windows使用者權限的通用命令執行器。
例外是上述的codex-script,它在MCP啟動時固定執行環境,並且只允許在授權的Workspace內執行Codex Windows sandbox中的既有腳本。這並非僅靠路徑允許就能將任意程式碼安全化的機制,而是必須使用OS sandbox的受限script runner。
若直接公開可執行任意程式碼的一般功能,Tunnel ID或runtime API key等連線資訊可能意外流出;一旦遭到入侵,攻擊者就可能以Windows使用者權限執行任意操作。因此,若要新增外部任意程式碼執行MCP,也請使用sandbox = "elevated"或sandbox = "unelevated",並將可寫入的root限制在最小範圍。
需要程式碼生成或轉換等不需要本機執行的作業,仍請優先使用ChatGPT側的sandbox。如果只是要提供本機原始碼,可以將download允許的檔案打包成ZIP。
保護Gateway執行碼
設定protect_gateway_app = true後,即使Gateway自身的app目錄與允許路徑重疊,也會對子MCP視為唯讀。Gateway程式碼上的預設值為false,但同捆的設定範例中為true。在Codex permission profile中,會將其新增為更具體的規則;在file-info中,則會拒絕讀取、替換、移動來源,並在file-info中將該路徑顯示為唯讀。
(譯者註:此段原文邏輯略有重複,已依語意調整。)此保護並非針對sandbox = "none"子程序的絕對邊界,因為此類子程序可以忽略Gateway的防護;若需要防止子MCP修改Gateway自身檔案,請搭配Codex OS sandbox使用。
路徑允許
allowed_directories會允許指定目錄及其子路徑,disallowed_path_globs則是以正規化後的完整路徑為對象、同時適用於檔案與資料夾的拒絕glob。
* 比對不含路徑分隔符號的任意字串,** 比對包含路徑分隔符號的任意字串,? 比對不含路徑分隔符號的任意單一字元。
例如'**.ssh**'會一律拒絕路徑中任何位置包含.ssh的項目。在Windows中,\與/視為相同的分隔符號,且不區分大小寫。
macOS與Linux中則以/作為分隔符號,並區分大小寫。
當拒絕規則觸發時,Gateway會回覆Child MCP,說明該路徑因disallowed_path_globs而被拒絕存取。
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則以/作為分隔符號,並區分大小寫。
Gateway的檢查是針對ChatGPT工具呼叫的防護層。同捆的filesystem、google-drive、mcp-builder、sequential-thinking均須通過此檢查,第三方MCP亦然。被拒絕的呼叫不會送達子MCP,也不會被執行。
請注意,allowed_directories與disallowed_path_globs無法完全防止子MCP自身進行檔案系統操作。若要嚴格限制,請在OS層級或sandbox中設定權限。
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'allowed_directories與disallowed_path_globs的設定值,會透過<prefix>__get_gateway_access_scope工具提供給子MCP與AI使用。
AI在規劃檔案操作時,應以get_gateway_access_scope回傳的有效範圍為準,不要僅憑對話歷史推測。
若設定了allow_workspace_write = true,則允許在allowed_directories內的所有路徑寫入(除非被disallowed_path_globs排除)。若為false,則僅允許在allowed_directories中明確設為可寫的目錄內寫入。
此外,allowed_directories中的路徑若帶有read_only標記,則該目錄即使位於可寫範圍內,也會被視為唯讀。
GXP4外部MCP会基于子MCP返回的annotations,并补全缺失的readOnlyHint、destructiveHint、idempotentHint、openWorldHint为显式值后对外公开。如果子MCP只返回了readOnlyHint = true,则在没有明确指定的情况下,会补充为destructiveHint = false、idempotentHint = true。
Gateway启动时,如果tool_annotations_path指定的TOML文件不存在则会创建,若不存在有效外部MCP前缀对应的[tool_annotations.<prefix>]部分,则会在末尾追加。从子MCP获取的工具标识名也会作为UNCLASSIFIED追加到[tool_annotations.<prefix>].tools中。不会覆盖已有的前缀配置或工具分配,也不会自动删除已消失的工具。
同捆的MCP在各server.mjs中定义了annotations,因此在gateway.toml中设置annotation_config = false。外部MCP在省略时按true处理。
自动生成的TOML文件中,会用注释说明以下缩写和4种hint的含义。open_world_hint用于整个前缀,open_world_tools用于覆盖单个工具的openWorldHint。
[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是一个未分类标记,它会保留子MCP返回的annotations的现有值,只补全缺失的hint。分类时,需要将各工具标识名的值改为READ_ONLY_ANNOTATIONS、LOCAL_STATE_ANNOTATIONS、LOCAL_DESTRUCTIVE_IDEMPOTENT_ANNOTATIONS、LOCAL_DESTRUCTIVE_NON_IDEMPOTENT_ANNOTATIONS、LOCAL_ADDITIVE_IDEMPOTENT_ANNOTATIONS中的一种。
Gateway设置
用户决定优先
Gateway的行为由用户在config/gateway.toml中明确设置的配置决定。它不会自动检测并注册MCP,也不会自动修改配置文件。
唯一的例外是,外部MCP的工具annotations只会在tool_annotations_path指定的独立TOML中,为未注册的前缀和新发现的工具标识名追加记录。新工具会标记为UNCLASSIFIED,但不会修改gateway.toml、已有前缀或已有工具设置。
要连接的MCP、其启动命令、参数、工作目录、环境变量、启用/禁用、Codex sandbox模式、sandbox的只读路径、不开放的工具、路径允许范围、串行执行、延迟启动等,全部由用户决定。
使用者決定優先
Gateway的行为由使用者在config/gateway.toml中显式设定的配置决定。它不会自动检测并注册MCP,也不会自动改写配置文件。
唯一的例外是,仅会向tool_annotations_path指定的独立TOML文件中追加未注册的前缀和新发现的工具标识名,用于外部MCP的工具annotations。新工具会成为UNCLASSIFIED,但不会修改gateway.toml、现有前缀或现有工具配置。
要连接哪些MCP、其启动命令、参数、工作目录、环境变量、启用/禁用、Codex sandbox模式、sandbox的只读路径、不公开的工具、路径允许范围、串行执行、延迟启动,全部由使用者在config/gateway.toml中明确决定。
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'項目 | 説明 |
| Gateway整体的必需设置。为了安全确认,必须设为 |
| 设为 |
| 外部MCP的annotations设置TOML。相对路径以 |
| 定义单个stdio MCP连接的单位。 |
| 启动子MCP的可执行文件或命令。若 |
| 以字符串数组指定传递给 |
| 子MCP的工作目录。相对路径会以 |
| 设为 |
| 子MCP的启动边界。有 |
| 当 |
| sandbox启用时,作为只读目录额外传递给Codex permission profile的绝对目录数组。不会像 |
| 向ChatGPT公开的工具名称前缀。原始 |
| 指定是否应用外部annotations设置。省略时为 |
| 默认为 |
| 等待子MCP启动和初始化的秒数。以正数指定,省略时为30秒。 |
| 等待子MCP工具调用的秒数。以正数指定,省略时为1800秒。 |
|
|
| 将具有相同值的MCP工具调用串行化。用于不希望同时操作的资源,如同一浏览器或仓库等。 |
| 设为 |
| 以完全匹配的字符串数组指定不向ChatGPT公开的工具名称。 |
| 指定不向ChatGPT公开的工具名称的部分字符串。不区分大小写,不作为glob或正则表达式处理。 |
| 允许访问指定的绝对路径目录及其子目录。sandbox启用时,也作为Codex permission profile的可写root。 |
| 仅以完全匹配方式允许指定的绝对路径文件。sandbox启用时,也作为可读的单独路径传递给Codex permission profile。 |
| 以绝对路径指定即使位于允许范围内也拒绝的目录及其子目录。 |
| 以绝对路径指定即使位于允许范围内也拒绝的文件。 |
| 指定应用于规范化后完整路径的拒绝glob。文件和文件夹均为对象。 |
| 在 |
| 在 |
| 额外传递给子MCP的环境变量。值可以指定字符串、数值、布尔值。不能覆盖为Gateway路径策略保留的环境变量。 |
通常的MCP以deferred = false或省略方式启动。此时,start_after不是必需的。
在sandbox = "elevated"或"unelevated"模式下,Codex权限配置文件中的网络功能会被禁用,只有sandbox = "onlineworkspace"会启用网络。在任何启用沙箱的模式下,allowed_directories配置为写入权限,allowed_files和sandbox_read_only_directories配置为读取权限。此外,MCP可执行文件的目录、已知解释器的入口脚本目录,以及对于捆绑MCP,Gateway的app目录会根据需要以读取权限添加。codex_executable必须放置在可写根目录之外,并且在elevated和onlineworkspace模式下,command本身也必须放置在可写根目录之外。
即使是沙箱化的外部MCP,通过绝对路径指定的disallowed_directories、disallowed_files、受保护的gateway.toml等也会作为Codex权限配置的deny传递,因此可以利用可写根目录内部的精确拒绝漏洞。另一方面,Gateway独有的disallowed_path_globs无法保证能等价转换为Codex侧的glob语义,因此在沙箱化的外部MCP中会以故障关闭方式拒绝。捆绑MCP自身也会验证Gateway的glob拒绝策略,因此是此兼容性检查的例外。
通过url进行的远程MCP配置将被拒绝。Codex特有的tool_output_token_limit即使被读取也不会被使用,在此Gateway上不产生效果。
Gateway自身的环境变量LOCAL_MCP_FILES_MAX_RESPONSE_BYTES和LOCAL_MCP_CODESPACE_MAX_RESPONSE_BYTES可以分别以字节为单位更改files__*和codespace__*返回给隧道的最终JSONL响应上限。两者均省略时,默认值为15KB(15360字节)。超过上限时,会以KB、MB、GB为单位显示实际返回字符串的大小,并代替结果主体返回原始最终JSONL的前1024字节(1KB)作为调试预览。同时保留“可能已执行破坏性操作。”的警告。对于files__*,会提示使用downloads__download_zip;对于codespace__*,会提示将大输出保存到文件并通过codespace__copy_from_codespace获取,或缩小查询范围。此Gateway最终响应限制仅适用于files__*和codespace__*,不适用于downloads__*或images__*的独立限制。在Codespace MCP内部,CODESPACE_MCP_MAX_OUTPUT_BYTES也会限制stdout/stderr的保留量,默认值为15KB。此值也可以通过环境变量更改。
内置工具目录
在顶层指定publish_tool_directory = true时,将公开gateway__list_available_tools、gateway__get_prefix_list、gateway__get_config。gateway__get_prefix_list返回当前启动并拥有公开工具的prefix,以及Gateway内置的gateway,如果捆绑MCP正在运行,则还包括isolated。
gateway__list_available_tools和gateway__get_prefix_list仅引用Gateway已持有的公开工具注册表。gateway__get_config仅从启动时已加载的配置中,以JSON形式返回各MCP的name、prefix、allowed_directories、allowed_files、disallowed_directories、disallowed_files、disallowed_path_globs以及沙箱用只读路径。不会重新读取配置文件,也不会返回配置文件自身的路径、env、args、command及其他秘密值。
enabled = false的MCP不会启动,在gateway__list_available_tools中仅将名称返回至disabledProxyNames,在gateway__get_config中仅将名称返回至disabledServerNames。
如果省略输入,则返回当前所有可用工具;如果指定prefix,则进行不区分大小写的完整标识符前缀匹配筛选。如果匹配结果为0件,则不视为错误,返回全部结果。
返回的工具信息仅为chrome-devtools__click这样的非缩写公开名称和说明。不返回输入模式、输出模式、启动命令、参数、路径、环境变量、被拒绝的工具名称。enabledProxyCount是配置中有效的MCP数量,rejectedToolCount是已启动MCP中拒绝公开的工具数量。
在Gateway初始化时的[gateway] INFO中,仅逐条记录被拒绝公开的工具,不列举已公开的个别工具名称。而是记录每个prefix的found/rejected/published数量、enabled = false的prefix、启动失败的prefix以及整体汇总。
公开工具的排除
工具名称的完全匹配可通过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。
设置为deferred = true的MCP在初始化时不会启动,可以在另一个MCP的指定工具成功之后,通过start_after启动。
同样,可以通过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]
gateway.toml中的command会执行本地程序。请仅注册可信的MCP。 某些命令会直接从互联网获取并执行MCP程序。 在gateway.toml中指定的命令,不是在沙箱内,而是在实际PC上以Windows用户的权限执行。 请勿指定不可信的MCP。
Gateway会拒绝以管理员权限启动,并且不会将父进程的疑似秘密环境变量原样继承给子MCP。但是,这并不能在操作系统层面隔离同一Windows用户可读取的文件。
建议将Tunnel仅关联到自己的Platform Organization和自己的ChatGPT Workspace,并且不要为runtime API key授予除Tunnels Read + Use以外的任何权限。详情请参阅SECURITY.md和INSTALL.md。
SDK
下载main分支的ZIP和tunnel-client-source并附加到ChatGPT,发送以下提示,即可创建可添加到此仓库的签名兼容捆绑stdio MCP。
仅将生成的MCP注册为普通外部MCP,不会发送Gateway的签名隔离工作区。请将其放置在mcp/<name>/server.mjs中,并应用将app/server-config.mjs的BUNDLED_SERVER_PATHS注册的差异。
请将<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
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