mixdog
v0.7.18
Published
Claude Code all-in-one bridge plugin: role-based bridge workers, continuous memory, and syntax-aware code editing.
Readme
mixdog
All-in-one agent plugin for the Claude Code CLI — autonomous sub-agents,
continuous memory, multi-provider routing, and syntax-aware code tools,
behind a single MCP server. Zero telemetry; all state under
~/.claude/plugins/data/mixdog-trib-plugin/.
- Role-based sub-agents — delegate scoped work to any provider through one
bridgeentry point - Continuous memory — conversations, decisions, and work persist across sessions; a prebuilt Postgres + pgvector runtime is auto-downloaded and supervised, with no database to install
- Lower cost — session-spanning prompt cache with per-provider / per-role token tracking
- Natural-language search — web search and URL scraping in one tool
- Syntax-aware code tools — AST-based symbol / reference / caller lookup, keyword→symbol search via
code_graph, and precise edits - Channels & automation — Discord front-end, cron schedules, and inbound webhooks
Quickstart
npm i -g mixdog # install the `mixdog` command
mixdog # launch Claude Code — the first run walks you through setup (Claude·Codex·Grok login + plugin registration), then opens it
mixdog --dangerously-skip-permissions # launch with full permissionsnpm i -g mixdog adds the mixdog command to your PATH; mixdog then launches
Claude Code with mixdog pre-loaded. The first mixdog run walks you through
setup (logins + plugin registration) and launches the moment it finishes — no
second run needed. Any extra Claude flags pass straight through; the claude
CLI must be on your PATH. (If mixdog isn't recognized right after install,
open a new terminal and run it again.)
Anthropic OAuth (the Claude Code login) is the default provider, so
bridge / recall / explore / memory work immediately — no API keys
required. Configure providers, presets, and role bindings in the in-browser
config UI — open it any time with /mixdog:config. (The config server is
pre-warmed in the background each session, so the window opens instantly.)
Or install from inside Claude Code:
/plugin marketplace add trib-plugin/mixdog
/plugin install mixdog@trib-pluginnpx mixdog # one-off run without a global install (leaves no persistent `mixdog` command)
mixdog install # (re)run setup only: detect Claude CLI, register plugin, OAuth login, prewarm deps
mixdog install --dry-run # preview the steps (no writes, prompts, or installs)
mixdog install --demo # preview in an isolated sandbox (no writes to your real config)Claude Code clones the repo as a marketplace, runs bun install --frozen-lockfile,
and registers the MCP server in .mcp.json. On first boot, scripts/bootstrap.mjs
locates bun (system PATH → plugin-local → npm install --no-save bun fallback),
installs runtime deps into the shared data dir, and seeds defaults under
~/.claude/plugins/data/mixdog-trib-plugin/. The memory runtime (a prebuilt
Postgres + pgvector build) is downloaded and checksum-verified once, then reused.
First boot takes 10–15 extra seconds if bun wasn't pre-installed, plus the
one-time runtime download; later boots are unaffected.
First boot also reconfigures two Claude Code surfaces, originals preserved for
restore: the built-in autoMemoryEnabled and awaySummaryEnabled settings are
turned off in ~/.claude/settings.json (mixdog's continuous memory and recap
replace both), and rules persistence takes over ~/.claude/CLAUDE.md (see
Configuration). Prior values are snapshotted under
~/.claude/backups/mixdog-user-data/install-restore/, and
node scripts/uninstall.mjs restores them (see UNINSTALL.md for full teardown).
To enable Discord / voice / schedule / webhook channels, launch with the development channel flag (see Channels & automation) and set the Discord token and channel IDs in the config UI.
Why mixdog
Claude Code is powerful, but out of the box it forgets everything between sessions, treats every request as a fresh context, and has no built-in way to delegate to cheaper or specialised models. Cost runs high, answers drift, and long-lived projects lose the thread.
mixdog replaces that pattern with a single MCP server that bundles four cooperating modules — agent, memory, search, and channels — so your Claude Code session gains persistent memory, multi-provider sub-agents, web lookup, and an optional Discord front-end, all behind one install. The goal is deployment-grade: plain ESM, zero build step for runtime code, documented local state, and every configuration surface readable as JSON you can diff.
Modules & tools
One MCP server composes four user-facing modules, plus code and filesystem tools shared across all of them:
- agent — a session orchestrator with a single
bridgeentry point: delegated sub-agent sessions, role → preset bindings, multi-provider routing, and session-spanning cache / cost handling. - memory — native Postgres +
pgvector+pg_trgmhybrid store; a prebuilt runtime is fetched and supervised automatically. A three-cycle pipeline scores, dedupes, and promotes durable knowledge to core memory. - search — one natural-language entry point routing across providers, scraping URLs through a Readability + Puppeteer pipeline, formatted for model consumption.
- channels — Discord, cron schedules, inbound webhooks, voice STT, and a heartbeat status surface (requires the channel flag).
agent
Sessions run as long-lived loops with trim / compress, a stream watchdog, and
background job tracking. A <final-answer> tag protocol separates a worker's
final reply from its internal deliberation.
| Tool | Purpose |
| --- | --- |
| bridge | Unified worker session control: type=spawn (default) delegates one scoped task to a role-bound worker; type=send resumes a worker by tag; type=close stops one; type=list enumerates active worker sessions |
| explore | Open-ended codebase exploration when scope is unknown; fans out one read-only sub-agent per query, each pinned to its own topic, and is ESC-cancellable mid-run |
| list_models | List configured provider presets |
| open_config | Open the settings UI (Providers + Presets) in the browser; starts the resident config server if needed and returns the UI URL |
memory
Every conversation chunk is scored, deduped, and — if durable — promoted to core memory. Cycle 1 extracts and scores chunks, cycle 2 is a unified curator gate that holds the active set to a cap (~100 entries), and cycle 3 reviews user-curated core memory. Keep/discard decisions follow a 3-layer framework (L1 relationship/communication, L2 behavior rules, L3 current project map). SessionStart injects durable context plus a recent recap.
| Tool | Purpose |
| --- | --- |
| recall | Retrieve stored memory (string or array fan-out; category / period / scope filters) |
| memory | Persistent memory operations (status / core add-edit-delete-list / manage / prune / rebuild / cycle1-3 / flush / backfill / purge) |
search
| Tool | Purpose |
| --- | --- |
| search | Web SERP search (string or array of queries) |
| web_fetch | Fetch a full page body from a URL (follow-up to search) |
channels
Inbound chat / webhook events drive a turn, schedules fire on cadence, and the status feed keeps long-running sessions observable.
| Tool | Purpose |
| --- | --- |
| reply / react / edit_message / download_attachment / fetch | Discord message operations |
| schedule_status / trigger_schedule / schedule_control | Inspect, fire, or defer / skip schedules |
| activate_channel_bridge / reload_config / inject_command | Runtime channel control |
Code & filesystem tools
Shared across all modules — AST navigation (@ast-grep/cli) plus
content-addressed edits with a session read-dedup cache, so navigation stays
syntax-correct without dumping whole files into context. Tool results are
compressed before they hit the model (head/tail truncation, ANSI / repeated-line
dedup, file-grouped grep output). apply_patch accepts unified and V4A hunks
with order-independent matching. read decodes UTF-8 and UTF-16 (LE/BE, with or
without BOM). bash auto-backgrounds a foreground command that outlives 30s into
a tracked job and streams live progress over MCP.
| Tool | Module | Purpose |
| --- | --- | --- |
| code_graph (find_symbol, references, callers, search, …) | code_graph | AST symbol lookup, keyword→symbols (search), references, callers |
| read / glob / list / grep | builtin | Read files, find paths, list dirs, ripgrep content |
| edit / write | builtin | Exact-string edit, whole-file write |
| apply_patch | patch | Unified / V4A multi-hunk, multi-file patch |
| bash / job_wait | builtin | Run shell commands; await background jobs |
| diagnostics | builtin | Run the matching project type/lint checker (tsc / eslint / ruff / …) once; no resident LSP |
| inject_input | host_input | Inject input into the host Claude Code session (Windows only) |
| cwd | cwd | Get / set / list the session working directory for relative-path resolution |
Skills & commands
Skills are auto-triggered by intent (Claude Code also surfaces them by name):
setup (onboarding & config), schedule-add, webhook-add, retro-skill-proposer.
Commands: /mixdog:setup (prerequisites + config UI), /mixdog:doctor
(health diagnostics), /mixdog:config (open the in-browser settings UI — the
primary way to change any configuration).
| Skill | Use |
| --- | --- |
| schedule-add | Register a recurring cron schedule |
| webhook-add | Register an inbound webhook endpoint |
| setup | Onboarding and config editing (channels, presets, roles, memory) |
| retro-skill-proposer | Propose a reusable skill draft after a session |
| Command | Purpose |
| --- | --- |
| /mixdog:setup | Check prerequisites and open the config UI |
| /mixdog:doctor | Health diagnostics (versions, runtime, cache, deps, log count/size, Postgres pgdata size, hook-pipe reachability) |
| /mixdog:config | Open the in-browser settings UI — the primary way to change configuration (providers, presets, roles, channels, memory) |
Hidden maintenance roles (under agents/, not user-invoked):
scheduler-task, webhook-handler, maintenance, memory-classification.
Public roles (worker, reviewer, debugger, etc.) are defined locally in
user-workflow.json, not bundled.
Providers
Anthropic (direct or OAuth), OpenAI (direct or OAuth), Google Gemini, and any
OpenAI-compatible endpoint (LM Studio, Ollama, vLLM, LiteLLM) are first-class
providers. Switch a role to a cheaper or faster model by editing one line in
user-workflow.json. A shared-prefix cache strategy propagates Anthropic and
OpenAI prompt caching across every role in a session, and token usage is logged
per provider and per role so you can see where cost lands before the bill arrives.
Safety
- Zero telemetry. No outbound calls beyond the providers you configure and the search endpoints you opt into.
- Protected paths. Destructive shell patterns (recursive root deletes, force pushes, disk formatting) are hard-blocked, unconditionally, with no override flag.
- Approval gates & tool scope. Out-of-workspace writes by sub-agents require confirmation; system paths are hard-denied; each role has an explicit tool preset (
readonly/full/ custom). - Untrusted inbound data. Webhook payloads are fenced as untrusted data, never executed as instructions.
- Fail-open hooks. Permission hooks are a guard layer, not a sandbox: if the daemon or hook pipe is down, decisions default to allow (
/mixdog:doctorwarns explicitly).
Full local-state, secret, and network model: SECURITY.md and
DATA-FLOW.md. To restore the pre-install CLAUDE.md and Claude
Code settings, run node scripts/uninstall.mjs (UNINSTALL.md).
Channel-driven features require launching Claude Code with the channel flag.
mixdog is not in Anthropic's curated channel allowlist, so --channels is
rejected at boot. Use the development variant instead:
claude --dangerously-load-development-channels plugin:mixdog@trib-pluginThis activates the Discord backend, voice STT, schedule runner, and webhook
receiver. Without the flag the plugin still works for direct tools (recall,
memory, bridge, explore, search, bash, etc.) — channel inbound events
are silently disabled.
Schedules and webhooks each live as a per-entry directory under the data
directory (schedules/<name>/, webhooks/<name>/), holding config.json
(cron time / secret / optional channel / model) and instructions.md.
Routing is decided purely by channel presence:
- No
channel→ injected into the current (Lead) session, which handles it with full context. channelset → dispatched directly to that Discord channel by a standalone handler (which then requires amodelpreset).
When a handler has nothing to report (no code change, non-default branch,
docs-only, dedup), it emits [meta:silent] as the first line — the notification
is dropped entirely (no session turn, no channel post).
Outbound notifications respect a shared quiet-hours window (timezone-aware, with
weekend and holiday handling); each channel can opt out via its respectQuiet
flag in the config UI's DND tab.
To switch to plain --channels, either submit mixdog to
claude-plugins-official (Anthropic curates the allowlist), or add
{marketplace: "trib-plugin", plugin: "mixdog"} to your organization's
allowedChannelPlugins managed setting (Team / Enterprise).
All user-editable config lives in the plugin data directory
(~/.claude/plugins/data/mixdog-trib-plugin/), NOT in the repository. The
easiest way to edit it is /mixdog:config (the in-browser UI); editing the JSON
files directly is also fully supported.
New installs default to CLAUDE.md mode: mixdog persists its rules block into
~/.claude/CLAUDE.md. On the first takeover of an existing file, the original is
backed up once to
~/.claude/backups/mixdog-user-data/install-restore/claude-md-original.md and
the file is replaced with the marker-delimited managed block; if that backup
can't be written, mixdog appends the block instead and leaves your content in
place. Prefer ephemeral injection? Switch to SessionStart hook mode in the config
UI — that mode never writes to ~/.claude/CLAUDE.md.
First install also disables Claude Code's built-in autoMemoryEnabled and
awaySummaryEnabled in ~/.claude/settings.json (mixdog's memory and recap
replace both) after snapshotting the prior values to
install-restore/claude-settings-original.json. Run
node scripts/uninstall.mjs to restore.
| File | How it gets there | Purpose |
| --- | --- | --- |
| mixdog-config.json | Auto-seeded on first boot | All user-configurable settings under named sections (channels, memory, agent, search, plus UI-managed extras). See src/shared/seed.mjs. |
| user-workflow.json | Seeded by the setup server when missing | Role → preset bindings for delegated agents |
| user-workflow.md | Auto-generated on first launch | Human-readable workflow description derived from user-workflow.json |
| schedules/<name>/ | Created via config UI or schedule-add | Per-schedule config.json + instructions.md |
| webhooks/<name>/ | Created via config UI or webhook-add | Per-webhook config.json + instructions.md |
Seed defaults and templates live under defaults/. Discord setup (optional):
set the bot token in the config UI (stored in the OS keychain, not a file) and
add channel IDs there, then enable channels.
The MCP server starts via scripts/bootstrap.mjs → scripts/run-mcp.mjs (stdio
supervisor) → server.mjs (thin client or shared daemon) → server-main.mjs.
Hooks are declared in hooks/hooks.json and routed through a native shim + CJS
files. SessionStart is split into three parts — rules (workflow / rules
injection + first-boot setup), core (durable memory context), and recap
(recent-session recap); PreToolUse / PostToolUse enforce permission gates,
sandbox checks, and status updates. Session state is journalled every turn, so a
mid-session crash resumes cleanly on next boot. SessionStart also installs a
version-independent status line (a stable launcher tagged
"source": "mixdog-auto" in ~/.claude/settings.json) that survives version
bumps and self-heals; a genuine user-configured statusLine is left untouched.
See ARCHITECTURE.md and DATA-FLOW.md.
mixdog is developed on Windows and tested on Windows + Linux. All scripts use
forward slashes or path.join, line endings are normalised to LF via
.gitattributes (except .cmd / .bat / .ps1, which stay CRLF), and Node
child-process calls resolve binaries through process.platform-aware shims.
The prebuilt memory runtime ships for Windows (win32-x64), Linux (linux-x64),
and macOS on Apple Silicon (darwin-arm64) and Intel (darwin-x64); the optional
voice helper publishes verified assets for the same platforms. linux-arm64 is
not yet built.
The bash MCP tool is OS-native: Windows runs commands through PowerShell
(pwsh.exe when available, otherwise Windows PowerShell), while macOS/Linux use
/bin/sh. No extra Windows shell runtime is required or auto-installed.
Contributing
Architecture notes live in ARCHITECTURE.md; contributor setup and PR expectations in CONTRIBUTING.md. Before opening a PR, run:
bun run ciLicense
MIT — see LICENSE.
