---
title: "Agent Skills Discovery"
description: "Publish local and externally hosted Agent Skills through the v0.2.0 well-known index."
canonical_url: "https://nuxtseo.com/docs/ai-ready/guides/agent-skills"
last_updated: "2026-10-04T05:21:40.809Z"
---

[Agent Skills Discovery](https://github.com/cloudflare/agent-skills-discovery-rfc) gives agents one URL for finding the skills published by your site:

```text
/.well-known/agent-skills/index.json
```

The index follows the discovery draft v0.2.0 schema. Every entry includes a SHA-256 digest so clients can verify the artifact before loading it.

## The `skills/` convention

Put each skill in `skills/<name>/SKILL.md`{lang="text"} at the project root or in a local layer:

```text
skills/
└── seo-audit/
    └── SKILL.md
```

Start with a complete skill file:

```md [skills/seo-audit/SKILL.md]
---
name: seo-audit
description: Audit a site for critical SEO issues.
---

# SEO audit

Check indexability, metadata, canonical URLs, and structured data.
```

Local discovery publishes `SKILL.md` only. If a skill needs scripts or supporting files, publish an archive as described below.

The module reads the frontmatter and computes the file digest. It publishes the index entry and these routes:

| Address                                                     | Purpose                                                                                                                                |
| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `/.well-known/agent-skills/seo-audit/SKILL.md`{lang="text"} | The artifact the index advertises, with the digest                                                                                     |
| `/skills/seo-audit/SKILL.md`{lang="text"}                   | Mirrors the repository path                                                                                                            |
| `/SKILL.md`{lang="text"}                                    | The root address installers try first. Added when the project has exactly one local skill, or for the skill named in `root`{lang="ts"} |

llms.txt gains an **Agent Skills** section that links every published skill.

The frontmatter `name`{lang="yaml"} must equal the directory name, as the Agent Skills specification requires. A mismatch, missing description, or invalid frontmatter stops the build and names the file. A directory without a `SKILL.md`{lang="text"} is ignored.

When the project and a layer both ship a skill with the same name, the project wins. Layers outside the project root are skipped.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    agentSkills: {
      dir: 'agent-skills',
      root: 'seo-audit',
      llmsTxt: false,
    },
  },
})
```

Set `dir: false` to skip discovery, `root: false` to omit the root alias, or `llmsTxt: false` to omit skill links.
Set `agentSkills: false`{lang="ts"} to disable the feature.

### Hook

The `ai-ready:agent-skills` hook runs after discovery and explicit entries merge, before the module applies the root alias.
For example, remove a skill from the published set:

```ts [modules/skills.ts]
export default defineNuxtModule({
  setup(_, nuxt) {
    nuxt.hook('ai-ready:agent-skills', ({ skills }) => {
      const index = skills.findIndex(skill => skill.name === 'internal-audit')
      if (index !== -1)
        skills.splice(index, 1)
    })
  },
})
```

## Explicit entries

Use `agentSkills.skills`{lang="ts"} to list files outside the discovery directory or externally hosted artifacts.
An explicit entry replaces a discovered skill with the same name.

## Local [SKILL.md](http://SKILL.md) files

Use a local entry when the skill consists of one `SKILL.md`{lang="text"} file:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    agentSkills: {
      skills: [{
        source: 'local',
        name: 'seo-audit',
        description: 'Audit a site for critical SEO issues.',
        file: './skills/seo-audit/SKILL.md',
      }],
    },
  },
})
```

Nuxt resolves `file`{lang="ts"} from the project root, reads it once during setup, and computes its digest from the original bytes. The path and its resolved symlink target must stay inside the project root. The index advertises this relative artifact URL:

```text
seo-audit/SKILL.md
```

The relative URL resolves from the index directory. This keeps local artifacts correct when Nuxt redirects discovery into a non-root app base.

The frontmatter `name`{lang="yaml"} and `description`{lang="yaml"} must exactly match the config.
The complete file shown above meets this example.

Local files must contain valid UTF-8 text and Markdown instructions after the frontmatter. Invalid config or unreadable files stop the Nuxt build with the failing entry and field.

### Serve the file at a root address

Discovered skills get `/skills/<name>/SKILL.md`{lang="text"} and, for a single skill, `/SKILL.md`{lang="text"} automatically. An explicit entry can name its own addresses with `alias`{lang="ts"}, one string or a list:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    agentSkills: {
      skills: [{
        source: 'local',
        name: 'seo-audit',
        description: 'Audit a site for critical SEO issues.',
        file: './skills/seo-audit/SKILL.md',
        alias: '/SKILL.md',
      }],
    },
  },
})
```

An alias must be a path-absolute route that ends in `.md`{lang="text"}, sit outside `/.well-known/`{lang="text"}, and avoid the module-owned `/index.md`{lang="text"} and `/sitemap.md`{lang="text"}. Content negotiation leaves aliases alone, so the response is the file itself, with no generated frontmatter and the same digest as the discovery artifact. The index keeps advertising the `.well-known`{lang="text"} URL.

## External files and archives

Use an external entry for a `SKILL.md`{lang="text"} or archive that you already host.
Compute its digest from the exact file you will upload:

```bash
sha256sum seo-toolkit.tar.gz
```

Set `SEO_TOOLKIT_SHA256` to the command's hexadecimal hash before running your Nuxt build:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    agentSkills: {
      skills: [{
        source: 'external',
        name: 'seo-toolkit',
        type: 'archive',
        description: 'Use the complete SEO toolkit and its supporting resources.',
        url: 'https://cdn.example.com/seo-toolkit.tar.gz',
        digest: `sha256:${process.env.SEO_TOOLKIT_SHA256}`,
      }],
    },
  },
})
```

External entries accept HTTP(S), path-absolute, and index-relative URLs. Nuxt validates the URL and digest format but does not download the artifact during setup. The uploaded bytes must match the hashed file. Recompute the digest whenever the artifact changes.

Use `type: 'skill-md'`{lang="ts"} for one Markdown file. Use `type: 'archive'`{lang="ts"} for a `.tar.gz`{lang="text"} or `.zip`{lang="text"} containing `SKILL.md`{lang="text"} plus scripts, references, or assets.

The index and embedded local files support GET and HEAD. Other methods return 405. Responses include public cache headers and `Access-Control-Allow-Origin: *`{lang="http"} for browser clients.

For non-root app bases, Nuxt redirects origin-root discovery requests to the base-aware index and artifact routes.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
