---
title: "Configuration"
description: "Nuxt configuration reference for Nuxt AI Ready."
canonical_url: "https://nuxtseo.com/docs/ai-ready/api/config"
last_updated: "2026-09-05T17:04:06.756Z"
---

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  aiReady: {
    // options
  }
})
```

## `enabled: boolean`{lang="ts"}

- Default: `true`{lang="ts"}

```ts
aiReady: {
  enabled: process.env.NODE_ENV === 'production'
}
```

## `debug: boolean`{lang="ts"}

- Default: `false`{lang="ts"}

Enable debug logging for module operations.

## `contentNegotiation: boolean`{lang="ts"}

- Default: Automatic per route

Set `false`{lang="ts"} to keep original page URLs as HTML, even when requests prefer Markdown through `Accept`{lang="http"} or an AI crawler `User-Agent`{lang="http"}. Explicit `.md` URLs, alternate links, `llms.txt`, MCP, and page indexing remain available.

In automatic mode, the module reads the effective route rule for each request. It disables negotiation for ISR and for Nitro response caches whose `varies`{lang="ts"} list is missing `accept`{lang="http"}, `sec-fetch-dest`{lang="http"}, or `user-agent`{lang="http"}. This includes `swr`{lang="ts"} rules after Nitro normalizes them. `headersOnly: true`{lang="ts"} remains safe because it does not cache the response body.

Set `false`{lang="ts"} for URL-only CDN or reverse proxy caching configured outside Nuxt. Set `true`{lang="ts"} to force negotiation and take responsibility for the cache key.

```ts
export default defineNuxtConfig({
  aiReady: {
    contentNegotiation: false
  }
})
```

## `apiCatalog: false | ApiCatalogConfig`{lang="ts"}

- Default: Disabled until you configure entries or an integration generates them

Publish an [RFC 9727 API Catalog](/docs/ai-ready/guides/api-catalog) at `/.well-known/api-catalog`{lang="bash"}. Relative URLs resolve against `site.url`{lang="ts"} and `app.baseURL`{lang="ts"} once during module setup. Non-root apps redirect the origin-root request to the base-aware route.

```ts
export default defineNuxtConfig({
  site: {
    url: 'https://example.com',
  },
  aiReady: {
    apiCatalog: {
      entries: [{
        anchor: '/api',
        serviceDesc: {
          href: '/openapi.json',
          type: 'application/vnd.oai.openapi+json;version=3.1',
        },
        serviceDoc: { href: '/docs/api', type: 'text/html' },
        status: { href: '/api/health', type: 'application/json' },
      }],
    },
  },
})
```

Each entry needs at least one relation target. A relation accepts one target or an array. Supported typed relations are `item`{lang="ts"}, `serviceDesc`{lang="ts"}, `serviceDoc`{lang="ts"}, `serviceMeta`{lang="ts"}, `status`{lang="ts"}, and `apiCatalog`{lang="ts"}. Use `relations`{lang="ts"} for other RFC 8288 relation names. Set `apiCatalog: false`{lang="ts"} to suppress configured and integration-generated entries.

## `mdreamOptions: MdreamOptions`{lang="ts"}

- Default: `{ minimal: true }`{lang="ts"}

Configure [mdream](https://github.com/harlan-zw/mdream) HTML-to-markdown conversion.

```ts
export default defineNuxtConfig({
  aiReady: {
    mdreamOptions: {
      minimal: true
    }
  }
})
```

## `markdownCacheHeaders: { maxAge?: number, swr?: boolean }`{lang="ts"}

- Default: `{ maxAge: 3600, swr: true }`{lang="ts"}

Cache settings for runtime markdown endpoints.

| Option   | Type      | Default | Description               |
| -------- | --------- | ------- | ------------------------- |
| `maxAge` | `number`  | `3600`  | Cache duration in seconds |
| `swr`    | `boolean` | `true`  | Stale-while-revalidate    |

## `agentSkills: false | AgentSkillsConfig`{lang="ts"}

- Default: `false`{lang="ts"}

Publish an [Agent Skills Discovery v0.2.0 index](/docs/ai-ready/guides/agent-skills). Non-root apps redirect origin-root requests to the base-aware route. Local entries embed one `SKILL.md`{lang="text"} file. External entries advertise an existing Markdown file or archive without fetching it during the build.

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

## `llmsTxt: LlmsTxtConfig`{lang="ts"}

- Default: Auto-generated

Configure llms.txt generation.

```ts
export default defineNuxtConfig({
  aiReady: {
    llmsTxt: {
      markdownLinks: true,
      sections: [
        {
          title: 'API Reference',
          links: [
            { title: 'REST API', href: '/docs/api', description: 'API docs' }
          ]
        },
        {
          title: 'Debug Endpoints',
          optional: true,
          links: [
            { title: 'Debug Route', href: '/__ai-ready-debug', description: 'Internal debugging' }
          ]
        }
      ],
      notes: 'Built with Nuxt AI Ready'
    }
  }
})
```

**LlmsTxtSection:**

| Property      | Type                              | Description                                                                                                     |
| ------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `title`       | `string`                          | Section title                                                                                                   |
| `description` | `string \| string[]`              | Section context rendered in the heading-free preamble, or in each optional link note                            |
| `links`       | `{ title, href, description? }[]` | Links in section                                                                                                |
| `optional`    | `boolean`                         | Put the section's links in the single `## Optional` file list, which LLMs may skip with shorter context windows |

