ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MCP for Unity `execute_custom_tool` 深度解析:项目级自定义工具的注册、路由与轮询执行

MCP for Unity `execute_custom_tool` 深度解析:项目级自定义工具的注册、路由与轮询执行 MCP for Unityexecute_custom_tool深度解析项目级自定义工具的注册、路由与轮询执行【免费下载链接】unity-mcpUnity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.项目地址: https://gitcode.com/GitHub_Trending/un/unity-mcpexecute_custom_tool是 MCP for Unity 服务器中用于调用 Unity 项目自定义工具的通用入口工具它把Unity 侧通过 C# 属性声明的工具与AI 助手/MCP 客户端侧的名称 参数调用连接起来。本文以该工具为主线结合仓库源码讲清它的参数契约、底层执行链路、项目作用域隔离机制、长任务轮询协议并给出从 C# 工具定义到 CLI 调用的完整实战方案。读完你既能直接调用execute_custom_tool也能理解它背后如何完成工具发现、实例路由、用户隔离与超时保护。工具定位一个调用任意 Unity 自定义工具的通用网关在 MCP for Unity 中AI 助手能操作场景、管理资产、执行编辑器命令靠的是服务器侧预先注册的一批工具如manage_gameobject、manage_scene。但这些是内置工具能力边界固定。要让 AI 调用你自己写的、属于某个具体 Unity 项目的工具就需要一个动态网关——这正是execute_custom_tool的角色。它的官方定义关联参考文档只有一句话Execute a project-scoped custom tool registered by Unity.执行一个由 Unity 注册的、项目作用域内的自定义工具归属于core工具组、模块为services.tools.execute_custom_tool。文档同时注明该页由 Python 工具注册表自动生成生成器为 tools/generate_docs_reference.py可见它并不是手写功能页而是对真实可调用工具的自动索引——真正完整的行为说明在服务端源码与 自定义工具指南 中。从源码看该工具本身只是一个薄网关它从 MCP 上下文解析当前活跃的 Unity 实例再把参数转交给CustomToolService完成真正的执行execute_custom_tool.py。装饰器mcp_for_unity_tool将其注册进工具注册表Server/src/services/registry/tool_registry.py并带有ToolAnnotations(titleExecute Custom Tool, destructiveHintTrue)向客户端标注这是一个可能产生破坏性副作用的工具。参数契约tool_name与parameters参考文档给出的参数表如下名称类型必填说明tool_namestr是要执行的自定义工具名称必须与 Unity 侧注册的名称完全一致parametersdict[str, Any] \| None否传给工具的参数对象无参数工具可省略传None两个参数的行为在源码中有明确处理逻辑tool_name大小写敏感它是查询工具定义的精确键。在 custom_tool_service.py 中get_tool_definition(project_id, tool_name)直接从self._project_tools[project_id]字典按名查找查不到会返回MCPResponse(successFalse, messageTool name not found for project id)。parameters为None的兼容处理execute_custom_tool.py 中特别说明签名允许None面向无参数工具因此None会被归一化为空字典{}而不是直接拒绝但如果传入的不是 dict例如字符串、列表则返回parameters must be an object/dictionary的失败响应。这是对可选参数类型语义的一次显式修正。调用该工具的典型 JSON 形态MCP tools/call 协议{ name: execute_custom_tool, arguments: { tool_name: capture_screenshot, parameters: { filename: scene_01, width: 1920, height: 1080 } } }返回值统一的MCPResponse结构文档声明返回包含 Unity 响应的dict具体形状取决于动作。服务端将所有自定义工具响应统一收敛为MCPResponse模型models.py字段类型含义successbool是否成功轮询状态为error或命令失败时为falsemessagestr \| None人类可读的消息成功/失败说明errorstr \| None错误详情dataAny \| None工具返回的结构化数据如截图路径、进度状态hintstr \| None给客户端的处理提示如retryUnity 正在重载应礼貌重试转换逻辑在_normalize_responsecustom_tool_service.pyUnity 返回的 dict 中success、message、error、data会被逐一映射若响应中同时没有success与_mcp_status字段则整个响应体被当作data原样透传响应含_mcp_status error时success强制置为false非 dict 响应如纯字符串则包装为successFalse的失败结果。因此无论 Unity 工具返回什么形状AI 助手拿到的都是稳定的四字段结构便于统一解析。底层执行链路从实例解析到命令下发execute_custom_tool的完整调用链如下对应 execute_custom_tool.py 与 custom_tool_service.py解析活跃 Unity 实例get_unity_instance_from_context(ctx)从 MCP 上下文读取Namehash形式的实例标识若为空返回提示No active Unity instance. Call set_active_instance with Namehash from mcpforunity://instances.——这是调用任何 Unity 侧工具的前置条件。解析项目 IDresolve_project_id_for_unity_instance将实例映射为project_id。stdio 传输下通过连接池discover_all_instances()按名称与 hash 前缀匹配实例优先返回 Unity 上报的原生project_hashcustom_tool_service.pyHTTP/WebSocket 传输下则借助PluginHub的_hash_to_project映射兜底。解析失败同样返回失败响应提示Ensure Unity is running and reachable.。查询工具定义get_tool_definition依次查项目级工具表 → 全局工具表 →PluginHub远程插件注册的工具三种来源任一命中即返回ToolDefinitionModelcustom_tool_service.py。下发命令send_with_unity_instance(async_send_command_with_retry, unity_instance, tool_name, params, user_id...)将命令发往对应 Unity 实例带重试能力Server/src/transport/legacy/unity_connection.py。按定义决定返回方式若工具定义requires_polling为假直接归一化响应返回否则进入轮询流程见下节。项目作用域为什么叫 project-scoped文档描述中的关键词project-scoped项目作用域是理解安全模型的核心。Unity 侧通过[McpForUnityTool]特性定义的工具会被插件扫描并注册到服务器注册时携带项目信息服务器按project_id分桶保存self._project_tools: dict[str, dict[str, ToolDefinitionModel]]见 custom_tool_service.py。注册通道有两条HTTP 路由/register-toolsPOSTUnity 插件把{project_id, project_hash, tools[]}以RegisterToolsPayload提交服务端返回ToolRegistrationResponse其中registered为新注册的工具、replaced为同名覆盖的工具custom_tool_service.py。WebSocketregister_tools消息经由PluginHub的_handle_register_tools处理按会话session维度记录工具并可通过sync_tool_visibility_from_unity在 stdio 模式下同步工具可见性plugin_hub.py。每个工具的定义结构ToolDefinitionModelmodels.py包含字段默认值含义name—工具名即execute_custom_tool的tool_namedescriptionNone给 AI 助手的工具说明structured_outputTrue是否输出结构化结果requires_pollingFalse是否长任务轮询模式poll_actionstatus轮询时携带的 action 名max_poll_seconds00 表示使用默认 600s轮询超时上限parameters[]ToolParameterModel列表名称、描述、类型、是否必填、默认值由此可推断工具发现是按项目隔离、按名称寻址的——同一个工具名在不同 Unity 项目中可以有不同的实现与参数AI 必须先选定实例set_active_instanceexecute_custom_tool才能解析到正确的项目作用域。长任务轮询pending / complete / error 协议自定义工具若耗时较长如烘焙光照、跑测试、打构建且可能触发 Unity 域重载可声明为轮询工具C# 侧RequiresPolling true, PollAction status。服务器侧的执行策略在 custom_tool_service.py首次调用返回后检查_mcp_status字段complete/error/ 非 dict 响应 / 无状态字段的非空 dict → 视为终态立即归一化返回pending→ 依据_mcp_poll_interval休眠后重发actionpoll_action的轮询请求None响应或空 dict{}→ 视为仍在工作按默认间隔继续轮询。间隔钳制_mcp_poll_interval会被限制在0.1s ~ 5.0s之间custom_tool_service.py防止过频请求打爆 Unity也避免响应迟缓网络瞬时异常时按min(interval*2, 5.0)退避重试。超时保护默认上限_MAX_POLL_SECONDS 60010 分钟工具定义中的max_poll_seconds可覆盖超时返回successFalse的Timeout waiting for tool to complete并附上最后一次响应_safe_response供排查。Unity 侧对应的轮询协议在 自定义工具指南 中有完整示例工具启动时返回PendingResponse实现Status方法返回_mcp_status为pending/complete/error的字典并用McpJobStateStoreMcpJobStateStore.cs把进度持久化到Library/目录以抵御域重载。实战从 C# 工具到 CLI 调用第一步在 Unity 中定义自定义工具在任意Editor/文件夹下新建 C# 文件用[McpForUnityTool]特性标记静态类HandleCommand(JObject)处理入参完整示例见 custom-tools.md[McpForUnityTool(capture_screenshot, Description Capture screenshots in Unity, saving them as PNGs)] public static class CaptureScreenshotTool { public class Parameters { [ToolParameter(Screenshot filename without extension)] public string filename { get; set; } [ToolParameter(Width in pixels, Required false)] public int? width { get; set; } } public static object HandleCommand(JObject params) { var p params.ToObjectParameters(); // ... 截图逻辑成功后返回 SuccessResponse return new SuccessResponse($Screenshot saved, new { path ..., width p.width }); } }第二步刷新 MCP 客户端服务器能动态注册工具但并非所有客户端都会自动感知变化。最稳妥的方式是断开并重连 MCP 服务器强制重新发现工具部分客户端如 Windsurf 需要删除后重新配置见 custom-tools.md。第三步用 CLI 列出并调用列出当前活跃项目的自定义工具unity-mcp tool list unity-mcp custom_tool list # 别名tool list在命令行工具组中的实现见 cli/commands/tool.py其底层调用run_list_custom_toolscli/utils/connection.py实际走的正是mcpforunity://custom-tools资源custom_tools.py——返回project_id、tool_count与工具定义列表。调用自定义工具unity-mcp editor custom-tool capture_screenshot unity-mcp editor custom-tool capture_screenshot --params {filename:scene_01,width:1920}editor custom-tool命令cli/commands/editor.py会把--paramsJSON 字符串默认{}解析成字典后以{tool_name: ..., parameters: {...}}调用execute_custom_tool。值得一提的细节当返回 tool not found 时CLI 会自动调用tool list获取已注册工具名并对tool_name做近似匹配suggest_matches给出纠错建议和可直接复制的示例命令——这是排查工具名拼错/未注册最省力的路径。在 AI 客户端中直接调用对接 MCP 的任意 AI 客户端Claude、Cline、Cursor 等可以直接通过 MCP 工具调用协议触发execute_custom_toolAI 会依据工具定义中声明的parameters元数据自动生成参数。多实例场景下务必先执行set_active_instance选定Namehash目标否则工具会返回 No active Unity instance 提示。多用户与远程托管user_id 隔离在http_remote_hosted远程托管模式下execute_custom_tool会从请求级上下文读取user_idcustom_tool_service.py并一路透传到工具定义查询、PluginHub工具发现与命令下发send_with_unity_instance(..., user_id...)。这是多租户安全模型的关键工具注册表按用户隔离测试用例 test_custom_tool_service_user_scope.py 用断言mock_send.call_args.kwargs[user_id] user-1验证了这条链路保证用户 A 只能看到、只能执行自己项目注册的工具本地 stdio 模式下user_id为None不做隔离。常见失败场景与排错思路现象可能原因处理方式No active Unity instance未选定实例或多实例未路由先调用set_active_instance实例列表来自mcpforunity://instancesCould not resolve project idUnity 未运行/不可达/实例 hash 为空确认 Unity 编辑器与 MCP 插件已启动且网络连通Tool X not found for project id工具名拼写不一致、未刷新客户端、工具未在Editor/目录unity-mcp tool list核对名称断开重连客户端确认 C# 文件位于 Editor 程序集parameters must be an object/dictionaryparameters传了非对象检查客户端调用参数是否 JSON 对象Timeout waiting for X to complete轮询工具 10 分钟内未达终态检查 Unity 侧Status方法是否持续返回pending可用max_poll_seconds调整上限小结execute_custom_tool是 MCP for Unity 自定义工具体系的总入口参数上只有tool_name与可选的parameters行为上却串联了实例路由、项目作用域寻址、统一响应归一化与最长 10 分钟的轮询协议并在远程托管模式下透传用户身份实现多租户隔离。它把 Unity 侧声明式工具注册[McpForUnityTool]/register-tools或 WebSocketregister_tools与 AI 侧按名动态调用完美衔接。想深入扩展自定义工具能力的读者可继续阅读 自定义工具完整指南含截图工具与光照烘焙轮询工具的全量 C# 示例、工具注册模型 与 集成测试。【免费下载链接】unity-mcpUnity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.项目地址: https://gitcode.com/GitHub_Trending/un/unity-mcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表