diff --git a/docs/3.upgrading-to-v4.md b/docs/3.upgrading-to-v4.md
index aa79273a18..c4f95d2b4d 100644
--- a/docs/3.upgrading-to-v4.md
+++ b/docs/3.upgrading-to-v4.md
@@ -130,6 +130,7 @@ The generic _open in editor_ action (from component and file links) is unaffecte
- `vueDevTools` (default `true`) — set to `false` to skip the Vue DevTools dock.
- `dataInspector` (default `true`) — set to `false` to skip the Data Inspector panel and its `Nuxt Application` source.
- `disableAuthorization` (default: on in sandboxes) — skips the authorization prompt described above.
+- `mcp` (default `'auto'`) — set to `false` to turn off the MCP endpoint that lets AI agents use DevTools.
## Deprecation warnings in your terminal
diff --git a/docs/index.md b/docs/index.md
index 182ccaf46e..86f3eae036 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -90,18 +90,19 @@ export default defineNuxtConfig({
})
```
-| Option | Default | Description |
-| ------------------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
-| `enabled` | `true` | Enable Nuxt DevTools. |
-| `componentInspector` | `true` | Inspect the DOM to find the component rendering it. |
-| `vueDevTools` | `true` | Register the Vue DevTools dock next to the `Nuxt` group. |
-| `viteInspect` | `true` | Register the [Inspect](/modules/devtools/features#inspect) dock, or its install launcher. |
-| `dataInspector` | `true` | Register the [Data Inspector](/modules/devtools/features#data-inspector) panel. |
-| `codeServer` | | [Code Server](/modules/devtools/features#code-server) options; `codeServer.enabled: false` removes it. |
-| `timeline` | | [Timeline](/modules/devtools/features#timeline) options; `timeline.enabled` defaults to `false`. |
-| `assets.uploadExtensions` | | File extensions the [Assets](/modules/devtools/features#assets) panel accepts for upload, or `'*'` for any. |
-| `disableAuthorization` | | Skip the browser authorization prompt. On by default in sandboxes. |
-| `telemetry` | | Anonymous telemetry. Follows your Nuxt telemetry setting; set to `false` to opt out. |
+| Option | Default | Description |
+| ------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- |
+| `enabled` | `true` | Enable Nuxt DevTools. |
+| `componentInspector` | `true` | Inspect the DOM to find the component rendering it. |
+| `vueDevTools` | `true` | Register the Vue DevTools dock next to the `Nuxt` group. |
+| `viteInspect` | `true` | Register the [Inspect](/modules/devtools/features#inspect) dock, or its install launcher. |
+| `dataInspector` | `true` | Register the [Data Inspector](/modules/devtools/features#data-inspector) panel. |
+| `codeServer` | | [Code Server](/modules/devtools/features#code-server) options; `codeServer.enabled: false` removes it. |
+| `timeline` | | [Timeline](/modules/devtools/features#timeline) options; `timeline.enabled` defaults to `false`. |
+| `assets.uploadExtensions` | | File extensions the [Assets](/modules/devtools/features#assets) panel accepts for upload, or `'*'` for any. |
+| `disableAuthorization` | | Skip the browser authorization prompt. On by default in sandboxes. |
+| `mcp` | `'auto'` | Expose the Vite DevTools [MCP](https://modelcontextprotocol.io) endpoint for AI agents; `false` turns it off. |
+| `telemetry` | | Anonymous telemetry. Follows your Nuxt telemetry setting; set to `false` to opt out. |
For every option, see the TSDocs in your IDE or the [type definition file](https://github.com/nuxt/devtools/blob/main/packages/devtools-kit/src/_types/options.ts).
diff --git a/packages/devtools-kit/src/_types/options.ts b/packages/devtools-kit/src/_types/options.ts
index ecaa2c6d32..798fa26c67 100644
--- a/packages/devtools-kit/src/_types/options.ts
+++ b/packages/devtools-kit/src/_types/options.ts
@@ -77,6 +77,22 @@ export interface ModuleOptions {
*/
disableAuthorization?: boolean
+ /**
+ * Expose the Vite DevTools MCP endpoint (`/__devtools/__mcp`), which
+ * lets AI agents call the DevTools' agent tools over the Model Context
+ * Protocol.
+ *
+ * - `'auto'`: mount the endpoint once any DevTools integration exposes an
+ * agent tool.
+ * - `true`: always mount it.
+ * - `false`: never mount it.
+ *
+ * Same as setting `vite.devtools.mcp`, which takes precedence.
+ *
+ * @default 'auto'
+ */
+ mcp?: boolean | 'auto'
+
/**
* Experimental features
*/
diff --git a/packages/devtools/src/module-main.ts b/packages/devtools/src/module-main.ts
index 639079a5df..0acca022ad 100644
--- a/packages/devtools/src/module-main.ts
+++ b/packages/devtools/src/module-main.ts
@@ -69,14 +69,22 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
await nuxt.callHook('devtools:before')
+ // Vite DevTools options Nuxt DevTools provides. They only fill in what the
+ // user left unset in `vite.devtools`, and are applied in one place below so
+ // both the Vite 8.3+ integration and the manual `DevTools()` plugin see them.
+ const viteDevToolsDefaults: DevToolsConfig = {}
+
// `disableAuthorization` disables the Vite DevTools client-auth prompt. The
// resolved value is used (default `isSandboxed`), so sandboxes keep
// auto-bypassing the prompt.
- if (options.disableAuthorization) {
- extendViteDevToolsConfig((devtools) => {
- devtools.clientAuth ??= false
- })
- }
+ if (options.disableAuthorization)
+ viteDevToolsDefaults.clientAuth = false
+
+ // `mcp` controls the aggregate MCP endpoint (`__mcp`) Vite DevTools
+ // mounts over every devframe's agent tools. Left `undefined` it follows
+ // Vite DevTools' own default (`'auto'`).
+ if (options.mcp !== undefined)
+ viteDevToolsDefaults.mcp = options.mcp
// Route the client-auth banner through Nuxt's terminal host where this Nuxt
// has one (`useTerminal`, @nuxt/kit >= 4.6): the Nuxt CLI 4 TUI shows a
@@ -86,10 +94,8 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
const kit = await import('@nuxt/kit')
if ('useTerminal' in kit) {
const { banner, onTrusted } = createTerminalAuthBanner(kit.useTerminal)
- extendViteDevToolsConfig((devtools) => {
- devtools.banner ??= banner
- devtools.onTrusted ??= onTrusted
- })
+ viteDevToolsDefaults.banner = banner
+ viteDevToolsDefaults.onTrusted = onTrusted
}
// Make unimport exposing more information, like the usage of each auto imported function
@@ -160,18 +166,23 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
windowTitle: 'Nuxt DevTools',
}
+ viteDevToolsDefaults.branding = branding
+
// Vite 8.3+ registers the Vite DevTools integration itself from the
// top-level `devtools` config option (vitejs/vite#23333), which keeps the
// toggle in user hands (`vite: { devtools: false }` in `nuxt.config`).
// Older Vite has no serve-mode integration, so fall back to installing the
- // `DevTools()` plugin manually.
+ // `DevTools()` plugin manually. That plugin resolves its config from its own
+ // options and overwrites `config.devtools`, so the defaults must be passed
+ // to it directly.
if (isGreaterThanOrEqual(viteVersion, '8.3.0')) {
extendViteDevToolsConfig((devtools) => {
- devtools.branding ??= branding
+ for (const [key, value] of Object.entries(viteDevToolsDefaults))
+ (devtools as Record)[key] ??= value
})
}
else {
- const DevTools = await import('@vitejs/devtools').then(r => r.DevTools({ branding }))
+ const DevTools = await import('@vitejs/devtools').then(r => r.DevTools(viteDevToolsDefaults))
addVitePlugin(DevTools)
}
diff --git a/skills-lock.json b/skills-lock.json
index ac14d15a02..d7ce4f62b0 100644
--- a/skills-lock.json
+++ b/skills-lock.json
@@ -39,14 +39,14 @@
"source": "mattpocock/skills",
"sourceType": "github",
"skillPath": "skills/engineering/code-review/SKILL.md",
- "computedHash": "57cfd4ceb011f05e58a1a4f4cad3b2e03419d371f8990f4bcb32ff0d435a039f",
+ "computedHash": "c2745e2be960b82b9fddd82cf45265f42431e7b045c403f297b25f0f311e9210",
"via": "@antfu/skills"
},
"codebase-design": {
"source": "mattpocock/skills",
"sourceType": "github",
"skillPath": "skills/engineering/codebase-design/SKILL.md",
- "computedHash": "b2888e4f4e8c0af3bfd557575a64b905c44e6248c3101d72077816882b3a92b9",
+ "computedHash": "aa11a96c08451f4ff86052d5da94004a8c97bb4ea41b2ac8a4300c189f66c89c",
"via": "@antfu/skills"
},
"create-adaptable-composable": {
@@ -95,7 +95,7 @@
"source": "mattpocock/skills",
"sourceType": "github",
"skillPath": "skills/productivity/grilling/SKILL.md",
- "computedHash": "ef1641a2047b71b60f1942cd35efb47d3afc9d584dff5a0b01f8c7db923aaa08",
+ "computedHash": "e40cc1d348f6d935e28f1e24474302d7368f0a400429271a43b35fe154891dc5",
"via": "@antfu/skills"
},
"handoff": {
@@ -137,7 +137,7 @@
"source": "mattpocock/skills",
"sourceType": "github",
"skillPath": "skills/engineering/research/SKILL.md",
- "computedHash": "c8c1cba327a6f824b554cd978079a3dadd7406d73174f8fb9bfef58824691970",
+ "computedHash": "5d85b64ecceed6b3f6d5996dc8af07180be8d1ff11ef3d26eda2acff078fbd39",
"via": "@antfu/skills"
},
"simple-english": {