← Google Tools MCP

Setup and configuration.

Everything the server reads, every place it reads it from, and what to do when your client says it timed out. Written against google-tools-mcp 3.4.4.

Guided setup

Start here. It does the console work for you.

One command. It opens each Google Cloud page in your browser as you reach it, enables the APIs, stores the credentials, authenticates, and writes the MCP entry for Claude Code or Codex when their CLIs are on the machine.

npx -y google-tools-mcp setup

Run it again any time. It is idempotent: an existing entry gets repaired rather than duplicated, and a half-written one gets finished. To see what it would change without changing anything, run doctor instead:

npx -y google-tools-mcp doctor

The wizard installs the package globally and points your client at that install rather than at npx. The reason is in the troubleshooting section, and it is the single most common cause of a server that will not connect.

Doing it by hand

Creating the OAuth credentials yourself.

The credentials are yours, in your own Google Cloud project. The server never sees a client ID that isn’t one you created.

  1. 01

    Create a project in the Google Cloud Console, or pick one you already have.

  2. 02

    Enable the API for each product you want: Drive, Docs, Sheets, Gmail, Calendar, Slides, Forms, Tasks.

  3. 03

    Configure the OAuth consent screen. External is fine for personal use.

  4. 04

    If the app is still in Testing, which is the default, add your own Google account under Test users. Skip this and the sign-in is blocked with an access-denied error that does not explain itself.

  5. 05

    Under Credentials, create an OAuth client ID and choose Desktop application as the type.

  6. 06

    Download the JSON, or copy the client ID and client secret.

Where to put them

Pick one. The server checks these in order and uses the first that defines a value, so a real environment variable always wins over a file.

04

~/.config/google-tools-mcp/credentials.json

Recommended. Shared across every project on the machine.

03

~/.config/google-tools-mcp/.env

Same place, as GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET instead of the downloaded JSON.

02

./credentials.json or ./.env

Scoped to one project directory. Keep it out of version control.

01

The env block of your MCP config

Read first of all, ahead of every file. Useful when a client manages its own secrets.

Numbered by precedence, highest first. On macOS and Linux, keep a .env at chmod 600. On Windows the default user-profile permissions are enough, and the user-scoped file is worth using: a client launched over stdio may not inherit a Windows environment variable that was set after the client started, but it can still read that file.

Registering the server

Telling your client the server exists.

Install once, so your client launches a fixed command instead of resolving a dependency tree on every start:

npm install -g google-tools-mcp

Claude Code

claude mcp add -s user google -- google-tools-mcp

The -s user flag makes it available in every project. Drop the flag to scope it to the current one.

Codex

codex mcp add google --env CODEX_MCP_PROTOCOL_VERSION=2026-07-28 -- google-tools-mcp

The env entry is required. Codex pins stdio servers to the legacy MCP lifecycle unless it is told which protocol version to speak.

Any other MCP client

{
  "mcpServers": {
    "google": {
      "command": "google-tools-mcp"
    }
  }
}

Add the entry to the client’s own config file, such as .mcp.json or claude_desktop_config.json.

Every one of these works with npx -y google-tools-mcp in place of the bare command if you can’t install globally. It costs a dependency resolution on every launch, which is exactly the cost the timeout section is about. If your client is a desktop app, give it the absolute path to Node rather than a bare node: GUI apps often launch with a minimal PATH that does not include whatever your shell resolves.

Signing in

Nothing opens a browser until the first tool call.

Starting your client does not trigger a sign-in. The first time the agent actually calls a tool, the server opens one Google consent screen, and the refresh token is saved to ~/.config/google-tools-mcp/token.json, written atomically with 0600 permissions in a 0700 directory. You are not asked again.

The authorization URL carries a random state and a PKCE challenge, and the loopback callback ignores anything that does not match, so a page you happen to visit during the sign-in window can’t hand the server a code that isn’t yours.

To run the flow on purpose, at any time:

npx google-tools-mcp auth

Working on a remote machine with the browser on your laptop? Set GOOGLE_MCP_OAUTH_PORT to a fixed port and forward it over SSH. logout drops the saved token and the next call starts a fresh sign-in.

Two Google accounts

Work and personal, kept fully apart.

Set GOOGLE_MCP_PROFILE in the server entry and its tokens, config, and HTTP state move into their own directory. Register the server twice under two names and two profiles to have both available at once.

{
  "mcpServers": {
    "google-work": {
      "command": "google-tools-mcp",
      "env": { "GOOGLE_MCP_PROFILE": "work" }
    },
    "google-personal": {
      "command": "google-tools-mcp",
      "env": { "GOOGLE_MCP_PROFILE": "personal" }
    }
  }
}

This one has to be a real environment variable. Put it in a .env file and it is ignored, with a warning at startup, because it is the value that decides which .env file to read.

Environment variables

Every setting the server reads.

None of them are required. The defaults are what the setup wizard leaves you with.

Credentials

GOOGLE_CLIENT_ID

OAuth 2.0 client ID. Not needed as an env var if it is in a .env or credentials.json file the server can find.

GOOGLE_CLIENT_SECRET

OAuth 2.0 client secret. Same lookup rules as the client ID.

