Skip to main content
Glama
mingrath
by mingrath

chatgpt-sol-local-bridge

A production-grade, cross-platform implementation of the original ChatGPT Web → OpenAI Secure MCP Tunnel → local workstation workflow.

It exposes the same 44 MCP tools as the full macOS reference implementation while supporting macOS, Linux, and Windows through platform adapters. ChatGPT can read and edit projects, run git/tests/builds, supervise processes, drive browsers and native applications, work with Office files, and optionally delegate to local Codex.

The local MCP endpoint binds to loopback by default. Tunnel connectivity is initiated outbound by tunnel-client over HTTPS—no public port or inbound firewall rule is required. Invoked tools such as web_fetch, browsers, package managers, project scripts, Codex, and tests may make their own outbound connections.

IMPORTANT

This bridge gives an AI agent the authority of the local user running it. The no-delete layer is a strong policy seatbelt with exact, expiring approval tokens; it isnot an OS sandbox. For sensitive work, use a dedicated OS account, VM/container, filesystem snapshots, limited workspace roots, and—when available—an independent external approval verifier.


Why this exists

ChatGPT can reason about a bug, but without tools a human still has to copy patches, run commands, paste logs, switch to a browser, and report results. This bridge closes that execution loop while keeping the workstation private:

  • Operate a development machine from ChatGPT Web—including from another device.

  • Reuse the ChatGPT product surface as the orchestrator while keeping local Codex optional.

  • Avoid public tunnel URLs and inbound network exposure.

  • Keep tool authority, workspace roots, output limits, and destructive approvals under code you control.

  • Preserve the original rule: create/update/edit are allowed; delete/reset/quit must be previewed and confirmed first.

ChatGPT and Codex limits/billing are product- and plan-dependent and can change. codex_run always uses the local Codex CLI and therefore consumes the Codex usage pool associated with that CLI authentication.

Related MCP server: MCP ChatGPT Full PC Dev

Architecture

ChatGPT Web / desktop browser
           │
           ▼
OpenAI-hosted Secure MCP Tunnel endpoint
           ▲
           │ outbound HTTPS :443 only
           │
     tunnel-client (local)
           │ loopback HTTP
           ▼
 http://127.0.0.1:8765/mcp
 chatgpt-sol-local-bridge
           │
 ┌─────────┼─────────────┬──────────────┐
 │         │             │              │
files/git  processes   browser/CDP   OS adapter
projects   Codex CLI   Penpot web    macOS/Linux/Windows

The bridge and tunnel are separate processes so they can be tested, restarted, logged, and supervised independently.

Exact 44-tool contract

The tool names are frozen and contract-tested:

Family

Tools

Policy

bridge_instructions, confirm_destructive, pending_destructive, penpot_status

Workspace

workspace_list, workspace_open, workspace_add_root, workspace_tree, workspace_snapshot

Files

read_file, search_text, write_file, apply_patch, edit_file

Git

git_status, git_diff, git_log, git_run

Project

project_test, project_lint, project_typecheck, project_build, project_dev

Process/system

shell, process_start, process_list, process_logs, process_stop, codex_run, health, system_info

Desktop/network/docs

dom_cdp, accessibility, input_event, vision, window, clipboard, notification, file_dialog, screen_record, audio, scheduler, web_fetch, office

project_* uses documented heuristics for Node/npm/pnpm/yarn/bun, Python/uv, Rust/Cargo, and Go projects; an explicit command override remains available. It does not implicitly download TypeScript. office reads and writes DOCX/XLSX cross-platform using document libraries rather than requiring Microsoft Office.

Platform support

Capability

macOS

Linux

Windows

Files/git/project/process/Codex

Native

Native

Native

Browser dom_cdp

interceptor

interceptor

interceptor

Native accessibility/input/window

interceptor macos

xdotool/wmctrl (X11; compositor-dependent on Wayland)

PowerShell + Windows UI Automation/Win32

Screenshot/OCR

interceptor or screencapture; Tesseract

grim/gnome-screenshot/scrot + Tesseract

System.Drawing + Tesseract

Clipboard/dialog/notification

native macOS

wl-clipboard/xclip, zenity/kdialog, notify-send

PowerShell/WinForms

Screen/audio

ffmpeg + avfoundation/afplay

ffmpeg + X11/PulseAudio

ffmpeg gdigrab/dshow/ffplay

Scheduler

launchd

systemd user timers

Windows Task Scheduler

Always-on user service

LaunchAgent

systemd --user

per-user Scheduled Tasks

Every tool is registered on every OS. If an optional backend is missing, the tool returns a clear capability-unavailable error and npm run doctor reports the dependency.

Wayland intentionally prevents some global input/window operations. Exact support depends on the compositor and portal permissions; this cannot be bypassed safely by an application.

