Inventory Format
Skill Item
Path:
skills/<name>.mdExample:
---
name: create-spec
description: Write a concise technical specification for a developer
targets:
- claude-code
- cursor
---
# Role
...Fields:
| Field | Required | Description |
|---|---|---|
name | yes | Skill identifier; must match the filename |
description | yes | Short skill description; without it the skill is invalid and is not applied |
targets | no | List of AI environments that restricts delivery of the skill; see below |
The Markdown body after the frontmatter must not be empty.
targets restricts delivery. The field affects apply on every path — apply, sync, apply --loadout, and pinned sync. If the field is absent or the list is empty, the skill is applied to every detected AI environment — this is the default behavior. If the list is non-empty, the skill is installed only into the listed environments among those detected.
This differs from the MCP Item, where targets is required: an empty list on an MCP Item is a validation error, while on a Skill Item it means "apply everywhere." The asymmetry is intentional — making the field required would break existing inventories that already have skills without targets.
Environment names in targets are not validated: a typo (for example, claud-code) does not raise an error — the skill simply is not delivered to any environment.
Folder Skill
A Skill Item can also be stored as a folder:
skills/<name>/SKILL.md
skills/<name>/agent-patterns.md # optional reference files
skills/<name>/delegation.md
skills/<name>/examples.mdSKILL.md is the primary skill file with frontmatter and body. The other files in the folder are reference materials that can be mentioned in SKILL.md via @mention. When the skill is installed, the entire folder is copied to the AI environment.
Priority: if both skills/<name>.md and skills/<name>/SKILL.md exist at the same time, the flat file (<name>.md) takes precedence.
For a folder skill, name comes from the directory name rather than from the frontmatter; description and a non-empty body in SKILL.md are required just as they are for a flat skill.
Limitation: apply --dry-run and delta calculation compare only the hash of SKILL.md. Changes to reference files inside the folder are not reflected in the change delta. For the same reason, aiman add skill <dir> and aiman import skill report the skill as already identical when SKILL.md has not changed — changes limited to reference files are not carried into the inventory.
Limitation: file permissions are not preserved, neither when adding to the inventory nor when installing into an AI environment — every file is written as 0644. The executable bit on scripts inside a folder skill is lost.
MCP Item
Path:
mcp/<name>.yamlExample:
name: context7
description: Library documentation via MCP
command: npx
args:
- -y
- "@upstash/context7-mcp"
targets:
- claude-code
- cursor
- codex
env:
- name: UPSTASH_REDIS_REST_URL
description: Upstash Redis store URL
required: true
example: https://example.upstash.ioFields:
| Field | Required | Description |
|---|---|---|
name | yes | MCP server identifier |
description | no | Short description |
command | yes | Launch command |
args | yes | Argument list; may be empty |
targets | yes | List of AI environments |
env | yes | List of environment variables; may be empty |
Env variable
| Field | Required | Description |
|---|---|---|
name | yes | Variable name |
description | no | Variable purpose |
required | yes | Whether a value is required at apply time |
example | no | Example value |
Env variable values are not stored in the MCP Item. They are set locally and saved in aim.local.yaml.
Loadout Item
Path:
loadouts/<name>.yamlExample:
name: Documentation Work
description: Skills and MCP servers for documentation work
targets:
- claude-code
items:
- skill:create-spec
- skill:wpage
- mcp:context7Fields:
| Field | Required | Description |
|---|---|---|
name | yes | Human-readable loadout identifier |
description | no | Purpose of the set; a warning is emitted if missing |
items | yes | Non-empty list of skill:<name> or mcp:<name> references |
targets | no | Restricts which AI environments the loadout may be applied to |
Invariants:
itemsmust not be empty;- every reference has a
skill:ormcp:prefix and a non-empty name; - every
skill:<name>exists asskills/<name>.mdorskills/<name>/SKILL.md; - every
mcp:<name>exists asmcp/<name>.yaml; - the filename is the normalized
namefield (spaces → hyphens, lowercase); a mismatch is a warning.
Format and referential integrity are checked by aiman push. aiman apply --loadout stops at the first format error; a reference to a missing or invalid inventory item produces a warning at apply time, and the item is skipped.
targets intersection
At the loadout level, targets is a whitelist of allowed environments, not a delivery selector:
targetsset — the loadout is applied only to the listed environments among those detected;targetsnot set — there is no loadout-level restriction, and each item's item-leveltargetsapplies;- loadout-level and item-level
targetscombine as an intersection: an item is applied to an environment only if it is allowed at both levels. This holds for both the MCP Item (targetsrequired) and the Skill Item (targetsoptional; an absent or empty item-level list does not narrow the intersection — only the loadout-level restriction applies).
The two restriction levels behave differently on removal. An environment cut off by the loadout-level targets is not part of the plan and is not modified at all. An environment that stays in the plan is brought to the desired set as a whole — so an item (a skill or an MCP server) that is part of the loadout but does not list that environment in its item-level targets will be removed from it if installed there. For a skill, this happens only on the declarative path (apply --loadout, pinned sync): on the additive paths (sync, apply without --loadout), a skill is only installed into allowed environments and is never removed, even if targets was later narrowed.
Targets
Supported values:
claude-code;cursor;codex.