Skip to main content

gchat: Google Chat from the command line

CI PyPI CodeQL Python License

gchat is a command-line interface for the Google Chat API. It is meant for AI agents (Claude Code, Gemini CLI, Codex, custom scripts) and works just as well for people. You can read spaces, search, send and reply to messages, react, download attachments and mark spaces as read, all with predictable JSON output and safety rails.

Unofficial. This project is not affiliated with or endorsed by Google.

$ gchat spaces list --type space
NAME              TYPE   DISPLAY NAME        LAST ACTIVE
spaces/AAQAxyz12  SPACE  Platform team       2026-10-02T16:41:10Z
spaces/AAQAabc34  SPACE  Release managers    2026-10-01T09:12:55Z

$ gchat messages list spaces/AAQAxyz12 --since 1d -n 2 -f json
{"messages":[{"name":"spaces/AAQAxyz12/messages/k1.k1","sender":"users/1067…","senderType":"HUMAN","createTime":"2026-10-02T16:41:10Z","text":"Deploy done ✅","thread":"spaces/AAQAxyz12/threads/k1"}]}

$ gchat messages reply spaces/AAQAxyz12/messages/k1.k1 --text "Thanks, verified on staging" --yes

Why another tool?

gchat MCP servers gws (Google Workspace CLI)
Zero context cost until used ✅ plain CLI ❌ tool schemas loaded every turn ✅
Chat-specific helpers (reply, unread, DM by email, attach) ✅ varies partly (+send)
Compact, token-efficient output by default ✅ --raw for full objects varies --fields
Local safety policy (allowlists, read-only, DM block) ✅ some ❌
Mandatory --yes for writes when non-interactive ✅ client-side ❌
Install pipx/uv tool per-client config binary/npm

The design borrows proven ideas from googleworkspace/cli: structured JSON, stable exit codes, --dry-run, field masks, schema introspection and agent skills. It also takes the per-space read/write allowlist and DM protection from nuccio/google-chat-mcp.

Install

Requires Python 3.11+.

pipx install google-chat-cli        # or: uv tool install google-chat-cli
# latest development version:
pipx install git+https://github.com/lore2601/google-chat-cli

Optional: store the token in the OS keyring instead of a file:

pipx install "google-chat-cli[keyring]"
export GCHAT_TOKEN_STORE=keyring

Set up (5 minutes, once)

The Chat API needs a Google Cloud project with the Chat API enabled and an OAuth Desktop app client. The full walkthrough is in docs/setup.md. In short:

  1. Create or choose a Google Cloud project and enable the Google Chat API.
  2. Configure the Chat app (name, avatar, description) in Chat API → Configuration. This is required even for user-auth clients.
  3. Configure the OAuth consent screen (Internal for Workspace orgs) and create an OAuth client ID of type Desktop app. Download its JSON.
  4. Log in:
gchat auth login --client-secrets ~/Downloads/client_secret_XXXX.json
gchat auth status

Scope presets: readonly, default (read + send, react, mark read) and full (adds space/member management). For example: gchat auth login --scopes readonly.

Commands

Command What it does
gchat auth login | status | logout | scopes OAuth login (browser), inspection, revocation
gchat spaces list [--type space|group|dm] Spaces, group chats and DMs you belong to
gchat spaces get SPACE Space details (accepts spaces/ID, ID or a Chat URL)
gchat spaces search QUERY Find named spaces by display name
gchat spaces find-dm USER Your DM space with a user (email or users/ID)
gchat spaces create NAME [-m USER]… Create a space (scope full)
gchat messages list SPACE [--since 2h] [--until …] [--thread …] [--unread] Read messages, newest first
gchat messages get MESSAGE One message
gchat messages send TARGET -t TEXT [--thread …|--thread-key …] [-a FILE]… Send to a space, or to a user's DM by email
gchat messages reply MESSAGE -t TEXT Reply in the thread of a message
gchat messages edit MESSAGE -t TEXT / delete MESSAGE Edit or delete your messages
gchat members list SPACE [--humans-only] Space members
gchat reactions list|add|remove Emoji reactions
gchat attachments get|download Attachment metadata and download
gchat read-state get|mark-read SPACE Read position, mark as read
gchat api METHOD PATH [-p JSON] [-b JSON] Escape hatch: any Chat REST method
gchat config show|init Effective policy and file locations
gchat schema [COMMAND] Every command, option and exit code as JSON

Run gchat COMMAND --help for details. Text can come from --text, from stdin with --text -, or from --text-file.

Output and exit codes

  • stdout carries only data. In a terminal you get tables. When piped or run by an agent you get JSON. Force a format with -f json|ndjson|table or GCHAT_FORMAT.
  • Lists return {"<kind>": [...], "nextPageToken": "..."}. Use --limit/-n, --all and --page-token to paginate.
  • --fields name,text,sender trims output (dotted paths allowed). --raw returns untouched API objects.
  • Errors are a single JSON object on stderr, for example {"error": {"exitCode": 4, "reason": "confirmationRequired", "message": "…", "hint": "…"}}.