Optional backend examples:

# macOS
brew install ripgrep ffmpeg tesseract
ffmpeg -f avfoundation -list_devices true -i ""  # discover capture devices

# Ubuntu/Debian X11 (choose Wayland equivalents where appropriate)
sudo apt install ripgrep ffmpeg tesseract-ocr xdotool wmctrl wl-clipboard xclip zenity libnotify-bin scrot

On Windows, install Node/Git/tunnel-client and place optional interceptor, ffmpeg, Tesseract, and Codex executables on PATH before service installation. Discover DirectShow devices with ffmpeg -list_devices true -f dshow -i dummy. Linux screen recording currently uses X11 (DISPLAY and optional SCREEN_SIZE); Wayland screenshots can use grim, but recording depends on compositor/portal support.


Quick start: local server

1. Requirements

Required:

  • Node.js 20+

  • Git

  • tunnel-client from OpenAI

  • An eligible ChatGPT web account with Developer Mode available (managed workspaces may require an admin grant)

  • An OpenAI Platform organization with tunnel permissions and a runtime API key

Recommended/optional:

# macOS examples
brew install openai/tools/tunnel-client
brew install ripgrep ffmpeg tesseract
# interceptor and codex are optional integrations

Windows users should install the current tunnel-client release from openai/tunnel-client.

2. Install

git clone https://github.com/mingrath/chatgpt-sol-local-bridge.git
cd chatgpt-sol-local-bridge
npm ci
cp .env.example .env

Edit .env and grant only the directories ChatGPT actually needs:

HOST=127.0.0.1
PORT=8765
WORKSPACE_ROOTS=/Users/you/projects
DEFAULT_WORKSPACE=/Users/you/projects
ALLOW_TOOL_ROOT_REGISTRATION=false
INCLUDE_COMMON_WORKSPACE_ROOTS=false
DESTRUCTIVE_APPROVAL_MODE=chat

On Windows, separate multiple roots with ;. On macOS/Linux, use :.

Workspace roots constrain the structured file/Office tools and command working directories; they are not a filesystem sandbox for absolute paths used inside shell, project scripts, browser tools, or Codex. workspace_add_root exists for contract compatibility but is disabled by default because allowing the model to expand its own filesystem authority is unsafe. No Desktop/Documents/home-directory roots are implicit unless INCLUDE_COMMON_WORKSPACE_ROOTS=true. Add roots to .env, or explicitly opt into broader authority only if you accept that risk. DEFAULT_WORKSPACE accepts exactly one directory, not a delimiter-separated list.

3. Diagnose, start, and smoke-test

npm run doctor
npm start

In another terminal:

npm run smoke

Expected result: exactly 44 tools, a write/read/edit round trip in a unique directory under BRIDGE_SCRATCH_DIR, a blocked destructive command, and a successful single-use confirmation.

Health endpoints:

curl http://127.0.0.1:8765/healthz
curl http://127.0.0.1:8765/readyz

Connect through OpenAI Secure MCP Tunnel

1. Create the OpenAI resources

  1. Create a tunnel at https://platform.openai.com/settings/organization/tunnels.

  2. Associate it with the ChatGPT workspace that should discover it.

  3. Create a runtime API key at https://platform.openai.com/settings/organization/api-keys with Tunnels Read + Use.

  4. Enable ChatGPT Developer Mode/custom apps in the target workspace.

Platform tunnel roles and ChatGPT workspace Developer Mode are separate permissions.

2. Guided configuration

macOS/Linux:

./scripts/connect-chatgpt.sh

Windows PowerShell:

.\scripts\windows\configure-tunnel.ps1

The wizard seeds a user-only runtime.env from the repository .env (intentionally omitting MCP_TOKEN because the documented tunnel profile uses sample_mcp_remote_no_auth), prompts separately for workspace roots/default workspace, initializes the profile from the configured MCP endpoint, and runs tunnel-client doctor. API keys are not embedded in service descriptors or process arguments. For persistent services, runtime.env is authoritative—edit it rather than .env, then restart the affected service.

Default runtime config locations:

  • macOS/Linux: ~/.config/chatgpt-sol-local-bridge/runtime.env (0600)

  • Windows: %APPDATA%\chatgpt-sol-local-bridge\runtime.env (user-only ACL)

3. Equivalent manual commands

export CONTROL_PLANE_API_KEY="sk-..."
tunnel-client init \
  --sample sample_mcp_remote_no_auth \
  --profile sol-local-bridge \
  --tunnel-id tunnel_0123456789abcdef0123456789abcdef \
  --health-listen-addr 127.0.0.1:8766 \
  --mcp-server-url http://127.0.0.1:8765/mcp

