MCP server for ChatGPT macOS desktop app — no focus stealing, clipboard paste, configurable polling
Project description
chatgpt-mcp
MCP server that automates the ChatGPT macOS desktop app. Access ChatGPT Pro features (o1, deep research, GPTs) from Claude Code or any MCP client — no API keys needed.
Forked from xncbf/chatgpt-mcp with significant fixes.
Why
ChatGPT Pro has models and features (o1 pro, deep research, custom GPTs) that aren't available via API. This server bridges the gap by automating the desktop app through AppleScript and the macOS accessibility tree.
Key differences from upstream
- No focus stealing on reads — reads the AX tree without activating ChatGPT, so you can keep working while it polls for completion
- Clipboard paste instead of per-character keystroke injection — instant, preserves formatting
- Configurable polling — quick mode (5s poll, 60s timeout) for fast queries, deep mode (15min poll, 1h timeout) for o1/deep research
- Text stability detection — fallback completion signal when the button heuristic misses (3 consecutive identical reads = done)
- Subprocess timeouts — all AppleScript calls timeout after 30s instead of hanging forever
How it works
- Send: activates ChatGPT once, opens new conversation (Cmd+N) or navigates to an existing one, pastes prompt via clipboard
- Poll: reads the accessibility tree passively (no focus steal) looking for two completion signals:
- Button heuristic: model selection button followed by voice/transcribe button = idle state
- Text stability: conversation text unchanged for 3 consecutive reads
- Return: extracts all static text from the AX tree, cleans up UI artifacts, returns the response
Conversation management
- List: reads the sidebar AX tree without activating ChatGPT — no focus steal
- Navigate: activates ChatGPT once (clicking requires focus), clicks the matching sidebar item
- Read: navigates to a conversation then reads its content via the existing passive reader
Install
pip install chatgpt-desktop-mcp
Or run without installing:
uvx chatgpt-desktop-mcp
The CLI entry point is chatgpt-mcp (both chatgpt-mcp and chatgpt-desktop-mcp work).
Configure with Claude Code
claude mcp add chatgpt -s user -- uvx chatgpt-desktop-mcp
Requirements
- macOS (AppleScript + accessibility tree)
- ChatGPT desktop app installed and logged in
- Accessibility permission granted to your terminal (System Settings > Privacy & Security > Accessibility)
Tools
ask_chatgpt_tool
Send a prompt to ChatGPT and wait for the response. Opens a new conversation by default, or continues an existing one if conversation is specified.
| Parameter | Type | Default | Description |
|---|---|---|---|
prompt |
str | required | The message to send |
quick |
bool | False |
True: 5s poll, 60s timeout. False: 15min poll, 1h timeout |
conversation |
str | "" |
Optional conversation title to continue (substring match, case-insensitive). If empty, starts a new conversation |
get_chatgpt_response_tool
Read the current conversation without sending anything. Waits for completion using deep polling.
list_conversations_tool
List conversations from the ChatGPT sidebar without stealing focus. Returns numbered titles that can be used with read_conversation_tool or the conversation parameter of ask_chatgpt_tool.
read_conversation_tool
Navigate to an existing conversation by title and read its full content.
| Parameter | Type | Default | Description |
|---|---|---|---|
conversation |
str | required | Title to match (substring, case-insensitive) |
Activates ChatGPT once to click the sidebar item, then reads the conversation text.
Limitations
- English-only button detection — the AppleScript checks for English button labels ("voice", "Transcribe", "model", "GPT"). Non-English ChatGPT UI will break completion detection.
- Completion detection is heuristic — it works by reading button sequences and text stability, not an API signal. Edge cases exist.
- Clipboard race window — there's a ~0.7s window during send where the clipboard contains your prompt. Restored afterwards.
- macOS only — relies on AppleScript and the accessibility tree.
- One conversation at a time — the desktop app has one active conversation. Concurrent sends will collide.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chatgpt_desktop_mcp-0.3.5.tar.gz.
File metadata
- Download URL: chatgpt_desktop_mcp-0.3.5.tar.gz
- Upload date:
- Size: 15.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd065e99c09e247dfe98bdb577839120ab8d62ace6e8fd230f60ce6b10501c13
|
|
| MD5 |
1d01a5668723d34262f4de6c31c2423c
|
|
| BLAKE2b-256 |
f04989badf67faab481eda9c4f86083d7bd82bfa7ad25edab2b3edf1c1668ac9
|
Provenance
The following attestation bundles were made for chatgpt_desktop_mcp-0.3.5.tar.gz:
Publisher:
publish.yaml on mark-liu/chatgpt-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatgpt_desktop_mcp-0.3.5.tar.gz -
Subject digest:
fd065e99c09e247dfe98bdb577839120ab8d62ace6e8fd230f60ce6b10501c13 - Sigstore transparency entry: 1248727198
- Sigstore integration time:
-
Permalink:
mark-liu/chatgpt-mcp@2229e8abded845f45964bbc01388a2eb9c62fe5c -
Branch / Tag:
refs/tags/v0.3.5 - Owner: https://github.com/mark-liu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@2229e8abded845f45964bbc01388a2eb9c62fe5c -
Trigger Event:
push
-
Statement type:
File details
Details for the file chatgpt_desktop_mcp-0.3.5-py3-none-any.whl.
File metadata
- Download URL: chatgpt_desktop_mcp-0.3.5-py3-none-any.whl
- Upload date:
- Size: 15.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d85d28a5b9da7eb855742984ca058540f370a4865664e9c744afdbb5c36e63b
|
|
| MD5 |
d21e782c8b8d64d40e3a4bcd5f7d7dab
|
|
| BLAKE2b-256 |
50fd4e7ebdeace4d8d899aedf443135a284b33347a53f52e15baaf124d70eded
|
Provenance
The following attestation bundles were made for chatgpt_desktop_mcp-0.3.5-py3-none-any.whl:
Publisher:
publish.yaml on mark-liu/chatgpt-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatgpt_desktop_mcp-0.3.5-py3-none-any.whl -
Subject digest:
6d85d28a5b9da7eb855742984ca058540f370a4865664e9c744afdbb5c36e63b - Sigstore transparency entry: 1248727202
- Sigstore integration time:
-
Permalink:
mark-liu/chatgpt-mcp@2229e8abded845f45964bbc01388a2eb9c62fe5c -
Branch / Tag:
refs/tags/v0.3.5 - Owner: https://github.com/mark-liu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@2229e8abded845f45964bbc01388a2eb9c62fe5c -
Trigger Event:
push
-
Statement type: