MCP Server
关于 MCP Server
每个 Movk Nuxt Docs 实例内置 Model Context Protocol (MCP) 服务器,任何 MCP 客户端(Claude、Cursor、VS Code 等)均可连接。
当连接到 AI 工具时,LLM 能够根据对话上下文智能地判断何时需要访问文档工具,从而在开发过程中为您提供更准确的文档引用和技术支持。
访问您的 MCP 服务器
您的 MCP 服务器可通过文档网址的 /mcp 路径自动访问。
https://docs.example.com,则您的 MCP 服务器 URL 为 https://docs.example.com/mcp。配置选项
禁用 MCP 服务器
在 nuxt.config.ts 中禁用 MCP 服务器:
export default defineNuxtConfig({
mcp: {
enabled: false
}
})
自定义服务器名称
export default defineNuxtConfig({
mcp: {
name: 'My Docs'
}
})
可用资源
Movk Nuxt Docs MCP 服务器提供以下资源供发现:
resource://docs/components: 浏览所有可用组件及其类别resource://docs/composables: 浏览所有可用组合函数及其类别resource://docs/examples: 浏览所有可用代码示例resource://docs/documentation-pages: 浏览所有可用文档页面
可用工具
Movk Nuxt Docs MCP 服务器提供以下按类别组织的工具:
搜索工具
search-composables: 通过名称或描述搜索组合函数。无参数时列出所有组合函数search-icons: 在 Iconify 集合中搜索图标(默认为lucide)。返回i-{prefix}-{name}格式的图标名称
组件工具
get_component: 获取组件文档和详细信息。支持sections参数(usage、examples、api、theme、changelog)以仅获取特定部分并减少响应大小get_component_metadata: 获取组件的详细元数据,包括 props、slots 和 events(轻量级,无文档内容)
文档工具
search_documentation: 通过标题、描述或部分搜索文档页面。无参数时列出所有页面。使用section过滤(例如"getting-started"、"components")get_documentation_page: 通过 URL 路径获取文档页面内容。支持headings参数仅获取特定 h2 部分(例如["Usage", "API"])并减少响应大小
示例工具
list_examples: 列出所有可用的示例和代码演示get_example: 获取特定示例的实现代码和详细信息
可用 Prompts
Movk Nuxt Docs MCP 服务器提供以下用于常见工作流的引导式 Prompt:
find_component_for_usecase: 根据具体使用场景推荐合适的组件implement_component_with_props: 基于组件文档和元数据生成完整实现示例
在支持 Prompt 的 MCP 客户端中,可通过 / 等方式直接调用这些 Prompt。
设置指南
MCP 服务器采用 HTTP 传输协议,可安装于不同 AI 助手中。
Claude Code
使用 CLI 命令添加服务器:
claude mcp add --transport http my-docs https://docs.example.com/mcp
Claude Desktop
- 打开 Claude Desktop,前往「Settings」>「Developer」
- 点击「Edit Config」,这将打开本地 Claude 目录
- 使用自定义 MCP 服务器配置修改
claude_desktop_config.json文件:
{
"mcpServers": {
"my-docs": {
"command": "npx",
"args": [
"mcp-remote",
"https://docs.example.com/mcp"
]
}
}
}
- 重启 Claude Desktop 应用
Cursor
或者在项目根目录创建或更新 .cursor/mcp.json:
{
"mcpServers": {
"my-docs": {
"type": "http",
"url": "https://docs.example.com/mcp"
}
}
}
Visual Studio Code
或者在项目的 .vscode 文件夹中创建或编辑 mcp.json 文件:
{
"servers": {
"my-docs": {
"type": "http",
"url": "https://docs.example.com/mcp"
}
}
}
ChatGPT
- 启用开发者模式:前往设置 → Connectors → Advanced settings → Developer mode
- 打开 ChatGPT 设置
- 在 Connectors 选项卡中,创建新连接器:
- 名称:
My Docs - MCP server URL:
https://docs.example.com/mcp - 认证:
None
- 名称:
- 点击创建
My Docs 连接器将在对话期间出现在撰写器的「开发者模式」工具中。
Opencode
在项目根目录创建 opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"my-docs": {
"type": "remote",
"url": "https://docs.example.com/mcp",
"enabled": true
}
}
}
使用示例
配置完成后,您可以向 AI 助手提出如下问题,它们将自动使用 MCP 服务器查询文档:
- "列出所有可用的组件"
- "获取 Button 组件的文档"
- "只显示 Button 的使用示例"
- "Input 组件接受哪些 props?"
- "找出与表单相关的组件"
- "在 lucide 图标集中搜索箭头图标"
- "显示安装指南"
- "列出所有示例"
- "获取 SearchForm 示例代码"
AI 助手将在生成响应时主动搜索文档,根据对话上下文智能判断何时需要查询工具,为您提供准确的文档引用和技术支持。
sections 参数(usage、examples、api、theme、changelog)仅获取相关部分。对于其他页面,使用 headings 参数指定 h2 标题(例如 ["Usage", "API"])。自定义扩展
您可以通过添加自定义工具、资源和 Prompt 来扩展 MCP 服务器的能力。
自定义工具
在 server/mcp/tools/ 目录中创建自定义工具文件:
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'
export default defineMcpTool({
description: '按关键词搜索组件文档',
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false
},
inputSchema: {
search: z.string().describe('搜索关键词')
},
inputExamples: [
{ search: 'table' },
{ search: 'theme' }
],
cache: '30m',
async handler({ search }) {
const event = useEvent()
const searchLower = search.toLowerCase()
const components = await queryCollection(event, 'docs')
.where('path', 'LIKE', '%/components/%')
.where('extension', '=', 'md')
.select('title', 'description', 'path', 'category')
.all()
const results = components.filter(component =>
component.title?.toLowerCase().includes(searchLower)
|| component.description?.toLowerCase().includes(searchLower)
)
return {
components: results,
total: results.length,
search
}
}
})
自定义资源
在 server/mcp/resources/ 目录中创建可被发现的资源:
import { queryCollection } from '@nuxt/content/server'
export default defineMcpResource({
uri: 'resource://docs/navigation',
description: '完整的文档导航结构',
cache: '1h',
async handler(uri: URL) {
const event = useEvent()
const pages = await queryCollection(event, 'docs')
.select('title', 'description', 'path', 'navigation')
.all()
const navigation = pages
.filter(page => page.navigation !== false)
.map(page => ({
title: page.title,
description: page.description,
path: page.path
}))
return {
contents: [{
uri: uri.toString(),
mimeType: 'application/json',
text: JSON.stringify(navigation, null, 2)
}]
}
}
})
资源示例与本项目现有实现一致,显式声明 uri、description 和 handler,由处理函数返回 contents。
自定义提示
在 server/mcp/prompts/ 目录中创建可重用的提示:
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'
export default defineMcpPrompt({
description: '根据使用场景推荐合适的文档页面',
inputSchema: {
usecase: z.string().describe('要解决的使用场景')
},
async handler({ usecase }) {
const event = useEvent()
const pages = await queryCollection(event, 'docs')
.select('title', 'description', 'path')
.all()
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `请根据这个使用场景推荐最相关的文档页面:"${usecase}"。\n\n候选页面:${JSON.stringify(pages, null, 2)}`
}
}],
}
}
})
添加自定义处理程序
可以在 server/mcp/ 目录下创建自定义处理器:
import { z } from 'zod'
const migrationTool = defineMcpTool({
description: '将旧版配置片段迁移为新版格式',
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false
},
inputSchema: {
code: z.string().describe('要迁移的配置代码')
},
async handler({ code }) {
const migrated = code
.replace(/oldOption/g, 'newOption')
.replace(/legacyTheme/g, 'theme')
return {
original: code,
migrated
}
}
})
export default defineMcpHandler({
name: 'migration',
version: '0.1.0',
route: '/mcp/migration',
tools: [migrationTool],
browserRedirect: '/',
})
覆盖默认工具
要覆盖内置的工具,只需在 server/mcp/tools/ 目录中创建同名文件即可。
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'
export default defineMcpTool({
description: '自定义文档搜索实现',
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false
},
inputSchema: {
search: z.string().optional().describe('标题或描述中的搜索词'),
section: z.string().optional().describe('文档分组,如 getting-started 或 components')
},
async handler({ search, section }) {
const event = useEvent()
let query = queryCollection(event, 'docs')
.select('title', 'description', 'path')
if (section) {
query = query.where('path', 'LIKE', `/docs/${section}/%`)
}
const pages = await query.all()
const searchLower = search?.toLowerCase()
const results = pages.filter(page =>
!searchLower
|| page.title?.toLowerCase().includes(searchLower)
|| page.description?.toLowerCase().includes(searchLower)
)
return {
pages: results,
total: results.length
}
}
})