tunnel-client doctor --profile sol-local-bridge --explain
tunnel-client run --profile sol-local-bridge

Leave both npm start and tunnel-client run running, use npm run start:all to start them in dependency order, or install the user services below. The tunnel wrapper waits for /readyz before launching tunnel-client, avoiding a cold-start probe race. If HOST/PORT changes, rerun tunnel profile initialization so its --mcp-server-url stays in sync. Service status also checks tunnel readiness at http://127.0.0.1:8766/readyz.

4. Attach ChatGPT on the website or desktop app

See ChatGPT website and desktop setup for the complete, current walkthrough and troubleshooting guide.

ChatGPT website

  1. On ChatGPT web, open Settings → Security and login and enable Developer mode.

  2. Open https://chatgpt.com/plugins, select +, and create a developer-mode connection.

  3. Choose Connection = Tunnel, select/paste your tunnel_... ID, and choose No Authentication.

  4. Verify that discovery returns exactly 44 tools.

  5. In a new conversation, choose Developer mode from the composer's + menu, enable the app, and ask:

Use SOL Local Bridge only. Call bridge_instructions, then workspace_list, then workspace_snapshot. Do not modify anything.

ChatGPT desktop app

OpenAI currently registers custom MCP connections on the website first. Sign into the desktop app with the same account/workspace and check its Plugins/Developer Mode picker. If the connection does not appear directly, copy its plugin_asdk_app_... technical ID from the website URL and use @plugin-creator in desktop Work mode to package it with a personal marketplace entry. Restart the desktop app, install it from the Plugins Directory, and test it in a new conversation. The detailed guide explains each step and the difference between tunnel_... and plugin_asdk_app_... IDs.

If Developer mode is absent on the website, confirm account/workspace eligibility and—on a managed workspace—ask its admin for access. If Work mode or the Plugins Directory is absent from the desktop app, update it; if the surface remains unavailable for that account/build, use the website integration.


Run persistently

Desktop automation must run in the logged-in user's session. Do not run it as a macOS LaunchDaemon, Windows Session-0 service, or headless system service if you expect UI control.

macOS LaunchAgents

./scripts/service-macos.sh install
./scripts/service-macos.sh status
./scripts/service-macos.sh logs
# restart / stop / start / uninstall are also supported

Two LaunchAgents are installed: one for the MCP server and one for tunnel-client. The plist files contain only paths—not secrets.

Linux systemd user services

./scripts/service-linux.sh install
./scripts/service-linux.sh status
./scripts/service-linux.sh logs

For an interactive desktop, keep these as user services. A dedicated system user is appropriate only for headless file/git/build workflows. User services normally follow the user's login session; intentional headless persistence may require loginctl enable-linger <user> and is not universally available in containers, minimal distributions, or WSL.

Windows Scheduled Tasks

.\scripts\windows\service.ps1 install
.\scripts\windows\service.ps1 status
.\scripts\windows\service.ps1 logs

Tasks run at user logon with limited privileges and MultipleInstances=IgnoreNew. They do not request highest privileges.


Delete/rollback approval model

The following are intercepted before execution at the structured file/command/network layer:

  • Unix/Windows/PowerShell file deletion and truncation

  • git clean, reset --hard, restore/checkout discard, branch deletion, force push

  • SQL drop/truncate/delete

  • destructive Docker/Podman prune and kubectl delete

  • patch-based file deletion

  • HTTP DELETE

  • native window close/quit/kill

A blocked operation returns:

DELETE BLOCKED — no destructive command was executed.
Token: del_...
Expires: ...
Preview: ...

The code-level default is deny (no destructive execution). The supplied .env.example and guided setup explicitly select chat to reproduce the original workflow. In chat mode, after the human explicitly confirms the exact preview, ChatGPT calls:

confirm_destructive(token=<same token>, userSaidYes=true)

Tokens are bound to the exact canonical operation, stored atomically, expire after ten minutes by default, and are single-use. chat mode relies on the MCP caller honestly representing the human's reply; it is a review workflow, not independent proof against a malicious/prompt-injected caller.

For independently enforced approval, configure a read-only verifier backed by a separate human-controlled channel/account:

DESTRUCTIVE_APPROVAL_MODE=external
APPROVAL_VERIFIER_COMMAND=/absolute/path/to/read-only-approval-verifier
APPROVAL_VERIFIER_SHA256=<pinned sha256 of that executable>

At confirmation time the bridge executes:

<verifier> verify <token> <operation-fingerprint>

The verifier must only report whether a separate human approval already exists; it must not let the bridge's shell create that approval. A same-user file or local CLI is not independent because the unrestricted shell tool could invoke it itself.

