Google Workspace Interface: Gmail, Drive, Docs, Sheets and Slides from the command line and as MCP tools.
Status: early development, not released. gwi is being assembled from the Google Workspace functionality of omni-dev.
gwi gmailandgwi drivework from source, and so does the MCP server with its Gmail and Drive tools. Progress is tracked in rust-works/omni-dev#2203.
cargo run -- gmail --help
cargo run -- drive --helpConfiguration lives in ~/.gwi/settings.json (not omni-dev's ~/.omni-dev), and
environment variables use the GWI_ prefix.
Set GWI_HOME to use another application home: settings then live at
<GWI_HOME>/.gwi/settings.json, and the default import source is
<GWI_HOME>/.omni-dev/settings.json. Set GWI_STATE_DIR to relocate the state base:
logs, the lease ledger and default backups live under <GWI_STATE_DIR>/gwi/, and
import looks for the source ledger under <GWI_STATE_DIR>/omni-dev/. Both variables
are read directly from the process environment, support native paths on every OS,
and use the usual platform directories when unset or empty. Set both for an isolated
installation; GWI_HOME alone does not relocate state. Explicit log, backup and
import source options still take precedence. MCP path protection covers relocated
application data as well as the platform's credential directories.
If you already configured Gmail in omni-dev, copy it across instead of logging in again:
gwi import --dry-run # show what would be imported; writes nothing
gwi import # copy the Gmail and Drive accounts and Google variablesIt only reads omni-dev's ~/.omni-dev/settings.json (use --source PATH for another file),
never changes it, never overwrites a different value you already have in gwi (pass
--force to), and never prints a secret. Anything gwi already has with the same value is
reported as unchanged, so running it twice is safe. It warns about any *_file secret path
that points inside ~/.omni-dev/, since that file would be lost if you later remove
omni-dev's directory.
The same command copies Drive's lease ledger (omni-dev/lease-ledger.jsonl in the state
directory; --source-ledger PATH for another file), so a lease taken with
omni-dev drive lease acquire works and can be restored through gwi drive. Every lease is
copied, expired ones too, because a restore needs them. A lease that is still live carries
over unchanged and stays valid until it expires, in both tools: the two ledgers are
copies: a lease released in omni-dev is released in gwi by the next gwi import when the
two rows are otherwise the same, not before. Audit history is not
copied. Unknown metadata, including literal private number keys, is retained; see
lease ledger JSON compatibility.
Selected API/Sheets payloads preserve unknown JSON; settings updates/import retain
a related JSON passthrough limitation.
See Coming from omni-dev for the details.
--dry-run lists conflicts as part of its preview and exits 0 for them, in both the settings
and the lease ledger, with a note saying so. It is a preview, not a check: the real run
still exits 1 on a conflict until you pass --force, so read the report before
gwi import --dry-run && gwi import (a dry run fails only when the import itself does).
A folder you synced with omni-dev drive sync needs nothing: gwi drive sync reads its
.omni-dev-sync.json and continues in .gwi-sync.json, leaving the old file alone.
gwi records every run, every Google API request and every Drive write attempt in a local JSON
Lines log, and keeps a separate fail-closed audit log for leased Drive writes. Read them with
gwi log and gwi log --audit; see the log reference for the location,
environment variables (GWI_LOG_*, GWI_AUDIT_LOG_FILE), the --query language, pruning
and the record schema.
gwi-mcp serves the Gmail and Drive tools to an AI assistant over the Model Context Protocol (stdio).
It is a separate binary, built with the mcp feature:
cargo install --path . --features mcp # installs `gwi` and `gwi-mcp`Then register it with your MCP client, for example:
{ "mcpServers": { "gwi": { "command": "gwi-mcp" } } }The 23 tools keep the names they had in omni-dev, so a client already configured for
omni-dev-mcp only needs the server command changed (and the omni-dev server's Gmail and
Drive tools removed once omni-dev drops them). The eight Gmail tools are gmail_auth_status, gmail_account_list,
gmail_search, gmail_message_read, gmail_thread_read, gmail_label_list,
gmail_draft_list and gmail_draft_show. They only read from Gmail: there is no tool to
send, delete or change anything in a mailbox, and none for the interactive
gwi gmail auth login, so sign in from a terminal first. (Some of the reading tools
accept an output_file to write a large result to a local file instead of returning it.)
The 15 Drive tools are:
- Read-only:
drive_auth_status,drive_account_list,drive_search,drive_dedupe,drive_file_read,drive_docs_info,drive_docs_read,drive_sheets_infoanddrive_sheets_read. - Writing:
drive_docs_replace,drive_docs_append,drive_sheets_write,drive_sheets_append,drive_sheets_clearanddrive_lease_acquire. Each is behind the write gate: the folder permission rules insettings.jsonmust allow the target, and a write lease (fromdrive_lease_acquireorgwi drive lease acquire) is required unless the call is a dry run or the rule saysrequire_lease: false. Acquiring a lease prompts for device-owner authentication (Touch ID or the account password), which exists on macOS only: elsewheredrive_lease_acquirefails unless the operator has setallow_headlessinsettings.json. The consent policy (allow_headless,biometrics_only), the ledger path and the permission rules cannot be set from a tool call. No MCP tool can create, move, rename, trash or delete a file, and the interactivegwi drive auth loginis CLI-only too.
Every tool except gmail_account_list and drive_account_list takes an optional account.
Two optional defaults come from the mcp block of ~/.gwi/settings.json: log_level (a
tracing directive; RUST_LOG wins) and max_response_bytes (the cap before a response is
truncated, default 100 KB, 0 for no limit). gwi import copies both from omni-dev.
Two kinds of tool parameter name a local path: the text_path and values_path sources of
the Drive write tools (read, then written into a Doc or Sheet) and output_file on the read
tools (written to disk). Both are chosen by the assistant, so gwi-mcp checks them before
touching the file, after following symlinks and collapsing ..:
-
A path must be inside an allowed directory. By default that is the server's working directory and the system temp directory; a working directory that is
/, the home directory or above it is not allowed by default. Themcp.allowed_pathslist insettings.json(absolute or~/entries) replaces that default, and[]allows nothing:{ "mcp": { "allowed_paths": ["~/work/exports", "/tmp"] } } -
Credential locations are refused whatever the list says: gwi's and omni-dev's own configuration (
~/.gwi,~/.omni-dev,~/.config/gwi, a.gwi/under the working directory) and state directory (the lease ledger andaudit.jsonl); credential stores (~/.ssh,~/.gnupg,~/.aws,~/.kube,~/.docker,~/.netrc,~/.git-credentials,~/.npmrc,~/.pypirc,~/.config/gcloud,~/.config/gh,~/Library/Keychains); shell startup files and~/.gitconfig; and shell history. -
A refused path fails the call with an error that names the setting, before any API request is made. If
settings.jsoncannot be parsed, or anallowed_pathsentry is not absolute, every path is refused and the error says why. No tool parameter can change the policy, and thegwiCLI is not restricted.
omni-dev's tools accept any readable or writable path; see ADR-0002 for why gwi does not.
gwi gmail: search, read, threads, drafts, labels, attachments, sync and insert (available from source)gwi-mcp: the Gmail MCP tools (available from source)gwi drive: files, Docs, Sheets, Slides, permissions and write leases (available from source)gwi-mcp: the Drive MCP tools (available from source)
BSD 3-Clause. See LICENSE.