mercury-agent 0.4.28 → 0.5.1

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 (122) hide show
  1. package/README.md +451 -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/ARCHITECTURE.md +4 -0
  8. package/docs/ROADMAP.md +4 -5
  9. package/docs/{backlog/applicative-profiles.md → archive/applicative-profiles/2026-07-01-applicative-profiles.md} +29 -18
  10. package/docs/{backlog/caller-bound-capability-token.md → archive/applicative-profiles/2026-07-01-caller-bound-capability-token.md} +15 -11
  11. package/docs/archive/summarization/2026-07-02-recent-dev-summary.md +71 -0
  12. package/docs/auth/dashboard.md +28 -28
  13. package/docs/auth/overview.md +109 -109
  14. package/docs/auth/whatsapp.md +173 -173
  15. package/docs/authoring-profiles.md +174 -0
  16. package/docs/configuration.md +54 -54
  17. package/docs/container-lifecycle.md +349 -349
  18. package/docs/{bugs/bwrap-privileged-linux-docker.md → debug/major/2026-07-02-bwrap-privileged-linux-docker.md} +21 -1
  19. package/docs/{bugs/e2big-prompt-delivery-fix.md → debug/major/2026-07-02-e2big-prompt-delivery-fix.md} +27 -1
  20. package/docs/{bugs/registry-pull-no-local-fallback.md → debug/major/2026-07-02-registry-pull-no-local-fallback.md} +27 -1
  21. package/docs/debug/summarization/2026-07-02-common-bug-patterns.md +72 -0
  22. package/docs/deployment.md +199 -199
  23. package/docs/extensions.md +375 -375
  24. package/docs/graceful-shutdown.md +62 -62
  25. package/docs/kb-distillation.md +77 -77
  26. package/docs/media/overview.md +140 -140
  27. package/docs/media/whatsapp.md +171 -171
  28. package/docs/memory.md +137 -137
  29. package/docs/permissions.md +217 -217
  30. package/docs/pipeline.md +228 -228
  31. package/docs/prd-chat-memory.md +76 -76
  32. package/docs/prd-config-load.md +82 -82
  33. package/docs/rate-limiting.md +229 -229
  34. package/docs/scheduler.md +288 -288
  35. package/docs/setup-discord.md +100 -100
  36. package/docs/setup-slack.md +119 -119
  37. package/docs/setup-whatsapp.md +94 -94
  38. package/docs/subagents.md +166 -166
  39. package/docs/web-search.md +62 -62
  40. package/examples/extensions/README.md +12 -12
  41. package/examples/extensions/charts/index.ts +13 -13
  42. package/examples/extensions/charts/skill/SKILL.md +98 -98
  43. package/examples/extensions/gws/README.md +52 -52
  44. package/examples/extensions/gws/skill/SKILL.md +57 -57
  45. package/examples/extensions/gws/skill/references/calendar.md +101 -101
  46. package/examples/extensions/gws/skill/references/docs.md +65 -65
  47. package/examples/extensions/gws/skill/references/drive.md +79 -79
  48. package/examples/extensions/gws/skill/references/gmail.md +85 -85
  49. package/examples/extensions/gws/skill/references/sheets.md +60 -60
  50. package/examples/extensions/napkin/skill/SKILL.md +728 -728
  51. package/examples/extensions/pdf/skill/LICENSE.txt +30 -30
  52. package/examples/extensions/pdf/skill/SKILL.md +314 -314
  53. package/examples/extensions/pdf/skill/forms.md +294 -294
  54. package/examples/extensions/pdf/skill/reference.md +611 -611
  55. package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -65
  56. package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -11
  57. package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -33
  58. package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -37
  59. package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -122
  60. package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -115
  61. package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -98
  62. package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -107
  63. package/examples/extensions/permission-guard/index.ts +65 -65
  64. package/examples/extensions/pinchtab/skill/SKILL.md +224 -224
  65. package/examples/extensions/pinchtab/skill/TRUST.md +69 -69
  66. package/examples/extensions/pinchtab/skill/references/api.md +297 -297
  67. package/examples/extensions/pinchtab/skill/references/env.md +45 -45
  68. package/examples/extensions/pinchtab/skill/references/profiles.md +107 -107
  69. package/examples/extensions/tradestation/host/refresh.ts +102 -102
  70. package/examples/extensions/tradestation/index.ts +153 -153
  71. package/examples/extensions/tradestation/skill/SKILL.md +67 -67
  72. package/examples/extensions/voice-synth/index.ts +94 -94
  73. package/examples/extensions/voice-synth/skill/SKILL.md +38 -38
  74. package/examples/extensions/voice-transcribe/requirements.txt +8 -8
  75. package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -179
  76. package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -53
  77. package/examples/extensions/yahoo-mail/cli/package.json +13 -13
  78. package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -78
  79. package/package.json +106 -106
  80. package/resources/agents/explore.md +50 -50
  81. package/resources/agents/worker.md +24 -24
  82. package/resources/connection-env-vars.json +25 -25
  83. package/resources/pi-extensions/subagent/agents.ts +126 -126
  84. package/resources/pi-extensions/subagent/index.ts +964 -964
  85. package/resources/profiles/coding/AGENTS.md +43 -43
  86. package/resources/profiles/coding/mercury-profile.yaml +15 -15
  87. package/resources/profiles/general/AGENTS.md +31 -31
  88. package/resources/profiles/general/mercury-profile.yaml +15 -15
  89. package/resources/profiles/research/AGENTS.md +40 -40
  90. package/resources/profiles/research/mercury-profile.yaml +15 -15
  91. package/resources/skills/config/SKILL.md +25 -25
  92. package/resources/skills/context/SKILL.md +33 -33
  93. package/resources/skills/conversation-recap/SKILL.md +19 -19
  94. package/resources/skills/mutes/SKILL.md +31 -31
  95. package/resources/skills/permissions/SKILL.md +19 -19
  96. package/resources/skills/preferences/SKILL.md +31 -31
  97. package/resources/skills/recall/SKILL.md +24 -24
  98. package/resources/skills/roles/SKILL.md +18 -18
  99. package/resources/skills/spaces/SKILL.md +18 -18
  100. package/resources/skills/tasks/SKILL.md +45 -45
  101. package/resources/templates/AGENTS.md +157 -157
  102. package/resources/templates/env.template +38 -38
  103. package/resources/templates/mercury.example.yaml +15 -0
  104. package/src/agent/container-runner.ts +23 -0
  105. package/src/cli/mercury.ts +38 -6
  106. package/src/cli/mrctl.ts +25 -0
  107. package/src/config-file.ts +3 -0
  108. package/src/config.ts +15 -0
  109. package/src/core/api.ts +23 -3
  110. package/src/core/caller-token.ts +101 -0
  111. package/src/core/permissions.ts +37 -5
  112. package/src/core/profiles.ts +110 -84
  113. package/src/core/routes/capability.ts +70 -0
  114. package/src/core/routes/index.ts +1 -0
  115. package/src/core/runtime.ts +14 -0
  116. package/src/dashboard/index.html +729 -729
  117. package/src/extensions/api.ts +21 -0
  118. package/src/extensions/loader.ts +15 -0
  119. package/src/extensions/types.ts +55 -0
  120. package/src/main.ts +19 -0
  121. package/docs/pending-updates/dm-auto-space.md +0 -15
  122. /package/docs/archive/{2026-07-01-dm-auto-space.md → applicative-profiles/2026-07-01-dm-auto-space.md} +0 -0
