Mini Me
No, no. We don't gnaw on our kitty.
Mini Me (mm) is a minimalist coding agent for local LLMs, written in Go, that runs in your terminal or inside an editor such as Zed.
What is mini-me?
Mini Me started as the preparation of a Tools-in-Action talk for Devoxx Belgium 2026, where I explain how an agent loop works with a single tool: bash. The model asks for a command, the agent runs it, the output goes back to the model, and so on until the model answers.
From there it grew into the coding agent I wanted for local models (Docker Model Runner, llama.cpp, llmman, Ollama): small enough to be read in an afternoon, and careful about what a small model does wrong:
- hallucinations — the agent shows the real output of every command before the model comments on it, and the prompt forbids stating anything a command did not return;
- silent failures — a failing command, a refused edit or a rejected permission goes back to the model as text, so it reads why and tries something else;
- endless loops — the same action with the same result, repeated, is detected and the model is told to change approach; if it keeps repeating anyway, the turn is stopped and the error is recorded in the session; a watchdog catches a connection that went silent.
What makes Mini Me a bit special is that it was designed from the start to be used from an editor through the Agent Client Protocol (ACP): the same loop runs in a terminal REPL, in a full-screen terminal window, and inside Zed.

Install
You need Go 1.27+ and a model server that can emit tool calls, through its OpenAI-compatible API: Docker Model Runner (provider: dmr, the default), llama.cpp's llama-server (llamacpp), llmman (llmman) or Ollama (ollama) — or any other OpenAI-compatible server or service with provider: openai (the OpenAI API by default, Mistral AI, Cerebras, Hugging Face, vLLM, LM Studio…: mm init asks its endpoint and the variable that holds its API key).
git clone https://git.rickub.com/bots-garden/mini-me.git
cd mini-me
./install.sh # go build, then copies mm to /usr/local/bin
mm -h # the flags
mm --version # which mm this is
mm --about # what it is, in one screen
install.shworks only on macOS and Linux
Or download a binary from the releases page and put it on your PATH — step by step for macOS, Linux and Windows.
Then pick a configuration file. Copy one to agent.yaml in your project and adjust the model: and system: keys to taste:
| File | For |
|---|---|
agent.dmr.yaml |
Docker Model Runner |
agent.llamacpp.yaml |
llama.cpp (llama-server) |
agent.llmman.yaml |
llmman |
agent.lsp.yaml |
the same agent with a language server behind an lsp tool |
agent.mcp-example.yaml |
the same agent with MCP servers |
For Ollama, see Run mini-me on Ollama and demos/ollama/.
Use
The base command is mm. Run it from the directory of the project you want to work on: that is where commands run and where files are read and written.
1. Terminal, line by line
mm # reads ./agent.yaml
mm agent.dmr.yaml # or name the file
Type a question at the > prompt. Each command the model runs is shown with its output, and every turn ends with a recap (⚙ 2 command(s)). Useful commands: /help, /new, /compact, /quit.
2. Terminal, one window
mm -tui
The conversation above, a box to type in below. Enter sends, Ctrl-J adds a line, Esc cancels a turn (or clears the box when nothing runs), F1 lists the keys. With sessions on, ↑ in the box brings back your earlier questions, from this session and the project's previous ones. /shell hands the terminal to your shell; exit brings the conversation back. With yolo: false in the YAML, the agent asks before running a command or writing a file — in the window, the line mode and an editor alike (yolo: true, the default, runs them unasked).
3. Inside an editor (ACP)
mm -acp
Speaks the Agent Client Protocol on stdin/stdout. You never run this one by hand: the editor launches it. See the next section.
Use with the Zed editor
-
Install
mmon yourPATH(see above). -
In Zed, open
settings.jsonand register the agent:{ "agent_servers": { "mini-me": { "type": "custom", "command": "mm", "args": ["-acp"], "env": { "AGENT_CONFIG": "/absolute/path/to/agent.yaml" } } } }AGENT_CONFIGmust be an absolute path: Zed startsmmin the project directory, and a relative path would not be found."type": "custom"is required. -
Open the Agent panel, pick mini-me, and talk to it. Every
bash,read_file,write_fileandedit_filecall shows up as a tool call, and file changes appear as real diffs. Withyolo: falsein the YAML, Zed asks you to allow each call before it runs; the shipped files sayyolo: true, and the calls run unasked. -
Handy things: Escape cancels a turn;
/newand/compactare in the slash-command menu (with/memoryand/docswhen you turn them on);@fileattaches a file for the model to read; withsessions.enabled: truein the YAML, Reload Agent brings the whole conversation back, and the Agent panel's thread history lists the project's past conversations so you can reopen one (it is not in the/menu). -
When something looks wrong, open
dev: open acp logs: the banner, warnings and the agent's[acp] …trail go there.

