npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mercury-agent

v0.7.0

Published

Personal AI assistant for chat platforms (WhatsApp, Slack, Discord, Telegram)

Readme

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 as the runtime.


Prerequisites

  • Node.js >= 18 — Required for npm install -g mercury-agent
  • Bun >= 1.2 — JavaScript runtime used by Mercury
  • 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.
  • Windows users: Mercury runs best under WSL2. Install WSL2 with wsl --install, then install Bun and Docker inside it.

Quick Start

npm install -g mercury-agent
mkdir my-assistant && cd my-assistant
mercury setup     # Interactive guided setup (recommended)
# -- or for manual setup: --
mercury init

Authenticate:

mercury auth login              # Interactive OAuth (Anthropic, GitHub Copilot, etc.)
mercury auth login anthropic    # Or specify provider directly
mercury auth status             # Check what's configured

Or set an API key in .env:

MERCURY_ANTHROPIC_API_KEY=sk-ant-...

Configure identity and adapters in .env:

MERCURY_BOT_USERNAME=Mercury
MERCURY_TRIGGER_PATTERNS=@Mercury,Mercury

# Enable adapters (pick one or more)
MERCURY_ENABLE_WHATSAPP=true
MERCURY_ENABLE_DISCORD=true
MERCURY_DISCORD_BOT_TOKEN=your-bot-token
MERCURY_ENABLE_TELEGRAM=true
MERCURY_TELEGRAM_BOT_TOKEN=your-bot-token

Start:

mercury run
# or install as a background service (macOS/Linux only):
mercury service install

mercury run runs in the foreground — on Windows (WSL2) this is the only option. On macOS/Linux, prefer mercury service install for long-running use — it runs in the background and auto-restarts.

Set up spaces and conversations

Mercury discovers conversations from incoming traffic. They start unlinked — you assign them to spaces (memory boundaries).

# Create spaces
mercury spaces create main
mercury spaces create work
mercury spaces create family

# Send a message from WhatsApp/Discord/Slack, then:
mercury conversations              # See discovered conversations
mercury conversations --unlinked   # See unlinked ones
mercury link <id> main             # Link a conversation to a space

Multiple conversations can point at the same space — they share memory, session, and vault.

Updating Mercury

# 1. Stop Mercury
#    macOS/Linux: mercury service uninstall
#    Windows/WSL2: Ctrl+C in the terminal running mercury run

# 2. Update the package
npm update -g mercury-agent

# 3. Rebuild the agent container image
mercury build

# 4. Start again
#    macOS/Linux: mercury service install
#    Windows/WSL2: mercury run

mercury build rebuilds the base agent image from the installed package source. The derived image (base + your extensions) rebuilds automatically on startup when the base changes.


How It Works

┌──────────────────────────────────────────────────────────────┐
│                        Host Process                          │
│                                                              │
│   ┌──────────┐  ┌─────────┐  ┌─────────┐  ┌───────────────┐  │
│   │ WhatsApp │  │  Slack  │  │ Discord │  │   Scheduler   │  │
│   │ Adapter  │  │ Adapter │  │ Adapter │  │ (cron tasks)  │  │
│   └───┬──────┘  └────┬────┘  └───┬─────┘  └──────┬────────┘  │
│       └──────────────┴───────────┴───────────────┘           │
│                              │                               │
│                     ┌────────▼────────┐                      │
│                     │  Router/Queue   │                      │
│                     └────────┬────────┘                      │
│                              │                               │
│                     ┌────────▼────────┐                      │
│                     │    SQLite DB    │                      │
│                     └────────┬────────┘                      │
└──────────────────────────────┼───────────────────────────────┘
                               │
                     ┌─────────▼──────────┐
                     │  Docker Container  │
                     │  ┌──────────────┐  │
                     │  │    pi CLI    │  │
                     │  └──────────────┘  │
                     │ /spaces/<space-id> │
                     └────────────────────┘

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.


Features

