mercury-agent 0.4.5

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 (218) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +438 -0
  3. package/container/Dockerfile +127 -0
  4. package/container/Dockerfile.base +109 -0
  5. package/container/Dockerfile.power +17 -0
  6. package/container/agent-package.json +8 -0
  7. package/container/build.sh +54 -0
  8. package/docs/TODOS.md +147 -0
  9. package/docs/auth/dashboard.md +28 -0
  10. package/docs/auth/overview.md +109 -0
  11. package/docs/auth/whatsapp.md +173 -0
  12. package/docs/configuration.md +54 -0
  13. package/docs/container-lifecycle.md +349 -0
  14. package/docs/context-architecture.md +87 -0
  15. package/docs/deployment.md +199 -0
  16. package/docs/extensions.md +375 -0
  17. package/docs/graceful-shutdown.md +62 -0
  18. package/docs/kb-distillation.md +77 -0
  19. package/docs/media/overview.md +140 -0
  20. package/docs/media/whatsapp.md +171 -0
  21. package/docs/memory.md +137 -0
  22. package/docs/permissions.md +217 -0
  23. package/docs/pipeline.md +228 -0
  24. package/docs/prd-chat-memory.md +76 -0
  25. package/docs/prd-config-load.md +82 -0
  26. package/docs/rate-limiting.md +166 -0
  27. package/docs/scheduler.md +288 -0
  28. package/docs/setup-discord.md +100 -0
  29. package/docs/setup-slack.md +119 -0
  30. package/docs/setup-whatsapp.md +94 -0
  31. package/docs/subagents.md +166 -0
  32. package/docs/web-search.md +62 -0
  33. package/examples/extensions/README.md +12 -0
  34. package/examples/extensions/charts/index.ts +13 -0
  35. package/examples/extensions/charts/skill/SKILL.md +98 -0
  36. package/examples/extensions/gws/README.md +52 -0
  37. package/examples/extensions/gws/index.ts +106 -0
  38. package/examples/extensions/gws/skill/SKILL.md +57 -0
  39. package/examples/extensions/gws/skill/references/calendar.md +101 -0
  40. package/examples/extensions/gws/skill/references/docs.md +65 -0
  41. package/examples/extensions/gws/skill/references/drive.md +79 -0
  42. package/examples/extensions/gws/skill/references/gmail.md +85 -0
  43. package/examples/extensions/gws/skill/references/sheets.md +60 -0
  44. package/examples/extensions/napkin/index.ts +821 -0
  45. package/examples/extensions/napkin/prompts/consolidation-monthly.md +73 -0
  46. package/examples/extensions/napkin/prompts/consolidation-weekly.md +67 -0
  47. package/examples/extensions/napkin/prompts/kb-distillation.md +176 -0
  48. package/examples/extensions/napkin/skill/SKILL.md +728 -0
  49. package/examples/extensions/pdf/index.ts +23 -0
  50. package/examples/extensions/pdf/skill/LICENSE.txt +30 -0
  51. package/examples/extensions/pdf/skill/SKILL.md +314 -0
  52. package/examples/extensions/pdf/skill/forms.md +294 -0
  53. package/examples/extensions/pdf/skill/reference.md +612 -0
  54. package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -0
  55. package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -0
  56. package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -0
  57. package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -0
  58. package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -0
  59. package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -0
  60. package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -0
  61. package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -0
  62. package/examples/extensions/permission-guard/index.ts +65 -0
  63. package/examples/extensions/pinchtab/index.ts +199 -0
  64. package/examples/extensions/pinchtab/lib/session-injector.ts +144 -0
  65. package/examples/extensions/pinchtab/skill/SKILL.md +224 -0
  66. package/examples/extensions/pinchtab/skill/TRUST.md +69 -0
  67. package/examples/extensions/pinchtab/skill/references/api.md +297 -0
  68. package/examples/extensions/pinchtab/skill/references/env.md +45 -0
  69. package/examples/extensions/pinchtab/skill/references/profiles.md +107 -0
  70. package/examples/extensions/tradestation/host/refresh.ts +102 -0
  71. package/examples/extensions/tradestation/index.ts +153 -0
  72. package/examples/extensions/tradestation/skill/SKILL.md +67 -0
  73. package/examples/extensions/tradestation/skill/scripts/ts-cli.ts +111 -0
  74. package/examples/extensions/voice-synth/index.ts +94 -0
  75. package/examples/extensions/voice-synth/skill/SKILL.md +38 -0
  76. package/examples/extensions/voice-transcribe/index.ts +381 -0
  77. package/examples/extensions/voice-transcribe/requirements.txt +8 -0
  78. package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -0
  79. package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -0
  80. package/examples/extensions/web-search/index.ts +22 -0
  81. package/examples/extensions/web-search/skill/SKILL.md +114 -0
  82. package/examples/extensions/web-search/skill/references/apartments.md +178 -0
  83. package/examples/extensions/web-search/skill/references/car-purchase.md +132 -0
  84. package/examples/extensions/web-search/skill/references/car-rental.md +113 -0
  85. package/examples/extensions/web-search/skill/references/flights.md +133 -0
  86. package/examples/extensions/web-search/skill/references/hotels.md +148 -0
  87. package/examples/extensions/yahoo-mail/cli/bun.lock +66 -0
  88. package/examples/extensions/yahoo-mail/cli/package.json +13 -0
  89. package/examples/extensions/yahoo-mail/cli/ymail.mjs +353 -0
  90. package/examples/extensions/yahoo-mail/index.ts +57 -0
  91. package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -0
  92. package/package.json +106 -0
  93. package/resources/agents/explore.md +50 -0
  94. package/resources/agents/worker.md +24 -0
  95. package/resources/builtin-extensions.txt +3 -0
  96. package/resources/connection-env-vars.json +25 -0
  97. package/resources/extensions/.gitkeep +0 -0
  98. package/resources/pi-extensions/subagent/agents.ts +126 -0
  99. package/resources/pi-extensions/subagent/index.ts +964 -0
  100. package/resources/profiles/coding/AGENTS.md +43 -0
  101. package/resources/profiles/coding/mercury-profile.yaml +15 -0
  102. package/resources/profiles/general/AGENTS.md +31 -0
  103. package/resources/profiles/general/mercury-profile.yaml +15 -0
  104. package/resources/profiles/research/AGENTS.md +40 -0
  105. package/resources/profiles/research/mercury-profile.yaml +15 -0
  106. package/resources/skills/config/SKILL.md +25 -0
  107. package/resources/skills/context/SKILL.md +33 -0
  108. package/resources/skills/conversation-recap/SKILL.md +19 -0
  109. package/resources/skills/media/SKILL.md +27 -0
  110. package/resources/skills/mutes/SKILL.md +31 -0
  111. package/resources/skills/permissions/SKILL.md +19 -0
  112. package/resources/skills/preferences/SKILL.md +31 -0
  113. package/resources/skills/recall/SKILL.md +24 -0
  114. package/resources/skills/roles/SKILL.md +18 -0
  115. package/resources/skills/spaces/SKILL.md +18 -0
  116. package/resources/skills/tasks/SKILL.md +45 -0
  117. package/resources/templates/AGENTS.md +157 -0
  118. package/resources/templates/env.template +34 -0
  119. package/resources/templates/mercury.example.yaml +75 -0
  120. package/src/adapters/discord-native.ts +534 -0
  121. package/src/adapters/discord.ts +38 -0
  122. package/src/adapters/setup.ts +89 -0
  123. package/src/adapters/slack.ts +9 -0
  124. package/src/adapters/whatsapp-media.ts +337 -0
  125. package/src/adapters/whatsapp.ts +629 -0
  126. package/src/agent/api-socket.ts +127 -0
  127. package/src/agent/container-entry.ts +967 -0
  128. package/src/agent/container-error.ts +49 -0
  129. package/src/agent/container-runner.ts +1272 -0
  130. package/src/agent/model-capabilities-core.ts +23 -0
  131. package/src/agent/model-capabilities.ts +231 -0
  132. package/src/agent/pi-failure-class.ts +83 -0
  133. package/src/agent/pi-jsonl-parser.ts +306 -0
  134. package/src/agent/preferences-prompt.ts +20 -0
  135. package/src/agent/user-error-messages.ts +78 -0
  136. package/src/bridges/discord.ts +171 -0
  137. package/src/bridges/slack.ts +177 -0
  138. package/src/bridges/teams.ts +160 -0
  139. package/src/bridges/telegram.ts +571 -0
  140. package/src/bridges/whatsapp.ts +290 -0
  141. package/src/chat-shim.ts +259 -0
  142. package/src/cli/mercury.ts +2508 -0
  143. package/src/cli/mrctl-http.ts +27 -0
  144. package/src/cli/mrctl.ts +611 -0
  145. package/src/cli/whatsapp-auth.ts +260 -0
  146. package/src/config-file.ts +397 -0
  147. package/src/config-model-chain.ts +30 -0
  148. package/src/config.ts +316 -0
  149. package/src/core/api-types.ts +58 -0
  150. package/src/core/api.ts +105 -0
  151. package/src/core/commands.ts +76 -0
  152. package/src/core/conversation.ts +47 -0
  153. package/src/core/handler.ts +206 -0
  154. package/src/core/media.ts +200 -0
  155. package/src/core/mute-duration.ts +22 -0
  156. package/src/core/outbox.ts +76 -0
  157. package/src/core/permissions.ts +192 -0
  158. package/src/core/profiles.ts +245 -0
  159. package/src/core/rate-limiter.ts +127 -0
  160. package/src/core/router.ts +191 -0
  161. package/src/core/routes/chat.ts +172 -0
  162. package/src/core/routes/config-builtin.ts +107 -0
  163. package/src/core/routes/config.ts +81 -0
  164. package/src/core/routes/connections.ts +190 -0
  165. package/src/core/routes/console.ts +668 -0
  166. package/src/core/routes/control.ts +46 -0
  167. package/src/core/routes/conversations.ts +66 -0
  168. package/src/core/routes/dashboard.ts +2491 -0
  169. package/src/core/routes/extensions.ts +37 -0
  170. package/src/core/routes/index.ts +14 -0
  171. package/src/core/routes/media.ts +72 -0
  172. package/src/core/routes/messages.ts +37 -0
  173. package/src/core/routes/mutes.ts +89 -0
  174. package/src/core/routes/prefs.ts +95 -0
  175. package/src/core/routes/roles.ts +125 -0
  176. package/src/core/routes/spaces.ts +60 -0
  177. package/src/core/routes/storage.ts +126 -0
  178. package/src/core/routes/tasks.ts +189 -0
  179. package/src/core/routes/tradestation.ts +268 -0
  180. package/src/core/routes/tts.ts +51 -0
  181. package/src/core/runtime.ts +1140 -0
  182. package/src/core/space-queue.ts +103 -0
  183. package/src/core/storage-cleanup.ts +140 -0
  184. package/src/core/storage-guard.ts +24 -0
  185. package/src/core/task-scheduler.ts +132 -0
  186. package/src/core/telegram-format.ts +178 -0
  187. package/src/core/trigger.ts +142 -0
  188. package/src/dashboard/index.html +729 -0
  189. package/src/dashboard/tokens.css +53 -0
  190. package/src/extensions/api.ts +252 -0
  191. package/src/extensions/catalog.ts +117 -0
  192. package/src/extensions/config-registry.ts +83 -0
  193. package/src/extensions/context.ts +36 -0
  194. package/src/extensions/hooks.ts +156 -0
  195. package/src/extensions/image-builder.ts +617 -0
  196. package/src/extensions/installer.ts +306 -0
  197. package/src/extensions/jobs.ts +122 -0
  198. package/src/extensions/loader.ts +271 -0
  199. package/src/extensions/permission-guard.ts +52 -0
  200. package/src/extensions/reserved.ts +28 -0
  201. package/src/extensions/skills.ts +123 -0
  202. package/src/extensions/types.ts +462 -0
  203. package/src/logger.ts +174 -0
  204. package/src/main.ts +586 -0
  205. package/src/server.ts +391 -0
  206. package/src/storage/db.ts +1624 -0
  207. package/src/storage/memory.ts +45 -0
  208. package/src/storage/pi-auth.ts +95 -0
  209. package/src/text/markdown.ts +117 -0
  210. package/src/text/rtl.ts +38 -0
  211. package/src/tradestation/host-api.ts +77 -0
  212. package/src/tradestation/pending-orders.ts +69 -0
  213. package/src/tts/azure.ts +52 -0
  214. package/src/tts/google.ts +128 -0
  215. package/src/tts/index.ts +8 -0
  216. package/src/tts/language.ts +20 -0
  217. package/src/tts/synthesize.ts +133 -0
  218. package/src/types.ts +295 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Michael Livshits
