Drop a SKILL.md file next to your ledger and bea ask follows your own bookkeeping conventions — your category names, your report layout, your house rules — without you repeating them in every question.
A skill is plain Markdown with a small YAML header. bea ask discovers it at startup and offers it to the hosted assistant, which loads the full text when a question calls for it.
This page assumes bea ask already works for you. It needs the ask extra (uv tool install 'beancount-io[ask]') and Beancount.io credentials from bea cloud login or BEA_TOKEN. Queries run against your local ledger, but the question and the skill context go to the hosted Beancount.io AI service. bea ask has no JSON output. See the CLI reference for the full command contract.
Where a skill lives
bea ask reads two directories, in this order:
| Location | Scope |
|---|---|
<ledger-dir>/.agents/skills/ | Project level — one ledger, and usually checked into its repository |
~/.config/bea/skills/ | User level — every ledger you open on this machine |
The project directory is resolved from the working directory you run bea ask in, not from --file. When both directories hold a skill with the same name, the project copy wins and the user copy is ignored.
BEA_CONFIG_DIR relocates the user-level directory: set it and skills are read from $BEA_CONFIG_DIR/skills/. Otherwise $XDG_CONFIG_HOME/bea/skills/ applies, falling back to ~/.config/bea/skills/.
Write the skill file
One directory per skill, holding one file named SKILL.md:
.agents/skills/
└── monthly-report/
└── SKILL.mdThe file is a YAML header followed by your instructions:
---
name: monthly-report
description: Generates monthly expense summaries grouped by category.
---
When the user asks for a spending summary or monthly report:
1. Group all expenses by the top-level account category.
2. Show totals for each category, sorted highest to lowest.
3. Include a grand total at the end.
4. Always specify the currency next to each amount.Two fields are required. A file missing either one is skipped in silence, so an absent skill is usually a header problem.
| Field | Required | What it does |
|---|---|---|
name | yes | Lowercase letters and hyphens. Keep it equal to the directory name — precedence between the two locations is matched on this value, so a mismatch makes overrides hard to predict. |
description | yes | One line telling the assistant when to apply the skill. It is what the assistant sees before it decides to load the body. |
license | no | Free text, recorded with the skill. |
compatibility | no | Free text, recorded with the skill. |
metadata | no | A key-value map, recorded with the skill. |
allowed-tools | no | A space-separated list, parsed and recorded. |
Write the body as instructions to a colleague: what to do, in what order, and how to present the result. Keep it to the conventions that are genuinely yours. Facts the assistant can read out of your ledger do not belong in a skill.
allowed-tools is not a permission boundary. bea 0.1.0 parses the field and nothing else reads it, so it restricts nothing. Treat it as documentation of intent. The controls that do hold are the ones in the command itself: interactive writes are previewed, confirmed and validated before they touch the file, global --yes does not grant write permission, and --print mode never applies a proposed write.
Check that it loaded
Give a throwaway skill an instruction you cannot miss, then ask anything at all.
Create the skill:
mkdir -p .agents/skills/test-skill
cat > .agents/skills/test-skill/SKILL.md << 'EOF'
---
name: test-skill
description: Test skill to verify skill loading works.
---
IMPORTANT: Whenever the user asks any question, start your response with the exact phrase "SKILL LOADED".
EOFAsk a question in one-answer mode:
bea ask "what accounts do I have?" --printA response starting with SKILL LOADED means the skill was discovered and offered to the assistant.
Then prove the phrase came from the skill, by moving the directory out of the skills tree and asking again:
mv .agents/skills/test-skill ./test-skill.off
bea ask "what accounts do I have?" --print
mv ./test-skill.off .agents/skills/test-skillThe phrase should be gone. Move the directory out of .agents/skills/, rather than renaming it in place: discovery matches on the name field in the header, so a directory renamed to test-skill.bak is still found and still loads.
To check a user-level skill, put the same file under ~/.config/bea/skills/test-skill/SKILL.md and repeat. To check precedence, keep both copies with the same name and give them different phrases: the project phrase is the one you should see.
Clean the test skill up when you are done. It applies to every question you ask from that directory.
Skills for bea ask are not skills for your agent
These skills extend the built-in bea ask helper only. They are a different thing from the canonical Beancount.io skills you install into an external coding agent such as Claude Code or Codex, which drive bea commands from outside. If that is what you are after, read Accounting with AI agents instead — it covers the external-agent recipes end to end, and none of them need the ask extra or a hosted account.