| Feature | Description | Docs | |---------|-------------|------| | Multi-platform | WhatsApp, Slack, Discord, Telegram | docs/pipeline.md | | Memory | Obsidian-compatible vault per space | docs/memory.md | | Scheduled Tasks | Cron-based recurring prompts | docs/scheduler.md | | Permissions | Role-based access control | docs/permissions.md | | Media | Images, documents, voice notes | docs/media/overview.md | | KB Distillation | Extract lasting knowledge from chats | docs/kb-distillation.md | | Dashboard | Web UI for managing spaces, tasks, permissions, extensions | docs/dashboard.md | | Extensions | TypeScript plugins for CLIs, skills, jobs, hooks | docs/extensions.md | | DM Auto-Space | Auto-create isolated spaces per user DM | docs/rate-limiting.md |

Default capabilities vs. extensions

Out of the box, Mercury is a capable chat assistant with conversation context, scheduled tasks, role-based permissions, multi-space management, message recall, and sub-agent delegation. It does not include web search, web browsing, a knowledge vault, voice, or third-party service integrations — those are added via extensions.

Install extensions from the dashboard (Features page), the CLI, or during setup with a profile:

# From the CLI
mercury add web-browser         # Web browsing & search (uses Brave Search, no API key needed)
mercury add napkin              # Obsidian-style knowledge vault

# Or pick a profile that bundles what you need
mercury setup --profile research

Run mercury extensions list or visit the dashboard's Features page to see what's available.


Workspaces

Each space gets an isolated workspace:

.mercury/spaces/<space-id>/
├── AGENTS.md              # Space instructions
├── .mercury.session.jsonl # pi session
├── inbox/                 # Media received from users
└── outbox/                # Files produced by the agent

Memory/vault structure (for example .obsidian/, knowledge/, daily/) is created by installed extensions.

Multiple platform conversations can point at the same space.


Agent Profiles

Profiles are shareable templates that bundle agent instructions, extensions, and defaults. Use them to start from a preconfigured assistant type.

Built-in profiles:

| Profile | Description | |---------|-------------| | general | General-purpose assistant — helpful, concise, chat-friendly | | coding | Code-focused with sub-agent delegation and web search | | research | Web search and knowledge distillation focused |

# Create from built-in profile
mercury setup --profile coding

# Create from git repo
mercury setup --profile https://github.com/user/mercury-stock-agent

# Create from local directory
mercury setup --profile ./my-profiles/ml-assistant

# List available profiles
mercury profiles list

# Export current project as a profile
mercury profiles export ./my-profile

CLI

mercury (host CLI)

# setup + runtime
mercury setup              # Interactive guided setup (recommended for new projects)
mercury setup --profile <name>   # Create from a profile (general, coding, research, or path/URL)
mercury init               # Manual init (creates .env, .mercury structure)
mercury run
mercury build              # rebuild agent container image (required after updates)
mercury status
mercury doctor             # preflight check — validates Docker, Bun, credentials, adapters

# profiles (agent templates)
mercury profiles list      # List built-in profiles
mercury profiles show <name>   # Show profile details
mercury profiles export <dir>  # Export current project as a reusable profile

# auth
mercury auth login [provider]
mercury auth logout [provider]
mercury auth status
mercury auth whatsapp

# chat + routing
mercury chat "hello"
mercury chat --file photo.jpg "what's in this?"
mercury chat --space work "check status"
echo "summarize" | mercury chat
mercury spaces list
mercury spaces create <id>
mercury conversations
mercury conversations --unlinked
mercury link <conversation-id> <space-id>

# extensions
mercury add ./path/to/extension
mercury add npm:<package>
mercury add git:<repo-url>
mercury add user/repo       # GitHub shorthand (e.g. mercury add user/mercury-ext-ml)
mercury add user/repo#subdir   # GitHub repo with subdirectory
mercury remove <name>
mercury extensions list
mercury ext create <name>   # Scaffold a new extension
mercury ext validate <name> # Validate extension structure and load
mercury ext test <name>     # Dry-run load extension

# service (macOS/Linux only — uses launchd/systemd)
mercury service install
mercury service uninstall
mercury service status
mercury service logs [-f]

mrctl (in-container API CLI)

mrctl whoami
mrctl tasks list|create|pause|resume|run|delete
mrctl roles list|grant|revoke
mrctl permissions show|set
mrctl config get|set
mrctl spaces list|name|delete
mrctl conversations list
mrctl stop
mrctl compact

For full command docs, run mercury --help, mercury <command> --help, or mrctl help.


Extensions