4
+ Copyright (c) 2026 Avishai Tsabari
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,438 @@
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
+ - **[Bun](https://bun.sh)** >= 1.0 — JavaScript runtime used by Mercury
21
+ - **[Docker](https://docs.docker.com/get-docker/)** — Required for running agent containers
22
+ - **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.
23
+
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ npm install -g mercury-agent
28
+ mkdir my-assistant && cd my-assistant
29
+ mercury setup # Interactive guided setup (recommended)
30
+ # -- or for manual setup: --
31
+ mercury init
32
+ ```
33
+
34
+ Authenticate:
35
+
36
+ ```bash
37
+ mercury auth login # Interactive OAuth (Anthropic, GitHub Copilot, etc.)
38
+ mercury auth login anthropic # Or specify provider directly
39
+ mercury auth status # Check what's configured
40
+ ```
41
+
42
+ Or set an API key in `.env`:
43
+
44
+ ```bash
45
+ MERCURY_ANTHROPIC_API_KEY=sk-ant-...
46
+ ```
47
+
48
+ Configure identity and adapters in `.env`:
49
+
50
+ ```bash
51
+ MERCURY_BOT_USERNAME=Mercury
52
+ MERCURY_TRIGGER_PATTERNS=@Mercury,Mercury
53
+
54
+ # Enable adapters
55
+ MERCURY_ENABLE_WHATSAPP=true
56
+ MERCURY_ENABLE_DISCORD=true
57
+ MERCURY_DISCORD_BOT_TOKEN=your-bot-token
58
+ ```
59
+
60
+ Start:
61
+
62
+ ```bash
63
+ mercury run
64
+ # or install as a background service:
65
+ mercury service install
66
+ ```
67
+
68
+ ### Set up spaces and conversations
69
+
70
+ Mercury discovers conversations from incoming traffic. They start **unlinked** — you assign them to **spaces** (memory boundaries).
71
+
72
+ ```bash
73
+ # Create spaces
74
+ mercury spaces create main
75
+ mercury spaces create work
76
+ mercury spaces create family
77
+
78
+ # Send a message from WhatsApp/Discord/Slack, then:
79
+ mercury conversations # See discovered conversations
80
+ mercury conversations --unlinked # See unlinked ones
81
+ mercury link <id> main # Link a conversation to a space
82
+ ```
83
+
84
+ Multiple conversations can point at the same space — they share memory, session, and vault.
85
+
86
+ ---
87
+
88
+ ## How It Works
89
+
90
+ ```
91
+ ┌──────────────────────────────────────────────────────────────┐
92
+ │ Host Process │
93
+ │ │
94
+ │ ┌──────────┐ ┌─────────┐ ┌─────────┐ ┌───────────────┐ │
95
+ │ │ WhatsApp │ │ Slack │ │ Discord │ │ Scheduler │ │
96
+ │ │ Adapter │ │ Adapter │ │ Adapter │ │ (cron tasks) │ │
97
+ │ └───┬──────┘ └────┬────┘ └───┬─────┘ └──────┬────────┘ │
98
+ │ └──────────────┴───────────┴───────────────┘ │
99
+ │ │ │
100
+ │ ┌────────▼────────┐ │
101
+ │ │ Router/Queue │ │
102
+ │ └────────┬────────┘ │
103
+ │ │ │
104
+ │ ┌────────▼────────┐ │
105
+ │ │ SQLite DB │ │
106
+ │ └────────┬────────┘ │
107
+ └──────────────────────────────┼───────────────────────────────┘
108
+
109
+ ┌─────────▼──────────┐
110
+ │ Docker Container │
111
+ │ ┌──────────────┐ │
112
+ │ │ pi CLI │ │
113
+ │ └──────────────┘ │
114
+ │ /spaces/<space-id> │
115
+ └────────────────────┘
116
+ ```
117
+
118
+ 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.
119
+
120
+ ---
121
+
122
+ ## Features
123
+
124
+ | Feature | Description | Docs |
125
+ |---------|-------------|------|
126
+ | **Multi-platform** | WhatsApp, Slack, Discord, Telegram | [docs/pipeline.md](docs/pipeline.md) |
127
+ | **Memory** | Obsidian-compatible vault per space | [docs/memory.md](docs/memory.md) |
128
+ | **Scheduled Tasks** | Cron-based recurring prompts | [docs/scheduler.md](docs/scheduler.md) |
129
+ | **Permissions** | Role-based access control | [docs/permissions.md](docs/permissions.md) |
130
+ | **Media** | Images, documents, voice notes | [docs/media/overview.md](docs/media/overview.md) |
131
+ | **KB Distillation** | Extract lasting knowledge from chats | [docs/kb-distillation.md](docs/kb-distillation.md) |
132
+ | **Extensions** | TypeScript plugins for CLIs, skills, jobs, hooks | [docs/extensions.md](docs/extensions.md) |
133
+
134
+ ---
135
+
136
+ ## Workspaces
137
+
138
+ Each space gets an isolated workspace:
139
+
140
+ ```text
141
+ .mercury/spaces/<space-id>/
142
+ ├── AGENTS.md # Space instructions
143
+ ├── .mercury.session.jsonl # pi session
144
+ ├── inbox/ # Media received from users
145
+ └── outbox/ # Files produced by the agent
146
+ ```
147
+
148
+ Memory/vault structure (for example `.obsidian/`, `knowledge/`, `daily/`) is created by installed extensions.
149
+
150
+ Multiple platform conversations can point at the same space.
151
+
152
+ ---
153
+
154
+ ## Agent Profiles
155
+
156
+ Profiles are shareable templates that bundle agent instructions, extensions, and defaults. Use them to start from a preconfigured assistant type.
157
+
158
+ **Built-in profiles:**
159
+
160
+ | Profile | Description |
161
+ |---------|-------------|
162
+ | `general` | General-purpose assistant — helpful, concise, chat-friendly |
163
+ | `coding` | Code-focused with sub-agent delegation and web search |
164
+ | `research` | Web search and knowledge distillation focused |
165
+
166
+ ```bash
167
+ # Create from built-in profile
168
+ mercury setup --profile coding
169
+
170
+ # Create from git repo
171
+ mercury setup --profile https://github.com/user/mercury-stock-agent
172
+
173
+ # Create from local directory
174
+ mercury setup --profile ./my-profiles/ml-assistant
175
+
176
+ # List available profiles
177
+ mercury profiles list
178
+
179
+ # Export current project as a profile
180
+ mercury profiles export ./my-profile
181
+ ```
182
+
183
+ ---
184
+
185
+ ## CLI
186
+
187
+ ### `mercury` (host CLI)
188
+
189
+ ```bash
190
+ # setup + runtime
191
+ mercury setup # Interactive guided setup (recommended for new projects)
192
+ mercury setup --profile <name> # Create from a profile (general, coding, research, or path/URL)
193
+ mercury init # Manual init (creates .env, .mercury structure)
194
+ mercury run
195
+ mercury build # only needed when developing the base image from source
196
+ mercury status
197
+ mercury doctor # preflight check — validates Docker, Bun, credentials, adapters
198
+
199
+ # profiles (agent templates)
200
+ mercury profiles list # List built-in profiles
201
+ mercury profiles show <name> # Show profile details
202
+ mercury profiles export <dir> # Export current project as a reusable profile
203
+
204
+ # auth
205
+ mercury auth login [provider]
206
+ mercury auth logout [provider]
207
+ mercury auth status
208
+ mercury auth whatsapp
209
+
210
+ # chat + routing
211
+ mercury chat "hello"
212
+ mercury chat --file photo.jpg "what's in this?"
213
+ mercury chat --space work "check status"
214
+ echo "summarize" | mercury chat
215
+ mercury spaces list
216
+ mercury spaces create <id>
217
+ mercury conversations
218
+ mercury conversations --unlinked
219
+ mercury link <conversation-id> <space-id>
220
+
221
+ # extensions
222
+ mercury add ./path/to/extension
223
+ mercury add npm:<package>
224
+ mercury add git:<repo-url>
225
+ mercury add user/repo # GitHub shorthand (e.g. mercury add user/mercury-ext-ml)
226
+ mercury add user/repo#subdir # GitHub repo with subdirectory
227
+ mercury remove <name>
228
+ mercury extensions list
229
+ mercury ext create <name> # Scaffold a new extension
230
+ mercury ext validate <name> # Validate extension structure and load
231
+ mercury ext test <name> # Dry-run load extension
232
+
233
+ # service (recommended for background)
234
+ mercury service install
235
+ mercury service uninstall
236
+ mercury service status
237
+ mercury service logs [-f]
238
+ ```
239
+
240
+ ### `mrctl` (in-container API CLI)
241
+
242
+ ```bash
243
+ mrctl whoami
244
+ mrctl tasks list|create|pause|resume|run|delete
245
+ mrctl roles list|grant|revoke
246
+ mrctl permissions show|set
247
+ mrctl config get|set
248
+ mrctl spaces list|name|delete
249
+ mrctl conversations list
250
+ mrctl stop
251
+ mrctl compact
252
+ ```
253
+
254
+ For full command docs, run `mercury --help`, `mercury <command> --help`, or `mrctl help`.
255
+
256
+ ---
257
+
258
+ ## Extensions
259
+
260
+ Mercury supports TypeScript extensions that add CLIs, skills, background jobs, lifecycle hooks, config keys, and dashboard widgets.
261
+
262
+ ### Creating Extensions
263
+
264
+ ```bash
265
+ mercury ext create my-extension # Scaffold a new extension
266
+ mercury ext validate my-extension # Check structure and load
267
+ mercury ext test my-extension # Dry-run load
268
+ ```
269
+
270
+ ```
271
+ .mercury/extensions/
272
+ ├── napkin/
273
+ │ ├── index.ts
274
+ │ └── skill/SKILL.md
275
+ └── my-extension/
276
+ └── index.ts
277
+ ```
278
+
279
+ Each extension exports a setup function:
280
+
281
+ ```typescript
282
+ export default function(mercury) {
283
+ mercury.cli({ name: "napkin", install: "bun add -g napkin-ai" });
284
+ mercury.permission({ defaultRoles: ["admin", "member"] });
285
+ mercury.env({ from: "MERCURY_NAPKIN_API_KEY" });
286
+ mercury.skill("./skill");
287
+ mercury.on("workspace_init", async ({ workspace, containerWorkspace }) => { ... });
288
+ mercury.on("before_container", async ({ workspace, containerWorkspace }) => {
289
+ return { env: { MY_VAR: containerWorkspace + "/data" } };
290
+ });
291
+ }
292
+ ```
293
+
294
+ Extensions with CLIs get auto-installed into a derived Docker image. Skills are symlinked for agent discovery. Permissions integrate with the existing RBAC system.
295
+
296
+ ### Official Extensions
297
+
298
+ Install curated extensions from the [`@mercuryai`](https://github.com/Michaelliv/mercury-extensions) scope:
299
+
300
+ ```bash
301
+ mercury add @mercuryai/knowledge # Obsidian-based knowledge vault with KB distillation
302
+ mercury add @mercuryai/web-browser # Web browsing via Playwright/Chromium
303
+ mercury add @mercuryai/charts # Chart generation
304
+ mercury add @mercuryai/github # GitHub CLI integration
305
+ mercury add @mercuryai/google-workspace # Google Workspace (Gmail, Calendar, Drive)
306
+ mercury add @mercuryai/pdf-tools # PDF processing, OCR, and form filling
307
+ ```
308
+
309
+ See [mercury-extensions](https://github.com/Michaelliv/mercury-extensions) for the full list and documentation.
310
+
311
+ See [docs/extensions.md](docs/extensions.md) for the extension system guide.
312
+
313
+ ---
314
+
315
+ ## Configuration
316
+
317
+ 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`.
318
+
319
+ ### Environment Variables
320
+
321
+ **Core:**
322
+
323
+ | Variable | Default | Description |
324
+ |----------|---------|-------------|
325
+ | `MERCURY_DATA_DIR` | `.mercury` | Data directory |
326
+ | `MERCURY_MAX_CONCURRENCY` | `3` | Max concurrent runs |
327
+ | `MERCURY_PORT` | `8787` | API port |
328
+ | `MERCURY_BOT_USERNAME` | `mercury` | Bot display name |
329
+ | `MERCURY_LOG_LEVEL` | `info` | Log level |
330
+
331
+ **Security:**
332
+
333
+ | Variable | Description |
334
+ |----------|-------------|
335
+ | `MERCURY_API_SECRET` | Shared secret for `/api/*` routes. When set, requires `Authorization: Bearer <secret>`. Auto-generated by `mercury setup`. |
336
+ | `MERCURY_CHAT_API_KEY` | Optional API key for `/chat` endpoint. When set, requires Bearer token. When unset, `/chat` is open (for local use). |
337
+
338
+ **Auth:**
339
+
340
+ Credentials are resolved in this order:
341
+ 1. OAuth credentials from `mercury auth login` (saved to `.mercury/global/auth.json`)
342
+ 2. API keys from `.env` (e.g., `MERCURY_ANTHROPIC_API_KEY`)
343
+
344
+ Supported OAuth providers: Anthropic, GitHub Copilot, Google Gemini CLI, Antigravity, OpenAI Codex.
345
+
346
+ **Model:**
347
+
348
+ | Variable | Default | Description |
349
+ |----------|---------|-------------|
350
+ | `MERCURY_MODEL_PROVIDER` | `anthropic` | Provider |
351
+ | `MERCURY_MODEL` | `claude-opus-4-6` | Model |
352
+ | `MERCURY_ANTHROPIC_API_KEY` | — | API key |
353
+ | `MERCURY_ANTHROPIC_OAUTH_TOKEN` | — | OAuth token (alternative) |
354
+
355
+ **Adapters:**
356
+
357
+ | Variable | Description |
358
+ |----------|-------------|
359
+ | `MERCURY_ENABLE_WHATSAPP` | Enable WhatsApp |
360
+ | `MERCURY_WHATSAPP_AUTH_DIR` | Auth storage path |
361
+ | `MERCURY_ENABLE_TELEGRAM` | Enable Telegram |
362
+ | `MERCURY_TELEGRAM_BOT_TOKEN` | Telegram bot token |
363
+ | `MERCURY_ENABLE_DISCORD` | Enable Discord |
364
+ | `MERCURY_DISCORD_BOT_TOKEN` | Discord bot token |
365
+ | `MERCURY_ENABLE_SLACK` | Enable Slack |
366
+ | `MERCURY_SLACK_BOT_TOKEN` | Slack bot token |
367
+ | `MERCURY_SLACK_SIGNING_SECRET` | Slack signing secret |
368
+
369
+ **Container:**
370
+
371
+ | Variable | Default | Description |
372
+ |----------|---------|-------------|
373
+ | `MERCURY_AGENT_CONTAINER_IMAGE` | `mercury-agent:latest` | Container image |
374
+ | `MERCURY_CONTAINER_TIMEOUT_MS` | `300000` | Container timeout (5 min) |
375
+
376
+ **KB Distillation:**
377
+
378
+ | Variable | Default | Description |
379
+ |----------|---------|-------------|
380
+ | `MERCURY_KB_DISTILL_INTERVAL_MS` | `0` (disabled) | Distillation interval |
381
+
382
+ **Triggers:**
383
+
384
+ | Variable | Default | Description |
385
+ |----------|---------|-------------|
386
+ | `MERCURY_TRIGGER_MATCH` | `mention` | `mention`, `prefix`, `always` |
387
+ | `MERCURY_TRIGGER_PATTERNS` | `@Mercury,Mercury` | Trigger patterns |
388
+ | `MERCURY_ADMINS` | — | Pre-seeded admin user IDs |
389
+
390
+ ### Per-space Config
391
+
392
+ 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.
393
+
394
+ ```bash
395
+ mrctl config set trigger_match always
396
+ mrctl config set trigger_patterns "@Bot,Bot"
397
+ ```
398
+
399
+ ---
400
+
401
+ ## Docs
402
+
403
+ - **Remaining work:** [TODOS](docs/TODOS.md) — Security, reliability, and ops gaps
404
+ - **Platform setup:** [WhatsApp](docs/setup-whatsapp.md) · [Discord](docs/setup-discord.md) · [Slack](docs/setup-slack.md)
405
+ - [Configuration](docs/configuration.md) (mercury.yaml + env) · [PRD: config load](docs/prd-config-load.md)
406
+ - [Authentication](docs/auth/overview.md)
407
+ - [Message pipeline](docs/pipeline.md)
408
+ - [Memory system](docs/memory.md)
409
+ - [Scheduled tasks](docs/scheduler.md)
410
+ - [Permissions](docs/permissions.md)
411
+ - [Media handling](docs/media/overview.md)
412
+ - [KB distillation](docs/kb-distillation.md)
413
+ - [Container lifecycle](docs/container-lifecycle.md)
414
+ - [Graceful shutdown](docs/graceful-shutdown.md)
415
+ - [Rate limiting](docs/rate-limiting.md)
416
+ - [Extensions](docs/extensions.md)
417
+
418
+ ---
419
+
420
+ ## Credits
421
+
422
+ 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.
423
+
424
+ Original repository: [github.com/Michaelliv/mercury](https://github.com/Michaelliv/mercury) (archived)
425
+
426
+ This fork is maintained by [Avishai Tsabari](https://github.com/Avishai-Tsabari).
427
+
428
+ ---
429
+
430
+ ## License
431
+
432
+ MIT — see [LICENSE](LICENSE)
433
+
434
+ ---
435
+
436
+ <p align="center">
437
+ <em>There are many claws, but this one is mine.</em> 🪽
438
+ </p>
@@ -0,0 +1,127 @@
1
+ # syntax=docker/dockerfile:1
2
+ # Mercury Agent Container
3
+ # Bun binary copied from official image — avoids bun.sh/install script deps
4
+ FROM oven/bun:1 AS bun-source
5
+ FROM node:22-slim AS node-source
6
+ FROM golang:1.24.1 AS go-source
7
+
8
+ FROM ubuntu:24.04
9
+
10
+ ENV DEBIAN_FRONTEND=noninteractive
11
+
12
+ # Install dev tools and language runtimes
13
+ RUN apt-get update && apt-get install -y --no-install-recommends \
14
+ # Core tools
15
+ ca-certificates git curl wget jq vim zsh openssh-client gpg unzip \
16
+ build-essential \
17
+ # Python
18
+ python3 python3-pip python3-venv \
19
+ # Sandboxing: bubblewrap for defense-in-depth in runc mode.
20
+ # Not used when CONTAINER_RUNTIME=runsc (gVisor handles isolation at the syscall boundary).
21
+ # Remove once runc mode is deprecated.
22
+ bubblewrap \
23
+ && rm -rf /var/lib/apt/lists/*
24
+
25
+ # Rename the built-in ubuntu user (UID 1000) to mercury
26
+ # Ubuntu 24.04 ships with an 'ubuntu' user at UID/GID 1000; useradd -u 1000 fails with exit code 4
27
+ RUN usermod -l mercury -d /home/mercury -m ubuntu && groupmod -n mercury ubuntu
28
+
29
+ # Copy Bun from official image
30
+ COPY --from=bun-source /usr/local/bin/bun /usr/local/bin/bun
31
+ COPY --from=bun-source /usr/local/bin/bunx /usr/local/bin/bunx
32
+
33
+ # Copy Node.js from official image (avoids flaky nodesource apt repository)
34
+ # npm/npx are symlinks in the upstream image; Docker COPY dereferences single-file
35
+ # symlinks, so recreate them with ln -s after copying node_modules.
36
+ COPY --from=node-source /usr/local/bin/node /usr/local/bin/node
37
+ COPY --from=node-source /usr/local/lib/node_modules /usr/local/lib/node_modules
38
+ COPY --from=node-source /usr/local/include/node /usr/local/include/node
39
+ RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
40
+ ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
41
+ ENV HOME="/home/mercury"
42
+ ENV BUN_INSTALL="/home/mercury/.bun"
43
+ ENV PATH="$BUN_INSTALL/bin:/usr/local/bin:$PATH"
44
+
45
+ # Copy Go from official image (avoids curl installer and network flakiness)
46
+ COPY --from=go-source /usr/local/go /usr/local/go
47
+ ENV PATH="/usr/local/go/bin:$PATH"
48
+
49
+ # Install Playwright + Chromium (used by multiple extensions: web-browser, diagrams, charts)
50
+ # HOME=/home/mercury causes playwright to install browsers to /home/mercury/.cache/ms-playwright
51
+ RUN npx playwright install --with-deps chromium
52
+
53
+ # Point puppeteer to Playwright's Chromium so npm packages skip downloading their own
54
+ ENV PUPPETEER_SKIP_DOWNLOAD=true
55
+ RUN ln -sf $(find /home/mercury/.cache/ms-playwright -name chrome -type f | head -1) /usr/local/bin/chromium
56
+ ENV PUPPETEER_EXECUTABLE_PATH=/usr/local/bin/chromium
57
+
58
+ # Allow Chromium to run without sandbox in Docker (required for non-root too)
59
+ RUN echo '{"args":["--no-sandbox"]}' > /home/mercury/.puppeteerrc.json
60
+ ENV CHROMIUM_FLAGS="--no-sandbox"
61
+
62
+ # Install CLIs
63
+ RUN bun add -g @mariozechner/pi-coding-agent@^0.67.2
64
+
65
+ WORKDIR /app
66
+
67
+ COPY container/agent-package.json /app/package.json
68
+ RUN bun install --production
69
+
70
+ # Patch pi: skip thinkingConfig for Gemma models (Google API rejects thinkingBudget for them,
71
+ # but pi marks gemma-4 as reasoning:true and sends thinkingBudget:0 to disable it)
72
+ RUN node <<'EOF'
73
+ const fs = require('fs'), path = require('path');
74
+ function patch(dir) {
75
+ try {
76
+ for (const f of fs.readdirSync(dir)) {
77
+ const p = path.join(dir, f);
78
+ try {
79
+ if (fs.statSync(p).isDirectory()) patch(p);
80
+ else if (f === 'google.js' && p.includes('@mariozechner/pi-ai')) {
81
+ let c = fs.readFileSync(p, 'utf8');
82
+ const noThinking = '&& !model.id.startsWith("gemma")';
83
+ const p1 = 'if (options.thinking?.enabled && model.reasoning) {';
84
+ const p2 = 'else if (model.reasoning && options.thinking && !options.thinking.enabled) {';
85
+ if (!c.includes(noThinking)) {
86
+ c = c.replace(p1, 'if (options.thinking?.enabled && model.reasoning ' + noThinking + ') {');
87
+ c = c.replace(p2, 'else if (model.reasoning && options.thinking && !options.thinking.enabled ' + noThinking + ') {');
88
+ fs.writeFileSync(p, c);
89
+ console.log('Patched:', p);
90
+ }
91
+ }
92
+ } catch(e) {}
93
+ }
94
+ } catch(e) {}
95
+ }
96
+ patch('/home/mercury/.bun');
97
+ patch('/app/node_modules');
98
+ EOF
99
+
100
+ COPY src/agent/container-entry.ts /app/src/agent/container-entry.ts
101
+ COPY src/agent/model-capabilities-core.ts /app/src/agent/model-capabilities-core.ts
102
+ COPY src/agent/pi-failure-class.ts /app/src/agent/pi-failure-class.ts
103
+ COPY src/agent/pi-jsonl-parser.ts /app/src/agent/pi-jsonl-parser.ts
104
+ COPY src/agent/preferences-prompt.ts /app/src/agent/preferences-prompt.ts
105
+ COPY src/cli/mrctl.ts /app/src/cli/mrctl.ts
106
+ COPY src/cli/mrctl-http.ts /app/src/cli/mrctl-http.ts
107
+ COPY src/extensions/reserved.ts /app/src/extensions/reserved.ts
108
+ COPY src/extensions/permission-guard.ts /app/src/extensions/permission-guard.ts
109
+ COPY src/types.ts /app/src/types.ts
110
+ COPY resources/ /app/resources/
111
+ COPY examples/extensions/ /tmp/examples-extensions/
112
+ RUN while IFS= read -r ext || [ -n "$ext" ]; do \
113
+ ext=$(echo "$ext" | xargs); \
114
+ [ -z "$ext" ] && continue; \
115
+ cp -r "/tmp/examples-extensions/$ext" "/app/resources/extensions/$ext"; \
116
+ done < /app/resources/builtin-extensions.txt && \
117
+ rm -rf /tmp/examples-extensions/
118
+
119
+ RUN echo '#!/bin/sh\nbun run /app/src/cli/mrctl.ts "$@"' > /usr/local/bin/mrctl && \
120
+ chmod +x /usr/local/bin/mrctl
121
+
122
+ # Fix ownership of all mercury home dir artifacts before switching user
123
+ RUN chown -R mercury:mercury /home/mercury
124
+
125
+ USER mercury
126
+
127
+ ENTRYPOINT ["bun", "run", "/app/src/agent/container-entry.ts"]