claude-for-chatgpt-desktop
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- exec() — Shell command execution in e2e/live.mjs
- spawnSync — Synchronous process spawning in e2e/live.mjs
- fs.rmSync — Destructive file system operation in e2e/live.mjs
- process.env — Environment variable access in e2e/live.mjs
- network request — Outbound network request in e2e/live.mjs
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Use Claude Fable, Opus, Sonnet and Haiku in the ChatGPT desktop app on macOS, in the model picker next to GPT, with the app's own tools.
Claude for ChatGPT Desktop
Claude in the ChatGPT desktop app's model picker, right next to GPT. For macOS.

- Pick Claude Fable, Opus, Sonnet or Haiku in any chat.
- Claude uses the app's own tools: the in-app browser, computer control, terminal, file edits and plugins.
- Switch between Claude and GPT in the same chat.
- Runs on your own Claude Code login. GPT keeps working exactly as before.
Full 50-second demo: docs/demo.mp4
Unofficial. Not affiliated with Anthropic or OpenAI. Usage counts against your Claude plan, like any Claude Code session (Anthropic's notes).
Install
You need
- a Mac
- the ChatGPT desktop app, opened once and signed in
- Claude Code, signed in (run
claudeonce)
Run
curl -fsSL \
https://raw.githubusercontent.com/wuchris-ch/claude-for-chatgpt-desktop/main/install.sh \
| bash
Then pick a Claude model in ChatGPT. The installer offers to reopen ChatGPT for you.
- Update: run the same command again.
- Remove: add
-s -- --uninstallafterbash. - Leave your normal ChatGPT untouched: add
-s -- --windowafterbashfor a separate Claude-only window.
- Checks for Node.js 24 or later (and offers to install it with Homebrew) and for your Claude Code sign-in.
- Downloads this repository to
~/Library/Application Support/Claude for ChatGPT Desktop/source. - Installs a small background service that listens only on 127.0.0.1.
- Backs up your ChatGPT settings and adds one setting,
openai_base_url. - Offers to reopen ChatGPT.
To read it before running it, clone the repository and run ./install.sh.
git clone https://github.com/wuchris-ch/claude-for-chatgpt-desktop.git
cd claude-for-chatgpt-desktop
npm ci
python3 scripts/setup.py
python3 scripts/install.py
python3 scripts/picker.py install
install.py installs the background service. picker.py install backs up your ChatGPT settings and adds the one setting. Then reopen ChatGPT. To undo it, run python3 scripts/picker.py uninstall and reopen ChatGPT.
The separate window (--window) has its own ChatGPT profile, so it can have its own instructions and skills:
- Put an
AGENTS.mdfile and askillsfolder in~/Library/Application Support/Claude for ChatGPT Desktop/codex/. Setup never replaces them. - Or share your usual ones:
python3 scripts/setup.py --agents-md codex --share-skillslinks~/.codex/AGENTS.mdand~/.codex/skills.
To open the window later, double-click Open ChatGPT with Claude.command in the downloaded folder, or run python3 scripts/launch.py. Sign into ChatGPT once in that window.
Features
Works like GPT does in the app
- The in-app browser, computer control, terminal, file edits, plugins and connectors, with the app's approvals and tool cards.
- Images, edits, regenerate, helper agents, review mode, chat titles and inline visuals.
- Message Claude while it works, even mid-reply. It answers you before its next step and carries on.
- Stop, then continue where it left off.
- A question card the app can't show goes back to Claude with the reason, so it asks in a form you can see.
Switch models freely
- Claude and GPT in the same chat. Claude sees what GPT did, and GPT can read Claude's summaries.
- Each Claude entry carries the version Claude Code runs, such as Claude Opus 5.5.
- GPT keeps its own login, connection and compaction.
Fast and cheap on long chats
- One warm Claude process per chat. In daily use, 97 to 98% of input tokens came from the prompt cache.
- Compaction reuses the cache, even when it fires in the middle of a turn.
- Chats full of screenshots stay under the request size limit, and a tool call the app never answers can't hold a session forever.
Tested
- 148 automated tests, plus live checks with real Claude Code, real OpenAI and the app's own runtime. The measurements behind each choice are in VERIFICATION.md.
Limits
- macOS only. Tested with ChatGPT 26.1007.71326 (Codex runtime 0.162.0-alpha.17.2), Claude Code 2.1.300 and Node.js 24.21. A later app or Claude Code release can need an update here.
- Local tasks only. Cloud tasks, voice, image generation and other OpenAI-hosted features stay with GPT. OpenAI-hosted tools, such as GPT's built-in web search, are left out of Claude's tools.
- GPT goes through the bridge in picker mode. If the service stops, GPT requests fail until macOS restarts it or you uninstall. Picker mode needs a ChatGPT sign-in, and isn't meant for ChatGPT workspaces with data-residency routing.
- GPT's summaries are encrypted for GPT. If a chat that GPT compacted switches to Claude, Claude gets the messages after the summary and a note that it's unavailable.
- Helper agents whose model family differs from their parent's are untested.
- Some request options are refused with an error instead of being ignored: forced tool choice, output-token caps, non-JSON text formats, and
parallel_tool_calls=falsewith tools. - No silent model switches. If Claude Code's safety classifiers re-run a request on a fallback model, such as Opus 4.8 for Opus 5.5, the bridge stops the turn and says why.
- Long browser runs drop older screenshots from Claude's context in batches (the app keeps them), so Claude takes a fresh screenshot when it needs one.
How it works
flowchart LR
subgraph app["ChatGPT desktop app"]
direction TB
Picker["<b>Model picker</b><br/>GPT and Claude models"]
Tools["<b>The app's tools</b><br/>computer use, in-app browser,<br/>terminal, plugins"]
end
Bridge["<b>Bridge</b><br/>127.0.0.1 on your Mac"]
OpenAI["<b>OpenAI</b><br/>with the app's own login"]
Claude["<b>Claude Code</b><br/>one warm claude -p per chat"]
Picker -->|"model request"| Bridge
Bridge -->|"GPT models"| OpenAI
Bridge -->|"Claude models"| Claude
Claude -.->|"tool call over MCP"| Bridge
Bridge -.->|"app runs it, with approval"| Tools
- One setting. Picker mode sets
openai_base_url, so the app's OpenAI connection goes to the bridge, which adds the Claude models to the app's model list. - GPT requests go on to OpenAI as the app sends them, with the app's own login, WebSocket connection and compaction. In a chat where Claude also answered, the bridge turns Claude's summaries into text and drops Claude's item ids, which OpenAI can't read.
- Claude requests are answered by the bridge: one headless Claude Code process per chat, with the app's tools offered over MCP.
- Tool calls go back to the app as ordinary tool calls. The app applies its approvals, runs the tool and returns the result to Claude.
- Nothing is patched. The app bundle isn't modified, and the bridge has no tools of its own. The separate window works the same way through its own model provider, without the OpenAI relay.
Compared with similar projects
Checked October 14, 2026. Stars are GitHub stars on that date.
| Project | How Claude runs | Claude uses the app's browser and computer control | Notes |
|---|---|---|---|
| This project | Bridge on the app's model API; one warm claude -p per thread; the app's tools over MCP |
Yes | Built only for the ChatGPT desktop app. Claude next to GPT in the normal picker with GPT traffic relayed to OpenAI, or a separate window |
| yetone/magpie (12.7k stars) | Model gateway for many agents and providers; Claude plan requests run the local claude with the client's tools over MCP |
Not documented for the desktop app | Adds its models next to GPT in the Codex picker through openai_base_url. A menu bar app that also routes Claude Code, Gemini CLI, OpenCode and other agents to any provider |
| gkorepanov/ccodex (33 stars) | Claude Agent SDK behind its own codex app-server gateway |
No; Claude uses Claude Code's own tools | Released almost daily. Claude next to GPT in the picker, model switching mid-chat, plan mode, /goal, side chats, sub-agents, the phone app, SSH servers and Linux |
| EthanSK/claude-in-codex (0 stars) | claude -p per message with --resume; the app's tools over MCP |
Computer use tested through Codex CLI; its README says the in-app browser wasn't tested | Installed from a clone |
| Reidond/codex-claude-models-plugin (3 stars) | Claude Agent SDK as a model provider | Not documented | No images or compaction for Claude; no updates since September 14 |
| wbopan/claude-in-codex (0 stars) | Menu bar app that hooks the app's internals through the Node inspector | Not documented | Notarized DMG; app version 26.924 disabled the hook |
| lidge-jun/opencodex (17.4k stars), router-for-me/CLIProxyAPI (55.2k stars) | General model proxies | Only through raw OAuth tokens or an API key | With raw Claude OAuth tokens: Anthropic blocked third-party use on January 9, 2026 and has billed it as extra usage since April 4, 2026. Their claude CLI mode is stateless and has no tools |
FAQ
Can this get my Claude account banned?The bridge runs the official, unmodified Claude Code CLI with your own login, the same as running claude -p in a terminal. It never reads, copies or forwards your Claude credentials, and it doesn't offer a Claude login of its own. Anthropic says you can still use claude -p and third-party apps with your plan's usage limits (update of October 7, 2026). For heavy use, switch to an Anthropic API key (see "Claude login or API key" under Configuration).
In picker mode, GPT requests pass through the bridge on your Mac and go on to OpenAI as the app sent them, with the app's own login, WebSocket connection and compaction. Picker mode changes one setting, openai_base_url, and --uninstall takes it back out. In a chat where Claude also answered, the bridge drops Claude's item ids before relaying, because OpenAI rejects ids it didn't create.
This gives Claude the ChatGPT app's tools and interface: the in-app browser, computer control, plugins and connectors, approvals and tool cards. You can also switch between Claude and GPT in the same chat.
Why not just ask Claude or Codex to build one?You can, and a basic bridge works in an afternoon. The hard part is the long tail that only shows up in daily use: keeping Claude's prompt cache warm (97 to 98% of input from the cache), compaction that doesn't resend the whole chat, Stop and resume without losing tool results, screenshots that push a long chat past the size limit, and GPT chats that keep working after Claude has answered in them. This one has been used daily for over two weeks, and VERIFICATION.md lists each problem found, its fix and the test that covers it.
Configuration
Run the commands below from the downloaded folder (~/Library/Application Support/Claude for ChatGPT Desktop/source) or your clone. python3 scripts/setup.py --help lists every option. Setup rewrites the Claude profile's settings each time it runs, then python3 scripts/install.py applies them to the service.
python3 scripts/picker.py installadds a markedopenai_base_urlline toconfig.tomlin your ChatGPT profile (~/.codex, or$CODEX_HOME), pointing at the bridge with a private key in the path.- It first saves
config.tomland the app's cached model list tobackups/in the runtime folder. - It refuses to run if you already set
openai_base_urlyourself or the profile uses another model provider.
- It first saves
python3 scripts/picker.py uninstallrestoresconfig.tomlbyte for byte when nothing else in it changed. Otherwise it removes only the marked line and keeps your later edits. It also restores the cached model list.python3 scripts/picker.py statusshows whether picker mode is on.
Reopen ChatGPT after either change.
Modelsclaude-models.json lists the picker entries.
- Each
claude_modelis passed toclaude --model. - The aliases
fable,opus,sonnetandhaikufollow Claude Code to new releases. On October 9, 2026 they startedclaude-fable-5-1,claude-opus-5-5,claude-sonnet-5-5andclaude-haiku-5-5. - An alias entry is named after the version Claude Code last started for it, so Claude Fable 5.1 becomes Claude Fable 5.5 after the first chat on the new release.
- The bridge checks the model Claude Code actually starts. An alias accepts any version of its family; a full model id must match exactly.
To pin a version or add a model, copy the file, edit it, and pass it to setup:
{"slug": "claude-opus-5-5", "claude_model": "claude-opus-5-5", "display_name": "Claude Opus 5.5",
"efforts": ["low", "medium", "high", "xhigh", "max"], "default_effort": "medium", "context_window": 1000000}
python3 scripts/setup.py --models ~/my-claude-models.json
Claude login or API key
- By default the bridge runs the unmodified
claudebinary with your normal Claude Code login. - It never reads Claude Code's credentials, and it clears inherited
ANTHROPIC_*andCLAUDE_*variables (exceptCLAUDE_CONFIG_DIR) so nothing else changes the account or endpoint. - For heavy use, an Anthropic API key is the better fit: Anthropic's plan limits assume ordinary, individual use of Claude Code. In API key mode Claude Code uses the key instead of your login.
python3 scripts/setup.py --auth api-key
ANTHROPIC_API_KEY=your-key python3 scripts/install.py
The key is stored only in the service definition, ~/Library/LaunchAgents/<label>.plist, written with mode 0600, and kept when you reinstall. Switch back with --auth claude-login.
python3 scripts/setup.py --web-search
python3 scripts/install.py
- This turns on the app's built-in
web.runtool for Claude. - The bridge forwards each search to OpenAI's search endpoint (
https://chatgpt.com/backend-api/codex/alpha/search) with the Claude window's own ChatGPT sign-in: only theAuthorizationandChatGPT-Account-Idheaders, to that one URL, with redirects refused. - Searches can include conversation context that the app adds. The bridge reads no credential files and logs only status codes and command types.
| Option | Default | Effect |
|---|---|---|
--port |
19480 | Local port of the bridge |
--label |
io.github.wuchris-ch.claude-for-chatgpt-desktop |
LaunchAgent label |
--agents-md |
none |
codex links ~/.codex/AGENTS.md into the Claude profile; claude copies ~/.claude/CLAUDE.md once |
--share-skills |
off | Links ~/.codex/skills into the Claude profile |
--app |
/Applications/ChatGPT.app |
The ChatGPT app to open |
Set CLAUDE_BRIDGE_RUNTIME to keep everything in another folder.
Files
Everything lives in ~/Library/Application Support/Claude for ChatGPT Desktop/:
| Path | Contents |
|---|---|
source/ |
The copy of this repository that install.sh downloads and updates |
app/ |
Installed copy of the bridge |
codex/ |
The Claude window's profile: settings, model catalog, plugins and task history |
user-data/ |
The Claude window's browser and app state |
sessions/ |
Native session records, system prompts and an encrypted retry cache that expires after 24 hours |
logs/ |
Request, model, tool-name and lifecycle metadata, and service errors |
launch.json, token, gateway-key |
Settings from setup, and the local keys between the app and the bridge |
picker.json, backups/ |
Picker mode's record of what it changed, and the backups it restores |
Claude Code keeps its own session transcripts as usual.
Security and privacy
- Local only. The bridge listens only on 127.0.0.1, requires a random local key, and refuses requests from browsers.
- Separate logins. Claude Code manages its own login. The app's ChatGPT credentials never reach Claude. In picker mode the bridge passes them, with the rest of each GPT request, only to OpenAI at
chatgpt.com. - No content in logs. Logs hold request, model, tool-name and lifecycle metadata. They never contain prompts, tool arguments, tool results, tokens or keys.
- One setting changed. Apart from the one setting picker mode adds, your usual ChatGPT profile in
~/.codexis only read, to copy its settings and plugins into the separate window's profile.
Uninstall
curl -fsSL \
https://raw.githubusercontent.com/wuchris-ch/claude-for-chatgpt-desktop/main/install.sh \
| bash -s -- --uninstall
Or from a clone:
python3 scripts/picker.py uninstall # take Claude out of the normal picker
python3 scripts/uninstall.py # stop and remove the service, keep the Claude profile
python3 scripts/uninstall.py --delete-data # also delete the Claude profile, history and logs
Design notes
Prompts, sessions, model switching and the WebSocket relay- Prompts. The app's base prompt is written for Codex. The bridge renames its identity lines for the selected Claude model and tells Claude to ignore Claude Code's own working-directory note. Developer messages before the conversation become the system prompt. Notes the app adds later, such as the date, the open page or an interrupted turn, reach Claude where they occur, so a note does not restart a tool cycle or invalidate the prompt cache.
- Patches and host habits. GPT's
apply_patchoutput is constrained by a grammar that MCP cannot carry, so the bridge adds a written patch format guide, plus notes on escaping inside JavaScript and on the shared output budget of anexeccell. It also passes on host habits found by benchmarking: render PDFs to images in a temporary folder, keep long jobs in the foreground, and avoidrm -rf, which the app refuses. - Sessions. Between user turns Claude Code resumes the saved session. Before resuming, the bridge checks the app's transcript against what the session saw. Edits, undo, regeneration and failed turns rebuild from the app's transcript; a turn stopped by the user or cut off by a bridge restart resumes its native session. While Claude thinks or writes a long tool call, the bridge sends a no-op event every 10 seconds so the app's stall timer does not fire.
- Model switching. Switching Claude models between turns resumes the same native session on the new model; that first request cannot reuse the previous model's cache. If GPT answered in between, its messages and tool activity are passed to the resumed session as history. A compaction keeps the model the session ran on, so its cache still applies.
- WebSocket relay. The bridge connects to OpenAI during the app's handshake, so the headers the app reads from it (turn routing, server model) arrive unchanged, then routes each
response.createby model. For Claude it rebuilds the full input from the increments the app sends after the first request, answers prewarm requests without inference, and treatsresponse.interruptas a Stop. A Claude compaction summary is a sealed item only the bridge can open, so it is turned back into text before a GPT request leaves for OpenAI.
Development
npm test # 148 tests with stand-ins for Claude Code and OpenAI
node e2e/live.mjs # fifteen short checks with real Claude Code
License
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found