目录

从 Unity MCP 目录结构看透本质:教你从零打造自己的 Model Context Protocol

先问自己:MCP 的核心使命是什么?

拆解 Unity MCP 目录:每个文件夹都是解题步骤

1. 根目录:为什么必须 "桥接 + 服务" 分离?

2. UnityMcpBridge:内部插件的 "五脏六腑"

3. UnityMcpServer:外部服务的 "三板斧"

提炼通用 MCP 开发框架:四步走战略

第一步:明确 "内部插件" 的核心模块

第二步:设计外部服务的分层架构

第三步:定义 "人机友好" 的命令体系

第四步:构建双向反馈闭环

从 "看懂" 到 "动手":开发自己的 MCP 小实验

最后:目录结构是思路的映射


当我们第一次看到一个复杂项目的目录结构时,往往会被密密麻麻的文件夹吓退。但实际上,目录结构就像项目的 "骨架"—— 看懂了骨架的设计逻辑,就掌握了项目的核心思路。

今天我们就以 Unity MCP 项目为标本,通过拆解它的目录结构,提炼出 Model Context Protocol(MCP)的通用设计模式。当你理解了这些底层逻辑,下次面对任何软件(无论是 Blender、Photoshop 还是 VS Code),都能举一反三,打造属于自己的 MCP 解决方案。

先问自己:MCP 的核心使命是什么?

在分析目录结构前,我们必须明确 MCP 的本质 —— 它不是简单的 "API 封装",而是让自然语言模型理解软件状态、操控软件功能的 "翻译层"。这个核心使命决定了任何 MCP 实现都必须包含三个关键能力:

  1. 状态感知:能获取软件当前的状态(比如 Unity 场景里有哪些物体)
  2. 命令执行:能将自然语言转化为软件可执行的命令(比如 "创建一个立方体")
  3. 双向通信:能在语言模型与软件之间传递信息(确保命令准确、结果可反馈)

带着这三个核心能力再看 Unity MCP 的目录结构,你会发现每一个文件夹的存在都有其必然性。

拆解 Unity MCP 目录:每个文件夹都是解题步骤

1. 根目录:为什么必须 "桥接 + 服务" 分离?

unity-mcp-master/
├── UnityMcpBridge/   # Unity 内部桥接
├── UnityMcpServer/   # 外部服务层

设计逻辑:这是 MCP 最关键的 "双核心" 架构。

  • UnityMcpBridge 必须嵌入软件内部(Unity 编辑器),因为只有内部组件才能直接调用软件 API、获取实时状态(比如场景数据、选中物体)。
  • UnityMcpServer 必须作为独立服务,因为语言模型(如 Claude)通常运行在外部进程,需要一个中间层处理协议解析、跨进程通信。

自己开发时的启示:无论你要对接什么软件,都必须区分 "内部插件" 和 "外部服务"。内部插件负责 "接地气"(调用软件 API),外部服务负责 "通云端"(对接语言模型)。比如要做 Blender MCP,就需要一个 Blender 插件(用 Python)+ 一个独立服务(可选任何语言)。

2. UnityMcpBridge:内部插件的 "五脏六腑"

UnityMcpBridge/
├── package.json              # 包配置
├── Editor/                   # 编辑器脚本
│   ├── UnityMcpBridge.cs     # 主通信入口
│   ├── Data/                 # 配置数据
│   ├── Helpers/              # 工具类
│   ├── Models/               # 数据模型
│   ├── Tools/                # 功能实现
│   └── Windows/              # 交互窗口

这个目录结构完美对应了 "内部插件" 的核心职责:连接内部 API + 处理通信 + 暴露可控功能

  • package.json:Unity 包管理配置,告诉 Unity 这是一个编辑器扩展。自己开发时,对应软件的插件格式(比如 Blender 的 .addon,VS Code 的 package.json)。

  • Editor/ 根目录

    • UnityMcpBridge.cs 是 "通信枢纽",负责与外部服务器建立 TCP 连接,接收命令并转发给内部工具 —— 这是所有 MCP 内部插件的 "必选组件",哪怕你用 HTTP 而非 TCP,也需要一个类似的入口类。
  • Data/:存储默认配置(如服务器地址、支持的客户端)。自己开发时,这里可以放软件特有的基础配置(比如 Blender 的默认材质库路径)。

  • Helpers/:通用工具类,比如 Vector3Helper 处理 3D 向量转换(Unity 里向量是 (x,y,z),语言模型更易理解 "位置" 描述)。这提示我们:MCP 必须处理 "软件数据格式" 与 "自然语言表达" 的转换,比如 Photoshop 里的图层 ID 要转换为 "背景层"" 文字层 " 这样的自然语言描述。

  • Models/:定义核心数据结构,尤其是 Command.cs(命令模型)。这里藏着 MCP 的 "语法规则"—— 命令应该包含哪些字段(操作类型、参数、上下文 ID 等)?自己设计时,命令模型要兼顾两点:机器能解析(清晰的结构)+ 模型能生成(符合自然语言习惯的参数名)。

  • Tools/:按功能划分的具体实现(如 ManageGameObject.cs 处理物体操作)。这是 MCP 的 "功能仓库",也是最需要根据目标软件定制的部分。Unity MCP 选择了 6 个核心功能(资源、场景、游戏对象等),我们自己开发时,也应该从软件最常用的 5-10 个功能起步(比如给 PS 做 MCP,先实现图层管理、选区操作、滤镜应用)。

  • Windows/:编辑器交互窗口,提供手动配置界面。这是 "用户友好性" 的关键 —— 再强大的技术,用户不会配置也白搭。自己开发时,至少需要一个 "连接状态窗口" 和 "功能配置窗口"。