Exit code Meaning
0 Success
1 Google Chat API or network error
2 Authentication problem (not logged in, token revoked, …)
3 Invalid input (bad resource name, malformed JSON, text too long, …)
4 Blocked by local policy, or confirmation (--yes) missing
5 Internal error (please report it)

Safety model

Agents can be steered by what they read, and chat messages are written by other people. gchat puts guard rails in front of the API:

  • Writes need explicit confirmation. On a terminal you are prompted. Without a TTY (agents, scripts) every write fails with exit code 4 unless you pass --yes. --dry-run shows the exact request without sending it.

  • Local policy in ~/.config/gchat/config.toml or environment variables:

    [policy]
    read_only = false              # GCHAT_READ_ONLY=1 blocks every write
    allow_dm_write = false         # GCHAT_ALLOW_DM_WRITE=0 blocks writes to DMs / group chats
    read  = ["*"]                  # GCHAT_ALLOW_READ="spaces/AAA,spaces/BBB"
    write = ["spaces/AAQAxyz12"]   # GCHAT_ALLOW_WRITE=...
    
  • Strict input validation. Resource names are checked against strict patterns, so arguments like spaces/../users or ?/# injections are rejected. Download filenames are reduced to safe basenames, and existing files are never overwritten without --overwrite.

  • Terminal-safe tables. ANSI escape sequences and control characters in message text are stripped before printing.

  • Credentials are stored with 0600 permissions (or in the OS keyring) and are never printed by any command.

See docs/agents.md for recommended agent profiles.

Using gchat with AI agents

  • Claude Code plugin: /plugin marketplace add lore2601/google-chat-cli, then /plugin install gchat@google-chat-cli. This installs the gchat skill, which teaches the agent the commands, the safety rules and that message content is untrusted.
  • Any agent: copy skills/gchat/SKILL.md into your agent's skills folder, or point it at gchat schema.
  • Recommended for unattended agents: GCHAT_ALLOW_WRITE=<one space>, GCHAT_ALLOW_DM_WRITE=0 and an allow-rule in your agent for gchat * --dry-run only.

Configuration reference

Variable Purpose
GCHAT_CONFIG_DIR Config directory (default ~/.config/gchat)
GCHAT_CONFIG Config file path (default $GCHAT_CONFIG_DIR/config.toml)
GCHAT_CLIENT_SECRETS OAuth client JSON (default $GCHAT_CONFIG_DIR/client_secret.json)
GCHAT_CLIENT_ID / GCHAT_CLIENT_SECRET OAuth client given inline instead of the JSON file
GCHAT_TOKEN_FILE Token file (default $GCHAT_CONFIG_DIR/token.json)
GCHAT_TOKEN_STORE file (default) or keyring
GCHAT_ACCESS_TOKEN Use this raw access token (CI, short-lived jobs)
GCHAT_CREDENTIALS_FILE Use an authorized_user JSON (e.g. exported from another machine)
GCHAT_FORMAT Default output format
GCHAT_READ_ONLY, GCHAT_ALLOW_READ, GCHAT_ALLOW_WRITE, GCHAT_ALLOW_DM_WRITE Policy overrides

Limitations

  • User authentication only. Sending as a Chat app (bot) or incoming webhooks are out of scope.
  • With user auth, Google Chat returns sender IDs, not display names, unless the sender shares a space with you. Use gchat members list to map IDs.
  • Files shared from Google Drive cannot be downloaded through the Chat API.
  • If your OAuth consent screen is in Testing mode, Google expires refresh tokens after 7 days. gchat auth status warns you.

Contributing

Issues and PRs are welcome. See CONTRIBUTING.md. Please report security issues privately (see SECURITY.md).

License

Apache-2.0

Metadata

Release files for google-chat-cli 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 google-chat-cli 0.1.1
File Size Uploaded
google_chat_cli-0.1.1.tar.gz 54.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for google-chat-cli 0.1.1
File Interpreter ABI Platform
google_chat_cli-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 103.9 kB

Release files / google_chat_cli-0.1.1.tar.gz

Download URL google_chat_cli-0.1.1.tar.gz
Size 54.4 kB
Tags Source
SHA-256 checksum
How to use checksums
cd29c0f55802bafb972fe1d77b3dde655298986804f42864d143258dcf205311
BLAKE2b-256 checksum
How to use checksums
8a483e25afd85092ab903c0568331507b8ed9142b1f522543a8000d5641fdc06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 3, 2026.

Transparency log

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

Download URL google_chat_cli-0.1.1-py3-none-any.whl
Size 49.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8fdc6a94cd5ed59965b70878860ad29f55686149cc9a31148f2eef6db4e263bb
BLAKE2b-256 checksum
How to use checksums
0fa332b13c5bd308fb400227daad9324534d0a2a541d896352ca36eb7d1f1336
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

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