Other ACP editors
Anything that speaks ACP can host mm -acp the same way: JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm…), Neovim (CodeCompanion, agentic.nvim, avante.nvim), Emacs (agent-shell), Visual Studio Code through third-party ACP extensions, Sublime Text and Qt Creator through their ACP plugins. The registration details differ; the agent side does not.
More features
- Create an agent:
mm init(ormm --init) asks which server, which model (from the server's list), what the agent is for and which machine runs it, then writes a commented agent.yaml — the model's facts read from the server (window, the GGUF's sampling, the reasoning switch), a family table sourced from model cards and the measured demos, every value with its reason;--checkproves the model answers, flags make it scriptable. For an OpenAI-compatible service (openai) it also asks the endpoint and the API key's variable, and lists the service's models when the key is set. See Create an agent withmm initanddemos/open-ai-compliant/. - One prompt and exit:
mm -p "…"— for scripts. See Run a single prompt. - Other agents: list other mm agents under
mmConfigs; you ask them with/ask-<name>, your agent calls them itself with itsask_agenttool, a script withmm --ask <name>. See Let your agent call other agents. - Questions to you: the agent asks with its
ask_usertool — pick one, pick several, type a text, yes or no — as numbered choices in the terminal, an arrow-key box in the window, a form or a dialog in an editor; a called agent's questions come up to you too.askUserTool: falseturns it off. See Let the agent ask you questions. - An agent that creates agents:
./mm -config agent.creator.yaml(Qwen3.8 27B), then "Create an agent that … with ". It reads the model's facts from llmman (skills/create-agent/model_facts.py: chat template, reasoning switches, tool-call format, sampling, context), asks what it is missing, writes a commentedagent.yamltuned to that model and checks that it loads and answers — thecreate-agentskill. - Project instructions: an
AGENTS.mdin the project directory is added to the system prompt of every conversation. See Give the agent your project's instructions. - Answers as JSON: declare the shape of the answer as Go types under
structuredOutput, andmm -p "…" | jqworks. See Get answers as JSON. - MCP servers: their tools, wrapped as mm tools. See the MCP tutorial.
- Sessions: with
sessions.enabled: true,/sessionslists the conversations of a project and/resumecontinues one; in the window, ↑ recalls your earlier questions to send them again; in an editor, its thread history lists them (session/list) and reopens one (session/load,session/resume). See Keep sessions and resume them. - Trace:
AGENT_TRACE=true mm …writes every request to the model and every response to.mm/traces/. See See the JSON sent to the model. - Hooks: your own commands — in any language — run before a question reaches the model, before and after each tool call, after the turn, and around each hand-off to another agent; they can deny a call, stop or rewrite a question, add context, mask what leaves for another agent, replace what comes back, or log.
displayHooks: trueshows each hook that ran and what it decided, after the answer (an editor shows each one as a tool call). See Guard the agent with hooks, Control the hand-offs to other agents with hooks,demos/hooks/anddemos/hooks-ask/. - Guard models: have every question checked by guard models (IBM's Granite Guardian), one agent per risk, before your assistant answers — a
preGenerationhook asks them without the conversation history, and the assistant refuses or answers according to their verdicts. See Screen questions with guard models,demos/guard/anddemos/guards/. - Plans: the built-in
plantool lets the agent turn a list of tasks into a tracked plan; mm shows its progress (📋 [2/3] …) after each plan action — per conversation, cleared by/newand/resume. See Manage plans and tasks. - Save an answer:
/savewrites the last answer to a Markdown file; withsaveAnswerTool: true, the model does it itself when you ask in your own words (save_answer). Never overwrites a file. See Save an answer to a file. - Unload a model:
/unload [model]frees a model from the server's memory — in the terminal, the window and an editor —, and theunload_modeltool lets the agent do it itself, e.g. on another agent's model once it has answered; llmman, Ollama and llama-server in router mode.unloadModels: falseturns both off. See Free a model's memory anddemos/unload-models/. - Search a documentation folder:
/docs <words>searches the text files of the folders named indocSearch.dirs(.md,.adoc,.txt… — only the extensions listed) and returns the best passages with theirpath:linelink, ranked with BM25 — no index, no model (docSearch.searchDocs); thesearch_docstool lets the model do it before it answers (docSearch.autoSearchDocs); both off by default. See Search a documentation folder anddemos/docs-search/. - Search earlier sessions: with sessions on,
/memory <words>searches the project's stored conversations (sessions.searchMemory), and thesearch_memorytool lets the model do it when a question refers to something decided before (sessions.autoSearchMemory); both off by default. The search matches words, not meanings. See Search earlier sessions anddemos/memory-search/. - Decision models: small models that answer questions about a text — a choice, a yes/no, a score — in a fraction of a second, through
/v1/systemone(llama-server, llmman, Ollama). An agent file with adecision:block is a decider: run it withmm -pfrom a script or a hook, let it pick the skill before each question (skillRouting), drop the tool groups a request does not need (toolRouting), or approve read-only commands from apreToolCallhook (allow). See Ask a decision model, Decision models and thedemos/decision-*folders. - Type while it answers: a message sent during a turn is queued and runs once the turn ends, in order — in the line mode and the window;
Esc(window) or/abortstops the turn. See the slash commands reference. - Struggle signals: when the model loops, fails several tool calls in a row, breaks a tool call, stalls, runs out of turns or fills its context window, mm says so apart from the answer — a coloured badge in the window's footer, a line in the terminal, a paragraph in an editor. The window also shows the completion's duration (
showCompletionTime). See Struggling models anddemos/struggle-signals/. - Download the models at start-up:
autoPull: truepulls the models the agent will use that the server does not have yet — its own, itsmmConfigsagents', its routing deciders' — with the progress on screen (llmman, Ollama, Docker Model Runner; llama.cpp gets advice instead). See Run mini-me with llmman anddemos/auto-pull/. - Models that take turns in memory:
unloadModels: trueon anmmConfigsentry unloads the asking agent's model before the hand-off and the asked agent's model after it, so two models are never loaded together. See Free a model's memory anddemos/coding-helpers-unload-option/. - Use mini-me from another program: drive
mm -acpover ACP —demo.acp.sdk/nodejs/minime.jsgives Node.jscomplete,stream, cancellation and a permission callback, with no dependency. Seedemo.acp.sdk/. - Test a model:
testing/holds two benches run by mm itself — a coordinator agent gives small tasks to a candidate agent whose model is under test, checks each result with a command, and writes a Markdown report: the model as a working agent (testing/model-check/) and function calling alone, with tools declared in the agent file (testing/function-calling/). Seetesting/. - Docker Sandboxes: the sandbox kit lives in its own repository, mini-me-kit;
sbx/explains how to use it (sbx run …), with two mixins (go-toolchain,cli-tools) and ready-made configurations — seesbx/README.mdand Run mini-me in a Docker Sandbox.
Demos
The demos/ directory holds ready-made set-ups (most with a README explaining how to run them):
| Directory | What it shows |
|---|---|
demos/dmr/ |
mm on Docker Model Runner, with skills, LSP and MCP configurations |
demos/llmman/ |
mm on llmman, and an agent that asks other agents |
demos/ollama/ |
mm on Ollama |
demos/structured-output/ |
agents that answer in JSON, and a coordinator using them |
demos/structured-output-pizza/ |
one JSON agent declared with Go types: a pizza's name → its ingredients (quantity, unit, category, allergens), whether it is vegetarian, its baking time (Gemma 4 E4B on llmman) |
demos/agents-md-file/ |
an agent following a project's AGENTS.md |
demos/mini-mes/ |
small teams of agents (riker coordinating a specifier and a coder, gopher a Go specialist) |
demos/little-coder/ |
a Go + htmx web-app generator for a small local model (Mellum2 12B on llmman, 32 GB RAM): a tested starter, skills, AGENTS.md, measured results |
demos/team/ |
a team of four agents (lead, specifier, coder, tester) on one small model (Ornith 1.5 9B on llmman) building Go + htmx apps through spec and test files, with measured results |
demos/open-ai-compliant/ |
mm init for OpenAI-compatible services: the steps, and agent files for OpenAI and Mistral AI (baseUrl, apiKeyEnv: MISTRAL_API_KEY) |
demos/coding-helpers-unload-option/ |
the same team as demos/coding-helpers/ with unloadModels: true on its mmConfigs entries instead of unload hooks: the two models never in memory together, measured on llmman |
demos/auto-pull/ |
autoPull: true with SmolLM2-135M: a model the server does not have is downloaded at start-up, with its progress; also a team, and a misspelt repository name |
demos/struggle-signals/ |
a fake OpenAI-compatible server and run-all.sh that trigger every struggle signal (loop, failed calls, broken call, stalled, max turns, context full…) without a real model |
demo.acp.sdk/ |
mini-me as a library from other languages, by driving mm -acp over ACP: nodejs/minime.js (ticket 167) — Agent.start, complete, stream, cancel with an AbortSignal, a permission callback; no dependency, 11 tests with a fake mm, four examples measured on llmman |
testing/ |
model testers run by mm itself: a coordinator (Gemma 4 12B) follows a skill, gives small tasks to a candidate agent whose model is under test (Qwen3.5 4B for model-check, Luciole 1B for function-calling), checks each result with a command and writes a Markdown report — model-check/ (tool calls, exact instructions, Go code that must run, several steps) and function-calling/ (only tools declared in the candidate's tools:) |
dev.team/ |
a team of five agents for a 32 GB laptop (ticket 152): a Qwen3.5 4B coordinator hands each request to a reformulator, a coder, a reviewer or a tutor (Gemma 4 12B, Mellum2 12B); hooks keep one model in memory at a time; measured: bug fixes, lessons and reviews work, new features not yet |
demos/blog-team/ |
the smallest team: a lead, a coder and a reviewer in 75 lines of YAML, one model (Mellum2 12B Q8_0 on llmman), written for a blog post |
demos/translator/ |
a French ↔ English translator (Gemma 4 E4B on llmman): AGENTS.md for the style, skills for technical texts, e-mails and idioms, $styles for professional / informal / Slack versions, translate.sh for files |
demos/qwen-style/ |
a general coding agent whose system prompt follows Qwen Code's, adapted to mm's tools, in three configurations on llmman: Qwen3.8 27B, Qwen3-Coder-Next, Qwen3.6 35B-A3B — Qwen Code's new-app and simplify skills, measured results |
demos/gemini-style/ |
the same idea with Gemini CLI's system prompt (Research → Strategy → Execution, Directives vs Inquiries, Context Efficiency), adapted to mm and to Gemma 4 26B-A4B on llmman; reads GEMINI.md; measured results |
demos/codex-style/ |
the same idea with Codex CLI's default instructions (preambles, plans, ambition vs. precision, final-answer format), adapted to mm and to gpt-oss 20B (harmony format, reasoning_effort, model_identity) on llmman; measured results |
demos/news-roundup/ |
a press-review agent: DuckDuckGo News through a small MCP server (Python standard library), Qwen3.5 9B on llmman, ready-made citations so no article is invented, measured results |
demos/project-wizard/ |
the interactive prompts (ask_user) in a small agent: a four-question form (text, two choices, several choices), then a yes/no confirmation carrying the plan before any file is written; Qwen3.5 9B on llmman, measured results |
demos/hooks/ |
hooks in Node.js around a small shell assistant (Gemma 4 E4B on llmman): a question holding a secret never reaches the model, today's date and the file list are added to every question, rm -r / sudo / curl | sh are denied, every tool call and turn is logged to .mm/hooks-audit.jsonl |
demos/hooks-ask/ |
preAsk and postAsk hooks in Node.js around a help desk that hands technical questions to an expert agent (both Gemma 4 E4B on llmman): secrets masked before they leave, at most 2 ask_agent calls per question, standing rules added for the expert, a failed hand-off turned into an instruction, every hand-off logged to .mm/ask-audit.jsonl |
demos/dungeon/ |
a solo role-playing game in the style of Dungeons & Dragons, same principle as demos/team: a Game Master hands each action to a storyteller, a referee or a scribe (Qwen3.5 4B on llmman for all four); real dice and the hero sheet in shell scripts, each specialist kept to its commands by a preToolCall hook; measured results |
demos/coding-helpers/ |
interactive documentation for Go and Rust: a coordinator (MiniCPM5 2B) hands each question to a Go or a Rust specialist (Mellum2 12B thinking) with ask_agent and the conversation (with_context), so "the same thing in Rust" works; explanations and snippets, a full program only on request; measured results |
demos/programming-answers/ |
a tutorial writer tuned for Mellum2.1 12B Thinking on llmman ("write me a Nu shell tutorial"), with the settings chosen and why; the original configuration kept as agent.orig.yaml |
demos/programming-answers-2/ |
Tuto: an agent that answers with mini tutorials in the conversation and saves one to Markdown only when asked (fetch_content + save_answer), Mellum2.1 12B Thinking on llmman, measured results |
demos/guard/ |
one guard model (Granite Guardian 3.2 3B-A800M on llmman) answering Yes/No to "is this question harmful?"; why its system: line is a risk name, not a prompt; custom risks |
demos/guards/ |
an assistant (Gemma 4 E4B) protected by seven guard agents, one per risk: a Node.js preGeneration hook asks them in parallel without the history, the assistant refuses or answers according to their verdicts; displayHooks: true; measured results |
demos/unload-models/ |
a coordinator (Qwen3.5 9B) hands programming questions to an expert (Qwen3.5 4B) with ask_agent, a preAsk hook unloads the coordinator's own model before the expert starts and a postAsk hook unloads the expert's once it has answered — the two models are never loaded together; /unload and unload_model on request; llmman, measured results |
demos/plans/ |
the plan tool at work: Planner (Qwen3.5 4B on llmman) builds a tiny Go program in four steps — module, code, test, README — while mm shows 📋 [C/N] … after each plan action; a failing variant ends on Plan finished: 2 done, 1 failed; measured results |
demos/docs-search/ |
an assistant answering from a documentation folder: nine Ratatui tutorials (Rust terminal UIs, each program checked against ratatui 0.30 by check-tutorials.sh), /docs <words> for you and the search_docs tool for the model; Qwen3.5 4B on llmman, measured results |
demos/memory-search/ |
an assistant that remembers a project's decisions: four earlier sessions (port, storage, logs in French, deployment as a /compact summary), /memory <words> for you and the search_memory tool for the model; Qwen3.5 4B on llmman, measured results — including what a word search cannot find |
demos/declared-tools/ |
an ops desk with no bash and no skills, acting only through four tools declared under tools: — release, version bump, service logs, slow requests — covering every parameter type (string, enum, boolean, integer, number), a safe default (dryRun: true) and an optional argument; Mellum2 12B on DMR, measured results |
demos/wasm-tools/ |
a notes desk acting only through four WebAssembly tools built with TinyGo and run by mm in a sandbox: one pure computation, two that may only read notes/, one that may only write out/; Qwen3.5 4B on llmman |
demos/wasm-hooks/ |
the hooks of demos/hooks (secret filter, bash guard, audit log) rewritten as WebAssembly modules built with TinyGo and run by mm in a sandbox — nothing to install; Gemma 4 E4B on llmman, measured against the Node versions |
demos/decision-skills/ |
a decision model (LiquidAI d1-3B on /v1/systemone) picks the skill before each turn of a Qwen3.5 4B coding agent (skillRouting), and answers about a shell command as an agent of its own; llmman, measured on the routing eval |
demos/decision-commands/ |
a preToolCall hook asks the decision model about each bash command and answers allow for what clearly only reads — the other commands ask, as with yolo: false; llmman |
demos/decision-tools/ |
a decision model leaves out the tool groups a request does not need (toolRouting) before each turn of a Qwen3.5 4B agent; llmman |
demos/decision-only/ |
a decision model alone, no chat model: a support inbox triaged by category, urgency, personal data and mood, one mm -p call per message; llmman |
demos/decision-reviews/ |
a decision model alone: customer reviews read for sentiment, topic, a named competitor and a recommendation, checked against expected answers; d1-3B and d1-omni-600M measured on llmman |
demos/decision-questions/ |
four deciders to learn the question types — symptom tickets, 421 dice, a wizard's spell, fight or flee — the examples of the guide How to write the questions of a decider; llmman |
demos/decision-chat/ |
a chat agent helped by a decider: a preGeneration hook sends each question to the decision model (level, hurry, upset) and passes its answers under the question; the system prompt says how to shape the answer; Qwen3.5 4B + d1-3B on llmman, measured with and without the hook |
demos/decision-chat-golang/ |
the same flow for Go programming, with the hook written in Go (its own module, go test-ed): the decider reads level, topic and whether code is wanted; Qwen3.5 4B + d1-3B on llmman, measured |
demos/decision-dnd/ |
a Dungeon Master (Qwen3.5 4B) helped by a decider that picks one of a wizard's five spells, through the Go hook of decision-chat-golang; a debug dump keeps one JSON file per question; measured with two system prompts |
demos/decision-moderation/ |
a decision model alone: blog comments flagged toxic, spam or off topic and sorted into publish / review / reject, checked against expected answers; d1-3B and d1-omni-600M measured on llmman |
demos/decision-injection/ |
a postToolCall hook asks a decision model whether what read_file or fetch_content just read hides instructions for an AI, and adds a warning under the output; Qwen3.5 4B on llmman, measured with and without the hook |
demos/decision-tool-errors/ |
a postToolCall hook asks a decision model whether a command's output shows an error — a script that prints one and exits 0 — and adds a note for the model; llmman |
demos/decision-ask-check/ |
a postAsk hook asks a decision model whether another agent's answer addresses the question, and warns the asking agent when it does not; llmman |
Learn more
- Documentation — tutorials, how-to guides, reference and explanations, in English and French.
- Release notes — what changed in each version, in English and French.
guides/— practical guides:- the agent settings for small models, in English and French: timeouts,
maxTurns,maxOutput,agentsMd.maxChars, context compression, sampling — what each one does, its default, and how to set it for a small local model; - the keyboard shortcuts of the window (
mm -tui), in English and French: typing, sending, stopping a turn, recalling questions, the pickers, pastes, permissions, the agent's questions, copy and mouse.
- the agent settings for small models, in English and French: timeouts,
- The
skills/directory: Markdown procedures the agent can load with itsread_skilltool. agent.lsp.yaml: the same agent with a language server behind anlsptool (definition, references, hover, symbols, diagnostics, rename) — see Navigate and refactor code with a language server.fetchContentTool: trueinagent.dmr.yaml: the built-infetch_contenttool, which fetches a web page as Markdown (honouring itsrobots.txt) and can save it to a file without showing it — see Fetch a web page as Markdown.
License
MIT — see LICENSE.