3. UnityMcpServer:外部服务的 "三板斧"

UnityMcpServer/src/
├── server.py           # 主服务入口
├── config.py           # 服务配置
├── unity_connection.py # 连接管理
├── tools/              # 命令映射

外部服务的职责更聚焦:对接语言模型 + 转发命令 + 处理跨进程通信

  • server.py:基于 FastMCP 框架的服务入口,定义了 MCP 协议的实现(如何解析客户端请求、如何调用工具)。自己开发时,框架可选(FastAPI、Flask 甚至 Node.js 的 Express),但核心是要实现一套 "协议解析逻辑"。

  • unity_connection.py:专门处理与 Unity 内部插件的连接。这体现了 "单一职责原则"—— 连接管理独立于业务逻辑,便于维护(比如以后想支持 WebSocket,只需修改这里)。

  • tools/:与 UnityMcpBridge/Tools 一一对应的命令映射(如 manage_gameobject.py)。为什么要在服务端再做一层映射?因为语言模型可能发送更抽象的指令("放个东西在地上"),服务端可以先做一层转换("地上"→(0,0,0) 坐标),再发给内部插件。这是优化语言模型交互体验的关键

提炼通用 MCP 开发框架:四步走战略

通过分析 Unity MCP 的目录结构,我们可以总结出开发任何 MCP 的通用框架。下次你想给某款软件做 MCP,只需按这四步拆解任务:

第一步:明确 "内部插件" 的核心模块

无论目标软件是什么,内部插件必须包含:

模块 作用 对应 Unity MCP 实现
通信模块 与外部服务建立连接 UnityMcpBridge.cs
状态获取模块 收集软件当前状态(如选中物体、场景信息) Models + Helpers
命令执行模块 将接收到的命令转化为软件操作 Tools 目录
配置模块 存储服务地址、功能开关等 Data 目录

开发技巧:先实现 "命令执行模块" 的最小集(比如只支持创建 / 删除对象),跑通流程后再扩展功能。

第二步:设计外部服务的分层架构

外部服务的核心是 "协议处理" 和 "命令转发",推荐分层:

  1. 协议层:定义请求 / 响应格式(参考 Unity MCP 的 Command 模型),处理序列化 / 反序列化。
  2. 路由层:将不同命令分发到对应的处理函数(参考 Unity MCP 的 CommandRegistry)。
  3. 转换层:将自然语言友好的参数转换为软件需要的格式(比如 "红色"→#FF0000 色值)。
  4. 连接层:管理与内部插件的通信(TCP/HTTP/WebSocket 等)。

Unity MCP 的 server.py + tools/ 完美实现了这四层,你可以直接复用这个架构。

第三步:定义 "人机友好" 的命令体系

命令设计是 MCP 的灵魂,从 Unity MCP 能学到三个原则:

  1. 功能模块化:按软件功能划分命令组(如 Unity 的 "场景操作"" 物体管理 "),对应目录里的 Tools 子文件夹。
  2. 参数自然化:避免软件内部的技术术语(比如不用 "GameObject",而用 "物体"),参数格式要符合语言模型的表达习惯(如向量用 [x,y,z] 而非自定义结构)。
  3. 支持上下文:命令中预留 "上下文 ID" 字段(如当前选中的物体 ID),让语言模型能理解 "把它移到左边" 中的 "它" 指什么。

第四步:构建双向反馈闭环

MCP 不是 "一发即忘" 的命令行,而是需要反馈的交互系统:

  • 执行结果必须返回给语言模型(成功 / 失败原因、操作后的状态变化)。
  • 定期主动推送关键状态变化(如用户手动修改了场景,需要同步给模型)。

Unity MCP 通过 Response 模型和 McpStatus 实现了这一点,你的 MCP 也需要类似的反馈机制。

从 "看懂" 到 "动手":开发自己的 MCP 小实验

如果你想快速验证,可以做一个 "记事本 MCP" 小项目:让 AI 能通过自然语言操控记事本(新建文件、写入内容、保存)。

  1. 内部插件:用 Python 写一个记事本插件(监听本地端口,调用记事本 API)。
  2. 外部服务:用 FastAPI 搭一个简单服务,接收自然语言指令(如 "写一段 hello world 到 test.txt")。
  3. 命令模型:定义简单的命令格式(如 {"action": "write", "path": "test.txt", "content": "hello"})。

这个小实验能帮你理解 MCP 的核心流程,再迁移到复杂软件就会轻松很多。

最后:目录结构是思路的映射

当你下次打开一个开源项目,先别急着看代码,先画一张目录结构图。每个文件夹的命名、层级关系,都在告诉你开发者的设计思路。

Unity MCP 的目录结构之所以清晰,是因为它的每个模块都对应着 MCP 必须解决的问题:如何通信?如何执行命令?如何让 AI 理解软件状态?

理解了这些问题,你不仅能开发自己的 MCP,更能看透任何复杂系统的设计本质 —— 这才是 "以小见大" 的终极意义。

现在,选一个你最常用的软件,试着画出它的 MCP 目录结构吧。第一个命令,你想让 AI 帮你实现什么功能?

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