Source profileQuality 86/100Review permissions

nanocoai/nanoclaw/.claude/skills/add-gmail-tool/SKILL.md

add-gmail-tool

Add Gmail as an MCP tool (read, search, send, label, draft) using OneCLI-managed OAuth. The agent gets Gmail tools in every enabled group; OneCLI injects real tokens at request time so no raw credentials are ever in the container or on disk in usable form.

Source repository stars
30,427
Declared platforms
0
Static risk flags
2
Last source update
2026-08-04
Source checked
2026-08-04

Decision brief

What it does—and where it fits

This skill wires the @gongrzhe/server-gmail-autoauth-mcp stdio MCP server into selected agent groups. The MCP server reads stub credentials containing the onecli-managed placeholder; the OneCLI gateway intercepts outbound calls to gmail.googleapis.com and injects the real OAuth…

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/nanocoai/nanoclaw --skill ".claude/skills/add-gmail-tool"
    Safe inspection promptEditorial

    Inspect the Agent Skill "add-gmail-tool" from https://github.com/nanocoai/nanoclaw/blob/8d04fde18fe071ce0b4870dc3094b66e2a29dcfe/.claude/skills/add-gmail-tool/SKILL.md at commit 8d04fde18fe071ce0b4870dc3094b66e2a29dcfe. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Phase 1: Pre-flight

      Expected: "connection": { "status": "connected" } with scopes including gmail.readonly, gmail.modify, gmail.send.

      Expected: "connection": { "status": "connected" } with scopes including gmail.readonly, gmail.modify, gmail.send.If not connected, tell the user:Open the OneCLI web UI at http://127.0.0.1:10254, go to Apps → Gmail, and click Connect. Sign in with the Google account you want the agent to act as.
    2. 02

      Phase 2: Apply Code Changes

      Both integration points this skill relies on live in the container (Bun) tree — the Dockerfile package install and the dynamic allow-pattern derivation in claude.ts — so the guards go there. cp overwrites, so re-running is safe.

      gmail-dockerfile.test.ts asserts the GMAILMCPVERSION ARG and the pinned pnpm install -g line are present — the gmail-mcp binary is a Dockerfile-installed CLI, not importable or typed, so this structural guard is what go…gmail-allow-pattern.test.ts asserts claude.ts still spreads Object.keys(this.mcpServers).map(mcpAllowPattern) into allowedTools — the derivation that makes registering gmail (Phase 3) enough to expose mcpgmail.Both integration points this skill relies on live in the container (Bun) tree — the Dockerfile package install and the dynamic allow-pattern derivation in claude.ts — so the guards go there. cp overwrites, so re-running…
    3. 03

      Phase 3: Wire Per-Agent-Group

      For each agent group that should have Gmail (ask the user — typically their personal DM and CLI agents, sometimes shared household agents), persist two changes to the central DB (data/v2.db): the mcpServers.gmail entry and an additionalMounts entry for .gmail-mcp. Both flow thro…

      For each agent group that should have Gmail (ask the user — typically their personal DM and CLI agents, sometimes shared household agents), persist two changes to the central DB (data/v2.db): the mcpServers.gmail entry…Approval behaviour depends on where you run it: from inside an agent's container ncl write verbs are approval-gated (admin approves before it lands); from a host operator shell with full scope, it executes immediately.…Register the mount with the host-only ncl groups config add-mount verb. For each chosen :
    4. 04

      Phase 4: Build, Validate, Restart

      All must be clean before proceeding. gmail-dockerfile.test.ts confirms the package install is wired into the image; gmail-allow-pattern.test.ts confirms the allow-pattern derivation that exposes mcpgmail. A failure means one drifted.

      All must be clean before proceeding. gmail-dockerfile.test.ts confirms the package install is wired into the image; gmail-allow-pattern.test.ts confirms the allow-pattern derivation that exposes mcpgmail. A failure mean…Run from your NanoClaw project root:
    5. 05

      Phase 5: Verify

      In your chat, send: "list my gmail labels" or "search my inbox for invoices from last month". The agent should use mcpgmaillistlabels / mcpgmailsearch. The first call may take a second or two while the MCP server starts and OneCLI does the token exchange.

      In your chat, send: "list my gmail labels" or "search my inbox for invoices from last month". The agent should use mcpgmaillistlabels / mcpgmailsearch. The first call may take a second or two while the MCP server starts…bash tail -100 logs/nanoclaw.log logs/nanoclaw.error.log | grep -iE 'gmail|mcp'

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 49

    The documentation includes network, browsing, or remote request actions.

    "redirect_uris": ["http://localhost:3000/oauth2callback"]

    Network access

    medium · line 59

    The documentation includes network, browsing, or remote request actions.

    "scope": "https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.send"

    Runs scripts

    medium · line 189

    The documentation asks the agent to run terminal commands or scripts.

    `--host` is the host path, `--container` is the in-container path (relative, lands at `/workspace/extra/.gmail-mcp`). No `--ro` — the MCP server writes refreshed token state back into the mount. The verb is idempotent (a re-run skips if the

    Runs scripts

    medium · line 198

    The documentation asks the agent to run terminal commands or scripts.

    pnpm run build

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score86/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars30,427SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    nanocoai/nanoclaw
    Skill path
    .claude/skills/add-gmail-tool/SKILL.md
    Commit
    8d04fde18fe071ce0b4870dc3094b66e2a29dcfe
    License
    MIT
    Collected
    2026-08-04
    Default branch
    main
    View the original SKILL.md

    Add Gmail Tool (OneCLI-native)

    This skill wires the @gongrzhe/server-gmail-autoauth-mcp stdio MCP server into selected agent groups. The MCP server reads stub credentials containing the onecli-managed placeholder; the OneCLI gateway intercepts outbound calls to gmail.googleapis.com and injects the real OAuth bearer from its vault.

    Tools exposed (from [email protected], surfaced to the agent as mcp__gmail__<name>): search_emails, read_email, send_email, draft_email, delete_email, modify_email, batch_modify_emails, batch_delete_emails, download_attachment, list_email_labels, create_label, update_label, delete_label, get_or_create_label, list_filters, get_filter, create_filter, create_filter_from_template, delete_filter.

    Why this pattern: v2's invariant is that containers never receive raw API keys — OneCLI is the sole credential path (see CHANGELOG v2.0.0). The stub-file pattern satisfies this: the container sees "onecli-managed" placeholders, the gateway swaps them in flight.

    Phase 1: Pre-flight

    Verify OneCLI has Gmail connected

    onecli apps get --provider gmail
    

    Expected: "connection": { "status": "connected" } with scopes including gmail.readonly, gmail.modify, gmail.send.

    If not connected, tell the user:

    Open the OneCLI web UI at http://127.0.0.1:10254, go to Apps → Gmail, and click Connect. Sign in with the Google account you want the agent to act as.

    Verify stub credentials exist

    ls -la ~/.gmail-mcp/gcp-oauth.keys.json ~/.gmail-mcp/credentials.json 2>&1
    

    If both exist and contain "onecli-managed":

    grep -l onecli-managed ~/.gmail-mcp/gcp-oauth.keys.json ~/.gmail-mcp/credentials.json
    

    ...skip to Phase 2.

    If either file exists but does not contain onecli-managed, STOP and tell the user — these are real OAuth credentials from a previous non-OneCLI install. Back them up, then delete before proceeding. The OneCLI migration normally handles this; if it didn't, something is wrong.

    If both files are absent, write them now:

    mkdir -p ~/.gmail-mcp
    cat > ~/.gmail-mcp/gcp-oauth.keys.json <<'EOF'
    {
      "installed": {
        "client_id": "onecli-managed.apps.googleusercontent.com",
        "client_secret": "onecli-managed",
        "redirect_uris": ["http://localhost:3000/oauth2callback"]
      }
    }
    EOF
    cat > ~/.gmail-mcp/credentials.json <<'EOF'
    {
      "access_token": "onecli-managed",
      "refresh_token": "onecli-managed",
      "token_type": "Bearer",
      "expiry_date": 99999999999999,
      "scope": "https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.send"
    }
    EOF
    chmod 600 ~/.gmail-mcp/gcp-oauth.keys.json ~/.gmail-mcp/credentials.json
    

    Verify mount allowlist covers the path

    cat ~/.config/nanoclaw/mount-allowlist.json
    

    ~/.gmail-mcp must sit under an allowedRoots entry (e.g. /home/<user>). If it doesn't, tell the user to run /manage-mounts first or add their home directory.

    Check agent secret-mode

    For each target agent group, confirm OneCLI will inject Gmail secrets into its container. Find the OneCLI agent ID that matches the group's agentGroupId:

    onecli agents list
    

    If that agent's secretMode is all, you're done — Gmail secrets (identified by OneCLI's Gmail hostPattern) will auto-inject. If it's selective, explicitly assign the Gmail secrets using the safe merge pattern (set-secrets replaces the entire list — always read first):

    GMAIL_IDS=$(onecli secrets list | jq -r '[.data[] | select(.name | test("(?i)gmail")) | .id] | join(",")')
    CURRENT=$(onecli agents secrets --id <agent-id> | jq -r '[.data[]] | join(",")')
    MERGED=$(printf '%s' "$CURRENT,$GMAIL_IDS" | tr ',' '\n' | sort -u | paste -sd ',' -)
    onecli agents set-secrets --id <agent-id> --secret-ids "$MERGED"
    onecli agents secrets --id <agent-id>
    

    Phase 2: Apply Code Changes

    Check if already applied

    grep -q 'GMAIL_MCP_VERSION' container/Dockerfile && \
    echo "ALREADY APPLIED — skip to Phase 3"
    

    Copy the skill's tests into the container tree

    Both integration points this skill relies on live in the container (Bun) tree — the Dockerfile package install and the dynamic allow-pattern derivation in claude.ts — so the guards go there. cp overwrites, so re-running is safe.

    S=.claude/skills/add-gmail-tool
    cp $S/gmail-dockerfile.test.ts    container/agent-runner/src/providers/gmail-dockerfile.test.ts
    cp $S/gmail-allow-pattern.test.ts container/agent-runner/src/providers/gmail-allow-pattern.test.ts
    
    • gmail-dockerfile.test.ts asserts the GMAIL_MCP_VERSION ARG and the pinned pnpm install -g line are present — the gmail-mcp binary is a Dockerfile-installed CLI, not importable or typed, so this structural guard is what goes red if the install is dropped.
    • gmail-allow-pattern.test.ts asserts claude.ts still spreads Object.keys(this.mcpServers).map(mcpAllowPattern) into allowedTools — the derivation that makes registering gmail (Phase 3) enough to expose mcp__gmail__*.

    Add MCP server to Dockerfile

    Edit container/Dockerfile. Find the pinned-version ARG block:

    ARG CLAUDE_CODE_VERSION=2.1.154
    ARG AGENT_BROWSER_VERSION=latest
    ARG VERCEL_VERSION=52.2.1
    ARG BUN_VERSION=1.3.12
    

    Add a new line:

    ARG GMAIL_MCP_VERSION=1.1.11
    

    Then find the last pnpm global-install RUN block (the one that installs @anthropic-ai/claude-code) and add a new block directly after it (before the # ---- ncl CLI wrapper section):

    RUN --mount=type=cache,target=/root/.cache/pnpm \
        pnpm install -g \
            "@gongrzhe/server-gmail-autoauth-mcp@${GMAIL_MCP_VERSION}" \
            "[email protected]"
    

    Pinned version matters — minimumReleaseAge in pnpm-workspace.yaml gates trunk installs, and CLAUDE.md requires a fixed ARG version for all Node CLIs installed into the image.

    Why the zod-to-json-schema pin: @gongrzhe/[email protected] has loose deps (zod-to-json-schema: ^3.22.1, zod: ^3.22.4). pnpm resolves zod-to-json-schema to the latest 3.25.x, which imports zod/v3 — a subpath that only exists in zod>=3.25. But zod resolves to 3.24.x (highest satisfying ^3.22.4 without breaking peer ranges). Result: ERR_PACKAGE_PATH_NOT_EXPORTED at import time. Pinning zod-to-json-schema to a pre-v3-subpath version avoids it. Re-check if you bump GMAIL_MCP_VERSION.

    The Gmail allow-pattern is derived automatically. container/agent-runner/src/providers/claude.ts builds allowedTools from each group's mcpServers map (Object.keys(this.mcpServers).map(mcpAllowPattern)), so registering gmail in Phase 3 exposes mcp__gmail__* to the agent.

    Rebuild the container image

    ./container/build.sh
    

    Must complete cleanly. The new pnpm install -g layer is ~60s first time (cached on rebuild).

    Phase 3: Wire Per-Agent-Group

    For each agent group that should have Gmail (ask the user — typically their personal DM and CLI agents, sometimes shared household agents), persist two changes to the central DB (data/v2.db): the mcpServers.gmail entry and an additionalMounts entry for .gmail-mcp. Both flow through materializeContainerJson on every spawn, so editing groups/<folder>/container.json by hand does not stick — that file is regenerated from the DB.

    List groups, pick which ones get Gmail

    ncl groups list
    

    Register the MCP server

    For each chosen <group-id>:

    ncl groups config add-mcp-server \
      --id <group-id> \
      --name gmail \
      --command gmail-mcp \
      --args '[]' \
      --env '{"GMAIL_OAUTH_PATH":"/workspace/extra/.gmail-mcp/gcp-oauth.keys.json","GMAIL_CREDENTIALS_PATH":"/workspace/extra/.gmail-mcp/credentials.json"}'
    

    Approval behaviour depends on where you run it: from inside an agent's container ncl write verbs are approval-gated (admin approves before it lands); from a host operator shell with full scope, it executes immediately. Either way, the response tells you which path it took.

    Add the .gmail-mcp mount

    Register the mount with the host-only ncl groups config add-mount verb. For each chosen <group-id>:

    ncl groups config add-mount \
      --id <group-id> \
      --host "$HOME/.gmail-mcp" \
      --container .gmail-mcp
    

    --host is the host path, --container is the in-container path (relative, lands at /workspace/extra/.gmail-mcp). No --ro — the MCP server writes refreshed token state back into the mount. The verb is idempotent (a re-run skips if the mount is already present) and operator-only (host-side; rejected from inside a container), so run it from a host operator shell when applying this skill.

    Why the container path is relative: mount-security rejects absolute containerPath values. Additional mounts are prefixed with /workspace/extra/, so containerPath: ".gmail-mcp" lands at /workspace/extra/.gmail-mcp. The MCP server's GMAIL_OAUTH_PATH / GMAIL_CREDENTIALS_PATH env vars point at that absolute location inside the container.

    Why this can't be groups/<folder>/container.json: post-migration 014-container-configs, materializeContainerJson in src/container-config.ts rewrites that file from the DB on every spawn. Anything hand-edited there is silently overwritten on next restart.

    Phase 4: Build, Validate, Restart

    pnpm run build
    pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit
    (cd container/agent-runner && bun test src/providers/gmail-dockerfile.test.ts src/providers/gmail-allow-pattern.test.ts)
    

    All must be clean before proceeding. gmail-dockerfile.test.ts confirms the package install is wired into the image; gmail-allow-pattern.test.ts confirms the allow-pattern derivation that exposes mcp__gmail__*. A failure means one drifted.

    Run from your NanoClaw project root:

    source setup/lib/install-slug.sh
    launchctl kickstart -k gui/$(id -u)/$(launchd_label)  # macOS
    systemctl --user restart $(systemd_unit)              # Linux
    

    Phase 5: Verify

    Test from the wired agent

    Tell the user:

    In your <agent-name> chat, send: "list my gmail labels" or "search my inbox for invoices from last month".

    The agent should use mcp__gmail__list_labels / mcp__gmail__search. The first call may take a second or two while the MCP server starts and OneCLI does the token exchange.

    Check logs if the tool isn't working

    tail -100 logs/nanoclaw.log logs/nanoclaw.error.log | grep -iE 'gmail|mcp'
    # Per-container logs — session-scoped:
    ls data/v2-sessions/*/stderr.log | head
    

    Common signals:

    • command not found: gmail-mcp → image wasn't rebuilt or PATH doesn't include /pnpm (should — ENV PATH="$PNPM_HOME:$PATH" in Dockerfile).
    • ENOENT: no such file or directory, open '/workspace/extra/.gmail-mcp/credentials.json' → mount is missing. Check ~/.config/nanoclaw/mount-allowlist.json includes a parent of ~/.gmail-mcp.
    • 401 Unauthorized from gmail.googleapis.com → OneCLI isn't injecting. Check the agent's secret mode (onecli agents secrets --id <agent-id>) and that the Gmail app is connected (onecli apps get --provider gmail).
    • Agent says "I don't have Gmail tools" → the gmail MCP server isn't registered in this group's mcpServers (re-run the ncl groups config add-mcp-server step in Phase 3 for that group and restart it), or the agent-runner image is stale (rebuild with ./container/build.sh, with --no-cache if suspicious).

    Removal

    See REMOVE.md for the idempotent removal procedure (delete the copied tests, unregister the MCP server per group, drop the mount, remove the Dockerfile install, rebuild, and optionally drop the stubs and disconnect OneCLI).

    Notes

    • Stub format is OneCLI-prescribed. The access_token: "onecli-managed" pattern with expiry_date: 99999999999999 tells the Google auth client the token is valid; OneCLI intercepts the outgoing Gmail API call and rewrites Authorization: Bearer onecli-managed to the real token. expiry_date: 0 (refresh-interception) is an alternative the OneCLI docs describe — both work but OneCLI's own migrate command writes the far-future variant, which is what this skill assumes.
    • Scopes are set at OAuth connect time. If the agent needs scopes beyond what's currently connected (e.g. the user later wants calendar.readonly for combined email/calendar workflows), disconnect and reconnect Gmail in the OneCLI web UI with the expanded scope set.
    • This is tool-only. Inbound email as a channel (emails trigger the agent) is a separate piece of work — it needs a src/channels/gmail.ts adapter that polls the inbox and routes to a messaging group. The pre-v2 qwibitai skill had this; it has not been ported to v2's channel architecture as of v2.0.0.

    Credits & references

    • MCP server: @gongrzhe/server-gmail-autoauth-mcp by GongRzhe — MIT-licensed.
    • OneCLI credential stubs: pattern documented at https://onecli.sh/docs/guides/credential-stubs/gmail.md.
    • Skill pattern: modeled on add-atomic-chat-tool and add-vercel.
    • Addresses: issue #1500 (proxy Gmail/Calendar OAuth tokens through credential proxy) for the Gmail side.
    • Related PRs: #1810 (pre-install Gmail/Notion MCP) overlaps on the "install the MCP server in the image" idea but bundles many unrelated changes; this skill is the focused OneCLI-native version.

    Alternatives

    Compare before choosing

    Computed 10042,968

    coreyhaines31/marketingskills

    ab-testing

    When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

    Computed 10023,781

    alirezarezvani/claude-skills

    app-store-optimization

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

    Computed 1004,922

    dotnet/skills

    migrate-vstest-to-mtp

    Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing

    Computed 100165

    JasonColapietro/suede-creator-skills

    suede-ab-testing

    Suede-owned experimentation discipline for hypotheses, sample sizing, test duration, significance, and repeatable experiment programs. Use when comparing variants, deciding whether a result is reliable, or building an experiment backlog and cadence. NOT FOR: analytics instrumentation (use suede-analytics), post-click conversion diagnosis (use suede-site-alchemy), or writing the variant copy itself (use suede-copy).