---
title: Agent readiness
description: Expose agents.md and MCP discovery files that help AI agents discover and use your docs site
type: guide
summary: Generate /agents.md and /.well-known/mcp.json from Geistdocs config so agents can find docs, Markdown surfaces, API specs, and MCP endpoints.
related:
  - /docs/llms-txt
  - /docs/md
  - /docs/proxy
---

Geistdocs can generate `/agents.md` and `/.well-known/mcp.json` discovery files from your site config. These files tell AI agents where your docs live and which machine-readable integration surfaces your product declares.

<CopyPrompt text="Review this Geistdocs site's /agents.md and /.well-known/mcp.json files. Check whether they list the product description, documentation links, llms.txt, sitemap.md, OpenAPI specs, and MCP servers accurately.">
  Review this Geistdocs site's `/agents.md` and `/.well-known/mcp.json` files. Check whether they list the product description, documentation links, `llms.txt`, `sitemap.md`, OpenAPI specs, and MCP servers accurately.
</CopyPrompt>

## What it provides

The generated `/agents.md` file gives agents a stable starting point before they crawl the rest of your documentation. Its product section states when to use the documented product, and the homepage serves the same guidance when an agent requests `text/markdown`. The optional `/.well-known/mcp.json` route advertises configured MCP servers without running an MCP server inside Geistdocs.

It can include:

- Product name, description, category, audience, and use cases
- Human-readable docs entry points
- `/llms.txt` for full documentation context
- `/sitemap.md` for semantic navigation
- Page-level Markdown guidance for `.md` and `.mdx` URLs
- OpenAPI, authentication, scopes, rate limit, and error docs when configured
- MCP manifests and server URLs when configured
- Additional links and agent instructions

## Add the route

Generated projects include a thin App Router adapter:

```ts title="app/[lang]/agents.md/route.ts"
import { createAgentsRoute } from "@vercel/geistdocs/routes/agents";
import { config } from "@/lib/geistdocs/config";

export const { GET, generateStaticParams } = createAgentsRoute({
  config,
});
```

Because the route is under `[lang]`, the Geistdocs proxy can serve `/agents.md` through the default language route.

Generated projects also include a thin adapter for MCP discovery:

```ts title="app/[lang]/.well-known/mcp.json/route.ts"
import { createMcpManifestRoute } from "@vercel/geistdocs/routes/mcp";
import { config } from "@/lib/geistdocs/config";

export const { GET, generateStaticParams } = createMcpManifestRoute({
  config,
});
```

The MCP discovery route returns `404` until you configure `agent.mcp.servers`, so generated sites do not claim MCP support by default.

When configured, `/.well-known/mcp.json` returns the declared MCP servers:

```json
{
  "name": "My Product",
  "description": "My Product helps teams build and deploy applications.",
  "servers": [
    {
      "name": "My Product MCP",
      "url": "https://example.com/api/mcp",
      "description": "Use product tools through MCP."
    }
  ]
}
```

## Configure agent metadata

Add agent-readiness metadata in `geistdocs.tsx`, then pass it through `defineConfig` in `lib/geistdocs/config.tsx`.

```tsx title="geistdocs.tsx"
import type { GeistdocsAgentReadinessConfig } from "@vercel/geistdocs/config";

export const agent = {
  product: {
    name: "My Product",
    description: "My Product helps teams build and deploy applications.",
    category: "Developer tools",
    audience: ["Frontend developers", "Platform teams"],
    useCases: ["Deploy applications", "Manage domains", "Inspect logs"],
  },
  api: {
    openApiUrl: "https://api.example.com/openapi.json",
    openApiSpecs: [
      {
        label: "Admin API OpenAPI specification",
        url: "https://api.example.com/admin/openapi.json",
        description: "Administrative API operations.",
      },
    ],
    authDocsUrl: "/docs/authentication",
    scopesDocsUrl: "/docs/scopes",
    rateLimitsUrl: "/docs/rate-limits",
    errorsUrl: "/docs/errors",
  },
  mcp: {
    manifestUrl: "/.well-known/mcp.json",
    servers: [
      {
        name: "My Product MCP",
        url: "https://example.com/api/mcp",
        description: "Use product tools through MCP.",
      },
    ],
  },
  links: [
    {
      label: "Support",
      href: "https://example.com/support",
      description: "Get help from the product team.",
    },
  ],
} satisfies GeistdocsAgentReadinessConfig;
```

