进阶主题
使用 hooks 扩展模块
使用 Nuxt 和 Nitro hooks 来扩展和自定义 MCP 模块。
该工具包提供两种 hooks:
- 构建时 hooks(作用于
NuxtHooks)—— 在nuxt build/nuxt prepare期间触发,可用于注册额外的定义目录。 - 运行时 hooks(作用于
NitroRuntimeHooks)—— 在 每个请求 内、Nitro 插件中触发,用于修改解析后的配置或访问 SDKMcpServer实例。
用户监听器采用尽力而为的方式:若某个 hook 抛出错误,会通过 consola 记录日志,而 MCP 请求会继续执行。
构建时 hooks
mcp:definitions:paths
添加额外目录以扫描工具 / 资源 / prompt / handler 定义。适用于在 Nuxt 层之间共享定义,或从自定义模块中分发这些定义。
Hook 签名
nuxt.hook('mcp:definitions:paths', (paths: {
tools: string[]
resources: string[]
prompts: string[]
handlers: string[]
}) => {
// 原地修改 paths
})
在 nuxt.config.ts 中使用
nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/mcp-toolkit'],
hooks: {
'mcp:definitions:paths'(paths) {
paths.tools.push('shared/tools')
paths.tools.push('legacy/tools')
paths.resources.push('shared/resources')
paths.prompts.push('shared/prompts')
paths.handlers.push('custom/handlers')
},
},
})
在自定义模块中使用
my-module.ts
export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('mcp:definitions:paths', (paths) => {
paths.tools.push('my-module/tools')
paths.resources.push('my-module/resources')
paths.prompts.push('my-module/prompts')
})
},
})
路径结构
{
tools: string[] // 要扫描的工具目录
resources: string[] // 要扫描的资源目录
prompts: string[] // 要扫描的 prompt 目录
handlers: string[] // 要扫描的 handler 目录
}
所有路径都相对于每个 Nuxt 层的 server/ 目录:
- 相对路径,例如
'tools',会解析为server/tools/。 - 以
/开头的绝对路径 会从项目根目录解析。 - 层级相关——每个 Nuxt 层都会相对于其自身的
server/目录解析路径。
运行时 hooks
运行时 hooks 会在 每个 MCP 请求 中,从 Nitro 服务器内部触发。可通过位于 server/plugins/ 的 Nitro 插件订阅这些 hooks。
server/plugins/mcp.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('mcp:server:created', ({ server, event }) => {
// ...
})
})
这些 hooks 的运行顺序如下:
H3 Event
│
▼
defineMcpHandler middleware(如果有)
│
▼
resolveDynamicDefinitions ──► mcp:config:resolved
│
▼
createMcpServer ──► mcp:server:created
│
▼
transport.handleRequest
mcp:config:resolved
在动态 tools / resources / prompts 解析器以及 enabled(event) 守卫运行之后、构建每次请求的 McpServer 之前触发。原地修改 ctx.config,即可仅为当前请求添加、移除或转换定义。
Hook 签名
import type { McpResolvedConfig } from '@nuxtjs/mcp-toolkit/server'
import type { H3Event } from 'h3'
nitroApp.hooks.hook('mcp:config:resolved', (ctx: {
config: McpResolvedConfig
event: H3Event
}) => {
// 原地修改 ctx.config
})
示例:对匿名客户端隐藏管理工具
server/plugins/mcp-auth.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('mcp:config:resolved', ({ config, event }) => {
if (!event.context.user) {
config.tools = config.tools.filter(
tool => !tool.tags?.includes('admin'),
)
}
})
})
示例:按请求重新命名服务器
server/plugins/mcp-rebrand.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('mcp:config:resolved', ({ config, event }) => {
const tenant = event.context.tenant?.name
if (tenant) {
config.name = `${tenant} MCP`
config.instructions = `你已连接到 ${tenant} 的 MCP 服务器。`
}
})
})
mcp:server:created
在 createMcpServer 注册完所有工具 / 资源 / prompt 之后、服务器连接到传输层之前触发。接收 SDK McpServer 实例。
可用于在后期注册定义,或通过 getSdkServer(ctx.server) 访问底层低级别 Server,以安装自定义 JSON-RPC 处理器。
Hook 签名
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import type { H3Event } from 'h3'
nitroApp.hooks.hook('mcp:server:created', (ctx: {
server: McpServer
event: H3Event
}) => {
// 访问 SDK
})
示例:动态注册工具
server/plugins/mcp-whoami.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('mcp:server:created', ({ server, event }) => {
server.registerTool(
'whoami',
{ description: '返回当前用户 ID' },
async () => ({
content: [{
type: 'text',
text: String(event.context.userId ?? 'anonymous'),
}],
}),
)
})
})
示例:为底层 SDK 服务器添加监测
server/plugins/mcp-instrument.ts
import { getSdkServer } from '@nuxtjs/mcp-toolkit/server'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('mcp:server:created', ({ server }) => {
const sdkServer = getSdkServer(server)
sdkServer.oninitialized = () => {
console.log('Client initialized')
}
})
})
需要请求级或会话级状态?请在 hook 内从
event.context 中读取——中间件(以及在 MCP 处理器之前运行的任何认证层)已经将其填充好了。错误处理
抛出错误的监听器会被捕获,并通过 consola(标签 mcp-toolkit)报告:
[error] [mcp-toolkit] Hook "mcp:server:created" 抛出错误 — 请求继续执行
MCP 请求始终会继续进行。如果你需要将错误暴露给客户端,请改为在对应的 tool / resource / prompt handler 中抛出——该工具包会将抛出的错误(包括 H3 errors)转换为符合 MCP 规范的 isError 结果。
后续步骤
- Middleware - 运行每个 MCP 请求的代码,包括
next()拦截。 - Dynamic Definitions - 从
defineMcpHandler中动态选择 tools / resources / prompts。 - Custom Paths - 自定义定义的扫描位置。
- Handlers - 创建多个 MCP 端点。