# Rosetta

> Programmatic access to ChatGPT (incl. Pro) by translating between an auth-holder Chrome page and a Node API. CDP Fetch interception + WebSocket second-leg streaming. Ships an MCP server for Claude Code / Codex / Cline.

- **Type:** MCP server
- **Install:** `agentstack add mcp-syntaxsmith-rosetta`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SyntaxSmith](https://agentstack.voostack.com/s/syntaxsmith)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [SyntaxSmith](https://github.com/SyntaxSmith)
- **Source:** https://github.com/SyntaxSmith/rosetta

## Install

```sh
agentstack add mcp-syntaxsmith-rosetta
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# rosetta

  

Programmatic access to **ChatGPT (incl. Pro)** from Node, by translating between an auth-holder Chrome page and a clean API. 

> Like the Rosetta Stone: the Pro web protocol on one side, a regular Node API on the other.

## What it does

- **Pro support**: `runConversation({ model: "gpt-6-pro", ... })` follows the `stream_handoff` event, opens the WebSocket second leg, and aggregates the live CoT until `message_stream_complete` — same UX as the chatgpt.com UI but returnable from Node.
- **Instant models too**: non-Pro slugs (`gpt-5-6` default; `gpt-5-5` is the web UI's 极速 lane) return in seconds via the same path.
- **Multi-turn**: pass `conversationId` + `parentMessageId` (or use `recall: "thread"` for persistence).
- **Concurrency**: each call spawns its own tab; many calls can stream in parallel.
- **Live token deltas**: optional `onChunk(delta)` callback streams the CoT as it arrives.
- **Idle-timeout watchdog**: long thinks (15 min+) keep going as long as the WS sends heartbeats; only true silence kills the call.

## Install

```bash
pnpm add @syntaxsmith/rosetta
# or
npm i @syntaxsmith/rosetta
```

Requires Node ≥ 22.

## Setup: launch Chrome

You need a Chrome with `--remote-debugging-port` open and **logged in to chatgpt.com once**. Profile is reused across runs.

### Linux

```bash
chromium \
  --remote-debugging-port=9222 \
  --user-data-dir=$HOME/.rosetta/profile \
  --no-first-run --no-default-browser-check \
  https://chatgpt.com/
```

### macOS

```bash
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --remote-debugging-port=9222 \
  --user-data-dir=$HOME/.rosetta/profile \
  --no-first-run --no-default-browser-check \
  https://chatgpt.com/
```

### Windows (PowerShell)

```powershell
& "C:\Program Files\Google\Chrome\Application\chrome.exe" `
  --remote-debugging-port=9222 `
  --user-data-dir=$env:USERPROFILE\.rosetta\profile `
  --no-first-run --no-default-browser-check `
  https://chatgpt.com/
```

Sign in once; the profile persists. Subsequent runs reuse the cookies.

## CLI

```bash
# default = Pro (gpt-6-pro, GPT-6)
rosetta run "Explain idempotent matrices in three sentences."

# cheaper tier via explicit slug
rosetta run -m gpt-5-6 "Reply with the single word: pong"

# stream live tokens
rosetta run --stream "Sketch a 3-paragraph plan for X"

# threaded recall — successive calls build on the same conversation
rosetta run --recall research "what's the prior on Y?"
rosetta run --recall research "given that, what would change?"

# inspect / clear persisted threads
rosetta threads
rosetta forget research

# list models the account exposes
rosetta probe

# attach a local file (repeatable) — image, PDF, CSV, code, ...
rosetta run --attach photo.png "What's in this image?"
rosetta run --attach report.pdf "Quote the third paragraph verbatim."
rosetta run --attach a.csv --attach b.csv "Merge these and find duplicates."
```

Common flags: `--port ` (default 9222), `--host ` (default 127.0.0.1), `--model `.

## Programmatic API

```ts
import { openSession, runConversation } from "@syntaxsmith/rosetta";

const session = await openSession({ port: 9222 });

// One-shot
const result = await runConversation(session, {
  prompt: "What's the area of a triangle with sides 3, 4, 5?",
  model: "gpt-6-pro",           // Pro (GPT-6)
});
console.log(result.text);       // "6"
console.log(result.modelSlug);  // "gpt-6-pro"
console.log(result.tookMs);     // ~30000 for trivial prompts

// Streaming
await runConversation(
  session,
  { prompt: "...", model: "gpt-6-pro" },
  { onChunk: (delta) => process.stdout.write(delta) },
);

// Multi-turn via persistent recall thread
await runConversation(
  session,
  { prompt: "Remember the token BANANA-77.", model: "gpt-5-6", recall: "demo" },
);
const r2 = await runConversation(
  session,
  { prompt: "What was the token I asked you to remember?", model: "gpt-5-6", recall: "demo" },
);
// r2.text === "BANANA-77"

// File attachments — same UX as drag-dropping in the web composer.
// Each file is fed into ChatGPT's hidden file input via DataTransfer
// and the page's React pipeline handles the rest. 20 MB per-file cap.
const r3 = await runConversation(session, {
  prompt: "What color is this image?",
  model: "gpt-5-6",
  attachments: [{ path: "./fixtures/red-square.png" }],
});

// Multiple files (sequential, fail-fast) + Pro for harder tasks.
await runConversation(session, {
  prompt: "Cross-reference these two PDFs and list contradictions.",
  model: "gpt-6-pro",
  attachments: [
    { path: "./paper-v1.pdf" },
    { path: "./paper-v2.pdf" },
  ],
});

await session.close();
```

### Concurrency

```ts
// 3 prompts in parallel — each gets its own Chrome tab.
const results = await Promise.all(
  ["red", "green", "blue"].map((color) =>
    runConversation(session, {
      prompt: `Reply with the single word: ${color}`,
      model: "gpt-5-6",
    }),
  ),
);
// 3/3 succeed; tabs auto-clean.
```

The typing phase (Chrome focus) is mutex-serialized; response streaming runs in parallel. Expected parallelism factor against instant models: ~0.8.

## Architecture

```
┌──────────────────┐                ┌──────────────────────────────┐
│ Node (rosetta)   │      CDP       │  Chrome (chatgpt.com page)   │
│                  │ ◄──────────►   │                              │
│  runConversation │                │  composer + sentinel SDK +   │
│   ├─ Fetch.req.  │                │  axios interceptor (all auth │
│   │   Paused →   │                │   headers attached HERE)     │
│   │   rewrite    │                │                              │
│   │   body       │   ──────►      │  POST /f/conversation         │
│   │              │                │   ◄────── bootstrap SSE       │
│   ├─ stream_     │                │                              │
│   │   handoff    │                │                              │
│   │   detected → │                │                              │
│   ├─ open WS     │ ─────►         │  wss://ws.chatgpt.com/...    │
│   │   subscribe  │                │     (encoded_item frames)    │
│   ├─ aggregate   │                │                              │
│   │   until      │                │                              │
│   │   message_   │                │                              │
│   │   stream_    │                │                              │
│   │   complete   │                │                              │
│   └─ return text │                │                              │
└──────────────────┘                └──────────────────────────────┘
```

The Chrome page generates **all** auth proofs (Authorization Bearer, X-OAI-IS, OAI-* headers, OpenAI-Sentinel-* tokens). We only override the request body and consume the response — so we don't reverse-engineer the rotating auth surface.

## MCP integration (Claude Code, Codex, Cline, …)

rosetta ships an MCP server (`rosetta-mcp` binary) that speaks Model Context Protocol over stdio. Any MCP-aware host — Claude Code, OpenAI Codex CLI, Cline, Continue, Zed, Cursor — can register it as a tool source. The server exposes one tool:

```
consult({
  prompt:           string,    // required
  pro?:             boolean,   // redundant — gpt-6-pro is already the default
  model?:           string,    // explicit slug (overrides `pro`)
  thinkingEffort?:  string,    // "standard" | "extended" | "max" (the UI's 中/高/极高 lanes)
  fresh?:           boolean,   // start a new conversation (see "Conversation model" below)
  recall?:          string,    // disk-persisted named thread (cross-session)
  conversationId?:  string,    // continue an explicit conversation by id
  parentMessageId?: string,    // branch from a specific message id
  attachments?:     string[],  // local file paths (PNG/PDF/CSV/...) — sequential upload, 20 MB per-file
}) → assistant text
```

### Conversation model

**Each `rosetta-mcp` process IS one conversation by default.** Two `consult` calls in a row from the same MCP session continue the same chatgpt.com conversation — multi-turn context retained automatically. Process exit (host shutdown, restart) = clean slate.

| You want… | What to pass |
|---|---|
| Continue this session's conversation (default) | nothing — just `{prompt}` |
| Continue with follow-ups, revisions, related subtasks, or new evidence | nothing — just `{prompt}` |
| Start a genuinely unrelated, independent adversarial/zero-context, or replacement conversation | `fresh: true` |
| Long-lived context that survives MCP restarts | `recall: "research-on-X"` |
| Reset a long-lived context | `fresh: true, recall: "research-on-X"` |
| Continue an arbitrary existing conversation | `conversationId: ""` |

Default to continuation. Do not pass `fresh` merely because the next prompt is
self-contained or moves to a related subtask. Reserve it for a genuinely
unrelated problem, an intentionally independent adversarial/zero-context
assessment, an overlong or contaminated thread, or an explicit user request.

Each host agent/MCP process has its own implicit conversation. That isolates
Claude Code session A from session B, but it also means Codex subagents or agent
threads may not share the root agent's implicit context. Use one stable
descriptive `recall` name when context must cross those boundaries or survive a
host restart.

### Claude Code skill

`skills/rosetta-consult/` ships a ready-made [Claude Code skill](https://docs.anthropic.com/en/docs/claude-code) that teaches Claude when (and when not) to reach for `consult` — model/effort selection, threading knobs, and prompt patterns. Install it by copying into your skills directory:

```bash
cp -r skills/rosetta-consult ~/.claude/skills/
```

### Configuration via env

| Variable | Default | Purpose |
|---|---|---|
| `ROSETTA_CDP_PORT` | `9222` | CDP debug port of the auth-holder Chrome |
| `ROSETTA_CDP_HOST` | `127.0.0.1` | CDP debug host |
| `ROSETTA_TIMEOUT_MS` | `3600000` | Wall-clock cap per call in ms (0 disables) |

The MCP server emits `notifications/progress` once a minute while a call runs
(elapsed time + streamed chars). This matters for hosts with idle watchdogs —
Claude Code aborts stdio tool calls that stay silent for 30 min, which plain
Pro CoT can exceed — and shows live progress in the host UI.

### Claude Code

Add via the CLI:

```bash
claude mcp add rosetta -- npx -y -p @syntaxsmith/rosetta rosetta-mcp
```

> The `-p` flag is required: this package ships two bins (`rosetta`, `rosetta-mcp`) and without `-p` npx runs the same-named bin (`rosetta`) and treats `rosetta-mcp` as a CLI subcommand.

Or hand-edit your global config (`~/.claude.json` on most platforms) and add:

```jsonc
{
  "mcpServers": {
    "rosetta": {
      "command": "npx",
      "args": ["-y", "-p", "@syntaxsmith/rosetta", "rosetta-mcp"],
      "env": {
        "ROSETTA_CDP_PORT": "9222"
      }
    }
  }
}
```

Reload Claude Code. You'll now have a `consult` tool. Ask Claude: *"Use the consult tool to ask ChatGPT Pro to solve this."* Claude will call `consult({ prompt: "...", pro: true })` and stream the answer back.

### OpenAI Codex CLI

Edit `~/.codex/config.toml`:

```toml
[mcp_servers.rosetta]
command = "npx"
args = ["-y", "-p", "@syntaxsmith/rosetta", "rosetta-mcp"]
tool_timeout_sec = 1800

[mcp_servers.rosetta.env]
ROSETTA_CDP_PORT = "9222"
```

Restart Codex (or run `codex mcp reload`). The tool surfaces as `rosetta__consult`.

### Cline (VS Code)

Open Cline's *MCP Servers* panel → *Edit MCP Settings*, then add:

```jsonc
{
  "mcpServers": {
    "rosetta": {
      "command": "npx",
      "args": ["-y", "-p", "@syntaxsmith/rosetta", "rosetta-mcp"],
      "env": { "ROSETTA_CDP_PORT": "9222" },
      "disabled": false,
      "autoApprove": ["consult"]   // optional: skip the per-call confirmation
    }
  }
}
```

### Local dev (without npm install)

If you're hacking on rosetta itself, point the host at the source instead of the published package:

```jsonc
{
  "mcpServers": {
    "rosetta": {
      "command": "node",
      "args": ["/absolute/path/to/rosetta/dist/bin/rosetta-mcp.js"]
    }
  }
}
```

Run `pnpm build` in the rosetta repo first so `dist/` exists.

### Common gotchas

- **Chrome must be running** with `--remote-debugging-port=` *before* the host invokes the tool. Hosts spawn the MCP server lazily; the server fails fast with a clear `auth error [not-logged-in]` if Chrome isn't there.
- **Pro thinking blocks the tool call** — Claude Code shows a long-running tool spinner; Codex shows nothing until done. The default rosetta idle timeout (90 s of WS silence) keeps it alive across normal CoT, but can be tuned via the programmatic API if you wrap the server.
- **Don't share Chrome between concurrent MCP requests** unless you've got CPU to spare — each `consult` call spawns a fresh tab and serializes the typing phase via mutex; concurrency is supported but typing latency stacks.

## Caveats

- ChatGPT's wire shapes shift periodically. The implementation tracks the protocol as of **2026-09** (model lineup: the picker's default 即时 lane sends `gpt-5-6` with no effort field, thinking lanes use `gpt-5-6-thinking`, and the Pro lane moved to **`gpt-6-pro`** (GPT-6) — all per-tier slugs hidden from `/backend-api/models`; fresh chats carry `parent_message_id: "client-created-root"`; bootstrap SSE emits `stream_handoff`; second-leg WS uses `encoded_item` chunks; send pipeline interleaves `/conversation/init`, `/f/conversation/prepare`, `/sentinel/chat-requirements`, autocompletions, and analytics before the actual `/f/conversation` POST — observed click-to-send latency commonly 15–25 s on multi-turn Pro, so we wait for `prepare` as the "click landed" signal rather than redoing). Wire-shape regressions are caught by a captured-frame replay test.
- **Reasoning level (`thinking_effort`)**: the 2026-09 picker is one popover (`composer-intelligence-picker-content`) with a 5-position 能力 slider plus model-family radios (最新 / GPT-5.6 Sol / GPT-5.5). Captured lane mapping (family 最新): 即时 → `gpt-5-6` (no effort field), 中/高/极高 → `gpt-5-6-thinking` + `standard`/`extended`/`max`, Pro → `gpt-6-pro` + `standard`. rosetta auto-aligns the field to the pinned model (`gpt-6-pro` → `standard`, `gpt-5-5-pro` → `extended`, others drop it — and `-pro` slugs *emit* their value even when the page omitted the field, matching the Pro lane wire) so an instant call doesn't inherit the account's thinking-lane effort; pass `thinkingEffort` (CLI `--effort`, e.g. `max`) to pick a lane explicitly.
- **Attachments**: per-file 20 MB cap (DataTransfer payload, base64-encoded over CDP). Sequential — multiple files attach one at a time, fail-fast if any errors. Pro and instant models accept different file types (vision-only vs file-search-only); if you attach a type the current model doesn't support, the call fails with `upload-timeout` because the page never renders the chip.
- Per-call tabs and the typing mutex assume one Chrome browser; for high concurrency consider multiple Chrome instances on different ports.
- Soft-delete on cleanup keeps the conversation list clean; persisted recall threads opt out of soft-delete automatically.
- Not affiliated with OpenAI. Use respectfully and within your account's terms of service.

## Acknowledgments

rosetta descends from **[oracle](https://github.com/steipete/oracle)** — the
predecessor that pioneered the auth-holder Chrome / CDP-orchestrator pattern
this library extends to Pro thinking. The cross-platform `~/.rosetta/` profile
convention, the `httpRequestViaChrome` shim that side-steps Cloudflare TLS
fingerprinting, and the conversation soft-delete dance are all lifted directly
from oracle's playbook. Thanks to that project for figuring out the hard parts
first.

## License

MIT
## Website
欢迎访问LINUX.DO社区[https://linux.do/]

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SyntaxSmith](https://github.com/SyntaxSmith)
- **Source:** [SyntaxSmith/rosetta](https://github.com/SyntaxSmith/rosetta)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-syntaxsmith-rosetta
- Seller: https://agentstack.voostack.com/s/syntaxsmith
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