**LlmsTxtConfig:**

| Property        | Type                 | Description                                                                                                     |
| --------------- | -------------------- | --------------------------------------------------------------------------------------------------------------- |
| `markdownLinks` | `boolean`            | Link automatically generated page and locale entries to available Markdown representations. Defaults to `false` |
| `sections`      | `LlmsTxtSection[]`   | Custom sections                                                                                                 |
| `notes`         | `string \| string[]` | Additional heading-free context rendered before file-list sections                                              |

## `contentSignal: false | { aiTrain?: boolean, contentUsage?: boolean, search?: boolean, aiInput?: boolean }`{lang="ts"}

- Default: `false`{lang="ts"}

Content Signal directives for robots.txt. See [Content Signals guide](/docs/ai-ready/guides/content-signals).

```ts
export default defineNuxtConfig({
  aiReady: {
    contentSignal: {
      aiTrain: false, // Block training
      contentUsage: false, // Omit Content-Usage from robots.txt
      search: true, // Allow search indexing
      aiInput: true, // Allow RAG/grounding
    }
  }
})
```

## `tools: SiteToolsConfig`{lang="ts"}

Configure the three built-in tools once, then attach each one to MCP, WebMCP or both.

| Tool              | Shared options | `mcp` options | `webmcp` options                         |
| ----------------- | -------------- | ------------- | ---------------------------------------- |
| `listPages`       | `defaultLimit` | `enabled`     | `enabled`, `maxOutputChars`, `exposedTo` |
| `searchPages`     | `defaultLimit` | `enabled`     | `enabled`, `maxOutputChars`, `exposedTo` |
| `getPageMarkdown` | None           | `enabled`     | `enabled`, `maxOutputChars`, `exposedTo` |

`defaultLimit` defaults to 20 for `listPages` and 10 for `searchPages`. Values are clamped to 50. WebMCP output defaults to 1,500 characters per tool.

```ts
export default defineNuxtConfig({
  aiReady: {
    tools: {
      listPages: {
        defaultLimit: 10,
        webmcp: { enabled: false },
      },
      searchPages: {
        defaultLimit: 5,
        webmcp: { maxOutputChars: 3000 },
      },
    },
  },
})
```

The module enables omitted attachment objects when their transport is active. Set `mcp.enabled`{lang="ts"} or `webmcp.enabled`{lang="ts"} to `false` on one tool to leave it off that transport.

## `mcp: { tools?: boolean, resources?: boolean }`{lang="ts"}

- Default: `{ tools: true, resources: true }`{lang="ts"}

Control MCP features when `@nuxtjs/mcp-toolkit` installed.

```ts
export default defineNuxtConfig({
  aiReady: {
    mcp: {
      tools: true, // list_pages, search_pages, get_page_markdown
      resources: true, // pages resource
    }
  }
})
```

See [MCP guide](/docs/ai-ready/guides/mcp) for tool/resource details.

## `mcpServerCard: false | McpServerCardConfig`{lang="ts"}

- Default: `{ cacheMaxAge: 3600 }`{lang="ts"}

Publish experimental SEP-2127 discovery metadata at `<mcp-route>/server-card`{lang="bash"} when MCP Toolkit runs on the server. For the default Toolkit route, the card is available at `/mcp/server-card`{lang="bash"}. Set this option to `false` to disable the route.

| Option        | Type     | Default                              | Description                                         |
| ------------- | -------- | ------------------------------------ | --------------------------------------------------- |
| `name`        | `string` | Derived from site host and MCP route | Reverse-DNS/server identity                         |
| `title`       | `string` | Existing Toolkit or site name        | Human-readable server title                         |
| `description` | `string` | Toolkit or site description          | Server description, up to 100 characters            |
| `websiteUrl`  | `string` | None                                 | Absolute HTTP or HTTPS project or documentation URL |
| `cacheMaxAge` | `number` | `3600`                               | Browser and shared cache lifetime in seconds        |

