
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
chatgpt-desktop-mcp
Advanced tools
MCP server exposing the official ChatGPT Desktop (Ubuntu) Chat surface as tools via AT-SPI
Turn your local, logged-in ChatGPT Desktop app (Ubuntu/Linux) into an MCP server — expose the official desktop client's normal Chat mode as MCP tools for Claude Code / Cursor / any MCP client.
把本机已登录的官方 ChatGPT Desktop(Ubuntu/Linux)变成 MCP Server, 供 Claude Code / Cursor / 任意 MCP Client 调用。
⚠️ Technical Validation PoC (
compliance_mode: poc_only). Completed 100-round stability validation, but still considered experimental software. Please do not use for bypassing login/MFA/rate limits or bulk scraping; confirm applicable OpenAI terms separately before production use.
English | 中文
request_id + operation store + commit verificationClaude Code / Cursor / Custom Agent
│ MCP (stdio)
▼
chatgpt-desktop-mcp (Node.js/TypeScript)
│ JSONL over stdio
▼
Python pyatspi sidecar (atspi_worker.py)
│ AT-SPI accessibility + clipboard + xdotool
▼
Official ChatGPT Desktop on Ubuntu
Why AT-SPI? CDP is disabled in the app's production build (renderer-level commands unresponsive) — see docs/ADR-001-adapter-selection.md.
gi (bundled with Ubuntu Desktop; otherwise
sudo apt install python3-gi gir1.2-atspi-2.0 gir1.2-gtk-3.0)xdotool (sudo apt install xdotool)The Chromium renderer does not expose its accessibility tree by default:
chatgpt --force-renderer-accessibility
Without this flag, chatgpt_health / probe return ADAPTER_BROKEN with a
restart hint. This project never silently kills or restarts the ChatGPT process.
git clone https://github.com/cantbeblank96/chatgpt-mcp.git
cd chatgpt-mcp/chatgpt-desktop-mcp
npm install
npm run build
npm test # offline unit tests
npm run probe # verify a11y access to the running app (needs GUI session)
.mcp.json{
"mcpServers": {
"chatgpt-desktop": {
"command": "node",
"args": ["/absolute/path/to/chatgpt-desktop-mcp/dist/main.js"]
}
}
}
~/.cursor/mcp.json or project .cursor/mcp.json{
"mcpServers": {
"chatgpt-desktop": {
"command": "node",
"args": ["/absolute/path/to/chatgpt-desktop-mcp/dist/main.js"]
}
}
}
Runnable examples: see chatgpt-desktop-mcp/examples/ directory for configuration templates.
// chatgpt_ask
{
"prompt": "Explain KV cache in one sentence",
"new_chat": true,
"request_id": "task-42-step-1", // always provide one for idempotency
"timeout_ms": 180000
}
Response:
{
"ok": true,
"conversation_handle": "cgpt_0679dcf5eb792699",
"message_id": "m_3f9a…",
"text": "……",
"adapter": "atspi",
"duration_ms": 17353,
"warnings": []
}
Use chatgpt_continue with the same conversation_handle for follow-up turns.
RATE_LIMITED).
连续提问建议间隔 ≥25 秒,避免触发 OpenAI 账号限流。USER_INTERFERENCE_DETECTED and the call aborts safely — retry after
the app settles.
调用期间不要手动操作 ChatGPT 窗口;如触发干扰检测,等界面稳定后重试。| Tool | Description |
|---|---|
chatgpt_health | Read-only health check: app process, a11y flag, chat surface, composer, current mode |
chatgpt_new_chat | Start a new conversation; returns an MCP-maintained conversation_handle (cgpt_*) |
chatgpt_ask | Send a prompt and wait for this turn's new reply (the core tool) |
chatgpt_continue | Continue within a conversation_handle (fingerprint-verified) |
chatgpt_cancel | Press Stop on an in-flight generation; no-op (cancelled=false) when idle |
chatgpt_list_conversations | Read-only enumeration of visible sidebar conversation titles (virtualized list) |
request_id + operation store + commit verification.
Retrying the same request_id never re-sends; a succeeded request replays its
result verbatim; when delivery cannot be confirmed, UNKNOWN_COMMIT_STATE is
returned for manual review.new assistant message present AND generation stopped (Stop button gone + status bar) AND text stable for stabilization_ms (default 1000ms).chatgpt_cancel bypasses the mutex so it can actually
interrupt a long ask that holds the lock (the sidecar is single-threaded and
serial, so this is concurrency-safe).USER_INTERFERENCE_DETECTED (requires ≥2 consecutive observations — debounced);
it never blindly keeps clicking.--classname ChatGPT
exactly — never by window title (a browser tab with the same title would
otherwise receive keystrokes).RATE_LIMITED; stale banners
present before sending are ignored.| Variable | Default | Description |
|---|---|---|
CDGMCP_PYTHON | /usr/bin/python3 | Sidecar interpreter (must be system Python with gi — not conda) |
CDGMCP_WORKER_SCRIPT | built-in | Override atspi_worker.py path |
CDGMCP_ASK_TIMEOUT_MS | 180000 | Default ask timeout |
CDGMCP_STABILIZATION_MS | 1000 | Reply text stabilization window |
CDGMCP_POLL_INTERVAL_MS | 500 | Poll interval while waiting for a reply |
CDGMCP_STATE_DIR | ~/.local/share/chatgpt-mcp | Operation/conversation store directory (0700) |
CDGMCP_LOG_LEVEL | info | debug/info/warn/error |
CDGMCP_LOG_FULL_CONTENT | unset | Set to 1 to log full prompts/replies |
npm test # 14 offline unit tests
npm run test:smoke # real-GUI E2E: initialize → list → health → new_chat →
# ask → continue → idempotent replay of the same request_id
node tests/smoke/e2e-chaos.mjs # chaos: cancel mid-generation, timeout releases the mutex
node tests/smoke/stress-100.mjs # 100-round stress driver (segmented, resumable)
Test reports (100-round acceptance, Phase 3 capability + injection) are kept locally; summary results live in CHANGELOG.md. Note: E2E tests require a running ChatGPT Desktop instance with accessibility enabled.
CDGMCP_LOG_FULL_CONTENT=1).operations.json / conversations.json) are 0600; directory 0700.npm run probe and npm run test:smoke as regression.--force-renderer-accessibility; no Wayland / headless.你说: / ChatGPT 说: headings and paragraph
nodes in the accessibility tree (zh + en); rich text (code blocks, quotes) is
returned as concatenated plain text.RATE_LIMITED is returned). This is a server-side constraint, not a bug —
in practice, ≥25s between turns runs stably.| Symptom | Cause & Fix |
|---|---|
ADAPTER_BROKEN on probe/health | App not started with --force-renderer-accessibility — restart it with the flag |
gi import error from the sidecar | Wrong interpreter (e.g. conda). Set CDGMCP_PYTHON=/usr/bin/python3 |
| Typing/paste appears to fail | IME in Chinese mode swallows synthetic keys (preedit). Fixed in v0.1.0 via an Escape pre-clear; keep the app window unobstructed |
USER_INTERFERENCE_DETECTED | You interacted with the app mid-flight — retry after the app settles |
RATE_LIMITED | OpenAI throttling — wait and slow down your request cadence |
| probe fails / timeouts | App not started with --force-renderer-accessibility; or session is Wayland (X11 required) — check with echo $XDG_SESSION_TYPE |
| clipboard not restored | In rare cases may need manual intervention; verify clipboard history |
| gitignore 中仍含 artifacts/ | artifacts/ 探测证据本地保留;确认 .gitignore 已加入 artifacts/ |
src/
main.ts # entry: MCP stdio server / probe subcommand
mcp/ server.ts tools.ts schemas.ts
core/ orchestrator.ts mutex.ts errors.ts
operation-store.ts conversation-store.ts
adapters/
interface.ts # ChatGPTAdapter abstraction
atspi/adapter.ts sidecar-client.ts
atspi/python/atspi_worker.py # the only component touching AT-SPI/xdotool
config/ logging/
tests/unit/ # offline unit tests
tests/smoke/e2e-smoke.mjs # real-GUI E2E smoke
tests/smoke/e2e-chaos.mjs # chaos injection
tests/smoke/stress-100.mjs # 100-round stress driver
scripts/worker_repl.py # manual sidecar debugging
scripts/audit_conv.py # virtualization-safe conversation audit
docs/ADR-001-adapter-selection.md
本项目通过 AT-SPI 无障碍接口驱动本机已登录的官方 ChatGPT Desktop, 将其普通 Chat 模式封装为 6 个 MCP tools。核心保证:
request_id 幂等 + 操作存储 + 提交验证完整中文设计文档:notes/Ubuntu_ChatGPT_Desktop_MCP_Server_技术设计方案_v1.0.md。
See CONTRIBUTING.md. Bug reports and capability-test evidence for new ChatGPT Desktop versions are especially welcome.
MIT © xukaiming. This project is not affiliated with or endorsed by OpenAI. ChatGPT is a trademark of OpenAI, Inc.
FAQs
MCP server exposing the official ChatGPT Desktop (Ubuntu) Chat surface as tools via AT-SPI
The npm package chatgpt-desktop-mcp receives a total of 46 weekly downloads. As such, chatgpt-desktop-mcp popularity was classified as not popular.
We found that chatgpt-desktop-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.