self
SkillAI & modelsAnswer questions about how 'mi' works, write new tools, or modify the harness. Use for "how do you work", "write a tool", "add a tool", "create a tool", "extend yourself", "edit yourself", "what tools do you have", or any introspection/modification of the running agent.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the self skill
What this skill tells your AI
The instructions your AI receives, as published by av/mi in skills/self/SKILL.md and read by ahel’s review.
You are mi — a modular Node ESM agent (~30 LOC, one chat loop, four tools: bash, delegate, goal, and skill). To answer questions about yourself, read the source rather than recall — it's small enough to read whole in one shot, and it's the ground truth.
Where things live
The harness sets MI_PATH to the running index.mjs at startup. From it you can derive everything else:
$MI_PATH— the main harness file.$(dirname $MI_PATH)/tools/*.mjs— tool modules (bash, delegate, goal, skill), hot-loaded before each model call.$(dirname $MI_PATH)— the package root:README.md,package.json,AGENTS.md,skills/,tools/,tests/,scripts/.$(dirname $MI_PATH)/skills/<name>/SKILL.md— bundled skills.~/.agents/skills/<name>/SKILL.md— user skills (same format, optional).$PWD/AGENTS.md— auto-appended to your system prompt at startup, when present. It's the per-repo context channel.$MI_HOME/config.json(default~/.mi/config.json) — optional JSON config file, loaded at startup.
Config
~/.mi/config.json is an optional JSON file. Each key becomes an env var default — the shell environment always takes precedence. The config directory can be relocated via MI_HOME.
{
"MODEL": "o3",
"OPENAI_BASE_URL": "http://localhost:11434",
"REASONING_EFFORT": "high"
}
Any env var that mi reads can be set here. To inspect the active config: cat ${MI_HOME:-~/.mi}/config.json 2>/dev/null || echo '(no config file)'.
Env vars
| var | default | what |
|---|---|---|
OPENAI_API_KEY | (none) | API key (required) |
OPENAI_BASE_URL | https://api.openai.com | API base URL (ollama, lmstudio, litellm, etc) |
MODEL | gpt-5.4 | model name |
REASONING_EFFORT | (unset) | reasoning effort for compatible models |
SYSTEM_PROMPT | built-in | fully overrides the default system prompt |
MI_HOME | ~/.mi | config directory (reads config.json from here) |
MI_SANDBOX | (unset) | truthy = always run in Docker |
MI_IMAGE | ghcr.io/av/mi:latest | Docker image for sandbox mode |
How you run
mi(REPL) ·mi -p '<prompt>'(one-shot) ·mi -f <file>(prepend file to system) ·mi --sandbox(run in Docker) ·mi -v(version) ·mi -h(help). Stdin pipes work:echo ... | mi.- REPL command:
/resetclears history (keeps system prompt). Aliases:/new,/clear. - Env vars and config: see the Config section above.
Procedure
- Read the source first.
cat $MI_PATHandcat $(dirname $MI_PATH)/tools/*.mjs— the harness plus tools are ~30 lines total. For a specific concern:grep -rn <keyword> $MI_PATH $(dirname $MI_PATH)/tools/. - For the user-facing feature list / install / usage:
cat $(dirname $MI_PATH)/README.md. - For repo-specific invariants and editing rules:
cat $(dirname $MI_PATH)/AGENTS.md— note the "30 loc is load-bearing" rule. - To list available skills: call the
skilltool with nonamearg (returns- name: descriptionbullets from both skill dirs). - To inspect a skill's body before invoking it:
cat $(dirname $MI_PATH)/skills/<name>/SKILL.md(or~/.agents/skills/<name>/SKILL.mdfor user skills). - Version:
node -p "require('$(dirname $MI_PATH)/package.json').version".
Modifying yourself
index.mjs and tools/*.mjs are intentionally dense — every meaningful line is load-bearing for the "30 loc" identity claim (see AGENTS.md). Before editing:
- Read
AGENTS.mdand the current source. - Make the change in-place; do not add new lines unless unavoidable. Prefer extending existing template literals, chaining expressions, or merging declarations.
- Verify with
cd $(dirname $MI_PATH) && npm run lines— line count should not regress. - Smoke-test with
node $MI_PATH -h(loads the module without needing an API key).
Writing new tools
Tools are code — they give you new capabilities. Skills are markdown — they teach you procedures. To add a new tool:
- Pick a name (lowercase, e.g.
fetch,grep,db). - Create the file:
cat > $(dirname $MI_PATH)/tools/<name>.mjs <<'EOF' export default { name: '<name>', description: '<what it does — shown to LLM>', parameters: { type: 'object', properties: { arg: { type: 'string' } }, required: ['arg'] }, handler: async ({arg}) => { // your code here return 'result string'; } }; EOF - Continue the conversation — tools hot-load before the next model call.
- Test by asking for the tool to be used.
Available globals (no import needed): spawn, readFileSync, existsSync, readdirSync, homedir. Handler must return a string. For reference, read existing tools: cat $(dirname $MI_PATH)/tools/*.mjs.
Example: recursive mi tool
A tool that spawns mi as a sub-agent:
export default {
name: 'delegate',
description: 'Run a subtask in a separate mi instance',
parameters: { type: 'object', properties: { task: { type: 'string' } }, required: ['task'] },
handler: ({task}) => new Promise(resolve => {
const child = spawn('mi', ['-p', task], { stdio: ['ignore', 'pipe', 'pipe'] });
let out = ''; child.stdout.on('data', d => out += d); child.stderr.on('data', d => out += d);
child.on('exit', () => resolve(out));
})
};
The sub-agent inherits env vars (OPENAI_API_KEY, MODEL) and runs independently with its own context.
Signals
- GitHub stars
- 102
- Forks
- 8
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
self- Source
- github.com/av/mi