GOOGLE_MAPS_API_KEY

Google Maps Platform key. Separate from OAuth, and only the maps tools use it.

SERVICE_ACCOUNT_PATH

Path to a service account JSON key, as an alternative to the interactive OAuth flow.

GOOGLE_IMPERSONATE_USER

Email address the service account impersonates.

Accounts and storage

GOOGLE_MCP_PROFILE

Profile name for multi-account use. Must be set in the real process environment, not in a .env file, and it selects the config directory.

GOOGLE_MCP_OAUTH_PORT

Fixed loopback port for the OAuth callback. Set it when you are forwarding the callback over SSH; otherwise the port is ephemeral.

GOOGLE_MCP_WORKSPACE_DIR

Where local working copies of Google Docs are written. Defaults to a per-user directory under the OS temp dir.

Shared HTTP mode

GOOGLE_MCP_TRANSPORT

stdio, the default, or http.

GOOGLE_MCP_PORT

Port for the HTTP transport. Defaults to 3939.

GOOGLE_MCP_ENDPOINT

URL path for the HTTP transport. Defaults to /mcp.

GOOGLE_MCP_HTTP_HOST

Bind address. Defaults to 127.0.0.1, and only loopback addresses are accepted.

GOOGLE_MCP_HTTP_TOKEN

Overrides the persistent bearer token. One is generated in the config directory on first run and is never printed.

GOOGLE_MCP_HTTP_ALLOWED_ORIGINS

Extra Origin values to accept, comma separated. Loopback origins are always allowed.

GOOGLE_MCP_HTTP_NO_AUTH

Set to 1 to drop the bearer-token requirement. Only safe if you trust every process on the machine.

Diagnostics and behavior

LOG_LEVEL

debug, info, warn, error, or silent.

GOOGLE_MCP_LOG_FILE

Plain log path. Defaults to ~/.config/google-tools-mcp/server.log; set 0, false, or off to disable it.

GOOGLE_MCP_JSONL_FILE

Structured per-tool-call log. Defaults alongside the plain log; the same values disable it.

GOOGLE_MCP_ENABLE_LEGACY_ALIASES

Set to true to register the deprecated snake_case tool names.

GOOGLE_MCP_NO_UPDATE_CHECK

Set to anything to skip the background check for a newer published version. NO_UPDATE_NOTIFIER does the same.

Shared HTTP mode

One server process for every session.

By default each client spawns its own server over stdio. Run five agent sessions and that is five Node processes holding memory. Shared HTTP mode runs one and points them all at it. Choose it during setup, or drive it directly:

google-tools-mcp start     # start it, or attach to a healthy one
google-tools-mcp status    # ask it who it is, as a real client
google-tools-mcp restart
google-tools-mcp stop
google-tools-mcp serve     # foreground, for a login item or service manager

How it is guarded

The endpoint exposes your authenticated Google account, so it is locked down rather than merely local. A bearer token is required on every route, including the 404 for paths that do not exist, so an unauthenticated caller cannot even probe which ones do. The token is generated once in the private config directory and never printed. It binds to 127.0.0.1 and refuses non-loopback hosts, and a request carrying a foreign browser Origin is rejected.

What changed in 3.0

HTTP is stateless now: every request is authenticated, served, and forgotten. The session lifecycle is gone, along with the legacy SSE transport and the unauthenticated ping route. What remains is one POST endpoint plus an authenticated GET /healthz.

Because read state can’t cross requests, a Docs edit over HTTP takes an explicit read handle that readDocument returns: single-use, expiring, and bound to the credential, profile, file, tab, revision, and document structure. If you use stdio, which is the default, none of this applies and nothing in your config changes — with one exception, Codex, which needs CODEX_MCP_PROTOCOL_VERSION=2026-07-28 in its env block either way.

When it won’t connect

The timeout that looks random and isn’t.

The symptom

Your client reports that the google server failed to connect or timed out, with no other error. It works sometimes and fails other times on the same machine.

The cause

If your config launches the server with npx -y google-tools-mcp, npx re-resolves and verifies the whole dependency tree on every launch, not just the first. On some machines, Windows especially, that reliably takes 30 seconds or more even when the exact version is already cached. Claude Code’s stdio connection timeout is a fixed 30 seconds, so an npx-launched server is sitting right on the failure line.

The fix

Install it globally and point the client at the binary. Re-running the setup wizard does exactly this for you.

npm install -g google-tools-mcp

Then updates stop arriving

That is the trade. The npx form auto-updated by accident, because it re-resolved to whatever was published. A global install launches a fixed path forever. Update it yourself, or re-run setup, which does the same thing and re-points your config:

npm install -g google-tools-mcp@latest

The server helps you notice. After the connection is established, it makes one non-blocking 2-second check against the npm registry, at most once a day, and logs a line if you are behind. It runs after the handshake and is never awaited, so a slow network can’t reintroduce the timeout this section is about.

Anything else

For a single tool failing rather than the server not starting, call the built-in troubleshoot tool: it summarizes the redacted per-call records the server writes by default. If that does not explain it, open an issue, or have the agent do it for you with the feedback tool.