Skip to content

google-ads server gets no credentials: .env ${VAR} placeholders aren't resolved by Claude Code #2

Description

@steig

Summary

On a fresh clone, the google-ads MCP server connects but every tool call fails with "No credentials found", even after copying .env.example.env and filling in all values. The documented auth flow does not actually wire credentials into the server.

This is separate from the entrypoint bug in #1 — both must be fixed for the server to work end-to-end.

Root cause

.mcp.json passes credentials via placeholder indirection:

"env": {
  "GOOGLE_ADS_DEVELOPER_TOKEN": "${GOOGLE_ADS_DEVELOPER_TOKEN}",
  "GOOGLE_ADS_CLIENT_ID": "${GOOGLE_ADS_CLIENT_ID}",
  ...
}

Claude Code resolves ${VAR} in .mcp.json from the process environment that launched Claude Code — it does not auto-load the repo's .env file. So unless the user has already exported all six vars into the shell before starting Claude Code, every placeholder resolves empty.

claude mcp list confirms it:

[Warning] [google-ads] mcpServers.google-ads: Missing environment variables:
  GOOGLE_ADS_DEVELOPER_TOKEN, GOOGLE_ADS_CLIENT_ID, GOOGLE_ADS_CLIENT_SECRET,
  GOOGLE_ADS_REFRESH_TOKEN, GOOGLE_ADS_LOGIN_CUSTOMER_ID, GOOGLE_ADS_CUSTOMER_ID

The server then reports:

Error calling tool 'list_accounts': No credentials found. Provide one of:
  • GOOGLE_ADS_CREDENTIALS pointing to a google-ads.yaml
  • GOOGLE_ADS_OAUTH_CONFIG_PATH pointing to an OAuth client JSON

But .env.example and the README both state the opposite:

.env.example: "Claude Code resolves ${VAR_NAME} placeholders in .mcp.json at server launch time."
README → Authentication: "Copy .env.example to .env and fill in..."

That instruction does not produce a working connection.

Reproduce

  1. git clone the repo, claude --plugin-dir .
  2. cp .env.example .env, fill in valid Google Ads credentials
  3. (apply the fix(mcp): correct google-ads server entrypoint to gads-mcp #1 entrypoint fix so the server boots)
  4. /reload-plugins, then ask Buddy to list accounts
  5. → "No credentials found"

Proposed fix

gads-mcp already supports GOOGLE_ADS_CREDENTIALS pointing to a standard google-ads.yaml. Honor the existing ${VAR}-only convention from CONTRIBUTING.md by using a var that's always in the process env:

"env": {
  "GOOGLE_ADS_CREDENTIALS": "${HOME}/.google-ads.yaml",
  ...
}

This works without the user sourcing anything, survives restarts, and aligns with the canonical Google Ads client-library location.

Doc changes needed alongside:

  • .env.example — remove the "Claude Code resolves .env" claim; document the ~/.google-ads.yaml path (or instruct users to export the vars / use a shell .env loader if the placeholder route is kept).
  • README → Authentication — same correction.

Happy to send a PR if the maintainer prefers the GOOGLE_ADS_CREDENTIALS yaml approach vs. keeping the six-var placeholder route with corrected docs.

Environment

  • Claude Code 2.1.x
  • googleadsagent-mcp gads-mcp (FastMCP 3.4.2)
  • macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions