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.
Files changed (125) hide show
  1. package/README.md +452 -451
  2. package/container/Dockerfile +127 -127
  3. package/container/Dockerfile.base +109 -109
  4. package/container/Dockerfile.power +17 -17
  5. package/container/agent-package.json +8 -8
  6. package/container/build.sh +54 -54
  7. package/docs/ROADMAP.md +3 -4
  8. package/docs/archive/summarization/2026-07-02-recent-dev-summary.md +71 -0
  9. package/docs/auth/dashboard.md +28 -28
  10. package/docs/auth/overview.md +109 -109
  11. package/docs/auth/whatsapp.md +173 -173
  12. package/docs/authoring-profiles.md +174 -174
  13. package/docs/configuration.md +54 -54
  14. package/docs/container-lifecycle.md +349 -349
  15. package/docs/{bugs/bwrap-privileged-linux-docker.md → debug/major/2026-07-02-bwrap-privileged-linux-docker.md} +21 -1
  16. package/docs/{bugs/e2big-prompt-delivery-fix.md → debug/major/2026-07-02-e2big-prompt-delivery-fix.md} +27 -1
  17. package/docs/{bugs/registry-pull-no-local-fallback.md → debug/major/2026-07-02-registry-pull-no-local-fallback.md} +27 -1
  18. package/docs/debug/summarization/2026-07-02-common-bug-patterns.md +72 -0
  19. package/docs/deployment.md +199 -199
  20. package/docs/extensions.md +375 -375
  21. package/docs/graceful-shutdown.md +62 -62
  22. package/docs/kb-distillation.md +77 -77
  23. package/docs/media/overview.md +140 -140
  24. package/docs/media/whatsapp.md +171 -171
  25. package/docs/memory.md +137 -137
  26. package/docs/permissions.md +217 -217
  27. package/docs/pipeline.md +228 -228
  28. package/docs/prd-chat-memory.md +76 -76
  29. package/docs/prd-config-load.md +82 -82
  30. package/docs/rate-limiting.md +229 -229
  31. package/docs/runbooks/publish-checklist.md +9 -1
  32. package/docs/scheduler.md +288 -288
  33. package/docs/setup-discord.md +100 -100
  34. package/docs/setup-slack.md +119 -119
  35. package/docs/setup-whatsapp.md +94 -94
  36. package/docs/subagents.md +166 -166
  37. package/docs/web-search.md +62 -62
  38. package/examples/extensions/README.md +12 -12
  39. package/examples/extensions/charts/index.ts +13 -13
  40. package/examples/extensions/charts/skill/SKILL.md +98 -98
  41. package/examples/extensions/gws/README.md +52 -52
  42. package/examples/extensions/gws/skill/SKILL.md +57 -57
  43. package/examples/extensions/gws/skill/references/calendar.md +101 -101
  44. package/examples/extensions/gws/skill/references/docs.md +65 -65
  45. package/examples/extensions/gws/skill/references/drive.md +79 -79
  46. package/examples/extensions/gws/skill/references/gmail.md +85 -85
  47. package/examples/extensions/gws/skill/references/sheets.md +60 -60
  48. package/examples/extensions/napkin/skill/SKILL.md +728 -728
  49. package/examples/extensions/pdf/skill/LICENSE.txt +30 -30
  50. package/examples/extensions/pdf/skill/SKILL.md +314 -314
  51. package/examples/extensions/pdf/skill/forms.md +294 -294
  52. package/examples/extensions/pdf/skill/reference.md +611 -611
  53. package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -65
  54. package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -11
  55. package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -33
  56. package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -37
  57. package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -122
  58. package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -115
  59. package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -98
  60. package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -107
  61. package/examples/extensions/permission-guard/index.ts +65 -65
  62. package/examples/extensions/pinchtab/skill/SKILL.md +224 -224
  63. package/examples/extensions/pinchtab/skill/TRUST.md +69 -69
  64. package/examples/extensions/pinchtab/skill/references/api.md +297 -297
  65. package/examples/extensions/pinchtab/skill/references/env.md +45 -45
  66. package/examples/extensions/pinchtab/skill/references/profiles.md +107 -107
  67. package/examples/extensions/tradestation/host/refresh.ts +102 -102
  68. package/examples/extensions/tradestation/index.ts +153 -153
  69. package/examples/extensions/tradestation/skill/SKILL.md +67 -67
  70. package/examples/extensions/voice-synth/index.ts +94 -94
  71. package/examples/extensions/voice-synth/skill/SKILL.md +38 -38
  72. package/examples/extensions/voice-transcribe/requirements.txt +8 -8
  73. package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -179
  74. package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -53
  75. package/examples/extensions/yahoo-mail/cli/package.json +13 -13
  76. package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -78
  77. package/package.json +106 -106
  78. package/resources/agents/explore.md +50 -50
  79. package/resources/agents/worker.md +24 -24
  80. package/resources/connection-env-vars.json +25 -25
  81. package/resources/pi-extensions/subagent/agents.ts +126 -126
  82. package/resources/pi-extensions/subagent/index.ts +964 -964
  83. package/resources/profiles/coding/AGENTS.md +43 -43
  84. package/resources/profiles/coding/mercury-profile.yaml +15 -15
  85. package/resources/profiles/general/AGENTS.md +31 -31
  86. package/resources/profiles/general/mercury-profile.yaml +15 -15
  87. package/resources/profiles/research/AGENTS.md +40 -40
  88. package/resources/profiles/research/mercury-profile.yaml +15 -15
  89. package/resources/skills/config/SKILL.md +25 -25
  90. package/resources/skills/context/SKILL.md +33 -33
  91. package/resources/skills/conversation-recap/SKILL.md +19 -19
  92. package/resources/skills/mutes/SKILL.md +31 -31
  93. package/resources/skills/permissions/SKILL.md +19 -19
  94. package/resources/skills/preferences/SKILL.md +31 -31
  95. package/resources/skills/recall/SKILL.md +24 -24
  96. package/resources/skills/roles/SKILL.md +18 -18
  97. package/resources/skills/spaces/SKILL.md +18 -18
  98. package/resources/skills/tasks/SKILL.md +45 -45
  99. package/resources/templates/AGENTS.md +157 -157
  100. package/resources/templates/env.template +38 -38
  101. package/resources/templates/mercury.example.yaml +99 -99
  102. package/src/agent/container-entry.ts +1 -1
  103. package/src/agent/container-runner.ts +1345 -1346
  104. package/src/cli/mercury.ts +39 -7
  105. package/src/cli/mrctl.ts +636 -636
  106. package/src/config-file.ts +540 -540
  107. package/src/config.ts +339 -339
  108. package/src/core/api.ts +125 -125
  109. package/src/core/caller-token.ts +101 -101
  110. package/src/core/permissions.ts +228 -228
  111. package/src/core/profiles.ts +271 -271
  112. package/src/core/routes/capability.ts +70 -70
  113. package/src/core/routes/index.ts +15 -15
  114. package/src/core/runtime.ts +1530 -1530
  115. package/src/dashboard/index.html +729 -729
  116. package/src/extensions/api.ts +273 -273
  117. package/src/extensions/loader.ts +286 -286
  118. package/src/extensions/types.ts +517 -517
  119. package/src/main.ts +605 -605
  120. package/docs/pending-updates/applicative-profiles.md +0 -15
  121. package/docs/pending-updates/caller-bound-capability-token.md +0 -15
  122. package/docs/pending-updates/dm-auto-space.md +0 -15
  123. /package/docs/archive/{2026-07-01-applicative-profiles.md → applicative-profiles/2026-07-01-applicative-profiles.md} +0 -0
  124. /package/docs/archive/{2026-07-01-caller-bound-capability-token.md → applicative-profiles/2026-07-01-caller-bound-capability-token.md} +0 -0
  125. /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.
@@ -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.
@@ -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