Receber por email
← Voltar para o catálogo

add-gmail-tool

Integre o Gmail como uma ferramenta MCP (ler, pesquisar, enviar, rotular, rascunhar) usando OAuth gerenciado pelo OneCLI. Isso permite que agentes em grupos habilitados acessem as ferramentas do Gmail, com o OneCLI injetando tokens de forma segura no momento da solicitação, evitando o armazenamento de credenciais brutas.

29.9kestrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add nanocoai/nanoclaw

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/add-gmail-tool/svg)](https://www.skillteca.com.br/skills/add-gmail-tool)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

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 gmail-mcp@1.1.11, 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"

Add MCP server to Dockerfile

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

ARG CLAUDE_CODE_VERSION=2.1.116
ARG AGENT_BROWSER_VERSION=latest
ARG VERCEL_VERSION=latest
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 after it, before # ---- Entrypoint:

RUN --mount=type=cache,target=/root/.cache/pnpm \
    pnpm install -g \
        "@gongrzhe/server-gmail-autoauth-mcp@${GMAIL_MCP_VERSION}" \
        "zod-to-json-schema@3.22.5"

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/server-gmail-autoauth-mcp@1.1.11 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.

No TOOL_ALLOWLIST edit needed. container/agent-runner/src/providers/claude.ts derives the allow-pattern dynamically from each group's mcpServers map (Object.keys(this.mcpServers).map(mcpAllowPattern)), so registering gmail in Phase 3 automatically allows mcp__gmail__*. Earlier versions of this skill instructed a static TOOL_ALLOWLIST edit — that's now redundant.

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

There is no ncl groups config add-mount verb yet (tracked in #2395). Until that ships, edit the DB directly via the in-tree wrapper (scripts/q.ts — setup/verify.ts:5 codifies that NanoClaw avoids depending on the sqlite3 CLI binary, so don't shell out to it):

GROUP_ID='<group-id>'
HOST_PATH="$HOME/.gmail-mcp"
MOUNT=$(jq -cn --arg h "$HOST_PATH" '{hostPath:$h, containerPath:".gmail-mcp", readonly:false}')
pnpm exec tsx scripts/q.ts data/v2.db "UPDATE container_configs \
  SET additional_mounts = json_insert(additional_mounts, '\$[#]', json('$MOUNT')), \
      updated_at = datetime('now') \
  WHERE agent_group_id = '$GROUP_ID';"

Run from your N

Compartilhar X LinkedIn