Skip to main content

gptty

English version. Russian version: README.ru.md

Terminal client for existing ChatGPT web sessions.

[!WARNING] Not the official OpenAI API. Uses an existing ChatGPT web session. Web backend behavior may change.

gptty is the successor to webchat-openai-cli. The project is being migrated from a standalone script into a terminal-native product powered by chatgpt-web-adapter.

The package distribution name is gptty-web because the PyPI name gptty is already occupied. The installed command is still gptty.

Product Direction

SDK = chatgpt-web-adapter
CLI = gptty

gptty is intended for terminal workflows:

gptty chat
gptty auth status
gptty auth refresh --mode wait
gptty ask "explain this error"
gptty ask --image screenshot.png "describe this UI"
git diff | gptty ask "review this patch"
gptty attach https://chatgpt.com/c/...
gptty send "continue from here"
gptty messages --last 5 --format markdown
gptty status --format json
gptty export --format markdown --output conversation.md

gptty ask, gptty send, the default gptty chat path, conversation inspection commands, and conversation export are SDK-backed. The legacy interactive runtime remains available through gptty chat --legacy while feature parity is migrated in later PRs.

Current Features

  • minimal SDK-backed interactive chat through gptty chat
  • inspect auth data through gptty auth status
  • refresh auth_data.json through gptty auth refresh
  • attach existing conversations through gptty attach
  • send prompts to attached, explicit, or new conversations through gptty send
  • SDK-backed image prompts through gptty ask --image and gptty send --image
  • inspect attached or explicit conversations through gptty messages and gptty status
  • export attached or explicit conversations through gptty export
  • output modes for messages, status, send, and export: plain, json, markdown
  • legacy interactive chat fallback through gptty chat --legacy
  • one-shot SDK-backed prompts through gptty ask
  • centralized stdin policy for pipe-friendly prompts
  • pipe-friendly prompts, for example git diff | gptty ask "review this patch"
  • streaming replies in the terminal
  • minimal SDK chat state file: gptty_state.json
  • legacy state file for --legacy: webchat_state.json
  • atomic writes for local state and auth_data.json
  • legacy image prompts through /img in gptty chat --legacy
  • auto and wait auth capture modes
  • English and Russian CLI localization in the legacy runtime

Requirements

  • Python 3.10+
  • system curl available in PATH
  • Chrome or Chromium for auth capture
  • valid auth_data.json for an existing ChatGPT web session

Installation

Base install:

python -m pip install gptty-web

Install with browser auth-capture dependencies:

python -m pip install "gptty-web[auth]"

From checkout for development:

python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e ".[auth,test]"

On Windows cmd.exe:

python -m venv venv
venv\Scripts\activate.bat
python -m pip install --upgrade pip
python -m pip install -e ".[auth,test]"

Get auth_data.json

Check the current auth file without opening a browser:

gptty auth status

Use JSON output for scripts:

gptty auth status --format json

Refresh auth data through the CLI wrapper:

gptty auth refresh --mode wait

Fast mode for an already logged-in browser session:

gptty auth refresh --mode auto

In wait mode the browser stays open until the chat is ready. After that, send any message manually in the browser to trigger auth capture.

Optional: override the one-shot probe prompt used by auto mode:

gptty auth refresh --mode auto --probe-prompt "Ping"

The legacy script entrypoints remain available from a checkout:

venv\Scripts\python.exe auth_fetcher.py --mode wait
venv\Scripts\python.exe auth_fetcher_wait.py

After a successful capture, auth_data.json will appear in the project directory. See docs/auth.md for lifecycle details and troubleshooting notes.

Run the CLI

Attach an existing ChatGPT conversation:

gptty attach https://chatgpt.com/c/...

Send a prompt to the attached conversation:

gptty send "continue from here"

Pipe stdin into the attached conversation:

git diff | gptty send "review this patch"

Send to an explicit conversation without changing first through attach:

