处理器

多处理器组织

通过文件夹约定自动将自动发现的定义归属到多个 MCP 处理器,并为交叉切分场景提供一个基于函数的逃生口。

当你拥有多个命名处理器(/mcp/admin/mcp/apps/mcp/api-v2…)时,通常希望每个工具、资源和提示都恰好落在一个位置,而不需要手动编写过滤器。

这个工具包为你提供了一种机制来归属定义,以及一个逃生口来处理其他所有情况。

A. 文件夹约定(归属的方式)

将命名处理器定义放在 server/mcp/handlers/<name>/ 下。tools/resources/prompts/ 下的每个文件都会通过 _meta.handler 自动附加到该处理器。

server/mcp/
├── tools/                          # → 默认处理器
├── resources/                      # → 默认处理器
├── prompts/                        # → 默认处理器
└── handlers/
    ├── admin/
   ├── index.ts                # defineMcpHandler({ middleware: requireAdmin })
   ├── tools/
   └── delete-user.ts      # → 处理器 'admin'(自动)
   └── prompts/
       └── help.ts             # → 处理器 'admin'(自动)
    └── widgets/
        ├── index.ts                # defineMcpHandler({})
        └── tools/
            └── carousel.ts         # → 处理器 'widgets'(自动)

处理器的 name 会从目录名中推断,并且优先于你在 index.ts 中设置的任何内容。

即使它只有一行,index.ts 也是必需的:export default defineMcpHandler({})。它用于注册 /mcp/<name> 路由,并允许你添加 middlewaredescriptionexperimental_codeMode 等。

B. 函数形式(逃生口)

对于交叉切分的场景——“每个标记了 X 的工具”、“每个孤立项”、“除了这一组之外的所有内容”——传入一个调用 getMcp* 辅助函数之一的函数:

server/mcp/handlers/searchable/index.ts
import { defineMcpHandler, getMcpTools } from '@nuxtjs/mcp-toolkit/server'

export default defineMcpHandler({
  // 每个标记为 'searchable' 的工具,不受文件夹影响。
  tools: event => getMcpTools({ event, tags: ['searchable'] }),
})

getMcpToolsgetMcpResourcesgetMcpPrompts 返回原始定义对象(保留处理器和 Zod schema 不变)——这正是 defineMcpHandler 所期望的。它们接受与对应 listMcp* 方法相同的选项:eventgrouptagshandlerorphansOnly。完整参考请参见 Listing definitions

默认处理器策略

默认的 /mcp 路由会遵循 nuxt.config.ts 中的 mcp.defaultHandlerStrategy

`'orphans'`
default
仅暴露未附加到任何命名处理器的定义。每个定义只会出现在一个地方。
`'all'`
暴露所有已发现的定义(多处理器之前的行为)。当你想在专门路由之外再提供一个“杂烩”路由时很有用。
nuxt.config.ts
export default defineNuxtConfig({
  mcp: {
    defaultHandlerStrategy: 'orphans', //(默认)
  },
})
零成本向后兼容:当没有任何定义使用文件夹约定时,'orphans' 的行为与 'all' 完全一致——因为每个定义都是孤立项,所以都会被暴露。升级后现有应用的行为不会改变。

解析规则

工具包使用一条单一规则、按文件位置确定性地决定每个定义出现在哪里:

处理器配置文件对于 tools | resources | prompts: undefined 的默认行为
server/mcp/index.ts(默认路由)遵循 defaultHandlerStrategy
server/mcp/handlers/<name>/index.ts(文件夹处理器)定义归属到 <name>
server/mcp/<name>.ts(顶层处理器)所有已发现的定义(向后兼容)
任意(数组)按原样使用
任意(函数 (event) => T[]每次请求时调用
“文件夹处理器”和“顶层处理器”之间的区别纯粹取决于文件所在位置——并非魔法。加载器会在文件夹处理器上注入 _meta.handler;运行时读取它以选择默认值。

迁移提示

  1. 先从小处开始。 一次迁移一个处理器到 handlers/<name>/ 中。现有的 tools: [...]tools: ev => [...] 会继续原样工作。
  2. 移除手动过滤器。 如果你之前在做 tools: allTools.filter(t => t._meta?.group === 'apps'),请把这些工具移动到 handlers/apps/tools/,让系统自动为它们归属。
  3. 包装所有内容的处理器。 一个包装每个工具的顶层处理器(例如 mcp/codemode.ts 中的代码模式包装器)会保持当前行为——顶层处理器默认使用完整池。若要过滤,请传入函数:tools: ev => getMcpTools({ event: ev, ... })
  4. 强制旧行为。mcp.defaultHandlerStrategy 设置为 'all',以便在采用文件夹处理器后,/mcp 仍然暴露所有内容。

另请参见