Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ page-actions:
title: Install agent skills
description: Skills for authoring Fern documentation, maintained in our open-source skills repo.
learn-more-url: https://buildwithfern.com/learn/docs/ai/agent-skills
repository: https://github.com/fern-api/skills
install-command: npx skills add fern-api/skills
skills:
- name: fern-docs
Expand Down
97 changes: 50 additions & 47 deletions fern/products/docs/pages/ai/host-skills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ description: Serve author-supplied agent skills from your Fern docs site and con
availability: beta
---

Fern Docs sites can serve your own [Agent Skills](https://www.skills.sh) so your users can discover and install them with the [skills CLI](https://www.skills.sh). You can also add an "Install skills" button to your docs UI that opens a modal with the install command and your skill list.
Fern Docs sites can serve your own [Agent Skills](https://www.skills.sh) so your users can discover and install them with the [skills CLI](https://www.skills.sh). Point `page-actions.options.skills.path` at a directory of skills in your docs repo, and Fern validates the bundle, generates the discovery manifest, and publishes it — so anyone can run `npx skills add https://<your-docs-domain>`. You can also add an "Install skills" button to your docs UI that opens a modal with the install command and your skill list.

<Steps toc={true} tocDepth={2}>
<Step title="Lay out the bundle">
<Step title="Lay out your skills directory">

Place your skills in your `fern/` folder under `.well-known/agent-skills/` (the current v0.2.0 spec) or `.well-known/skills/` (the legacy v0.1.0 layout). Both are supported and can coexist. Each skill is a subdirectory holding at least a `SKILL.md`, with optional supporting files alongside it.
Put your skills in a single directory, with each skill in its own subdirectory holding at least a `SKILL.md`. Supporting files (references, scripts) live alongside it.

The directory can live anywhere in your repo. A common choice is a repo-root `.agents/skills/` folder, which doubles as the location local coding agents (Claude Code, Cursor, and others) read from:

<Files>
<Folder name="fern" defaultOpen>
<File name="docs.yml" />
<Folder name=".well-known" defaultOpen>
<Folder name="agent-skills" defaultOpen>
<File name="index.json" comment="discovery manifest (required)" />
<Folder name="your-repo" defaultOpen>
<Folder name=".agents" defaultOpen>
<Folder name="skills" defaultOpen>
<Folder name="plant-care" defaultOpen>
<File name="SKILL.md" comment="skill instructions" />
</Folder>
Expand All @@ -28,15 +28,18 @@ Place your skills in your `fern/` folder under `.well-known/agent-skills/` (the
</Folder>
</Folder>
</Folder>
<Folder name="fern" defaultOpen>
<File name="docs.yml" />
</Folder>
</Folder>
</Files>

</Step>
<Step title="Write each SKILL.md">

Each `SKILL.md` needs YAML frontmatter with `name` and `description`, following the [Agent Skills spec](https://agentskills.io):
Each `SKILL.md` needs YAML frontmatter with `name` and `description`, following the [Agent Skills spec](https://agentskills.io). The `name` must be kebab-case, at most 64 characters, and match its parent directory name:

```markdown title="fern/.well-known/agent-skills/plant-care/SKILL.md"
```markdown title=".agents/skills/plant-care/SKILL.md"
---
name: plant-care
description: Guide for diagnosing and treating common plant diseases.
Expand All @@ -48,43 +51,36 @@ When diagnosing a plant issue, check for...
```

</Step>
<Step title="Add the discovery manifest">

The `index.json` at the root of the skills directory is required. It enumerates every skill so clients can discover them in a single request, referencing each by `url` and `digest`:

```json title="fern/.well-known/agent-skills/index.json"
{
"$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
"skills": [
{
"name": "plant-care",
"type": "skill-md",
"description": "Guide for diagnosing and treating common plant diseases.",
"url": "/.well-known/agent-skills/plant-care/SKILL.md",
"digest": "sha256:c4d5e6f7..."
}
]
}
```
<Step title="Declare the skills path in docs.yml">

Point `page-actions.options.skills.path` at your skills directory. The path resolves relative to the folder containing `docs.yml`, and `../` is allowed — so a `docs.yml` in `fern/` can reach a repo-root `.agents/skills/` directory:

The legacy v0.1.0 manifest lists a `files` array per skill instead of `url` and `digest`.
```yaml title="fern/docs.yml"
page-actions:
options:
skills:
path: ../.agents/skills
```

</Step>
<Step title="Publish">

Fern uploads the bundle during `fern generate --docs` and serves the files as-is — no `docs.yml` configuration is required. `fern check` validates the bundle at upload time, flagging:
Fern discovers and publishes your skills during `fern generate --docs`. For every subdirectory containing a `SKILL.md`, it generates the `/.well-known/skills/index.json` discovery manifest and uploads the skill's files — nothing is written back to your repo.

- A missing or unparseable `index.json`
`fern check` validates the bundle at build time and blocks publishing on:

- A declared path that doesn't exist or contains no skills
- A `SKILL.md` whose `name` isn't kebab-case, exceeds 64 characters, or doesn't match its parent directory name
- A `SKILL.md` with a missing or empty `description` (max 1,024 characters)
- Duplicate skill names across the directory
- A markdown reference that escapes the skill's directory (`../`), which would dangle once the skill is installed

Once published, skills are served at:
Once published, your skills are served at:

- `https://your-docs-domain.com/.well-known/agent-skills/index.json` (discovery manifest)
- `https://your-docs-domain.com/.well-known/agent-skills/<skill-name>/SKILL.md` (individual skill)
- `https://your-docs-domain.com/.well-known/skills/index.json` (legacy v0.1.0 manifest)
- `https://your-docs-domain.com/.well-known/skills/index.json` (discovery manifest)
- `https://your-docs-domain.com/.well-known/skills/<skill-name>/SKILL.md` (individual skill)

For sites with a basepath like `/docs`, the endpoints live under that basepath (e.g., `https://example.com/docs/.well-known/agent-skills/index.json`).
For sites with a basepath like `/docs`, the endpoints live under that basepath (e.g., `https://example.com/docs/.well-known/skills/index.json`).

</Step>
<Step title="Install the skills">
Expand All @@ -98,25 +94,32 @@ npx skills add https://your-docs-domain.com
The `https://` scheme is required: a bare domain is treated as a GitHub repository shorthand.

</Step>
<Step title="Configure the Install skills button">
<Step title="Customize the Install skills button">

Surface your skills in the docs UI by adding an "Install skills" button to the [page action bar](/learn/docs/configuration/site-level-settings#page-actions-configuration). Set `page-actions.options.skills` in `docs.yml` and the button opens a modal with a copyable install command, the list of available skills, and an optional link to the source repository.
Setting `page-actions.options.skills` already adds an "Install skills" button to the [page action bar](/learn/docs/configuration/site-level-settings#page-actions-configuration). The button opens a modal with a copyable install command and your skill list (read from the generated manifest). Customize the modal with `title`, `description`, and `learn-more-url`:

```yaml docs.yml
```yaml title="fern/docs.yml"
page-actions:
options:
skills:
path: ../.agents/skills
title: Plant API Skills
description: Skills for working with the Plant Store API.
repository: https://github.com/your-org/plant-api-skills
install-command: npx skills add https://your-docs-domain.com
skills:
- name: plant-care
description: Guide for diagnosing and treating common plant diseases.
url: https://github.com/your-org/plant-api-skills/tree/main/plant-care
- name: garden-planner
description: Plan garden layouts and planting schedules.
learn-more-url: https://your-docs-domain.com/skills
```

By default the modal shows `npx skills add https://<your-docs-domain>`. Override it with `install-command` when that command won't work as-is — for example auth-walled docs, a private registry, or a multi-step install:

```yaml title="fern/docs.yml"
page-actions:
options:
skills:
path: ../.agents/skills
install-command:
- npm login --registry https://npm.your-org.com
- npx skills add https://your-docs-domain.com
```

</Step>
</Steps>

Expand Down
9 changes: 9 additions & 0 deletions fern/products/docs/pages/changelog/2026-06-22.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
tags: ["ai"]
---

## Host agent skills from a directory in your repo

The "Install skills" page action now accepts `page-actions.options.skills.path`, pointing at a skills directory in the same repo as your `docs.yml`. The CLI validates the bundle, generates the `/.well-known/skills/index.json` manifest, and publishes it so users can install with `npx skills add https://<your-domain>`.

<Button intent="none" outlined rightIcon="arrow-right" href="/learn/docs/ai-features/host-skills">Read the docs</Button>
8 changes: 2 additions & 6 deletions fern/products/docs/pages/navigation/site-level-settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -871,19 +871,15 @@ Toggle the built-in actions on or off with a boolean. **Copy Page** (`copy-page`

### Install skills action

Add an "Install skills" button to the page action bar that opens a modal showing how to install your site's [custom skills](/learn/docs/ai-features/host-skills). The modal displays a copyable install command, the list of available skills, and links to the skill source.
Add an "Install skills" button to the page action bar that opens a modal showing how to install your site's [custom skills](/learn/docs/ai-features/host-skills). The modal displays a copyable install command and the list of available skills. Point `path` at a directory of skills in your repo and Fern publishes them and reads the modal's skill list from the generated manifest:

```yaml docs.yml
page-actions:
options:
skills:
path: ../.agents/skills
title: Plant API Skills
description: Skills for working with the Plant Store API.
repository: https://github.com/your-org/plant-api-skills
skills:
- name: plant-care
description: Guide for diagnosing and treating common plant diseases.
url: https://github.com/your-org/plant-api-skills/tree/main/plant-care
```

<Markdown src="/products/docs/snippets/install-skills-properties.mdx" />
Expand Down
12 changes: 6 additions & 6 deletions fern/products/docs/snippets/install-skills-properties.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Enables the "Install skills" page action and configures the modal it opens. Omit to hide it.
</ParamField>

<ParamField path="page-actions.options.skills.path" type="string" required={false} toc={true}>
Path to a directory of agent skills in this repo. Resolved relative to the folder containing `docs.yml`; `../` is allowed (e.g. a repo-root `.agents/skills/` directory that also serves local coding agents). Every subdirectory containing a `SKILL.md` is published as one skill: the CLI validates the bundle, generates the `/.well-known/skills/index.json` discovery manifest, and uploads every file so that `npx skills add https://<your-docs-domain>` works. Nothing is written back to your repo.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[FernStyles.Acronyms] 'SKILL' has no definition.

</ParamField>

<ParamField path="page-actions.options.skills.title" type="string" required={false} toc={true}>
Overrides the modal title.
</ParamField>
Expand All @@ -14,14 +18,10 @@
URL for a "Learn more" link shown alongside the description.
</ParamField>

<ParamField path="page-actions.options.skills.repository" type="string" required={false} toc={true}>
Source repository URL displayed as a "View source" button in the modal.
</ParamField>

<ParamField path="page-actions.options.skills.install-command" type="string or list of strings" required={false} toc={true}>
Command(s) shown as a copyable block in the modal. A single string is shown as-is; an array is joined with newlines for multi-step installs. Defaults to `npx skills add https://<your-docs-domain>` when omitted.
Command(s) shown as a copyable block in the modal. A single string is shown as-is; an array is joined with newlines for multi-step installs. Defaults to `npx skills add https://<your-docs-domain>` when omitted. Set this when the generated command won't work as-is — for example auth-walled docs, a private registry, or a multi-step install.
</ParamField>

<ParamField path="page-actions.options.skills.skills" type="list of objects" required={false} toc={true}>
List of skills displayed in the modal. Each entry has a `name` (required), `description` (optional), and `url` (optional link to the skill source). When the site serves a `/.well-known/agent-skills/index.json` or `/.well-known/skills/index.json` manifest, the manifest replaces this list.
List of skills displayed in the modal. Each entry has a `name` (required), `description` (optional), and `url` (optional link to the skill source). When `path` is set, or the site serves a `/.well-known/skills/index.json` (or `/.well-known/agent-skills/index.json`) manifest, the generated manifest replaces this hand-listed array.
</ParamField>
Loading