Gmail No Send

Other

Read-only Gmail CLI that cannot send email by design. Search, read, create drafts, update drafts, and archive messages — with zero send capability in the codebase. Use when the agent needs Gmail access for reading email, drafting responses, searching inbox, or archiving messages, but sending must be impossible. Ideal for AI agents that should never autonomously send email. Requires Google Cloud OAuth credentials (user provides their own client_secret.json).

Install

openclaw skills install gmail-no-send

gmail-no-send

Gmail CLI that cannot send email. Not "won't" — can't. There is no send function in the codebase.

Install

Requires Python 3.9+.

cd <skill-dir>/scripts/gmail-no-send
pip install -e .

Or install from the GitHub repo:

pip install git+https://github.com/meimakes/gmail-no-send.git

First-Time Auth

Each user needs their own Google Cloud OAuth credentials:

  1. Create a project at console.cloud.google.com
  2. Enable the Gmail API
  3. Create OAuth 2.0 credentials (Desktop app type)
  4. Download client_secret.json

Then authenticate:

gmail-no-send auth --client-secret /path/to/client_secret.json --account myname

This opens a browser for Google OAuth consent. Token is saved to ~/.config/gmail-no-send/token.json and auto-refreshes.

Commands

All commands require --account <name> (matches the name used during auth).

Search

gmail-no-send search --account mei --query "from:someone@example.com newer_than:7d" --max 10

Returns JSON array of message IDs and thread IDs.

Read

gmail-no-send read --account mei --message-id <id>

Returns full message payload (headers, body, labels).

Create Draft

gmail-no-send draft-create --account mei --to "someone@example.com" --subject "Re: topic" --body "Draft text here"
gmail-no-send draft-create --account mei --to "someone@example.com" --subject "Long draft" --body-file /path/to/body.txt

Update Draft

gmail-no-send draft-update --account mei --draft-id <id> --to "someone@example.com" --subject "Updated" --body "New body"

Archive

gmail-no-send archive --account mei --message-id <id>

Removes INBOX label (message stays in All Mail).

Security Model

  • No send command exists. The CLI has 6 commands: auth, search, read, draft-create, draft-update, archive. None send.
  • OAuth scope caveat: Gmail API has no "drafts-only" scope. The compose scope technically allows send via API. This tool enforces no-send at the application layer — the code simply doesn't call the send endpoint.
  • Audit log: All operations logged to ~/.config/gmail-no-send/audit.log with timestamps.
  • Token storage: ~/.config/gmail-no-send/token.json — user-local, not shared.

For a deeper security analysis, see references/threat-model.md.

Agent Usage Notes

  • Search returns message IDs, not content. Call read to get the actual message.
  • Draft creation returns the draft ID for future updates.
  • Use --body-file for long draft bodies instead of --body to avoid shell escaping issues.
  • The tool does NOT support attachments, labels, or filters — intentionally minimal.