# Contextual menu

Every page gets a "Copy page" menu next to its `<h1>`, and a Markdown copy of itself at its own URL with `.md` appended instead of a trailing slash (`/guides/webhooks/` → `/guides/webhooks.md`). Both are on by default, with every option — `contextMenu` in `writedocs.json` only narrows or turns them off.

## Choosing the options

<Parameter name="contextMenu" type='array of "copy" / "view" / "chatgpt" / "claude" / "perplexity" / "mcp" / "cursor" / "vscode", or false' default="every option" />

List the options to show:

```json
{
  "contextMenu": ["copy", "claude"]
}
```

The menu keeps its own order (copy, view, ChatGPT, Claude, Perplexity, then the MCP server's options), whatever order the list uses. With only `copy`, it's a single button. Without `copy`, one other option is the button itself (`["claude"]` shows **Open in Claude**), and several sit behind a **Page options** button.

## Turning it off

```json
{
  "contextMenu": false
}
```

No menu, and no `.md` copies of the pages. `llms.txt` then links to the pages themselves.

## The options

- **`copy`** — copies the page's Markdown to the clipboard, for pasting into any AI tool as context.
- **`view`** — opens the page's `.md` copy.
- **`chatgpt`, `claude`, `perplexity`** — opens the assistant with a prompt pointing at this page's `.md` URL, so it fetches the current content rather than a snapshot baked into the link.
- **`mcp`** — copies the address of the site's [MCP server](/docs/configuration/mcp/) (`/mcp`), to add to any AI tool that supports MCP.
- **`cursor`, `vscode`** — adds the site's MCP server to Cursor or VS Code, through the editor's own install link: the editor opens and asks to confirm.

The last three are about the MCP server, so they're left out when `"mcp": false` turns it off.

<Callout type="note">
  The "Open in…" links hand the assistant the page's full address, and the MCP options the MCP server's. With a top-level `domain` (see [SEO and sitemap](/docs/configuration/seo-and-sitemap/)) it's written into the page; without one, the page fills it in from the address it's served from. Either way, the assistant can only read a page that's publicly reachable — not one on `localhost`.
</Callout>

<Callout type="note">
  The earlier form, `"contextMenu": { "openIn": ["chatgpt", "claude"] }`, still works: copy and view, plus the assistants listed.
</Callout>

## Where it appears

The dropdown renders next to the page's auto-generated `<h1>` — which means it's only shown on pages that have one. It's hidden on **`mode: custom` and `mode: blank` pages** — see [Page modes](/docs/content/page-modes/). These render no auto `<h1>` at all (a hand-built canvas page controls its own layout), so there's nothing for the dropdown to sit next to.

The underlying `.md` route, unlike the dropdown, is still generated for every page regardless of `mode` — a `mode: custom` page is still reachable at its own `.md` URL, just without a menu pointing at it.

**API reference pages** get the menu too. Their Markdown copy is the operation written out from the OpenAPI spec — method and path, description, parameters, body fields, responses and examples — after any text of the page's own, so copying the page or opening it in an assistant hands over the whole endpoint.

<Callout type="tip">
  See `docs.json-examples/00-kitchen-sink/` in the Writedocs repo for a complete, buildable example — ordinary pages get the dropdown, and `about.mdx` (`mode: custom`) doesn't, since there's no auto `<h1>` for it to sit next to.
</Callout>