mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
Merge branch 'main' into fix/2484-2485-v1-name-hardcoding
This commit is contained in:
@@ -92,7 +92,6 @@ onecli agents list
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
grep -q 'CALENDAR_MCP_VERSION' container/Dockerfile && \
|
grep -q 'CALENDAR_MCP_VERSION' container/Dockerfile && \
|
||||||
grep -q "mcp__calendar__\*" container/agent-runner/src/providers/claude.ts && \
|
|
||||||
echo "ALREADY APPLIED — skip to Phase 3"
|
echo "ALREADY APPLIED — skip to Phase 3"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -121,9 +120,7 @@ RUN --mount=type=cache,target=/root/.cache/pnpm \
|
|||||||
pnpm install -g "@cocal/google-calendar-mcp@${CALENDAR_MCP_VERSION}"
|
pnpm install -g "@cocal/google-calendar-mcp@${CALENDAR_MCP_VERSION}"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add tools to allowlist
|
**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 `calendar` in Phase 3 automatically allows `mcp__calendar__*`. Earlier versions of this skill instructed a static `TOOL_ALLOWLIST` edit — that's now redundant.
|
||||||
|
|
||||||
Edit `container/agent-runner/src/providers/claude.ts`. Add `'mcp__calendar__*'` to `TOOL_ALLOWLIST` after `'mcp__nanoclaw__*'` (or after `'mcp__gmail__*'` if present).
|
|
||||||
|
|
||||||
### Rebuild the container image
|
### Rebuild the container image
|
||||||
|
|
||||||
@@ -133,33 +130,46 @@ Edit `container/agent-runner/src/providers/claude.ts`. Add `'mcp__calendar__*'`
|
|||||||
|
|
||||||
## Phase 3: Wire Per-Agent-Group
|
## Phase 3: Wire Per-Agent-Group
|
||||||
|
|
||||||
For each agent group, merge into `groups/<folder>/container.json`:
|
For each agent group, persist two changes to the **central DB** (`data/v2.db`): the `mcpServers.calendar` entry and an `additionalMounts` entry for `.calendar-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.
|
||||||
|
|
||||||
```jsonc
|
### Register the MCP server
|
||||||
{
|
|
||||||
"mcpServers": {
|
For each chosen `<group-id>` (use `ncl groups list` to enumerate):
|
||||||
"calendar": {
|
|
||||||
"command": "google-calendar-mcp",
|
```bash
|
||||||
"args": [],
|
ncl groups config add-mcp-server \
|
||||||
"env": {
|
--id <group-id> \
|
||||||
"GOOGLE_OAUTH_CREDENTIALS": "/workspace/extra/.calendar-mcp/gcp-oauth.keys.json",
|
--name calendar \
|
||||||
"GOOGLE_CALENDAR_MCP_TOKEN_PATH": "/workspace/extra/.calendar-mcp/credentials.json"
|
--command google-calendar-mcp \
|
||||||
}
|
--args '[]' \
|
||||||
}
|
--env '{"GOOGLE_OAUTH_CREDENTIALS":"/workspace/extra/.calendar-mcp/gcp-oauth.keys.json","GOOGLE_CALENDAR_MCP_TOKEN_PATH":"/workspace/extra/.calendar-mcp/credentials.json"}'
|
||||||
},
|
|
||||||
"additionalMounts": [
|
|
||||||
{
|
|
||||||
"hostPath": "/home/<user>/.calendar-mcp",
|
|
||||||
"containerPath": ".calendar-mcp",
|
|
||||||
"readonly": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Substitute `<user>` with `echo $HOME`. `containerPath` is relative (mount-security rejects absolute paths — additional mounts land at `/workspace/extra/<relative>`).
|
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.
|
||||||
|
|
||||||
**Same-group-as-gmail tip:** if this group already has the gmail MCP + `.gmail-mcp` mount, **merge, don't replace** — both entries coexist in `mcpServers` and `additionalMounts`.
|
### Add the `.calendar-mcp` mount
|
||||||
|
|
||||||
|
There is no `ncl groups config add-mount` verb yet (tracked in [#2395](https://github.com/nanocoai/nanoclaw/issues/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):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GROUP_ID='<group-id>'
|
||||||
|
HOST_PATH="$HOME/.calendar-mcp"
|
||||||
|
MOUNT=$(jq -cn --arg h "$HOST_PATH" '{hostPath:$h, containerPath:".calendar-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 NanoClaw project root (where `data/v2.db` lives). The `$[#]` placeholder is SQLite JSON1's append-to-end notation; it's `\$`-escaped so bash doesn't arithmetic-expand it before sqlite sees it. `updated_at` is ISO-string everywhere else in the schema, so use `datetime('now')` — not `strftime('%s','now')`, which would silently mix epoch ints into a column of YYYY-MM-DD HH:MM:SS strings.
|
||||||
|
|
||||||
|
**Switch to `ncl groups config add-mount` once #2395 lands.** Update this skill at that time.
|
||||||
|
|
||||||
|
`containerPath` is relative (mount-security rejects absolute paths — additional mounts land at `/workspace/extra/<relative>`).
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
**Same-group-as-gmail tip:** if this group already has the gmail MCP + `.gmail-mcp` mount, both coexist — `ncl groups config add-mcp-server` only updates the named entry, and `json_insert` appends to `additional_mounts` without disturbing existing entries.
|
||||||
|
|
||||||
## Phase 4: Build and Restart
|
## Phase 4: Build and Restart
|
||||||
|
|
||||||
@@ -193,16 +203,28 @@ Common signals:
|
|||||||
- `command not found: google-calendar-mcp` → image not rebuilt.
|
- `command not found: google-calendar-mcp` → image not rebuilt.
|
||||||
- `ENOENT ...credentials.json` → mount missing. Check the mount allowlist.
|
- `ENOENT ...credentials.json` → mount missing. Check the mount allowlist.
|
||||||
- `401 Unauthorized` from `*.googleapis.com` → OneCLI isn't injecting; verify agent's secret mode and that Google Calendar is connected.
|
- `401 Unauthorized` from `*.googleapis.com` → OneCLI isn't injecting; verify agent's secret mode and that Google Calendar is connected.
|
||||||
- Agent says "I don't have calendar tools" → `mcp__calendar__*` missing from `TOOL_ALLOWLIST`, or image cache stale (`./container/build.sh` again).
|
- Agent says "I don't have calendar tools" → the `calendar` 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 (`./container/build.sh`, `--no-cache` if suspicious).
|
||||||
|
|
||||||
## Removal
|
## Removal
|
||||||
|
|
||||||
1. Delete `"calendar"` from `mcpServers` and the `.calendar-mcp` mount from `additionalMounts` in each group's `container.json`.
|
1. For each group that had Calendar wired, remove the MCP server from the DB:
|
||||||
2. Remove `'mcp__calendar__*'` from `TOOL_ALLOWLIST`.
|
```bash
|
||||||
|
ncl groups config remove-mcp-server --id <group-id> --name calendar
|
||||||
|
```
|
||||||
|
2. Remove the `.calendar-mcp` mount from the DB (no `remove-mount` verb yet — same #2395 dependency):
|
||||||
|
```bash
|
||||||
|
pnpm exec tsx scripts/q.ts data/v2.db "UPDATE container_configs \
|
||||||
|
SET additional_mounts = (SELECT json_group_array(value) FROM json_each(additional_mounts) \
|
||||||
|
WHERE json_extract(value, '\$.containerPath') != '.calendar-mcp'), \
|
||||||
|
updated_at = datetime('now') \
|
||||||
|
WHERE agent_group_id = '<group-id>';"
|
||||||
|
```
|
||||||
3. Remove `CALENDAR_MCP_VERSION` ARG and the calendar package from the Dockerfile install block.
|
3. Remove `CALENDAR_MCP_VERSION` ARG and the calendar package from the Dockerfile install block.
|
||||||
4. `pnpm run build && ./container/build.sh && systemctl --user restart nanoclaw`.
|
4. `pnpm run build && ./container/build.sh && systemctl --user restart nanoclaw`.
|
||||||
5. Optional: `rm -rf ~/.calendar-mcp/` and `onecli apps disconnect --provider google-calendar`.
|
5. Optional: `rm -rf ~/.calendar-mcp/` and `onecli apps disconnect --provider google-calendar`.
|
||||||
|
|
||||||
|
No `TOOL_ALLOWLIST` removal step — Phase 2 no longer edits it.
|
||||||
|
|
||||||
## Credits & references
|
## Credits & references
|
||||||
|
|
||||||
- **MCP server:** [`@cocal/google-calendar-mcp`](https://github.com/cocal-com/google-calendar-mcp) — MIT-licensed, actively maintained, multi-account and multi-calendar.
|
- **MCP server:** [`@cocal/google-calendar-mcp`](https://github.com/cocal-com/google-calendar-mcp) — MIT-licensed, actively maintained, multi-account and multi-calendar.
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ onecli agents secrets --id <agent-id>
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
grep -q 'GMAIL_MCP_VERSION' container/Dockerfile && \
|
grep -q 'GMAIL_MCP_VERSION' container/Dockerfile && \
|
||||||
grep -q "mcp__gmail__\*" container/agent-runner/src/providers/claude.ts && \
|
|
||||||
echo "ALREADY APPLIED — skip to Phase 3"
|
echo "ALREADY APPLIED — skip to Phase 3"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -132,9 +131,7 @@ Pinned version matters — `minimumReleaseAge` in `pnpm-workspace.yaml` gates tr
|
|||||||
|
|
||||||
**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`.
|
**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`.
|
||||||
|
|
||||||
### Add tools to allowlist
|
**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.
|
||||||
|
|
||||||
Edit `container/agent-runner/src/providers/claude.ts`. Find `'mcp__nanoclaw__*',` in `TOOL_ALLOWLIST` and add `'mcp__gmail__*',` after it.
|
|
||||||
|
|
||||||
### Rebuild the container image
|
### Rebuild the container image
|
||||||
|
|
||||||
@@ -146,36 +143,51 @@ Must complete cleanly. The new `pnpm install -g` layer is ~60s first time (cache
|
|||||||
|
|
||||||
## Phase 3: Wire Per-Agent-Group
|
## 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), edit `groups/<folder>/container.json` to add the mount and MCP server.
|
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.
|
||||||
|
|
||||||
Merge these into the group's `container.json`:
|
### List groups, pick which ones get Gmail
|
||||||
|
|
||||||
```jsonc
|
```bash
|
||||||
{
|
ncl groups list
|
||||||
"mcpServers": {
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalMounts": [
|
|
||||||
{
|
|
||||||
"hostPath": "/home/<user>/.gmail-mcp",
|
|
||||||
"containerPath": ".gmail-mcp",
|
|
||||||
"readonly": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Substitute `<user>` with the host user's home (use `echo $HOME`, don't assume `~` will expand — `container-runner.ts` does expand `~` via `expandPath`, but an explicit absolute path is clearer and matches what `/manage-mounts` writes).
|
### Register the MCP server
|
||||||
|
|
||||||
|
For each chosen `<group-id>`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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](https://github.com/nanocoai/nanoclaw/issues/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):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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 NanoClaw project root (where `data/v2.db` lives). The `$[#]` placeholder is SQLite JSON1's append-to-end notation; it's `\$`-escaped so bash doesn't arithmetic-expand it before sqlite sees it. `updated_at` is ISO-string everywhere else in the schema, so use `datetime('now')` — not `strftime('%s','now')`, which would silently mix epoch ints into a column of YYYY-MM-DD HH:MM:SS strings.
|
||||||
|
|
||||||
|
**Switch to `ncl groups config add-mount` once #2395 lands.** Update this skill at that time.
|
||||||
|
|
||||||
**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 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 and Restart
|
## Phase 4: Build and Restart
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -206,17 +218,29 @@ 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).
|
- `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`.
|
- `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`).
|
- `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" → `mcp__gmail__*` wasn't added to `TOOL_ALLOWLIST`, or the agent-runner wasn't rebuilt (image cache — run `./container/build.sh` again with `--no-cache` if suspicious).
|
- 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
|
## Removal
|
||||||
|
|
||||||
1. Delete the `"gmail"` entry from `mcpServers` and the `.gmail-mcp` entry from `additionalMounts` in each group's `container.json`.
|
1. For each group that had Gmail wired, remove the MCP server from the DB:
|
||||||
2. Remove `'mcp__gmail__*'` from `TOOL_ALLOWLIST` in `container/agent-runner/src/providers/claude.ts`.
|
```bash
|
||||||
|
ncl groups config remove-mcp-server --id <group-id> --name gmail
|
||||||
|
```
|
||||||
|
2. Remove the `.gmail-mcp` mount from the DB (no `remove-mount` verb yet — same #2395 dependency):
|
||||||
|
```bash
|
||||||
|
pnpm exec tsx scripts/q.ts data/v2.db "UPDATE container_configs \
|
||||||
|
SET additional_mounts = (SELECT json_group_array(value) FROM json_each(additional_mounts) \
|
||||||
|
WHERE json_extract(value, '\$.containerPath') != '.gmail-mcp'), \
|
||||||
|
updated_at = datetime('now') \
|
||||||
|
WHERE agent_group_id = '<group-id>';"
|
||||||
|
```
|
||||||
3. Remove the `GMAIL_MCP_VERSION` ARG and the `pnpm install -g @gongrzhe/server-gmail-autoauth-mcp` block from `container/Dockerfile`.
|
3. Remove the `GMAIL_MCP_VERSION` ARG and the `pnpm install -g @gongrzhe/server-gmail-autoauth-mcp` block from `container/Dockerfile`.
|
||||||
4. `pnpm run build && ./container/build.sh && systemctl --user restart nanoclaw`.
|
4. `pnpm run build && ./container/build.sh && systemctl --user restart nanoclaw`.
|
||||||
5. (Optional) `rm -rf ~/.gmail-mcp/` if no other host-side tool needs the stubs.
|
5. (Optional) `rm -rf ~/.gmail-mcp/` if no other host-side tool needs the stubs.
|
||||||
6. (Optional) Disconnect Gmail in OneCLI: `onecli apps disconnect --provider gmail`.
|
6. (Optional) Disconnect Gmail in OneCLI: `onecli apps disconnect --provider gmail`.
|
||||||
|
|
||||||
|
No `TOOL_ALLOWLIST` removal step — Phase 2 no longer edits it.
|
||||||
|
|
||||||
## Notes
|
## 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.
|
- **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.
|
||||||
|
|||||||
Reference in New Issue
Block a user