Toolkit icons are copied into the card. The card route is omitted when Toolkit is absent, disabled or unavailable in a static deployment.

## `webmcp: boolean | WebMcpConfig`{lang="ts"}

- Default: `false`{lang="ts"}

Register [WebMCP](/docs/ai-ready/guides/webmcp) tools for browser agents through `document.modelContext`{lang="ts"}.

| Option      | Type       | Default | Description                                                                            |
| ----------- | ---------- | ------- | -------------------------------------------------------------------------------------- |
| `tools`     | `boolean`  | `true`  | Attach tools enabled under `aiReady.tools`                                             |
| `exposedTo` | `string[]` | None    | Default trusted origins for built-in and composable tools. Same-origin only by default |

```ts
export default defineNuxtConfig({
  aiReady: {
    tools: {
      listPages: {
        webmcp: { enabled: false },
      },
      searchPages: {
        defaultLimit: 20,
        webmcp: { maxOutputChars: 3000 },
      },
    },
    webmcp: {
      exposedTo: ['https://agent.example.com'],
    },
  },
})
```

Nuxt auto-imports `useWebMcpTool()`{lang="ts"} and `useWebMcpSupported()`{lang="ts"} when you enable WebMCP. Set `webmcp.tools`{lang="ts"} to `false` to register your own tools without the built-in definitions or `/__ai-ready/pages`{lang="bash"} endpoint.

## `llmsTxtCacheSeconds: number`{lang="ts"}

- Default: `600`{lang="ts"} (10 minutes)

Cache duration for llms.txt route handlers. Uses stale-while-revalidate.

```ts
export default defineNuxtConfig({
  aiReady: {
    llmsTxtCacheSeconds: 3600 // 1 hour
  }
})
```

## `database: false | { type?: string, filename?: string, bindingName?: string, url?: string, authToken?: string }`{lang="ts"}

- Default: Disabled until a requested feature needs stored pages.

Configure the database for page storage. The module auto-detects the best driver based on the deployment platform.

