On 29 April the Nuxt team put an AI agent on nuxt.com, labelled beta. The announcement says it answers from the official docs, the modules catalogue, the blog and the deployment guides, and it reads all of them through the Nuxt MCP server. That server is public: you can connect the AI assistant in your own editor to it, so the assistant can check the current Nuxt docs before it writes your code.
MCP, the Model Context Protocol, is a standard way for an AI assistant to call tools on a server: "list the docs pages", "fetch this page", "look up this module". An assistant connected to an MCP server can read the source instead of guessing from its training data.
What the agent does
The agent replaces the docs chat widget that Kapa.ai had powered for the past few years, and the post thanks them for that sponsorship. The new one was built in-house, and the post lists four things it does:
- It grounds its answers in the official docs and ecosystem data through MCP tools, rather than through chunks of retrieved text.
- It renders rich answers. Modules (with live data from
api.nuxt.com), templates, blog posts, hosting providers and StackBlitz playground links generated from the conversation come back as clickable cards. - It streams everything, including the progress of each tool call.
- It closes the loop: thumbs up or down on every answer, and a Report issue form that creates a ticket for the team with the conversation attached.
There are three ways in: a side panel, toggled from the header or with ⌘I (Ctrl+I on Windows and Linux) on any page; an ask bar at the bottom of /docs and /blog pages; and a full-screen chat at /chat. While you read a docs page, the agent pulls that page in as context, and a small "Agent is using this page" indicator in the footer tells you so. You can dismiss it.
It also has a search across GitHub issues in the nuxt, nuxt-modules and nuxt-content organisations. Paste an error and it searches the issues first. It can search the web too, but the system prompt limits that to things the model could not know, such as a release from this week.
How the agent is built
The whole agent is one Nitro route, server/api/agent.post.ts, in the open-source nuxt.com repository:
- Client: a
Chatinstance from@ai-sdk/vue, pointed at/api/agent. - Server: AI SDK 6's
streamTextcalls Anthropic'sclaude-sonnet-4.6model with two sets of tools merged together: the ones from the Nuxt MCP server, and native UI tools namedshow_*,open_playgroundandreport_issue. - Interface and storage: Nuxt UI components, with chats stored through Drizzle ORM.
The site's package.json on launch day lists ai 6, @ai-sdk/vue 3, @ai-sdk/mcp 1, @nuxt/ui 4.7, @nuxtjs/mcp-toolkit 0.15 and Nuxt 4.4.
The post calls one design choice the single most important: the agent connects to its own MCP endpoint over HTTP, the same /mcp that outside assistants use. The route opens the connection with createMCPClient from @ai-sdk/mcp:
const httpClient = await createMCPClient({
transport: { type: 'http', url: `${getRequestURL(event).origin}${MCP_PATH}` }
})
const mcpTools = await httpClient.tools()
MCP_PATH is '/mcp', so the client calls the site's own endpoint. httpClient.tools() returns every tool the server lists, ready to merge with the native ones and pass to streamText. Any tool added to the MCP server therefore reaches the agent and every outside assistant at once, with no extra wiring.
Two other details are worth copying in your own agents:
- A custom stop condition ends the loop as soon as the model answers in text without calling another tool, with a hard ceiling of 10 steps.
- The chat is saved with
event.waitUntil(), so the user's stream finishes without waiting for the database.
Limits of the beta
- 20 messages per day per IP fingerprint. The cap is there to stop runaway costs.
- No history across devices. A conversation resumes after a reload, but history that follows you to another device needs user accounts, which the post lists as the next step rather than a feature.
- Still improving. The team's short-term plans are better answer quality, richer memory across turns and cleaner source citations, which suggests where the agent is weakest today.
- It can be wrong, like any model. The cards and source links make an answer easier to check, so check them.
Add the Nuxt MCP server to your editor
The server lives at https://nuxt.com/mcp, uses the HTTP transport and needs no authentication. The MCP server guide gives the setup for each assistant. For Claude Code it is one command:
claude mcp add --transport http nuxt-remote https://nuxt.com/mcp
nuxt-remote is only the name Claude Code lists the server under; any name works. Run claude mcp list afterwards to confirm it connected.
For Cursor, put this in .cursor/mcp.json at the project root:
{
"mcpServers": {
"nuxt": {
"type": "http",
"url": "https://nuxt.com/mcp"
}
}
}
VS Code with GitHub Copilot Chat reads .vscode/mcp.json, with the same entry under a servers key instead of mcpServers. The guide also covers Claude Desktop, ChatGPT, Windsurf, Zed, Le Chat and Opencode. Commit the project file and everyone on the team gets the server when they open the repository.
The server's tools, prompts and resources
When the agent launched, the server had ten tools in four groups:
- Docs:
list-documentation-pages(with a search term and a version, 4.x by default),get-documentation-pageandget-getting-started-guide. - Blog:
list-blog-postsandget-blog-post. - Hosting:
list-deploy-providersandget-deploy-provider. - Ecosystem:
list-modules,get-module, andget-changelog, which returns recent releases of Nuxt and the official modules.
The docs page writes the names with underscores; the server reports them with hyphens, and your assistant shows the server's version. There are also three prompts (find-documentation-for-topic, deployment-guide, migration-help) and three resources. In Claude Code you reach prompts by typing / and resources by typing @.
What a tool call looks like
MCP messages are JSON-RPC 2.0: a request names a method and its params, and carries an id that the answer repeats. When you ask "how do I upgrade to Nuxt 4?", the assistant sends a message like this:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "get-documentation-page",
"arguments": { "path": "/docs/4.x/getting-started/upgrade" }
}
}
The server answers with the page as Markdown inside a content array:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [{ "type": "text", "text": "(the page as Markdown)" }]
}
}
Long pages are cut at 12,000 characters with a note telling the model to ask for specific sections, which it can do with an optional sections argument listing ## headings. You never write these messages yourself, but knowing their shape helps: when an answer looks wrong, your assistant's tool log shows which page it read.
Ask your assistant to read the docs first
Most AI assistants learned Nuxt from a web full of Nuxt 2 and Nuxt 3 code. Ask one to add a page and it may put pages/ at the project root, where Nuxt 4 expects app/pages/. With the server connected, tell it to check the docs first ("check the Nuxt docs, then add a dynamic route for /users/[id]") and it can read the 4.x page before writing anything.
Three habits pay off quickly:
- Before installing a module, ask for its details:
get-modulereturns its README, compatibility and maintainers. - After a release, ask what changed:
get-changelogreads the actual release notes. - When a fix depends on a version, ask for the source link and open it.
Build your own MCP server with the toolkit
The nuxt.com server is built with the Nuxt MCP Toolkit, and you can use it to give assistants tools for your own app. Install it with npx nuxt module add mcp-toolkit. Every file in server/mcp/tools/ then becomes a tool named after the file, so this one is get-opening-hours:
import { z } from 'zod'
export default defineMcpTool({
description: 'Returns the opening hours for one shop',
inputSchema: {
shop: z.string().describe('The shop slug, for example "leeds"'),
},
handler: async ({ shop }) => ({
content: [{ type: 'text', text: `${shop}: 9:00 to 17:30, Monday to Saturday` }],
}),
})
inputSchema lists the arguments as Zod fields. The assistant sees them as JSON Schema, with the .describe() text telling the model what to pass, and the server refuses a call whose arguments do not match. The handler returns the same content array you saw in the server's answer above.
Your server is then at /mcp on your own domain, ready for the same claude mcp add command. By default it asks for no sign-in, so give it only tools you would be happy to expose as a public API route.