根目录

Model Context Protocol(MCP)为客户端提供了一种标准化的方式来向服务器暴露文件系统的"根目录"。根目录是客户端文件系统中的特定目录,它们被指定为可供服务器访问的入口点。这种机制使服务器能够以受控和安全的方式访问客户端的文件系统,同时保持客户端对其文件系统的完全控制权。

用户交互模型

MCP 中的根目录通常通过工作区或项目配置界面进行暴露。

例如,实现可以提供一个工作区/项目选择器,允许用户选择服务器可以访问的目录和文件。这可以与版本控制系统或项目文件的自动工作区检测相结合。

然而,实现可以通过任何适合其需求的界面模式来暴露根目录—协议本身并不强制要求特定的用户交互模型。

能力

支持根目录的客户端必须初始化期间声明 roots 能力:

{
  "capabilities": {
    "roots": {
      "listChanged": true
    }
  }
}

listChanged 表示客户端是否会在根目录列表变更时发送通知。

协议消息

列出根目录

服务器通过发送 roots/list 请求获取根目录列表:

请求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "roots/list"
}

响应:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "roots": [
      {
        "uri": "file:///home/user/projects/myproject",
        "name": "我的项目"
      }
    ]
  }
}

根目录列表变更

当根目录列表发生变化时,支持 listChanged 的客户端必须发送通知:

{
  "jsonrpc": "2.0",
  "method": "notifications/roots/list_changed"
}

消息流程

客户端 服务器 客户端 服务器 发现阶段 变更通知 roots/list可用根目录列表notifications/roots/list_changedroots/list更新后的根目录列表

数据结构

根目录定义

根目录定义包含:

  • uri: 根目录的唯一标识符(当前规范中必须是 file:// 格式的URI)
  • name: 可选的人类可读名称(用于显示)

不同使用场景的根目录示例:

项目目录

{
  "uri": "file:///home/user/projects/myproject",
  "name": "我的项目"
}

多仓库配置

[
  {
    "uri": "file:///home/user/repos/frontend",
    "name": "前端仓库"
  },
  {
    "uri": "file:///home/user/repos/backend",
    "name": "后端仓库"
  }
]

错误处理

客户端应该返回标准 JSON-RPC 错误代码:

  • 客户端不支持根目录功能:-32601(方法不存在)
  • 内部错误:-32603

错误示例:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "不支持根目录功能",
    "data": {
      "reason": "客户端未声明 roots 能力"
    }
  }
}

安全考虑

  1. 客户端必须

    • 仅暴露具有适当权限的根目录
    • 验证所有根目录 URI 以防止路径遍历攻击
    • 实施适当的访问控制
    • 监控根目录的可访问性
  2. 服务器应该

    • 处理根目录不可用的情况
    • 在操作中遵守根目录边界
    • 根据提供的根目录验证所有路径

实现指南

  1. 客户端应该

    • 在向服务器暴露根目录前获取用户确认
    • 提供清晰的根目录管理界面
    • 在暴露前验证根目录可访问性
    • 监控根目录变更
  2. 服务器应该

    • 使用前检查 roots 能力支持
    • 优雅处理根目录列表变更
    • 在操作中遵守根目录边界
    • 适当缓存根目录信息