How to drive mini-me from a program
This guide shows how to use a mini-me agent from your own Go, Kotlin or Node.js code: ask it questions, stream its answers, cancel a turn, and decide which tools it may run. It assumes you already have a working agent file (see Create an agent with mm init) and the mm binary.
Your program starts mm -acp as a child process and talks to it over ACP, the protocol editors such as Zed use. Nothing changes in mm, so every agent file works, with its tools, hooks, MCP servers and other agents.
Steps
- Make
mmreachable: on the PATH, or name it withMM_BIN=/path/to/mm. - Pick the client for your language and add it to your project:
- Go: the
minimemodule indemo.acp.sdk/go/. Until it is published, point yourgo.modat it:go mod edit -require=minime@v0.0.0 -replace=minime=../path/to/demo.acp.sdk/go go mod tidy - Kotlin (JDK ≥ 21): the Gradle build in
demo.acp.sdk/kotlin/. Until it is published, include it from yoursettings.gradle.ktswithincludeBuild("../path/to/demo.acp.sdk/kotlin"), then depend onminime:minime:0.1.0(plus an SLF4J backend such asorg.slf4j:slf4j-nop, for the SDK's logs). - Node.js (≥ 20), two clients with the same API:
demo.acp.sdk/nodejs/: copylib/minime.js, which has no dependency;demo.acp.sdk/nodejs-sdk/: built on the official ACP SDK@agentclientprotocol/sdk;npm install ../path/to/demo.acp.sdk/nodejs-sdk, thenimport { Agent } from "minime-sdk".
- Go: the
- Start an agent on your agent file, ask a question, and close it:
agent, err := minime.Start(ctx, minime.Options{Config: "agent.yaml"}) if err != nil { log.Fatal(err) } defer agent.Close() res, err := agent.Complete(ctx, "What is in this folder?")Agent.start(Options(config = "agent.yaml")).use { agent -> val result = agent.complete("What is in this folder?") }import { Agent } from "./lib/minime.js"; // or "minime-sdk" const agent = await Agent.start({ config: "agent.yaml" }); const { text } = await agent.complete("What is in this folder?"); await agent.close(); - To show the answer as it comes, use the stream form instead (
agent.Stream(ctx, prompt)in Go, theagent.stream(prompt)flow in Kotlin,agent.stream(prompt)in Node.js) and print the text events. - If your agent file has
yolo: false, give a permission callback, or every tool call is refused:minime.Options{ Config: "agent.yaml", OnPermission: func(_ context.Context, call minime.ToolCall) minime.Decision { if call.Kind == "read" { return minime.Allow } return minime.Reject }, }Options(config = "agent.yaml", onPermission = { call -> if (call.kind == "read") Decision.Allow else Decision.Reject })Agent.start({ config: "agent.yaml", onPermission: (call) => call.toolKind === "read" });
Variants
- To stop a long turn, cancel it: in Go, cancel the
ctxyou passed (for examplecontext.WithTimeout); in Kotlin, callagent.cancel()from another coroutine; in Node.js, pass{ signal }from anAbortController. The turn ends withstopReason: "cancelled"and the text answered so far. mm drops the unfinished question from the conversation. - To start the conversation over without restarting mm, call
Reset(ctx)(Go) orreset()(Kotlin, Node.js). - To work on several things in parallel, start several agents: each one is its own mm process and runs one turn at a time.
- To run the tools in another directory than your program's, set
Cwd(Go) orcwd(Kotlin, Node.js). - To see what mm logs (banner, warnings,
[acp]lines), setOnStderr(Go) oronStderr(Kotlin, Node.js).
See also
- Every option, event and error of each client: Go, Kotlin, Node.js, Node.js with the ACP SDK.
- The ACP messages behind the clients:
demo.acp.sdk/README.en.md. - Confirming tool calls in mm itself: Confirm tool calls.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|