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.
- package/README.md +451 -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/ARCHITECTURE.md +4 -0
- package/docs/ROADMAP.md +4 -5
- package/docs/{backlog/applicative-profiles.md → archive/applicative-profiles/2026-07-01-applicative-profiles.md} +29 -18
- package/docs/{backlog/caller-bound-capability-token.md → archive/applicative-profiles/2026-07-01-caller-bound-capability-token.md} +15 -11
- 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 -0
- 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/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 +15 -0
- package/src/agent/container-runner.ts +23 -0
- package/src/cli/mercury.ts +38 -6
- package/src/cli/mrctl.ts +25 -0
- package/src/config-file.ts +3 -0
- package/src/config.ts +15 -0
- package/src/core/api.ts +23 -3
- package/src/core/caller-token.ts +101 -0
- package/src/core/permissions.ts +37 -5
- package/src/core/profiles.ts +110 -84
- package/src/core/routes/capability.ts +70 -0
- package/src/core/routes/index.ts +1 -0
- package/src/core/runtime.ts +14 -0
- package/src/dashboard/index.html +729 -729
- package/src/extensions/api.ts +21 -0
- package/src/extensions/loader.ts +15 -0
- package/src/extensions/types.ts +55 -0
- package/src/main.ts +19 -0
- package/docs/pending-updates/dm-auto-space.md +0 -15
- /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>
|