gptty send --to https://chatgpt.com/c/... "continue there"

Start a new conversation and store its returned conversation reference in gptty_state.json:

gptty send --new "start a new conversation"

Send image prompts through the SDK-backed commands:

gptty ask --image screenshot.png "describe this UI"
gptty ask --image https://example.com/chart.png "summarize this chart"
gptty send --image diagram.webp "continue with this image"
gptty send --image before.png --image after.png "compare these images"

--image accepts local file paths, http(s) URLs, and data URIs. It can be used more than once. Supported SDK image formats are PNG, JPEG/JPG, GIF, and WebP.

Inspect the attached conversation:

gptty messages --last 5
gptty status

Use JSON or Markdown output for scripts and exports:

gptty messages --last 5 --format json
gptty messages --last 5 --format markdown
gptty status --format json
gptty send --format json "summarize the current thread"
gptty export --format markdown --output conversation.md
gptty export --format json --output conversation.json

When gptty send uses --format json or --format markdown, streaming is disabled internally so the output stays complete and parseable.

You can also inspect or export an explicit conversation without attaching it:

gptty messages https://chatgpt.com/c/... --last 5
gptty status https://chatgpt.com/c/...
gptty export https://chatgpt.com/c/... --last 20 --output conversation.md

gptty export defaults to Markdown output. When --output points to an existing file, add --overwrite to replace it.

Minimal SDK-backed interactive chat:

gptty chat

The SDK-backed chat loop currently supports:

/help
/new
/exit
/quit

Run the full legacy interactive runtime:

gptty chat --legacy

One-shot SDK-backed prompt:

gptty ask "explain this error"

Pipe stdin into the prompt:

git diff | gptty ask "review this patch"

When stdin and a prompt are both present, gptty ask and gptty send send stdin as context, followed by the prompt under User prompt:.

Force reading stdin:

gptty ask --stdin "summarize this input"

Ignore piped stdin:

cat noisy.log | gptty ask --no-stdin "explain this from the prompt only"

Disable streaming and print the final response:

gptty ask --no-stream "summarize this session"
gptty send --no-stream "summarize this conversation"

Legacy entrypoint, still supported from a checkout:

python main.py

You can also override local paths:

gptty auth status --auth ./auth_data.json
gptty auth refresh --auth ./auth_data.json --mode wait
gptty attach https://chatgpt.com/c/... --auth ./auth_data.json --state ./gptty_state.json
gptty send --auth ./auth_data.json --state ./gptty_state.json "hello"
gptty send --auth ./auth_data.json --state ./gptty_state.json --image ./screenshot.png "describe this"
gptty export --auth ./auth_data.json --state ./gptty_state.json --output conversation.md
gptty chat --auth ./auth_data.json --state ./gptty_state.json
gptty chat --legacy --auth ./auth_data.json --state ./webchat_state.json
gptty ask --auth ./auth_data.json --timeout 120 "hello"

Useful Legacy Chat Commands

Available in gptty chat --legacy:

  • /help
  • /models
  • /new
  • /list
  • /use <chat_id>
  • /reset
  • /img <path_or_url> :: <prompt>
  • /settings
  • /model <name>
  • /lang <en|ru>
  • /ws <true|false>
  • /effort <standard|extended|off>
  • /metrics <true|false>

Important Files

  • auth_data.json - local auth data, do not commit it
  • gptty_state.json - minimal SDK-backed chat state, do not commit it
  • webchat_state.json - legacy chat history and runtime settings, do not commit it