```tsx title="lib/geistdocs/config.tsx"
import { agent } from "@/geistdocs";

export const config = defineConfig({
  // ...
  agent,
});
```

## Describe the documentation site's own API

`agent.api.openApiUrl` points at your product's API. The documentation site also has HTTP endpoints of its own: `/api/search`, `/api/chat`, and the Markdown discovery routes. Geistdocs owns those implementations, so it can describe them for you. Add the route adapter and tell `/agents.md` where it lives:

```ts title="app/[lang]/openapi.json/route.ts"
import { createOpenApiRoute } from "@vercel/geistdocs/routes/openapi";
import { config } from "@/lib/geistdocs/config";

export const { GET, generateStaticParams } = createOpenApiRoute({
  config,
});
```

```tsx title="geistdocs.tsx"
export const agent = {
  api: {
    openApiUrl: "https://api.example.com/openapi.json",
    siteOpenApiUrl: "/openapi.json",
  },
} satisfies GeistdocsAgentReadinessConfig;
```

The generated OpenAPI 3.1 document states that it describes the documentation site and not the product, links the product spec when `openApiUrl` is set, and lists the languages the site serves. `/agents.md` renders `siteOpenApiUrl` as a separate "Documentation site API" link so agents do not confuse the two.

The document always lists the Markdown discovery routes (`/agents.md`, `/sitemap.md`, `/llms.txt`, and page-level `.md`), so keep those route files mounted. `/api/search` and the chat route follow `search.enabled` and `ai.enabled`; pass `endpoints: { chat: false }` or `endpoints: { search: false }` to `createOpenApiRoute` when the route files differ from the feature flags. The document lists the chat route at `ai.endpoint`, which defaults to `/api/chat`. `/.well-known/mcp.json` appears only when `agent.mcp.servers` is configured.

The server URL comes from `siteUrl` when it is set, and from the request origin otherwise. Set `siteUrl` so the document names your production host.

Publishing the document makes `/api/chat` discoverable for programmatic use. That endpoint runs a language model on your account and has no built-in rate limit. Set `endpoints: { chat: false }` if that is not acceptable for your site.

## Select the article in rendered HTML

Docs pages mark the visible article parts in their HTML, so a tool that reads the rendered page (a crawler, or a check that compares the page with its Markdown route) can select the content without depending on Fumadocs element IDs or class names. The frontmatter description remains available through metadata and AI-readable routes, but is not repeated below the page title.

| Attribute | Element |
| --- | --- |
| `data-geistdocs-article="title"` | The page's `h1` |
| `data-geistdocs-article="body"` | The rendered MDX body |

Page actions, breadcrumbs, the table of contents, and the previous/next links sit outside these elements, so their text never mixes with the article's.

## Keep it honest

Only list OpenAPI specs, authentication flows, or MCP servers that actually exist. Geistdocs validates new `openApiSpecs` entries and MCP servers rendered by `/.well-known/mcp.json` as absolute `http` or `https` URLs or root-relative paths. Existing `/agents.md` URL fields keep the same URL handling as previous versions. Geistdocs makes product capabilities discoverable, but it does not create APIs or MCP tools for you.

Use `/agents.md` and `/.well-known/mcp.json` with [llms.txt](/docs/llms-txt), [.md extension](/docs/md), and [Proxy and markdown routes](/docs/proxy) to give agents a complete discovery path.