Browser/native UI tools are marked destructiveHint=true, and obvious Delete/Trash/Close actions are token-gated, but coordinate clicks, JavaScript evaluation, and keyboard input cannot be semantically proven non-destructive. Likewise, no generic regex can make unrestricted shell access mathematically unable to delete data—for example, an interpreter can implement deletion indirectly. Use OS isolation/snapshots when that guarantee matters. See docs/SECURITY.md.


Security defaults

  • Loopback-only bind is enforced. Non-loopback operation is intentionally refused; any external TLS/auth proxy requires a separate security design and keeps the bridge itself on loopback.

  • Host-header validation against DNS rebinding.

  • Optional bearer authentication with timing-safe comparison.

  • Explicit workspace roots; tool-driven authority expansion disabled. A dedicated BRIDGE_SCRATCH_DIR is the only automatic tool root.

  • Internal approvals/process metadata/audit state is never a file-tool root; realpath/symlink-aware containment and protected credential/system paths are enforced.

  • Bridge-owned process IDs only, with start-identity checks and process-tree termination.

  • Bounded request bodies, command output, fetch/Office responses, timeouts, concurrent tool calls, process-log size, record count, and retention.

  • Hash-chained, redacted audit JSONL under ~/.chatgpt-sol-local-bridge/audit/.

  • web_fetch blocks private, loopback, link-local, multicast, mapped-IPv6/NAT64, and cloud-metadata ranges by default; redirects are revalidated and cross-origin redirects are rejected unless explicitly enabled (then downgraded to header-safelisted GET).

  • Runtime API keys live only in a user-owned secret file. The tunnel key is excluded from the MCP server, and secret-like environment variables are stripped from shell/project/Codex children unless explicitly allowlisted.

To intentionally call local/intranet HTTP services:

WEB_FETCH_ALLOW_HOSTS=localhost,api.dev.internal.example
# or, broader and riskier:
ALLOW_PRIVATE_NETWORK=true

Tool arguments/results can include source code or local data and are sent through the calling OpenAI product. Do not expose a workspace whose data policy forbids that processing.


Penpot

Two supported shapes:

  1. Run Penpot MCP as a second local server and attach it through another Secure MCP Tunnel profile.

  2. Use dom_cdp to drive https://design.penpot.app in an already signed-in browser.

npx -y @penpot/mcp@stable
# manifest: http://127.0.0.1:4400/manifest.json
# MCP:      http://127.0.0.1:4401/mcp

penpot_status reports these endpoints; the bridge intentionally does not impersonate or proxy Penpot's own MCP tools.

Development and validation

npm run lint
npm test                 # unit + integration
npm run test:unit
npm run test:integration
npm run check            # lint + all tests
npm run doctor -- --json
npm run doctor -- --live       # require local /readyz
# For service configuration, load runtime.env without echoing secrets:
node scripts/run-with-env.mjs ~/.config/chatgpt-sol-local-bridge/runtime.env -- npm run doctor -- --tunnel

The test suite covers:

  • exact 44-tool contract

  • authenticated Streamable HTTP MCP lifecycle

  • workspace and symlink escape protection

  • read/write/edit/patch round trips

  • destructive detection and one-time confirmations

  • managed-process ownership/logging/stopping

  • DOCX/XLSX round trips

  • private-network blocking

  • project command detection

Repository layout

src/
  server.js              Streamable HTTP MCP server
  tool-contract.js       frozen exact 44-tool list
  lib/                   policy, paths, process, audit, Office, fetch
  platform/              macOS/Linux/Windows adapters
  tools/                 seven tool-family modules
docs/
  CHATGPT_SETUP.md       website + desktop app connection guide
  SECURITY.md            trust boundaries and hardening
  OPERATIONS.md          service and incident runbook
scripts/
  connect-chatgpt.sh     Unix tunnel setup wizard
  service-macos.sh       LaunchAgent lifecycle
  service-linux.sh       systemd-user lifecycle
  windows/               PowerShell setup/service scripts
  smoke.mjs              live MCP smoke test
examples/python-minimal/  original small FastMCP teaching example

Operational caveats

  • The workstation must be awake, logged in, connected, and running both services.

  • macOS Accessibility/Screen Recording/Microphone permissions are granted to the executable actually running the bridge (Terminal/Node/interceptor).

  • Linux Wayland support varies by compositor.

  • Windows desktop automation requires an interactive user session.

  • Cross-platform DOCX/XLSX support covers document data, not Office macros, rendering fidelity, or Excel formula recalculation.

  • Attaching browser automation to a personal profile exposes that profile's signed-in sessions to the agent.

References

License

MIT. tunnel-client itself is OpenAI's separate Apache-2.0 project; it is not vendored here.

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

Maintenance

Maintainers
Response 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

View all related MCP servers

Related MCP Connectors

  • MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

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/mingrath/chatgpt-sol-local-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server