mercury-agent 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +452 -451
- package/container/Dockerfile +127 -127
- package/container/Dockerfile.base +109 -109
- package/container/Dockerfile.power +17 -17
- package/container/agent-package.json +8 -8
- package/container/build.sh +54 -54
- package/docs/ROADMAP.md +3 -4
- package/docs/archive/summarization/2026-07-02-recent-dev-summary.md +71 -0
- package/docs/auth/dashboard.md +28 -28
- package/docs/auth/overview.md +109 -109
- package/docs/auth/whatsapp.md +173 -173
- package/docs/authoring-profiles.md +174 -174
- package/docs/configuration.md +54 -54
- package/docs/container-lifecycle.md +349 -349
- package/docs/{bugs/bwrap-privileged-linux-docker.md → debug/major/2026-07-02-bwrap-privileged-linux-docker.md} +21 -1
- package/docs/{bugs/e2big-prompt-delivery-fix.md → debug/major/2026-07-02-e2big-prompt-delivery-fix.md} +27 -1
- package/docs/{bugs/registry-pull-no-local-fallback.md → debug/major/2026-07-02-registry-pull-no-local-fallback.md} +27 -1
- package/docs/debug/summarization/2026-07-02-common-bug-patterns.md +72 -0
- package/docs/deployment.md +199 -199
- package/docs/extensions.md +375 -375
- package/docs/graceful-shutdown.md +62 -62
- package/docs/kb-distillation.md +77 -77
- package/docs/media/overview.md +140 -140
- package/docs/media/whatsapp.md +171 -171
- package/docs/memory.md +137 -137
- package/docs/permissions.md +217 -217
- package/docs/pipeline.md +228 -228
- package/docs/prd-chat-memory.md +76 -76
- package/docs/prd-config-load.md +82 -82
- package/docs/rate-limiting.md +229 -229
- package/docs/runbooks/publish-checklist.md +9 -1
- package/docs/scheduler.md +288 -288
- package/docs/setup-discord.md +100 -100
- package/docs/setup-slack.md +119 -119
- package/docs/setup-whatsapp.md +94 -94
- package/docs/subagents.md +166 -166
- package/docs/web-search.md +62 -62
- package/examples/extensions/README.md +12 -12
- package/examples/extensions/charts/index.ts +13 -13
- package/examples/extensions/charts/skill/SKILL.md +98 -98
- package/examples/extensions/gws/README.md +52 -52
- package/examples/extensions/gws/skill/SKILL.md +57 -57
- package/examples/extensions/gws/skill/references/calendar.md +101 -101
- package/examples/extensions/gws/skill/references/docs.md +65 -65
- package/examples/extensions/gws/skill/references/drive.md +79 -79
- package/examples/extensions/gws/skill/references/gmail.md +85 -85
- package/examples/extensions/gws/skill/references/sheets.md +60 -60
- package/examples/extensions/napkin/skill/SKILL.md +728 -728
- package/examples/extensions/pdf/skill/LICENSE.txt +30 -30
- package/examples/extensions/pdf/skill/SKILL.md +314 -314
- package/examples/extensions/pdf/skill/forms.md +294 -294
- package/examples/extensions/pdf/skill/reference.md +611 -611
- package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -65
- package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -11
- package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -33
- package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -37
- package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -122
- package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -115
- package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -98
- package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -107
- package/examples/extensions/permission-guard/index.ts +65 -65
- package/examples/extensions/pinchtab/skill/SKILL.md +224 -224
- package/examples/extensions/pinchtab/skill/TRUST.md +69 -69
- package/examples/extensions/pinchtab/skill/references/api.md +297 -297
- package/examples/extensions/pinchtab/skill/references/env.md +45 -45
- package/examples/extensions/pinchtab/skill/references/profiles.md +107 -107
- package/examples/extensions/tradestation/host/refresh.ts +102 -102
- package/examples/extensions/tradestation/index.ts +153 -153
- package/examples/extensions/tradestation/skill/SKILL.md +67 -67
- package/examples/extensions/voice-synth/index.ts +94 -94
- package/examples/extensions/voice-synth/skill/SKILL.md +38 -38
- package/examples/extensions/voice-transcribe/requirements.txt +8 -8
- package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -179
- package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -53
- package/examples/extensions/yahoo-mail/cli/package.json +13 -13
- package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -78
- package/package.json +106 -106
- package/resources/agents/explore.md +50 -50
- package/resources/agents/worker.md +24 -24
- package/resources/connection-env-vars.json +25 -25
- package/resources/pi-extensions/subagent/agents.ts +126 -126
- package/resources/pi-extensions/subagent/index.ts +964 -964
- package/resources/profiles/coding/AGENTS.md +43 -43
- package/resources/profiles/coding/mercury-profile.yaml +15 -15
- package/resources/profiles/general/AGENTS.md +31 -31
- package/resources/profiles/general/mercury-profile.yaml +15 -15
- package/resources/profiles/research/AGENTS.md +40 -40
- package/resources/profiles/research/mercury-profile.yaml +15 -15
- package/resources/skills/config/SKILL.md +25 -25
- package/resources/skills/context/SKILL.md +33 -33
- package/resources/skills/conversation-recap/SKILL.md +19 -19
- package/resources/skills/mutes/SKILL.md +31 -31
- package/resources/skills/permissions/SKILL.md +19 -19
- package/resources/skills/preferences/SKILL.md +31 -31
- package/resources/skills/recall/SKILL.md +24 -24
- package/resources/skills/roles/SKILL.md +18 -18
- package/resources/skills/spaces/SKILL.md +18 -18
- package/resources/skills/tasks/SKILL.md +45 -45
- package/resources/templates/AGENTS.md +157 -157
- package/resources/templates/env.template +38 -38
- package/resources/templates/mercury.example.yaml +99 -99
- package/src/agent/container-entry.ts +1 -1
- package/src/agent/container-runner.ts +1345 -1346
- package/src/cli/mercury.ts +39 -7
- package/src/cli/mrctl.ts +636 -636
- package/src/config-file.ts +540 -540
- package/src/config.ts +339 -339
- package/src/core/api.ts +125 -125
- package/src/core/caller-token.ts +101 -101
- package/src/core/permissions.ts +228 -228
- package/src/core/profiles.ts +271 -271
- package/src/core/routes/capability.ts +70 -70
- package/src/core/routes/index.ts +15 -15
- package/src/core/runtime.ts +1530 -1530
- package/src/dashboard/index.html +729 -729
- package/src/extensions/api.ts +273 -273
- package/src/extensions/loader.ts +286 -286
- package/src/extensions/types.ts +517 -517
- package/src/main.ts +605 -605
- package/docs/pending-updates/applicative-profiles.md +0 -15
- package/docs/pending-updates/caller-bound-capability-token.md +0 -15
- package/docs/pending-updates/dm-auto-space.md +0 -15
- /package/docs/archive/{2026-07-01-applicative-profiles.md → applicative-profiles/2026-07-01-applicative-profiles.md} +0 -0
- /package/docs/archive/{2026-07-01-caller-bound-capability-token.md → applicative-profiles/2026-07-01-caller-bound-capability-token.md} +0 -0
- /package/docs/archive/{2026-07-01-dm-auto-space.md → applicative-profiles/2026-07-01-dm-auto-space.md} +0 -0
package/docs/ROADMAP.md
CHANGED
|
@@ -25,9 +25,6 @@ Single source of truth for priority. Rule: ≤15 min/week to maintain.
|
|
|
25
25
|
| # | Item | Doc | Depends on | Why now |
|
|
26
26
|
|---|------|-----|-----------|---------|
|
|
27
27
|
| 1 | **autonomous-planning-tier** | [doc](backlog/autonomous-planning-tier.md) | — | Let agents decompose ideas, keep human gate |
|
|
28
|
-
| 2 | **dm-auto-space** | [doc](backlog/dm-auto-space.md) | — | Auto-create space per customer DM |
|
|
29
|
-
| 3 | **applicative-profiles** | [doc](backlog/applicative-profiles.md) | caller-bound-capability-token | Generic profile layer; host-side broker keeps secrets off customer containers |
|
|
30
|
-
| 4 | **caller-bound-capability-token** | [doc](backlog/caller-bound-capability-token.md) | — | Per-turn token so brokers can trust callerId; also hardens TradeStation |
|
|
31
28
|
|
|
32
29
|
## Later
|
|
33
30
|
|
|
@@ -41,4 +38,6 @@ Single source of truth for priority. Rule: ≤15 min/week to maintain.
|
|
|
41
38
|
|
|
42
39
|
| Item | Shipped | What |
|
|
43
40
|
|------|---------|------|
|
|
44
|
-
|
|
|
41
|
+
| **applicative-profiles** | 2026-07-01 | Generic profile layer: manifest schema, exhaustive member scoping, host-side capability broker |
|
|
42
|
+
| **caller-bound-capability-token** | 2026-07-01 | Per-turn unspoofable caller token for host API auth; also hardens TradeStation |
|
|
43
|
+
| **dm-auto-space** | 2026-07-01 | Auto-create space per customer DM with rate limits and dashboard controls |
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Recent Dev Summary
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-02
|
|
4
|
+
**Covers:** 3 shipped features · 2026-06-30 → 2026-07-01
|
|
5
|
+
|
|
6
|
+
Three tightly-related features shipped together to lay the groundwork for customer-facing (member) profiles: a per-DM auto-space so each customer gets isolated persistent context, a caller-bound capability token so the host can trust *who* is calling, and applicative profiles that scope member capabilities and route privileged work through a host-side broker. The unifying thread is a **security pivot**: moving from "trust whoever holds a tool" to "keep secrets on the host and bind identity cryptographically" — a prerequisite for exposing capabilities to untrusted members.
|
|
7
|
+
|
|
8
|
+
## Shipped
|
|
9
|
+
|
|
10
|
+
| Feature | Slug | Date shipped | Key takeaway |
|
|
11
|
+
|---------|------|-------------|--------------|
|
|
12
|
+
| Auto-Create Space per DM | dm-auto-space | 2026-07-01 | Config-driven per-customer spaces; default-off, idempotent seeding via read-before-write |
|
|
13
|
+
| Caller-Bound Capability Token | caller-bound-capability-token | 2026-07-01 | Per-turn HMAC token binds `{callerId, spaceId}`; host trusts the token, not spoofable headers |
|
|
14
|
+
| Applicative Profiles | applicative-profiles | 2026-07-01 | Profiles scope member permissions + run privileged work host-side; secrets never enter member containers |
|
|
15
|
+
|
|
16
|
+
## Build patterns
|
|
17
|
+
|
|
18
|
+
### 1. Security by architecture, not by guardrail
|
|
19
|
+
|
|
20
|
+
Rather than hardening a bypassable boundary, these features removed the sensitive material from the untrusted zone entirely.
|
|
21
|
+
|
|
22
|
+
| Feature | Observation |
|
|
23
|
+
|---------|-------------|
|
|
24
|
+
| applicative-profiles | Credentials stay in host storage; member containers get only a self-scoped per-turn token — so `printenv` leaks nothing. Explicitly does *not* rely on the bypassable permission guard (TODO-2). |
|
|
25
|
+
| caller-bound-capability-token | Signing key never enters the container; the container holds only its own turn's token and cannot forge another caller. |
|
|
26
|
+
|
|
27
|
+
**Rule:** When an untrusted actor shares an execution environment, don't guard the secret — remove it from that environment. Security should come from where the secret lives, not from blocking the paths to it.
|
|
28
|
+
|
|
29
|
+
### 2. Reuse the proven pattern over inventing one
|
|
30
|
+
|
|
31
|
+
New capabilities deliberately mirrored an existing production mechanism instead of designing fresh machinery.
|
|
32
|
+
|
|
33
|
+
| Feature | Observation |
|
|
34
|
+
|---------|-------------|
|
|
35
|
+
| applicative-profiles | The host-side capability broker is the TradeStation pattern generalized (`mrctl`→control-plane API, creds host-side), not a new transport. |
|
|
36
|
+
| caller-bound-capability-token | TradeStation's confirm guard needed *no code change* — it already read identity from `c.get("auth")`, which the new middleware now populates from the token. |
|
|
37
|
+
|
|
38
|
+
**Rule:** Before building new infrastructure, find the closest production-proven pattern and generalize it. Consumers that read from the right abstraction inherit the upgrade for free.
|
|
39
|
+
|
|
40
|
+
### 3. Backward-compatible, additive rollout
|
|
41
|
+
|
|
42
|
+
Every feature shipped default-off or fallback-preserving so existing deployments were unaffected.
|
|
43
|
+
|
|
44
|
+
| Feature | Observation |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| dm-auto-space | `enabled` defaults to `false`; global daily rate limits default to `0` (unlimited). |
|
|
47
|
+
| caller-bound-capability-token | Absent a token, the old shared-secret + header path is unchanged, so old container images keep working during rollout. |
|
|
48
|
+
| applicative-profiles | All new profile schema fields optional; brokers additive; existing profiles still parse. |
|
|
49
|
+
|
|
50
|
+
**Rule:** Ship member-facing and security-sensitive changes as additive with a safe default; make the new path authoritative only when explicitly present, so rollout never breaks in-flight deployments.
|
|
51
|
+
|
|
52
|
+
### 4. Plan-vs-reality divergence on the crypto detail
|
|
53
|
+
|
|
54
|
+
Each retrospective flagged where the plan's shortcut was unsafe and was corrected during implementation.
|
|
55
|
+
|
|
56
|
+
| Feature | Observation |
|
|
57
|
+
|---------|-------------|
|
|
58
|
+
| caller-bound-capability-token | Plan proposed deriving the signing key from `API_SECRET`; rejected because `API_SECRET` is readable in the container — switched to an ephemeral host-only key. |
|
|
59
|
+
| applicative-profiles | Profile activation moved from per-space `space_config` writes to a module-level registry + persisted `.mercury/active-profile.json`; schema dropped `.strict()` to honor the strict-yaml crash post-mortem. |
|
|
60
|
+
|
|
61
|
+
**Rule:** Re-examine any "derive the key from the existing secret" shortcut against the threat model — if the base secret is reachable by the attacker, the derived key is too.
|
|
62
|
+
|
|
63
|
+
## Comparison with previous dev summary
|
|
64
|
+
|
|
65
|
+
None — this is the first dev summary. Future summaries should watch whether the "security by architecture" and "reuse the proven pattern" themes persist as more member-facing profiles land in the private repo.
|
|
66
|
+
|
|
67
|
+
## Action items
|
|
68
|
+
|
|
69
|
+
1. **Land the private barber-appointments profile** against the now-public contract (schema + broker + caller token) to validate the design end-to-end.
|
|
70
|
+
2. **Audit remaining header-trusting routes** to migrate onto token-derived identity now that the mechanism exists.
|
|
71
|
+
3. **Document the host-side broker contract** (`docs/authoring-profiles.md`) as the canonical reference for external profile authors, and keep it in sync as capabilities grow.
|
package/docs/auth/dashboard.md
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
# Dashboard Authentication
|
|
2
|
-
|
|
3
|
-
The Mercury dashboard (`/dashboard/*`) is protected by `MERCURY_API_SECRET`. All htmx partial requests and the SSE events stream require a valid `mercury_token` session cookie.
|
|
4
|
-
|
|
5
|
-
## How it works
|
|
6
|
-
|
|
7
|
-
### Login route
|
|
8
|
-
|
|
9
|
-
`GET /dashboard/login?token=<secret>` — the entry point for browser sessions.
|
|
10
|
-
|
|
11
|
-
- Validates `token` against `MERCURY_API_SECRET` using `timingSafeEqual`
|
|
12
|
-
- On success: sets `mercury_token` HttpOnly cookie and redirects to `/dashboard`
|
|
13
|
-
- On failure: returns `401 Invalid or missing token`
|
|
14
|
-
- Not protected by the dashboard auth middleware (it's the login endpoint itself)
|
|
15
|
-
|
|
16
|
-
## Auth flow
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
User navigates to https://<host>:<port>/dashboard/login?token=<MERCURY_API_SECRET>
|
|
20
|
-
→ agent sets mercury_token HttpOnly cookie
|
|
21
|
-
→ 302 /dashboard
|
|
22
|
-
→ dashboard loads, htmx requests include cookie ✅
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Key constraints
|
|
26
|
-
|
|
27
|
-
- `MERCURY_API_SECRET` should be set to a long random string. `mercury setup` auto-generates one.
|
|
28
|
-
- The cookie is HttpOnly — not accessible from JavaScript.
|
|
1
|
+
# Dashboard Authentication
|
|
2
|
+
|
|
3
|
+
The Mercury dashboard (`/dashboard/*`) is protected by `MERCURY_API_SECRET`. All htmx partial requests and the SSE events stream require a valid `mercury_token` session cookie.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
### Login route
|
|
8
|
+
|
|
9
|
+
`GET /dashboard/login?token=<secret>` — the entry point for browser sessions.
|
|
10
|
+
|
|
11
|
+
- Validates `token` against `MERCURY_API_SECRET` using `timingSafeEqual`
|
|
12
|
+
- On success: sets `mercury_token` HttpOnly cookie and redirects to `/dashboard`
|
|
13
|
+
- On failure: returns `401 Invalid or missing token`
|
|
14
|
+
- Not protected by the dashboard auth middleware (it's the login endpoint itself)
|
|
15
|
+
|
|
16
|
+
## Auth flow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
User navigates to https://<host>:<port>/dashboard/login?token=<MERCURY_API_SECRET>
|
|
20
|
+
→ agent sets mercury_token HttpOnly cookie
|
|
21
|
+
→ 302 /dashboard
|
|
22
|
+
→ dashboard loads, htmx requests include cookie ✅
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Key constraints
|
|
26
|
+
|
|
27
|
+
- `MERCURY_API_SECRET` should be set to a long random string. `mercury setup` auto-generates one.
|
|
28
|
+
- The cookie is HttpOnly — not accessible from JavaScript.
|
package/docs/auth/overview.md
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
# Authentication
|
|
2
|
-
|
|
3
|
-
Mercury needs credentials for two things:
|
|
4
|
-
|
|
5
|
-
1. **AI model provider** — to call the LLM (Anthropic, OpenAI, etc.)
|
|
6
|
-
2. **Chat platforms** — to connect to WhatsApp, Discord, Slack, Teams
|
|
7
|
-
|
|
8
|
-
## Model Provider Auth
|
|
9
|
-
|
|
10
|
-
### OAuth Login (Recommended)
|
|
11
|
-
|
|
12
|
-
Mercury reuses [pi](https://github.com/badlogic/pi)'s OAuth providers. No API key needed — just login:
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
mercury auth login # Interactive provider picker
|
|
16
|
-
mercury auth login anthropic # Or specify directly
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Supported providers:
|
|
20
|
-
|
|
21
|
-
| Provider | ID | What it gives you |
|
|
22
|
-
|----------|----|-------------------|
|
|
23
|
-
| Anthropic (Claude Pro/Max) | `anthropic` | Claude access via your subscription |
|
|
24
|
-
| GitHub Copilot | `github-copilot` | Models via Copilot subscription |
|
|
25
|
-
| Google Gemini CLI | `google-gemini-cli` | Gemini via Google Cloud |
|
|
26
|
-
| Antigravity | `antigravity` | Gemini 3, Claude, GPT-OSS via Google Cloud |
|
|
27
|
-
| ChatGPT Plus/Pro | `openai-codex` | OpenAI models via ChatGPT subscription |
|
|
28
|
-
|
|
29
|
-
Credentials are saved to `.mercury/global/auth.json` and auto-refreshed when expired.
|
|
30
|
-
|
|
31
|
-
### API Key
|
|
32
|
-
|
|
33
|
-
Alternatively, set an API key in `.env`:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
MERCURY_ANTHROPIC_API_KEY=sk-ant-...
|
|
37
|
-
# or
|
|
38
|
-
MERCURY_ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-...
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Resolution Order
|
|
42
|
-
|
|
43
|
-
Mercury resolves credentials in this order:
|
|
44
|
-
|
|
45
|
-
1. OAuth credentials from `auth.json` (via `mercury auth login`)
|
|
46
|
-
2. `MERCURY_ANTHROPIC_OAUTH_TOKEN` from `.env`
|
|
47
|
-
3. `MERCURY_ANTHROPIC_API_KEY` from `.env`
|
|
48
|
-
|
|
49
|
-
> **OAuth always takes precedence over API keys.** If a provider has both an OAuth connection (in `auth.json` or `MERCURY_*_OAUTH_TOKEN`) and an API key (`MERCURY_*_API_KEY`), the OAuth token is used and the API key is ignored. This applies both to the CLI and to agents provisioned via the cloud console.
|
|
50
|
-
|
|
51
|
-
### Managing Credentials
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
mercury auth status # Show what's configured
|
|
55
|
-
mercury auth logout anthropic # Remove saved credentials
|
|
56
|
-
mercury auth logout # List what's logged in
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Chat Platform Auth
|
|
60
|
-
|
|
61
|
-
### WhatsApp
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
mercury auth whatsapp # QR code (recommended)
|
|
65
|
-
mercury auth whatsapp --pairing-code --phone 1234 # Pairing code (headless)
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
See [whatsapp.md](whatsapp.md) for details.
|
|
69
|
-
|
|
70
|
-
### Discord
|
|
71
|
-
|
|
72
|
-
Set in `.env`:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
MERCURY_ENABLE_DISCORD=true
|
|
76
|
-
MERCURY_DISCORD_BOT_TOKEN=your-bot-token
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Slack
|
|
80
|
-
|
|
81
|
-
Set in `.env`:
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
MERCURY_ENABLE_SLACK=true
|
|
85
|
-
MERCURY_SLACK_BOT_TOKEN=xoxb-...
|
|
86
|
-
MERCURY_SLACK_SIGNING_SECRET=...
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Teams
|
|
90
|
-
|
|
91
|
-
Set in `.env`:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
MERCURY_ENABLE_TEAMS=true
|
|
95
|
-
MERCURY_TEAMS_APP_ID=...
|
|
96
|
-
MERCURY_TEAMS_APP_PASSWORD=...
|
|
97
|
-
MERCURY_TEAMS_APP_TENANT_ID=...
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Dashboard Auth
|
|
101
|
-
|
|
102
|
-
The web dashboard is protected by `MERCURY_API_SECRET`. Browser sessions are established via a login handshake managed by the cloud console — see [dashboard.md](dashboard.md).
|
|
103
|
-
|
|
104
|
-
## Security
|
|
105
|
-
|
|
106
|
-
- `auth.json` has `0600` permissions (owner read/write only)
|
|
107
|
-
- WhatsApp credentials in `.mercury/whatsapp-auth/` are sensitive — treat like passwords
|
|
108
|
-
- All `MERCURY_*` env vars are passed into containers with the prefix stripped
|
|
109
|
-
- Never commit `.env` or `auth.json` to version control
|
|
1
|
+
# Authentication
|
|
2
|
+
|
|
3
|
+
Mercury needs credentials for two things:
|
|
4
|
+
|
|
5
|
+
1. **AI model provider** — to call the LLM (Anthropic, OpenAI, etc.)
|
|
6
|
+
2. **Chat platforms** — to connect to WhatsApp, Discord, Slack, Teams
|
|
7
|
+
|
|
8
|
+
## Model Provider Auth
|
|
9
|
+
|
|
10
|
+
### OAuth Login (Recommended)
|
|
11
|
+
|
|
12
|
+
Mercury reuses [pi](https://github.com/badlogic/pi)'s OAuth providers. No API key needed — just login:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
mercury auth login # Interactive provider picker
|
|
16
|
+
mercury auth login anthropic # Or specify directly
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Supported providers:
|
|
20
|
+
|
|
21
|
+
| Provider | ID | What it gives you |
|
|
22
|
+
|----------|----|-------------------|
|
|
23
|
+
| Anthropic (Claude Pro/Max) | `anthropic` | Claude access via your subscription |
|
|
24
|
+
| GitHub Copilot | `github-copilot` | Models via Copilot subscription |
|
|
25
|
+
| Google Gemini CLI | `google-gemini-cli` | Gemini via Google Cloud |
|
|
26
|
+
| Antigravity | `antigravity` | Gemini 3, Claude, GPT-OSS via Google Cloud |
|
|
27
|
+
| ChatGPT Plus/Pro | `openai-codex` | OpenAI models via ChatGPT subscription |
|
|
28
|
+
|
|
29
|
+
Credentials are saved to `.mercury/global/auth.json` and auto-refreshed when expired.
|
|
30
|
+
|
|
31
|
+
### API Key
|
|
32
|
+
|
|
33
|
+
Alternatively, set an API key in `.env`:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
MERCURY_ANTHROPIC_API_KEY=sk-ant-...
|
|
37
|
+
# or
|
|
38
|
+
MERCURY_ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-...
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Resolution Order
|
|
42
|
+
|
|
43
|
+
Mercury resolves credentials in this order:
|
|
44
|
+
|
|
45
|
+
1. OAuth credentials from `auth.json` (via `mercury auth login`)
|
|
46
|
+
2. `MERCURY_ANTHROPIC_OAUTH_TOKEN` from `.env`
|
|
47
|
+
3. `MERCURY_ANTHROPIC_API_KEY` from `.env`
|
|
48
|
+
|
|
49
|
+
> **OAuth always takes precedence over API keys.** If a provider has both an OAuth connection (in `auth.json` or `MERCURY_*_OAUTH_TOKEN`) and an API key (`MERCURY_*_API_KEY`), the OAuth token is used and the API key is ignored. This applies both to the CLI and to agents provisioned via the cloud console.
|
|
50
|
+
|
|
51
|
+
### Managing Credentials
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mercury auth status # Show what's configured
|
|
55
|
+
mercury auth logout anthropic # Remove saved credentials
|
|
56
|
+
mercury auth logout # List what's logged in
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Chat Platform Auth
|
|
60
|
+
|
|
61
|
+
### WhatsApp
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
mercury auth whatsapp # QR code (recommended)
|
|
65
|
+
mercury auth whatsapp --pairing-code --phone 1234 # Pairing code (headless)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See [whatsapp.md](whatsapp.md) for details.
|
|
69
|
+
|
|
70
|
+
### Discord
|
|
71
|
+
|
|
72
|
+
Set in `.env`:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
MERCURY_ENABLE_DISCORD=true
|
|
76
|
+
MERCURY_DISCORD_BOT_TOKEN=your-bot-token
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Slack
|
|
80
|
+
|
|
81
|
+
Set in `.env`:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
MERCURY_ENABLE_SLACK=true
|
|
85
|
+
MERCURY_SLACK_BOT_TOKEN=xoxb-...
|
|
86
|
+
MERCURY_SLACK_SIGNING_SECRET=...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Teams
|
|
90
|
+
|
|
91
|
+
Set in `.env`:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
MERCURY_ENABLE_TEAMS=true
|
|
95
|
+
MERCURY_TEAMS_APP_ID=...
|
|
96
|
+
MERCURY_TEAMS_APP_PASSWORD=...
|
|
97
|
+
MERCURY_TEAMS_APP_TENANT_ID=...
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Dashboard Auth
|
|
101
|
+
|
|
102
|
+
The web dashboard is protected by `MERCURY_API_SECRET`. Browser sessions are established via a login handshake managed by the cloud console — see [dashboard.md](dashboard.md).
|
|
103
|
+
|
|
104
|
+
## Security
|
|
105
|
+
|
|
106
|
+
- `auth.json` has `0600` permissions (owner read/write only)
|
|
107
|
+
- WhatsApp credentials in `.mercury/whatsapp-auth/` are sensitive — treat like passwords
|
|
108
|
+
- All `MERCURY_*` env vars are passed into containers with the prefix stripped
|
|
109
|
+
- Never commit `.env` or `auth.json` to version control
|