Mercury supports TypeScript extensions that add CLIs, skills, background jobs, lifecycle hooks, config keys, and dashboard widgets.

Creating Extensions

mercury ext create my-extension   # Scaffold a new extension
mercury ext validate my-extension # Check structure and load
mercury ext test my-extension     # Dry-run load
.mercury/extensions/
├── napkin/
│   ├── index.ts
│   └── skill/SKILL.md
└── my-extension/
    └── index.ts

Each extension exports a setup function:

export default function(mercury) {
  mercury.cli({ name: "napkin", install: "bun add -g napkin-ai" });
  mercury.permission({ defaultRoles: ["admin", "member"] });
  mercury.env({ from: "MERCURY_NAPKIN_API_KEY" });
  mercury.skill("./skill");
  mercury.on("workspace_init", async ({ workspace, containerWorkspace }) => { ... });
  mercury.on("before_container", async ({ workspace, containerWorkspace }) => {
    return { env: { MY_VAR: containerWorkspace + "/data" } };
  });
}

Extensions with CLIs get auto-installed into a derived Docker image. Skills are symlinked for agent discovery. Permissions integrate with the existing RBAC system.

See docs/extensions.md for the extension system guide.


Configuration

Optional project file mercury.yaml (or mercury.yml) supplies non-secret defaults; any set MERCURY_* variable overrides it. See docs/configuration.md and resources/templates/mercury.example.yaml.

Environment Variables

Core:

| Variable | Default | Description | |----------|---------|-------------| | MERCURY_DATA_DIR | .mercury | Data directory | | MERCURY_MAX_CONCURRENCY | 2 | Max concurrent runs | | MERCURY_PORT | 8787 | API port | | MERCURY_BOT_USERNAME | mercury | Bot display name | | MERCURY_LOG_LEVEL | info | Log level |

Security:

| Variable | Description | |----------|-------------| | MERCURY_API_SECRET | Shared secret for /api/* routes. When set, requires Authorization: Bearer <secret>. Auto-generated by mercury setup. | | MERCURY_CHAT_API_KEY | Optional API key for /chat endpoint. When set, requires Bearer token. When unset, /chat is open (for local use). |

Auth:

Credentials are resolved in this order:

  1. OAuth credentials from mercury auth login (saved to .mercury/global/auth.json)
  2. API keys from .env (e.g., MERCURY_ANTHROPIC_API_KEY)

Supported OAuth providers: Anthropic, GitHub Copilot, Google Gemini CLI, Antigravity, OpenAI Codex.

Model:

| Variable | Default | Description | |----------|---------|-------------| | MERCURY_MODEL_PROVIDER | anthropic | Provider | | MERCURY_MODEL | claude-opus-4-8 | Model | | MERCURY_ANTHROPIC_API_KEY | — | API key | | MERCURY_ANTHROPIC_OAUTH_TOKEN | — | OAuth token (alternative) |

Adapters:

| Variable | Description | |----------|-------------| | MERCURY_ENABLE_WHATSAPP | Enable WhatsApp | | MERCURY_WHATSAPP_AUTH_DIR | Auth storage path | | MERCURY_ENABLE_TELEGRAM | Enable Telegram | | MERCURY_TELEGRAM_BOT_TOKEN | Telegram bot token | | MERCURY_ENABLE_DISCORD | Enable Discord | | MERCURY_DISCORD_BOT_TOKEN | Discord bot token | | MERCURY_ENABLE_SLACK | Enable Slack | | MERCURY_SLACK_BOT_TOKEN | Slack bot token | | MERCURY_SLACK_SIGNING_SECRET | Slack signing secret |

Container:

| Variable | Default | Description | |----------|---------|-------------| | MERCURY_AGENT_IMAGE | ghcr.io/avishai-tsabari/mercury-agent:latest | Container image | | MERCURY_CONTAINER_TIMEOUT_MS | 300000 | Container timeout (5 min) | | MERCURY_CONTAINER_RUNTIME | runc | runc (default) or runsc (gVisor) | | MERCURY_CONTAINER_BWRAP_DOCKER_COMPAT | false | Set true on Linux Docker Engine (see note below) | | MERCURY_AGENT_ID | — | Unique ID for this assistant (required when running multiple assistants on the same Docker daemon) |

Multiple assistants on the same machine: Mercury builds a derived Docker image (mercury-agent-ext:<hash>) from the base image plus your extensions. When a new image is built, older tags in the same repo are pruned. If two assistants share a Docker daemon without distinct MERCURY_AGENT_ID values, they share the same image repo and one will silently prune the other's image, causing container launch failures. Set MERCURY_AGENT_ID to a unique value per project (e.g. in .env). Cloud console deployments set this automatically.

Linux Docker Engine: Mercury uses 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 and set MERCURY_CONTAINER_RUNTIME=runsc to skip bwrap entirely.

KB Distillation:

| Variable | Default | Description | |----------|---------|-------------| | MERCURY_KB_DISTILL_INTERVAL_MS | 0 (disabled) | Distillation interval |

Triggers:

| Variable | Default | Description | |----------|---------|-------------| | MERCURY_TRIGGER_MATCH | mention | mention, prefix, always | | MERCURY_TRIGGER_PATTERNS | @Mercury,Mercury | Trigger patterns | | MERCURY_ADMINS | — | Pre-seeded admin user IDs |

DM Auto-Space

Auto-create isolated spaces for each user who DMs your bot. Each user gets their own space with persistent context, configurable permissions, and rate limits.

# mercury.yaml
dm_auto_space:
  enabled: true
  admin_ids:                                    # platform IDs — auto-link to "main" space
    - "24417056866472"                          # WhatsApp LID, Telegram user ID, etc.
  default_system_prompt: "You are a helpful assistant."
  default_member_permissions: "prompt,prefs.get"  # restrict users to chat only

runtime:
  rate_limit_daily_member: 20                   # global daily cap for members (0 = unlimited)
  rate_limit_daily_admin: 0                     # global daily cap for admins (0 = unlimited)

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).

Auto-created spaces are seeded with trigger.match=always, context.mode=context, and the configured member permissions. Changing rate_limit_daily_member in mercury.yaml propagates to all auto-created spaces immediately — no per-space update needed. Explicit per-space overrides (set via dashboard or API) still take precedence.

Broadcast

Send a message to all auto-created DM spaces at once (e.g. maintenance notices, promotions):

curl -X POST http://localhost:8787/api/broadcast \
  -H "Authorization: Bearer $API_SECRET" \
  -H "X-Mercury-Caller: <your-admin-id>" \
  -H "X-Mercury-Space: main" \
  -H "Content-Type: application/json" \
  -d '{"text": "Maintenance tonight 10pm-2am."}'

Returns { total, delivered, failed, errors }. Only global admins (admins or dm_auto_space.admin_ids) may broadcast. Messages are sent as literal text — no LLM processing.

Bot Character

Global admins can set a bot-wide character (tone, greeting style, personality) that applies to all spaces — including every DM auto-space. Stored in the database; survives profile deploys.

The recommended flow is conversational: tell the bot to change its character, it drafts the update, confirms with you, then saves via mrctl character set --file <path>. Programmatic access:

# Set
curl -X PUT http://localhost:8787/api/character \
  -H "Authorization: Bearer $API_SECRET" \
  -H "X-Mercury-Caller: <admin-id>" \
  -H "X-Mercury-Space: main" \
  -H "Content-Type: application/json" \
  -d '{"text": "Be warm and professional. Greet with שלום וברכה."}'

# Get current character
curl http://localhost:8787/api/character ...

# Clear
curl -X DELETE http://localhost:8787/api/character ...

Only global admins may set the character (same gate as broadcast). Per-space tone adjustments use the existing per-space system_prompt in dashboard settings.

Per-space Config

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.

mrctl config set trigger_match always
mrctl config set trigger_patterns "@Bot,Bot"

Docs


Credits

Mercury was originally created by Michael Livshits. Full credit for the foundational architecture, extension system, and platform adapters goes to him.

Original repository: github.com/Michaelliv/mercury (archived)

This fork is maintained by Avishai Tsabari.


License

MIT — see LICENSE

Third-party licenses

The WhatsApp adapter depends on @whiskeysockets/baileys, which transitively includes libsignal (GPL-3.0) for Signal Protocol encryption. This component runs inside an isolated Docker container and is loaded as a runtime dependency, not statically linked into Mercury's codebase. If your use case has strict copyleft concerns, consult legal counsel or omit the WhatsApp adapter.