AI skills
One folder where you write your product's skills - instructions your AI loads on demand - reaching the assistant, external MCP clients, and Mastra Studio with no wiring.
A skill is prose your AI reads when it judges the skill relevant: a refund policy, a house style guide, the steps a support agent must follow. Instructions you would otherwise paste into every prompt live once in packages/ai/skills.
The folder ships empty. Everything in it is yours, and generatesaas update never merges into a folder it did not create.
Write one
Create packages/ai/skills/<name>/SKILL.md. The folder name and the name field must match.
---
name: refund-policy
description: Use when a customer asks about a refund, a chargeback, or a downgrade mid-term.
---
Refunds inside 30 days are approved automatically. Past 30 days, check whether the
workspace used metered credits this period before offering a partial refund.
Never promise a specific refund date. Say "within 5 to 10 business days".| Field | Required | Rule |
|---|---|---|
name | yes | 1-64 characters, lowercase letters, digits and hyphens. Must equal the folder name. |
description | yes | 1-1024 characters. Say what it does and when to use it - this is all the model sees when deciding whether to read it. |
license | no | An SPDX identifier, for a skill you publish. |
compatibility | no | Free-form notes about what the skill assumes. |
user-invocable | no | false keeps it out of direct user invocation. Defaults to true. |
metadata | no | Anything else you want to carry, nested freely. |
Everything below the frontmatter is the body. Keep it under ~500 lines: it rides in a prompt, so length costs tokens on every run that reads it.
Build after every change
pnpm --filter @repo/ai skills:buildThis validates each skill and inlines them all into packages/ai/src/skills/skills.generated.ts, which is committed. A test fails when the folder and that module disagree, so a forgotten build is caught in CI rather than in production.
Nothing reads the folder at runtime. A bundled server and Next's output tracing both drop adjacent markdown, so a skill referenced by path resolves in development and throws in production. Inlining at build time is what makes a skill behave identically in both.
Where your skills appear
| Surface | What it gets |
|---|---|
| The in-app assistant | The skills themselves, loaded on demand. With at least one skill it also gains Mastra's skill, skill_search and skill_read tools - see Agents. |
| Automations and dispatched runs | The skills_list and skill_get tools. |
| External MCP clients | The same two tools, plus each skill as a prompt a person can pick by name. |
| Mastra Studio | A read-only listing of the folder, read from disk so a skill you just wrote shows up without a build. |
The two tools are registered on every build, even with no skills, so the tool surface never changes shape with your content. With none, skills_list answers that the product has none.
The MCP server does not consult config.ai.enabled, exactly as its existing toolset behaves: a project generated with ai false and mcpServer true still serves these tools.
Not to be confused with
The skills the CLI installs into .claude/skills steer your coding agent while it works on this repository. These steer your product's AI while it serves your users. Never write a product skill into .claude/skills.