Notes

  • auth_data.json is the primary auth source.
  • ChatGPT web-session auth may expire after some time; in practice, expect to refresh it periodically.
  • Run gptty auth status when requests start failing or before long terminal sessions.
  • .env is optional. If present, accessToken is used as a fallback even when auth_data.json is missing, but a full auth_data.json remains the most compatible setup.
  • In auto mode, auth refresh sends one probe message to trigger capture. The default text is "Hello", and you can override it with --probe-prompt.
  • In wait mode, auth refresh does not send the probe automatically. Log in or register, then send any message manually in the browser to trigger capture.
  • New auth captures write canonical accessToken plus the legacy-compatible api_key field.
  • Do not mix cookies and api_key/accessToken from different accounts.
  • Local state and auth files are written atomically to reduce the chance of truncated JSON after interruption.
  • If main.py says that curl is missing, install system curl.exe and check curl --version.

Troubleshooting

  • curl not found Install system curl.exe and make sure curl --version works.
  • auth_data.json is missing Run gptty auth refresh --mode wait, complete login in the browser, then send any message in the chat window.
  • Auth may be expired Run gptty auth status. If it reports expired, run gptty auth refresh --mode wait.
  • gptty auth refresh says auth dependencies are missing Reinstall auth dependencies with python -m pip install -e ".[auth]" from checkout, or python -m pip install "gptty-web[auth]" from an installed package.
  • gptty send, gptty messages, gptty status, or gptty export says there is no attached conversation Run gptty attach <url-or-id> first, pass a conversation URL/id directly to the command, or use gptty send --new.
  • gptty ask --image or gptty send --image says an image file does not exist Check the local path, or pass an http(s) image URL instead.
  • ImportError: cannot import name 'nodriver' Reinstall auth dependencies with python -m pip install -e ".[auth]". Recent g4f releases use zendriver instead of the older nodriver package name.
  • The wrong account opens in auth refresh The browser profile already contains another session. Log out there first, or use the wait mode and sign in to the intended account.
  • Requests start failing after working before Your session cookies or api_key/accessToken may have expired. Regenerate auth_data.json with gptty auth refresh --mode wait.
  • gptty chat starts but cannot answer Check that auth_data.json exists and the captured browser session still belongs to the same account.
  • gptty chat --legacy starts but cannot answer Check that auth_data.json exists, curl is installed, and the captured browser session still belongs to the same account.

Status

This repository is in transition from webchat-openai-cli to gptty.

PR0 establishes the package skeleton and console command. PR1 adds the SDK client boundary. PR2 adds the first SDK-backed command, gptty ask. PR3 centralizes stdin pipe handling. PR4 migrates the default gptty chat path to a minimal SDK-backed loop with legacy fallback. PR5 adds attach/messages/status conversation operations. PR6 adds send-to-attached, explicit, and new conversation workflows. PR7 adds shared output modes for messages/status/send. PR8 adds conversation export. PR9 adds SDK-backed image prompts for ask/send. PR10 adds auth status/refresh UX. PR11 prepares the first gptty-web release flow. Later PRs will add richer pipe workflows and SDK chat /img parity.

See CHANGELOG.md and docs/release.md for release details.

Metadata

Release files for gptty-web 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gptty-web 0.1.1
File Size Uploaded
gptty_web-0.1.1.tar.gz 60.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gptty-web 0.1.1
File Interpreter ABI Platform
gptty_web-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 110.8 kB

Release files / gptty_web-0.1.1.tar.gz

Download URL gptty_web-0.1.1.tar.gz
Size 60.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d509e7a23b2d26d80d46a3d44562b0a62e03ed73269d0929b439e293d46a59fe
BLAKE2b-256 checksum
How to use checksums
ea4a0db2ff9f25ffd18b8a67d4eb06e811426113471e5b19f500f831fa652013
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 24, 2026.

Transparency log

Release files / gptty_web-0.1.1-py3-none-any.whl

Download URL gptty_web-0.1.1-py3-none-any.whl
Size 50.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d7844e18c273e7486ced2ca714c962eaf3ac5529ac63907fcdc50cb01cbae1d0
BLAKE2b-256 checksum
How to use checksums
d58284a01b40617a50fc7d9adc0b0ce55d063d848227a90f59d356ae52617e6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page