| Option        | Type                                                                      | Default                     | Description                                   |
| ------------- | ------------------------------------------------------------------------- | --------------------------- | --------------------------------------------- |
| `type`        | `'none' \| 'sqlite' \| 'bun' \| 'd1' \| 'libsql' \| 'neon' \| 'postgres'` | `'sqlite'`                  | Database type. `'none'` disables the database |
| `filename`    | `string`                                                                  | `'.data/ai-ready/pages.db'` | [SQLite](https://sqlite.org) file path        |
| `bindingName` | `string`                                                                  | `'AI_READY_DB'`             | D1 binding name                               |
| `url`         | `string`                                                                  | -                           | LibSQL, Neon, or PostgreSQL URL               |
| `authToken`   | `string`                                                                  | -                           | LibSQL/Turso auth token                       |

::code-group
```ts [Default (SQLite)]
export default defineNuxtConfig({
  aiReady: {
    database: {
      filename: '.data/ai-ready/pages.db'
    }
  }
})
```

```ts [Cloudflare D1]
export default defineNuxtConfig({
  aiReady: {
    database: {
      type: 'd1',
      bindingName: 'AI_READY_DB'
    }
  }
})
```

```ts [Turso/LibSQL]
export default defineNuxtConfig({
  aiReady: {
    database: {
      type: 'libsql',
      url: process.env.TURSO_URL,
      authToken: process.env.TURSO_AUTH_TOKEN
    }
  }
})
```

```ts [PostgreSQL]
export default defineNuxtConfig({
  aiReady: {
    database: {
      type: 'postgres',
      url: process.env.DATABASE_URL
    }
  }
})
```

```ts [No database]
export default defineNuxtConfig({
  aiReady: {
    database: false
  }
})
```
::

**Driver auto-detection:**

| Platform                                           | Driver           | Extra dependency |
| -------------------------------------------------- | ---------------- | ---------------- |
| [Node.js](https://nodejs.org) 22.13+               | `node:sqlite`    | None             |
| Earlier [Node.js](https://nodejs.org)              | `better-sqlite3` | `better-sqlite3` |
| [Bun](https://bun.sh)                              | `bun:sqlite`     | None             |
| [Cloudflare](https://cloudflare.com)               | D1               | None             |
| [Vercel](https://vercel.com) (with `POSTGRES_URL`) | Neon Postgres    | None             |
| Node.js with `database.type: 'postgres'`           | PostgreSQL       | `postgres`       |

On Node.js before 22.13, the default `sqlite` type requires the optional [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) peer dependency: `pnpm add better-sqlite3`{lang="bash"}.

For [PostgreSQL](https://postgresql.org), install the optional [`postgres`](https://github.com/porsager/postgres) peer dependency: `pnpm add postgres`{lang="bash"}. The driver reads `database.url`{lang="ts"}, `POSTGRES_URL`, then `DATABASE_URL`.

For serverless deployments, the module generates a compressed dump at build time that's restored on cold start.

### No Database

The database stays off when no requested feature needs stored pages.
Set `database: false`{lang="ts"} (or `database: { type: 'none' }`{lang="ts"}) to force it off.
No driver enters the server bundle, so the runtime needs no `better-sqlite3`.
On Node.js before 22.13, build time indexing needs `better-sqlite3`.

Runtime indexing, MCP page tools, and WebMCP page tools enable storage automatically.
An explicit database config also enables storage.

Build time generation still works. You keep:

- `llms.txt` and `llms-full.txt`, written during prerender.
- `.md` twins for every prerendered page.
- The `Link` headers, content signals, API Catalog and Agent Skills.

The following features need a database, so they turn off:

- `list_pages`, `search_pages` and `get_page_markdown`, for both MCP and WebMCP.
- The MCP pages resource.
- Runtime `.md` requests for routes that you did not prerender.
- Runtime `llms-full.txt`. Prerender the route instead.

A disabled database conflicts with `runtimeSync` and `cron`.
If you set any of them, the build fails with a message naming the option.

**Table naming:**

All tables are prefixed with `ai_ready_` to avoid conflicts with existing database tables:

- `ai_ready_pages` - Main pages table
- `ai_ready_pages_fts` - FTS5 full-text search index
- `_ai_ready_info` - Schema version tracking

This allows safe use with existing D1/LibSQL databases without risk of overwriting user tables.

## `cron: boolean`{lang="ts"}

- Default: `false`{lang="ts"}

Enable the scheduled task that runs every minute. It automatically enables `runtimeSync` for background indexing.

```ts
export default defineNuxtConfig({
  aiReady: {
    cron: true
  }
})
```

## `runtimeSyncSecret: string`{lang="ts"}

- Default: (no auth required)

Secret token for authenticating runtime sync endpoints. When set, it requires an `Authorization: Bearer <token>`{lang="html"} header.

```ts
export default defineNuxtConfig({
  aiReady: {
    runtimeSyncSecret: process.env.AI_READY_SECRET
  }
})
```

## `runtimeSync: boolean | { ttl?: number, batchSize?: number, pruneTtl?: number }`{lang="ts"}

- Default: `false`{lang="ts"}

**Opt-in runtime sync for dynamic content sites.** Most sites don't need this - prerendering handles page indexing automatically.

Enable only if your site has frequently changing content that can't be prerendered. Set to `true` for defaults or object to customize.

| Option      | Type     | Default | Description                                                |
| ----------- | -------- | ------- | ---------------------------------------------------------- |
| `ttl`       | `number` | `3600`  | Re-index pages & refresh sitemap older than this (seconds) |
| `batchSize` | `number` | `50`    | Pages per batch (max: 50)                                  |
| `pruneTtl`  | `number` | `0`     | Prune routes not in sitemap for this long (0 = never)      |

```ts
export default defineNuxtConfig({
  aiReady: {
    runtimeSync: {
      ttl: 3600,
      batchSize: 20,
      pruneTtl: 604800 // prune after 7 days
    },
    runtimeSyncSecret: process.env.AI_READY_SECRET,
    cron: true // enable scheduled indexing
  }
})
```

**When enabled:**

- `GET /__ai-ready/status` - Check indexing progress
- `POST /__ai-ready/poll` - Trigger batch indexing (requires `Authorization: Bearer <token>`{lang="html"} header)
- `POST /__ai-ready/prune` - Prune stale routes (requires `Authorization: Bearer <token>`{lang="html"} header)

See [Runtime Sync guide](/docs/ai-ready/guides/runtime-indexing) for details.

## `autoI18n: boolean`{lang="ts"}

- Default: `true`{lang="ts"}

Auto-detect [`@nuxtjs/i18n`](https://i18n.nuxtjs.org/) (or `nuxt-i18n-micro`) at build time and integrate locale data into:

- **`llms.txt`**: adds an `## Available Languages on Website` file-list section linking to every locale root
- **`Link` headers**: emits `Link: <…>; rel="alternate"; hreflang="…"` per locale on `.md` and HTML responses (RFC 8288)
- **Frontmatter**: markdown bodies include a `locale` field
- **Database**: each indexed page persists its `locale` for filtered queries
- **FTS5 tokenizer**: auto-switches to `trigram` for CJK locales (zh / ja / ko)

Disable to skip the integration even with an i18n module present:

```ts
export default defineNuxtConfig({
  aiReady: {
    autoI18n: false
  }
})
```

See [i18n guide](/docs/ai-ready/guides/i18n) for details.