@nolbuk/miau
v0.5.1
Published
Copy AI configurations per-project
Readme
miau
Author once, replicate everywhere. Portable skills, agents, commands and MCP servers for every AI tool.
miau is a configuration manager that lets you write your AI tooling — skills, subagents, slash commands, MCP servers — in a single source of truth, and replicates them across Claude Code, OpenCode, Gemini CLI, Copilot, Cursor and OpenAI Codex with each tool's native format.
Supported AI Tools
| Feature | Claude Code | OpenCode | Gemini CLI | Copilot | Cursor | Codex | |---------|:-----------:|:--------:|:----------:|:-------:|:------:|:-----:| | Skills | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Agents | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Commands | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | | MCP Servers | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
Legend: ✅ Full support | ❌ Not supported (tool limitation)
See provider matrix for detailed configuration info.
Install
npm install -g @nolbuk/miau
miau initNode.js >= 20 required.
Quick Start
miau # interactive wizard
miau init # set up global config + link AI tools
miau sync # regenerate provider configurations
miau validate # check skills/agents/commands schema
miau status # show current state
miau doctor # diagnose issuesHow It Works
You author resources once in ~/.miau/ (or, for project-scoped overrides, in <repo>/.ai/). miau sync then fans them out to each AI tool in its own format.
~/.miau/ ────────────────────┬──▶ miau sync ──▶ Claude Code
│ │ ├──▶ OpenCode
│ miau project init │ ├──▶ Gemini CLI
▼ │ ├──▶ Copilot
repo/.ai/ ────────────────┘ ├──▶ Cursor
└──▶ OpenAI Codexmiau init— set up the global config and link AI tool directoriesmiau project init— copy selected resources into a repo's.ai/miau sync— regenerate provider-specific files (settings, agents, MCP)
Override the default config path with MIAU_CONFIG:
export MIAU_CONFIG=~/my-configs/miauResource Schema
Every resource is a Markdown file with YAML frontmatter at the top. miau validates these schemas with Zod (see Validation).
Skill — SKILL.md
---
name: search # kebab-case, must match dir name
description: Fast codebase exploration # 1..1024 chars (folded `>` allowed)
license: Apache-2.0 # optional
metadata: # free-form per-skill data
author: marcos
version: "1.0"
scope: [root]
auto_invoke: # optional — top-level (NOT under metadata)
- "When user asks to find code"
- "When user runs /search"
---| Field | Required | Type | Notes |
| ------------- | -------- | ---------------------- | ---------------------------------------------------------------------- |
| name | yes | string (kebab-case) | Must match directory name |
| description | yes | string (1–1024) | Used by AI tools to decide when to load the skill. Folded > allowed. |
| license | no | string | SPDX identifier (e.g. Apache-2.0) |
| metadata | no | object | Free-form. Standard fields: author, version, scope[]. Extras (e.g. capabilities, defaults) allowed for skill-internal use. |
| auto_invoke | no | string[] (≥1, unique) | Trigger phrases. Must be top-level — common bug: indenting under metadata. |
⚠️
auto_invoke,name,descriptionandlicensemust be at the root level. Indenting them undermetadatais a frequent slip;miau validateflags it explicitly.
Agent — AGENT.md
miau supports three agent shapes; they're auto-detected from the frontmatter shape.
Claude shape (most common)
---
name: coder
description: Primary development agent
tools: Bash,Edit,Glob,Grep,Read,Skill,Task,TodoWrite,Write
model: inherit
permissionMode: default
---| Field | Required | Type |
| ---------------- | -------- | ---------------------------------------------- |
| name | yes | string (kebab-case) |
| description | yes | string (1–1024) |
| tools | yes | comma-separated tool names, PascalCase (e.g. Read,Write,Bash) |
| model | rec. | string — defaults to inherit |
| permissionMode | no | default | bypassPermissions |
OpenCode shape
---
description: Codebase exploration subagent
mode: subagent # primary | subagent | all
model: anthropic/claude-haiku-4-5
temperature: 0.2
tools:
read: true
grep: true
glob: true
edit: false
---name is derived from the directory. tools is an object of booleans.
Universal shape
---
name: planner
description: Planning and analysis agent
type: primary # primary | subagent
model:
default: claude-sonnet-4.6
fast: claude-haiku-4.5 # optional
temperature: 0.3
capabilities:
- file-reading
- code-search
- planning
- plan-persistence
restrictions:
- "Never edits production code"
auto_skills:
- plan
---Command — COMMAND.md
---
name: changelog # optional, kebab-case
description: Create a changelog entry
agent: coder # optional
parameters:
- name: description
type: string # string | number | boolean
required: true
description: Brief description for the entry
---| Field | Required | Type |
| ------------- | -------- | --------------------------------------------------- |
| name | no | kebab-case (defaults to directory name) |
| description | yes | string (1–1024) |
| agent | no | string — agent that handles the command |
| model | no | string |
| subtask | no | boolean |
| parameters | no | array of { name, type, required?, default?, description? } |
MCP Servers — mcp/servers.yaml
Secrets use ${VAR} placeholders resolved from mcp/.env (gitignored).
servers:
# npx-based
context7:
command: npx
args: ["-y", "@upstash/context7-mcp@latest"]
# with secrets
mcp-linear:
command: npx
args: ["-y", "@anthropic/mcp-linear"]
env:
LINEAR_API_KEY: "${LINEAR_API_KEY}"
# docker
github:
command: docker
args: ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_PERSONAL_ACCESS_TOKEN}"
# HTTP server
grep:
type: http
url: https://mcp.grep.appmiau project init generates .ai/mcp/.env.template listing the variables your team needs to provide.
Validation
miau validate # check global + project
miau validate --global # only ~/.miau
miau validate --project # only ./.ai
miau validate --skills # restrict scope
miau validate --strict # treat warnings as errors
miau check # aliasWhat it checks:
- YAML preflight: rejects tab indentation, warns on tabs inside string values
- Schema (Zod): required fields, types, kebab-case names, enums (
type,mode,permissionMode), comma-separated tool lists in PascalCase, length limits - Unknown fields: typo detection with "did you mean" via Levenshtein (e.g.
auto-invoke→auto_invoke) - Cross-checks:
namemust match directory, common indentation slips (e.g.auto_invokenested undermetadata)
Example output:
project: /path/to/.ai
✗ skills/foo/SKILL.md: `auto_invoke` is nested under `metadata`
hint: unindent it so it sits at the same level as `name`/`description`
⚠ skills/bar/SKILL.md: unknown field `descripton`
hint: did you mean `description`?
✓ agents
✓ commands
1 error(s), 1 warning(s).Exit code is non-zero on errors (or on warnings with --strict) — drop it in CI.
Project Setup
When you run miau project init inside a repository, miau copies selected resources into .ai/ and creates an env template:
.ai/mcp/
servers.yaml # MCP server config (committed)
.env.template # Required variables (committed)
.env # Your actual secrets (gitignored)Each teammate copies the template and provides their own secrets:
cp .ai/mcp/.env.template .ai/mcp/.env
# fill in tokensCommands
| Command | Description |
| -------------------------------------- | -------------------------------------------- |
| miau | Interactive wizard |
| miau init | Initialize global config + link AI tools |
| miau sync | Regenerate provider configurations |
| miau status | Show configuration status |
| miau doctor | Diagnose configuration issues |
| miau validate / miau check | Validate frontmatter schema |
| miau skill list \| add \| remove | Manage skills |
| miau agent list \| add \| remove | Manage agents |
| miau command list \| add \| remove | Manage commands |
| miau mcp list \| add \| remove | Manage MCP servers |
| miau provider list | View provider status |
| miau project init \| sync \| status | Manage project-local config |
Use -f to force overwrite, -y to skip prompts.
Provider Matrix
Details of what each tool gets after miau sync:
| Provider | Skills | Agents | Commands | MCP |
|----------|--------|--------|----------|-----|
| Claude Code | symlink → ~/.claude/skills | AGENTS.md | as-is directories | settings.local.json |
| OpenCode | symlink → skills/ | opencode.jsonc | frontmatter remap | opencode.jsonc |
| Gemini CLI | symlink | symlink | TOML files | settings.json |
| GitHub Copilot | .github/instructions/ | .github/agents/ | — | — |
| Cursor | .cursor/skills/ | .cursor/agents/ | .cursor/commands/ | .cursor/mcp.json |
| OpenAI Codex | symlink → ~/.codex/skills | symlink → ~/.codex/AGENTS.md | — | config.toml |
Notes:
- Codex uses a skills-based architecture (no slash commands). Skills activate contextually based on their description.
- Codex agents are supported via
~/.codex/AGENTS.md(symlink to project AGENTS.md). - Gemini commands are converted to TOML format (not COMMAND.md directories).
- Copilot doesn't support custom slash commands by design.
- Cursor commands work via Composer interface (
/command).
License
MIT