package/README.md CHANGED
@@ -1,451 +1,451 @@
1
- <p align="center">
2
- <img src="assets/logo-with-text.svg" alt="Mercury" height="120" />
3
- </p>
4
-
5
- <p align="center">
6
- <em>There are many claws, but this one is mine.</em>
7
- </p>
8
-
9
- <p align="center">
10
- <a href="https://github.com/Avishai-Tsabari/mercury"><img alt="GitHub" src="https://img.shields.io/badge/github-mercury-181717?style=flat-square&logo=github" /></a>
11
- <a href="https://www.npmjs.com/package/mercury-agent"><img alt="npm" src="https://img.shields.io/npm/v/mercury-agent?style=flat-square&logo=npm" /></a>
12
- </p>
13
-
14
- Mercury is a personal AI assistant that lives where you chat. It connects to WhatsApp, Slack, Discord, and Telegram, runs agents inside containers for isolation, and uses [pi](https://github.com/badlogic/pi) as the runtime.
15
-
16
- ---
17
-
18
- ## Prerequisites
19
-
20
- - **[Node.js](https://nodejs.org/)** >= 18 — Required for `npm install -g mercury-agent`
21
- - **[Bun](https://bun.sh)** >= 1.0 — JavaScript runtime used by Mercury
22
- - **[Docker](https://docs.docker.com/get-docker/)** — Required for running agent containers. On Linux, also install `docker-buildx` (`apt-get install docker-buildx`) — Docker Desktop includes it, but Docker Engine on Linux does not.
23
- - **Windows users:** Mercury runs best under [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install). Install WSL2 with `wsl --install`, then install Bun and Docker inside it.
24
-
25
- ## Quick Start
26
-
27
- ```bash
28
- npm install -g mercury-agent
29
- mkdir my-assistant && cd my-assistant
30
- mercury setup # Interactive guided setup (recommended)
31
- # -- or for manual setup: --
32
- mercury init
33
- ```
34
-
35
- Authenticate:
36
-
37
- ```bash
38
- mercury auth login # Interactive OAuth (Anthropic, GitHub Copilot, etc.)
39
- mercury auth login anthropic # Or specify provider directly
40
- mercury auth status # Check what's configured
41
- ```
42
-
43
- Or set an API key in `.env`:
44
-
45
- ```bash
46
- MERCURY_ANTHROPIC_API_KEY=sk-ant-...
47
- ```
48
-
49
- Configure identity and adapters in `.env`:
50
-
51
- ```bash
52
- MERCURY_BOT_USERNAME=Mercury
53
- MERCURY_TRIGGER_PATTERNS=@Mercury,Mercury
54
-
55
- # Enable adapters
56
- MERCURY_ENABLE_WHATSAPP=true
57
- MERCURY_ENABLE_DISCORD=true
58
- MERCURY_DISCORD_BOT_TOKEN=your-bot-token
59
- ```
60
-
61
- Start:
62
-
63
- ```bash
64
- mercury run
65
- # or install as a background service:
66
- mercury service install
67
- ```
68
-
69
- ### Set up spaces and conversations
70
-
71
- Mercury discovers conversations from incoming traffic. They start **unlinked** — you assign them to **spaces** (memory boundaries).
72
-
73
- ```bash
74
- # Create spaces
75
- mercury spaces create main
76
- mercury spaces create work
77
- mercury spaces create family
78
-
79
- # Send a message from WhatsApp/Discord/Slack, then:
80
- mercury conversations # See discovered conversations
81
- mercury conversations --unlinked # See unlinked ones
82
- mercury link <id> main # Link a conversation to a space
83
- ```
84
-
85
- Multiple conversations can point at the same space — they share memory, session, and vault.
86
-
87
- ---
88
-
89
- ## How It Works
90
-
91
- ```
92
- ┌──────────────────────────────────────────────────────────────┐
93
- │ Host Process │
94
- │ │
95
- │ ┌──────────┐ ┌─────────┐ ┌─────────┐ ┌───────────────┐ │
96
- │ │ WhatsApp │ │ Slack │ │ Discord │ │ Scheduler │ │
97
- │ │ Adapter │ │ Adapter │ │ Adapter │ │ (cron tasks) │ │
98
- │ └───┬──────┘ └────┬────┘ └───┬─────┘ └──────┬────────┘ │
99
- │ └──────────────┴───────────┴───────────────┘ │
100
- │ │ │
101
- │ ┌────────▼────────┐ │
102
- │ │ Router/Queue │ │
103
- │ └────────┬────────┘ │
104
- │ │ │
105
- │ ┌────────▼────────┐ │
106
- │ │ SQLite DB │ │
107
- │ └────────┬────────┘ │
108
- └──────────────────────────────┼───────────────────────────────┘
109
-
110
- ┌─────────▼──────────┐
111
- │ Docker Container │
112
- │ ┌──────────────┐ │
113
- │ │ pi CLI │ │
114
- │ └──────────────┘ │
115
- │ /spaces/<space-id> │
116
- └────────────────────┘
117
- ```
118
-
119
- Each space is a user-defined memory boundary with its own workspace and pi session. Incoming platform conversations are discovered automatically, then linked into spaces.
120
-
121
- ---
122
-
123
- ## Features
124
-
125
- | Feature | Description | Docs |
126
- |---------|-------------|------|
127
- | **Multi-platform** | WhatsApp, Slack, Discord, Telegram | [docs/pipeline.md](docs/pipeline.md) |
128
- | **Memory** | Obsidian-compatible vault per space | [docs/memory.md](docs/memory.md) |
129
- | **Scheduled Tasks** | Cron-based recurring prompts | [docs/scheduler.md](docs/scheduler.md) |
130
- | **Permissions** | Role-based access control | [docs/permissions.md](docs/permissions.md) |
131
- | **Media** | Images, documents, voice notes | [docs/media/overview.md](docs/media/overview.md) |
132
- | **KB Distillation** | Extract lasting knowledge from chats | [docs/kb-distillation.md](docs/kb-distillation.md) |
133
- | **Extensions** | TypeScript plugins for CLIs, skills, jobs, hooks | [docs/extensions.md](docs/extensions.md) |
134
- | **DM Auto-Space** | Auto-create isolated spaces per customer DM | [docs/rate-limiting.md](docs/rate-limiting.md) |
135
-
136
- ---
137
-
138
- ## Workspaces
139
-
140
- Each space gets an isolated workspace:
141
-
142
- ```text
143
- .mercury/spaces/<space-id>/
144
- ├── AGENTS.md # Space instructions
145
- ├── .mercury.session.jsonl # pi session
146
- ├── inbox/ # Media received from users
147
- └── outbox/ # Files produced by the agent
148
- ```
149
-
150
- Memory/vault structure (for example `.obsidian/`, `knowledge/`, `daily/`) is created by installed extensions.
151
-
152
- Multiple platform conversations can point at the same space.
153
-
154
- ---
155
-
156
- ## Agent Profiles
157
-
158
- Profiles are shareable templates that bundle agent instructions, extensions, and defaults. Use them to start from a preconfigured assistant type.
159
-
160
- **Built-in profiles:**
161
-
162
- | Profile | Description |
163
- |---------|-------------|
164
- | `general` | General-purpose assistant — helpful, concise, chat-friendly |
165
- | `coding` | Code-focused with sub-agent delegation and web search |
166
- | `research` | Web search and knowledge distillation focused |
167
-
168
- ```bash
169
- # Create from built-in profile
170
- mercury setup --profile coding
171
-
172
- # Create from git repo
173
- mercury setup --profile https://github.com/user/mercury-stock-agent
174
-
175
- # Create from local directory
176
- mercury setup --profile ./my-profiles/ml-assistant
177
-
178
- # List available profiles
179
- mercury profiles list
180
-
181
- # Export current project as a profile
182
- mercury profiles export ./my-profile
183
- ```
184
-
185
- ---
186
-
187
- ## CLI
188
-
189
- ### `mercury` (host CLI)
190
-
191
- ```bash
192
- # setup + runtime
193
- mercury setup # Interactive guided setup (recommended for new projects)
194
- mercury setup --profile <name> # Create from a profile (general, coding, research, or path/URL)
195
- mercury init # Manual init (creates .env, .mercury structure)
196
- mercury run
197
- mercury build # only needed when developing the base image from source
198
- mercury status
199
- mercury doctor # preflight check — validates Docker, Bun, credentials, adapters
200
-
201
- # profiles (agent templates)
202
- mercury profiles list # List built-in profiles
203
- mercury profiles show <name> # Show profile details
204
- mercury profiles export <dir> # Export current project as a reusable profile
205
-
206
- # auth
207
- mercury auth login [provider]
208
- mercury auth logout [provider]
209
- mercury auth status
210
- mercury auth whatsapp
211
-
212
- # chat + routing
213
- mercury chat "hello"
214
- mercury chat --file photo.jpg "what's in this?"
215
- mercury chat --space work "check status"
216
- echo "summarize" | mercury chat
217
- mercury spaces list
218
- mercury spaces create <id>
219
- mercury conversations
220
- mercury conversations --unlinked
221
- mercury link <conversation-id> <space-id>
222
-
223
- # extensions
224
- mercury add ./path/to/extension
225
- mercury add npm:<package>
226
- mercury add git:<repo-url>
227
- mercury add user/repo # GitHub shorthand (e.g. mercury add user/mercury-ext-ml)
228
- mercury add user/repo#subdir # GitHub repo with subdirectory
229
- mercury remove <name>
230
- mercury extensions list
231
- mercury ext create <name> # Scaffold a new extension
232
- mercury ext validate <name> # Validate extension structure and load
233
- mercury ext test <name> # Dry-run load extension
234
-
235
- # service (recommended for background)
236
- mercury service install
237
- mercury service uninstall
238
- mercury service status
239
- mercury service logs [-f]
240
- ```
241
-
242
- ### `mrctl` (in-container API CLI)
243
-
244
- ```bash
245
- mrctl whoami
246
- mrctl tasks list|create|pause|resume|run|delete
247
- mrctl roles list|grant|revoke
248
- mrctl permissions show|set
249
- mrctl config get|set
250
- mrctl spaces list|name|delete
251
- mrctl conversations list
252
- mrctl stop
253
- mrctl compact
254
- ```
255
-
256
- For full command docs, run `mercury --help`, `mercury <command> --help`, or `mrctl help`.
257
-
258
- ---
259
-
260
- ## Extensions
261
-
262
- Mercury supports TypeScript extensions that add CLIs, skills, background jobs, lifecycle hooks, config keys, and dashboard widgets.
263
-
264
- ### Creating Extensions
265
-
266
- ```bash
267
- mercury ext create my-extension # Scaffold a new extension
268
- mercury ext validate my-extension # Check structure and load
269
- mercury ext test my-extension # Dry-run load
270
- ```
271
-
272
- ```
273
- .mercury/extensions/
274
- ├── napkin/
275
- │ ├── index.ts
276
- │ └── skill/SKILL.md
277
- └── my-extension/
278
- └── index.ts
279
- ```
280
-
281
- Each extension exports a setup function:
282
-
283
- ```typescript
284
- export default function(mercury) {
285
- mercury.cli({ name: "napkin", install: "bun add -g napkin-ai" });
286
- mercury.permission({ defaultRoles: ["admin", "member"] });
287
- mercury.env({ from: "MERCURY_NAPKIN_API_KEY" });
288
- mercury.skill("./skill");
289
- mercury.on("workspace_init", async ({ workspace, containerWorkspace }) => { ... });
290
- mercury.on("before_container", async ({ workspace, containerWorkspace }) => {
291
- return { env: { MY_VAR: containerWorkspace + "/data" } };
292
- });
293
- }
294
- ```
295
-
296
- Extensions with CLIs get auto-installed into a derived Docker image. Skills are symlinked for agent discovery. Permissions integrate with the existing RBAC system.
297
-
298
- See [docs/extensions.md](docs/extensions.md) for the extension system guide.
299
-
300
- ---
301
-
302
- ## Configuration
303
-
304
- Optional project file **`mercury.yaml`** (or **`mercury.yml`**) supplies non-secret defaults; any set **`MERCURY_*`** variable overrides it. See [docs/configuration.md](docs/configuration.md) and `resources/templates/mercury.example.yaml`.
305
-
306
- ### Environment Variables
307
-
308
- **Core:**
309
-
310
- | Variable | Default | Description |
311
- |----------|---------|-------------|
312
- | `MERCURY_DATA_DIR` | `.mercury` | Data directory |
313
- | `MERCURY_MAX_CONCURRENCY` | `3` | Max concurrent runs |
314
- | `MERCURY_PORT` | `8787` | API port |
315
- | `MERCURY_BOT_USERNAME` | `mercury` | Bot display name |
316
- | `MERCURY_LOG_LEVEL` | `info` | Log level |
317
-
318
- **Security:**
319
-
320
- | Variable | Description |
321
- |----------|-------------|
322
- | `MERCURY_API_SECRET` | Shared secret for `/api/*` routes. When set, requires `Authorization: Bearer <secret>`. Auto-generated by `mercury setup`. |
323
- | `MERCURY_CHAT_API_KEY` | Optional API key for `/chat` endpoint. When set, requires Bearer token. When unset, `/chat` is open (for local use). |
324
-
325
- **Auth:**
326
-
327
- Credentials are resolved in this order:
328
- 1. OAuth credentials from `mercury auth login` (saved to `.mercury/global/auth.json`)
329
- 2. API keys from `.env` (e.g., `MERCURY_ANTHROPIC_API_KEY`)
330
-
331
- Supported OAuth providers: Anthropic, GitHub Copilot, Google Gemini CLI, Antigravity, OpenAI Codex.
332
-
333
- **Model:**
334
-
335
- | Variable | Default | Description |
336
- |----------|---------|-------------|
337
- | `MERCURY_MODEL_PROVIDER` | `anthropic` | Provider |
338
- | `MERCURY_MODEL` | `claude-opus-4-6` | Model |
339
- | `MERCURY_ANTHROPIC_API_KEY` | — | API key |
340
- | `MERCURY_ANTHROPIC_OAUTH_TOKEN` | — | OAuth token (alternative) |
341
-
342
- **Adapters:**
343
-
344
- | Variable | Description |
345
- |----------|-------------|
346
- | `MERCURY_ENABLE_WHATSAPP` | Enable WhatsApp |
347
- | `MERCURY_WHATSAPP_AUTH_DIR` | Auth storage path |
348
- | `MERCURY_ENABLE_TELEGRAM` | Enable Telegram |
349
- | `MERCURY_TELEGRAM_BOT_TOKEN` | Telegram bot token |
350
- | `MERCURY_ENABLE_DISCORD` | Enable Discord |
351
- | `MERCURY_DISCORD_BOT_TOKEN` | Discord bot token |
352
- | `MERCURY_ENABLE_SLACK` | Enable Slack |
353
- | `MERCURY_SLACK_BOT_TOKEN` | Slack bot token |
354
- | `MERCURY_SLACK_SIGNING_SECRET` | Slack signing secret |
355
-
356
- **Container:**
357
-
358
- | Variable | Default | Description |
359
- |----------|---------|-------------|
360
- | `MERCURY_AGENT_CONTAINER_IMAGE` | `ghcr.io/avishai-tsabari/mercury-agent:latest` | Container image |
361
- | `MERCURY_CONTAINER_TIMEOUT_MS` | `300000` | Container timeout (5 min) |
362
- | `MERCURY_CONTAINER_RUNTIME` | `runc` | `runc` (default) or `runsc` ([gVisor](https://gvisor.dev)) |
363
- | `MERCURY_CONTAINER_BWRAP_DOCKER_COMPAT` | `false` | Set `true` on Linux Docker Engine (see note below) |
364
-
365
- > **Linux Docker Engine:** Mercury uses [bubblewrap](https://github.com/containers/bubblewrap) for in-container sandboxing. On Linux Docker Engine (not Docker Desktop), bwrap cannot mount `/proc` without extra privileges. Either set `container_bwrap_docker_compat: true` in `mercury.yaml` (adds `--privileged` to `docker run`), or install [gVisor](https://gvisor.dev/docs/user_guide/install/) and set `MERCURY_CONTAINER_RUNTIME=runsc` to skip bwrap entirely.
366
-
367
- **KB Distillation:**
368
-
369
- | Variable | Default | Description |
370
- |----------|---------|-------------|
371
- | `MERCURY_KB_DISTILL_INTERVAL_MS` | `0` (disabled) | Distillation interval |
372
-
373
- **Triggers:**
374
-
375
- | Variable | Default | Description |
376
- |----------|---------|-------------|
377
- | `MERCURY_TRIGGER_MATCH` | `mention` | `mention`, `prefix`, `always` |
378
- | `MERCURY_TRIGGER_PATTERNS` | `@Mercury,Mercury` | Trigger patterns |
379
- | `MERCURY_ADMINS` | — | Pre-seeded admin user IDs |
380
-
381
- ### DM Auto-Space
382
-
383
- Auto-create isolated spaces for each customer who DMs your bot. Each customer gets their own space with persistent context, configurable permissions, and rate limits.
384
-
385
- ```yaml
386
- # mercury.yaml
387
- dm_auto_space:
388
- enabled: true
389
- admin_ids: # platform IDs — auto-link to "main" space
390
- - "24417056866472" # WhatsApp LID, Telegram user ID, etc.
391
- default_system_prompt: "You are a helpful assistant."
392
- default_member_permissions: "prompt,prefs.get" # restrict customers to chat only
393
-
394
- runtime:
395
- rate_limit_daily_member: 20 # global daily cap for members (0 = unlimited)
396
- rate_limit_daily_admin: 0 # global daily cap for admins (0 = unlimited)
397
- ```
398
-
399
- `admin_ids` values are platform-specific identifiers — check the dashboard Conversations page to see the format (e.g. WhatsApp LID digits, Telegram numeric user ID).
400
-
401
- Auto-created spaces are seeded with `trigger.match=always`, `context.mode=context`, and the configured member permissions. Per-space rate limits are manageable from the dashboard.
402
-
403
- ### Per-space Config
404
-
405
- Conversations are discovered from incoming traffic. Unlinked conversations stay idle until you attach them to a space via `mercury link <conversation-id> <space-id>` or the dashboard.
406
-
407
- ```bash
408
- mrctl config set trigger_match always
409
- mrctl config set trigger_patterns "@Bot,Bot"
410
- ```
411
-
412
- ---
413
-
414
- ## Docs
415
-
416
- - **Remaining work:** [TODOS](docs/TODOS.md) — Security, reliability, and ops gaps
417
- - **Platform setup:** [WhatsApp](docs/setup-whatsapp.md) · [Discord](docs/setup-discord.md) · [Slack](docs/setup-slack.md)
418
- - [Configuration](docs/configuration.md) (mercury.yaml + env) · [PRD: config load](docs/prd-config-load.md)
419
- - [Authentication](docs/auth/overview.md)
420
- - [Message pipeline](docs/pipeline.md)
421
- - [Memory system](docs/memory.md)
422
- - [Scheduled tasks](docs/scheduler.md)
423
- - [Permissions](docs/permissions.md)
424
- - [Media handling](docs/media/overview.md)
425
- - [KB distillation](docs/kb-distillation.md)
426
- - [Container lifecycle](docs/container-lifecycle.md)
427
- - [Graceful shutdown](docs/graceful-shutdown.md)
428
- - [Rate limiting](docs/rate-limiting.md)
429
- - [Extensions](docs/extensions.md)
430
-
431
- ---
432
-
433
- ## Credits
434
-
435
- Mercury was originally created by [Michael Livshits](https://github.com/Michaelliv). Full credit for the foundational architecture, extension system, and platform adapters goes to him.
436
-
437
- Original repository: [github.com/Michaelliv/mercury](https://github.com/Michaelliv/mercury) (archived)
438
-
439
- This fork is maintained by [Avishai Tsabari](https://github.com/Avishai-Tsabari).
440
-
441
- ---
442
-
443
- ## License
444
-
445
- MIT — see [LICENSE](LICENSE)
446
-
447
- ---
448
-
449
- <p align="center">
450
- <em>There are many claws, but this one is mine.</em> 🪽
451
- </p>
1
+ <p align="center">
2
+ <img src="assets/logo-with-text.svg" alt="Mercury" height="120" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <em>There are many claws, but this one is mine.</em>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://github.com/Avishai-Tsabari/mercury"><img alt="GitHub" src="https://img.shields.io/badge/github-mercury-181717?style=flat-square&logo=github" /></a>
11
+ <a href="https://www.npmjs.com/package/mercury-agent"><img alt="npm" src="https://img.shields.io/npm/v/mercury-agent?style=flat-square&logo=npm" /></a>
12
+ </p>
13
+
14
+ Mercury is a personal AI assistant that lives where you chat. It connects to WhatsApp, Slack, Discord, and Telegram, runs agents inside containers for isolation, and uses [pi](https://github.com/badlogic/pi) as the runtime.
15
+
16
+ ---
17
+
18
+ ## Prerequisites
19
+
20
+ - **[Node.js](https://nodejs.org/)** >= 18 — Required for `npm install -g mercury-agent`
21
+ - **[Bun](https://bun.sh)** >= 1.0 — JavaScript runtime used by Mercury
22
+ - **[Docker](https://docs.docker.com/get-docker/)** — Required for running agent containers. On Linux, also install `docker-buildx` (`apt-get install docker-buildx`) — Docker Desktop includes it, but Docker Engine on Linux does not.
23
+ - **Windows users:** Mercury runs best under [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install). Install WSL2 with `wsl --install`, then install Bun and Docker inside it.
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ npm install -g mercury-agent
29
+ mkdir my-assistant && cd my-assistant
30
+ mercury setup # Interactive guided setup (recommended)
31
+ # -- or for manual setup: --
32
+ mercury init
33
+ ```
34
+
35
+ Authenticate:
36
+
37
+ ```bash
38
+ mercury auth login # Interactive OAuth (Anthropic, GitHub Copilot, etc.)
39
+ mercury auth login anthropic # Or specify provider directly
40
+ mercury auth status # Check what's configured
41
+ ```
42
+
43
+ Or set an API key in `.env`:
44
+
45
+ ```bash
46
+ MERCURY_ANTHROPIC_API_KEY=sk-ant-...
47
+ ```
48
+
49
+ Configure identity and adapters in `.env`:
50
+
51
+ ```bash
52
+ MERCURY_BOT_USERNAME=Mercury
53
+ MERCURY_TRIGGER_PATTERNS=@Mercury,Mercury
54
+
55
+ # Enable adapters
56
+ MERCURY_ENABLE_WHATSAPP=true
57
+ MERCURY_ENABLE_DISCORD=true
58
+ MERCURY_DISCORD_BOT_TOKEN=your-bot-token
59
+ ```
60
+
61
+ Start:
62
+
63
+ ```bash
64
+ mercury run
65
+ # or install as a background service:
66
+ mercury service install
67
+ ```
68
+
69
+ ### Set up spaces and conversations
70
+
71
+ Mercury discovers conversations from incoming traffic. They start **unlinked** — you assign them to **spaces** (memory boundaries).
72
+
73
+ ```bash
74
+ # Create spaces
75
+ mercury spaces create main
76
+ mercury spaces create work
77
+ mercury spaces create family
78
+
79
+ # Send a message from WhatsApp/Discord/Slack, then:
80
+ mercury conversations # See discovered conversations
81
+ mercury conversations --unlinked # See unlinked ones
82
+ mercury link <id> main # Link a conversation to a space
83
+ ```
84
+
85
+ Multiple conversations can point at the same space — they share memory, session, and vault.
86
+
87
+ ---
88
+
89
+ ## How It Works
90
+
91
+ ```
92
+ ┌──────────────────────────────────────────────────────────────┐
93
+ │ Host Process │
94
+ │ │
95
+ │ ┌──────────┐ ┌─────────┐ ┌─────────┐ ┌───────────────┐ │
96
+ │ │ WhatsApp │ │ Slack │ │ Discord │ │ Scheduler │ │
97
+ │ │ Adapter │ │ Adapter │ │ Adapter │ │ (cron tasks) │ │
98
+ │ └───┬──────┘ └────┬────┘ └───┬─────┘ └──────┬────────┘ │
99
+ │ └──────────────┴───────────┴───────────────┘ │
100
+ │ │ │
101
+ │ ┌────────▼────────┐ │
102
+ │ │ Router/Queue │ │
103
+ │ └────────┬────────┘ │
104
+ │ │ │
105
+ │ ┌────────▼────────┐ │
106
+ │ │ SQLite DB │ │
107
+ │ └────────┬────────┘ │
108
+ └──────────────────────────────┼───────────────────────────────┘
109
+
110
+ ┌─────────▼──────────┐
111
+ │ Docker Container │
112
+ │ ┌──────────────┐ │
113
+ │ │ pi CLI │ │
114
+ │ └──────────────┘ │
115
+ │ /spaces/<space-id> │
116
+ └────────────────────┘
117
+ ```
118
+
119
+ Each space is a user-defined memory boundary with its own workspace and pi session. Incoming platform conversations are discovered automatically, then linked into spaces.
120
+
121
+ ---
122
+
123
+ ## Features
124
+
125
+ | Feature | Description | Docs |
126
+ |---------|-------------|------|
127
+ | **Multi-platform** | WhatsApp, Slack, Discord, Telegram | [docs/pipeline.md](docs/pipeline.md) |
128
+ | **Memory** | Obsidian-compatible vault per space | [docs/memory.md](docs/memory.md) |
129
+ | **Scheduled Tasks** | Cron-based recurring prompts | [docs/scheduler.md](docs/scheduler.md) |
130
+ | **Permissions** | Role-based access control | [docs/permissions.md](docs/permissions.md) |
131
+ | **Media** | Images, documents, voice notes | [docs/media/overview.md](docs/media/overview.md) |
132
+ | **KB Distillation** | Extract lasting knowledge from chats | [docs/kb-distillation.md](docs/kb-distillation.md) |
133
+ | **Extensions** | TypeScript plugins for CLIs, skills, jobs, hooks | [docs/extensions.md](docs/extensions.md) |
134
+ | **DM Auto-Space** | Auto-create isolated spaces per customer DM | [docs/rate-limiting.md](docs/rate-limiting.md) |
135
+
136
+ ---
137
+
138
+ ## Workspaces
139
+
140
+ Each space gets an isolated workspace:
141
+
142
+ ```text
143
+ .mercury/spaces/<space-id>/
144
+ ├── AGENTS.md # Space instructions
145
+ ├── .mercury.session.jsonl # pi session
146
+ ├── inbox/ # Media received from users
147
+ └── outbox/ # Files produced by the agent
148
+ ```
149
+
150
+ Memory/vault structure (for example `.obsidian/`, `knowledge/`, `daily/`) is created by installed extensions.
151
+
152
+ Multiple platform conversations can point at the same space.
153
+
154
+ ---
155
+
156
+ ## Agent Profiles
157
+
158
+ Profiles are shareable templates that bundle agent instructions, extensions, and defaults. Use them to start from a preconfigured assistant type.
159
+
160
+ **Built-in profiles:**
161
+
162
+ | Profile | Description |
163
+ |---------|-------------|
164
+ | `general` | General-purpose assistant — helpful, concise, chat-friendly |
165
+ | `coding` | Code-focused with sub-agent delegation and web search |
166
+ | `research` | Web search and knowledge distillation focused |
167
+
168
+ ```bash
169
+ # Create from built-in profile
170
+ mercury setup --profile coding
171
+
172
+ # Create from git repo
173
+ mercury setup --profile https://github.com/user/mercury-stock-agent
174
+
175
+ # Create from local directory
176
+ mercury setup --profile ./my-profiles/ml-assistant
177
+
178
+ # List available profiles
179
+ mercury profiles list
180
+
181
+ # Export current project as a profile
182
+ mercury profiles export ./my-profile
183
+ ```
184
+
185
+ ---
186
+
187
+ ## CLI
188
+
189
+ ### `mercury` (host CLI)
190
+
191
+ ```bash
192
+ # setup + runtime
193
+ mercury setup # Interactive guided setup (recommended for new projects)
194
+ mercury setup --profile <name> # Create from a profile (general, coding, research, or path/URL)
195
+ mercury init # Manual init (creates .env, .mercury structure)
196
+ mercury run
197
+ mercury build # only needed when developing the base image from source
198
+ mercury status
199
+ mercury doctor # preflight check — validates Docker, Bun, credentials, adapters
200
+
201
+ # profiles (agent templates)
202
+ mercury profiles list # List built-in profiles
203
+ mercury profiles show <name> # Show profile details
204
+ mercury profiles export <dir> # Export current project as a reusable profile
205
+
206
+ # auth
207
+ mercury auth login [provider]
208
+ mercury auth logout [provider]
209
+ mercury auth status
210
+ mercury auth whatsapp
211
+
212
+ # chat + routing
213
+ mercury chat "hello"
214
+ mercury chat --file photo.jpg "what's in this?"
215
+ mercury chat --space work "check status"
216
+ echo "summarize" | mercury chat
217
+ mercury spaces list
218
+ mercury spaces create <id>
219
+ mercury conversations
220
+ mercury conversations --unlinked
221
+ mercury link <conversation-id> <space-id>
222
+
223
+ # extensions
224
+ mercury add ./path/to/extension
225
+ mercury add npm:<package>
226
+ mercury add git:<repo-url>
227
+ mercury add user/repo # GitHub shorthand (e.g. mercury add user/mercury-ext-ml)
228
+ mercury add user/repo#subdir # GitHub repo with subdirectory
229
+ mercury remove <name>
230
+ mercury extensions list
231
+ mercury ext create <name> # Scaffold a new extension
232
+ mercury ext validate <name> # Validate extension structure and load
233
+ mercury ext test <name> # Dry-run load extension
234
+
235
+ # service (recommended for background)
236
+ mercury service install
237
+ mercury service uninstall
238
+ mercury service status
239
+ mercury service logs [-f]
240
+ ```
241
+
242
+ ### `mrctl` (in-container API CLI)
243
+
244
+ ```bash
245
+ mrctl whoami
246
+ mrctl tasks list|create|pause|resume|run|delete
247
+ mrctl roles list|grant|revoke
248
+ mrctl permissions show|set
249
+ mrctl config get|set
250
+ mrctl spaces list|name|delete
251
+ mrctl conversations list
252
+ mrctl stop
253
+ mrctl compact
254
+ ```
255
+
256
+ For full command docs, run `mercury --help`, `mercury <command> --help`, or `mrctl help`.
257
+
258
+ ---
259
+
260
+ ## Extensions
261
+
262
+ Mercury supports TypeScript extensions that add CLIs, skills, background jobs, lifecycle hooks, config keys, and dashboard widgets.
263
+
264
+ ### Creating Extensions
265
+
266
+ ```bash
267
+ mercury ext create my-extension # Scaffold a new extension
268
+ mercury ext validate my-extension # Check structure and load
269
+ mercury ext test my-extension # Dry-run load
270
+ ```
271
+
272
+ ```
273
+ .mercury/extensions/
274
+ ├── napkin/
275
+ │ ├── index.ts
276
+ │ └── skill/SKILL.md
277
+ └── my-extension/
278
+ └── index.ts
279
+ ```
280
+
281
+ Each extension exports a setup function:
282
+
283
+ ```typescript
284
+ export default function(mercury) {
285
+ mercury.cli({ name: "napkin", install: "bun add -g napkin-ai" });
286
+ mercury.permission({ defaultRoles: ["admin", "member"] });
287
+ mercury.env({ from: "MERCURY_NAPKIN_API_KEY" });
288
+ mercury.skill("./skill");
289
+ mercury.on("workspace_init", async ({ workspace, containerWorkspace }) => { ... });
290
+ mercury.on("before_container", async ({ workspace, containerWorkspace }) => {
291
+ return { env: { MY_VAR: containerWorkspace + "/data" } };
292
+ });
293
+ }
294
+ ```
295
+
296
+ Extensions with CLIs get auto-installed into a derived Docker image. Skills are symlinked for agent discovery. Permissions integrate with the existing RBAC system.
297
+
298
+ See [docs/extensions.md](docs/extensions.md) for the extension system guide.
299
+
300
+ ---
301
+
302
+ ## Configuration
303
+
304
+ Optional project file **`mercury.yaml`** (or **`mercury.yml`**) supplies non-secret defaults; any set **`MERCURY_*`** variable overrides it. See [docs/configuration.md](docs/configuration.md) and `resources/templates/mercury.example.yaml`.
305
+
306
+ ### Environment Variables
307
+
308
+ **Core:**
309
+
310
+ | Variable | Default | Description |
311
+ |----------|---------|-------------|
312
+ | `MERCURY_DATA_DIR` | `.mercury` | Data directory |
313
+ | `MERCURY_MAX_CONCURRENCY` | `3` | Max concurrent runs |
314
+ | `MERCURY_PORT` | `8787` | API port |
315
+ | `MERCURY_BOT_USERNAME` | `mercury` | Bot display name |
316
+ | `MERCURY_LOG_LEVEL` | `info` | Log level |
317
+
318
+ **Security:**
319
+
320
+ | Variable | Description |
321
+ |----------|-------------|
322
+ | `MERCURY_API_SECRET` | Shared secret for `/api/*` routes. When set, requires `Authorization: Bearer <secret>`. Auto-generated by `mercury setup`. |
323
+ | `MERCURY_CHAT_API_KEY` | Optional API key for `/chat` endpoint. When set, requires Bearer token. When unset, `/chat` is open (for local use). |
324
+
325
+ **Auth:**
326
+
327
+ Credentials are resolved in this order:
328
+ 1. OAuth credentials from `mercury auth login` (saved to `.mercury/global/auth.json`)
329
+ 2. API keys from `.env` (e.g., `MERCURY_ANTHROPIC_API_KEY`)
330
+
331
+ Supported OAuth providers: Anthropic, GitHub Copilot, Google Gemini CLI, Antigravity, OpenAI Codex.
332
+
333
+ **Model:**
334
+
335
+ | Variable | Default | Description |
336
+ |----------|---------|-------------|
337
+ | `MERCURY_MODEL_PROVIDER` | `anthropic` | Provider |
338
+ | `MERCURY_MODEL` | `claude-opus-4-6` | Model |
339
+ | `MERCURY_ANTHROPIC_API_KEY` | — | API key |
340
+ | `MERCURY_ANTHROPIC_OAUTH_TOKEN` | — | OAuth token (alternative) |
341
+
342
+ **Adapters:**
343
+
344
+ | Variable | Description |
345
+ |----------|-------------|
346
+ | `MERCURY_ENABLE_WHATSAPP` | Enable WhatsApp |
347
+ | `MERCURY_WHATSAPP_AUTH_DIR` | Auth storage path |
348
+ | `MERCURY_ENABLE_TELEGRAM` | Enable Telegram |
349
+ | `MERCURY_TELEGRAM_BOT_TOKEN` | Telegram bot token |
350
+ | `MERCURY_ENABLE_DISCORD` | Enable Discord |
351
+ | `MERCURY_DISCORD_BOT_TOKEN` | Discord bot token |
352
+ | `MERCURY_ENABLE_SLACK` | Enable Slack |
353
+ | `MERCURY_SLACK_BOT_TOKEN` | Slack bot token |
354
+ | `MERCURY_SLACK_SIGNING_SECRET` | Slack signing secret |
355
+
356
+ **Container:**
357
+
358
+ | Variable | Default | Description |
359
+ |----------|---------|-------------|
360
+ | `MERCURY_AGENT_CONTAINER_IMAGE` | `ghcr.io/avishai-tsabari/mercury-agent:latest` | Container image |
361
+ | `MERCURY_CONTAINER_TIMEOUT_MS` | `300000` | Container timeout (5 min) |
362
+ | `MERCURY_CONTAINER_RUNTIME` | `runc` | `runc` (default) or `runsc` ([gVisor](https://gvisor.dev)) |
363
+ | `MERCURY_CONTAINER_BWRAP_DOCKER_COMPAT` | `false` | Set `true` on Linux Docker Engine (see note below) |
364
+
365
+ > **Linux Docker Engine:** Mercury uses [bubblewrap](https://github.com/containers/bubblewrap) for in-container sandboxing. On Linux Docker Engine (not Docker Desktop), bwrap cannot mount `/proc` without extra privileges. Either set `container_bwrap_docker_compat: true` in `mercury.yaml` (adds `--privileged` to `docker run`), or install [gVisor](https://gvisor.dev/docs/user_guide/install/) and set `MERCURY_CONTAINER_RUNTIME=runsc` to skip bwrap entirely.
366
+
367
+ **KB Distillation:**
368
+
369
+ | Variable | Default | Description |
370
+ |----------|---------|-------------|
371
+ | `MERCURY_KB_DISTILL_INTERVAL_MS` | `0` (disabled) | Distillation interval |
372
+
373
+ **Triggers:**
374
+
375
+ | Variable | Default | Description |
376
+ |----------|---------|-------------|
377
+ | `MERCURY_TRIGGER_MATCH` | `mention` | `mention`, `prefix`, `always` |
378
+ | `MERCURY_TRIGGER_PATTERNS` | `@Mercury,Mercury` | Trigger patterns |
379
+ | `MERCURY_ADMINS` | — | Pre-seeded admin user IDs |
380
+
381
+ ### DM Auto-Space
382
+
383
+ Auto-create isolated spaces for each customer who DMs your bot. Each customer gets their own space with persistent context, configurable permissions, and rate limits.
384
+
385
+ ```yaml
386
+ # mercury.yaml
387
+ dm_auto_space:
388
+ enabled: true
389
+ admin_ids: # platform IDs — auto-link to "main" space
390
+ - "24417056866472" # WhatsApp LID, Telegram user ID, etc.
391
+ default_system_prompt: "You are a helpful assistant."
392
+ default_member_permissions: "prompt,prefs.get" # restrict customers to chat only
393
+
394
+ runtime:
395
+ rate_limit_daily_member: 20 # global daily cap for members (0 = unlimited)
396
+ rate_limit_daily_admin: 0 # global daily cap for admins (0 = unlimited)
397
+ ```
398
+
399
+ `admin_ids` values are platform-specific identifiers — check the dashboard Conversations page to see the format (e.g. WhatsApp LID digits, Telegram numeric user ID).
400
+
401
+ Auto-created spaces are seeded with `trigger.match=always`, `context.mode=context`, and the configured member permissions. Per-space rate limits are manageable from the dashboard.
402
+
403
+ ### Per-space Config
404
+
405
+ Conversations are discovered from incoming traffic. Unlinked conversations stay idle until you attach them to a space via `mercury link <conversation-id> <space-id>` or the dashboard.
406
+
407
+ ```bash
408
+ mrctl config set trigger_match always
409
+ mrctl config set trigger_patterns "@Bot,Bot"
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Docs
415
+
416
+ - **Remaining work:** [TODOS](docs/TODOS.md) — Security, reliability, and ops gaps
417
+ - **Platform setup:** [WhatsApp](docs/setup-whatsapp.md) · [Discord](docs/setup-discord.md) · [Slack](docs/setup-slack.md)
418
+ - [Configuration](docs/configuration.md) (mercury.yaml + env) · [PRD: config load](docs/prd-config-load.md)
419
+ - [Authentication](docs/auth/overview.md)
420
+ - [Message pipeline](docs/pipeline.md)
421
+ - [Memory system](docs/memory.md)
422
+ - [Scheduled tasks](docs/scheduler.md)
423
+ - [Permissions](docs/permissions.md)
424
+ - [Media handling](docs/media/overview.md)
425
+ - [KB distillation](docs/kb-distillation.md)
426
+ - [Container lifecycle](docs/container-lifecycle.md)
427
+ - [Graceful shutdown](docs/graceful-shutdown.md)
428
+ - [Rate limiting](docs/rate-limiting.md)
429
+ - [Extensions](docs/extensions.md)
430
+
431
+ ---
432
+
433
+ ## Credits
434
+
435
+ Mercury was originally created by [Michael Livshits](https://github.com/Michaelliv). Full credit for the foundational architecture, extension system, and platform adapters goes to him.
436
+
437
+ Original repository: [github.com/Michaelliv/mercury](https://github.com/Michaelliv/mercury) (archived)
438
+
439
+ This fork is maintained by [Avishai Tsabari](https://github.com/Avishai-Tsabari).
440
+
441
+ ---
442
+
443
+ ## License
444
+
445
+ MIT — see [LICENSE](LICENSE)
446
+
447
+ ---
448
+
449
+ <p align="center">
450
+ <em>There are many claws, but this one is mine.</em> 🪽
451
+ </p>