创建自定义工具

您可以通过在任何 C# 方法上添加简单的属性来扩展 MCPServer。无需修改 Python、无需重启服务器、无需注册工具——只需在 Unity中重新编译,AI 代理就能看到您的新工具。

基础示例


using realvirtual.MCP;

public static class MyTools
{
    [McpTool("Get current time")]
    public static string GetTime()
    {
        return $"{{\"time\":\"{System.DateTime.Now}\"}}";
    }

    [McpTool("Add two numbers")]
    public static string Add(
        [McpParam("First number")] float a,
        [McpParam("Second number")] float b)
    {
        return $"{{\"result\":{a + b}}}";
    }
}

就是这样。重新编译后,get_timeadd 就可供任何连接的 AI 代理使用。

属性

McpTool

在返回字符串的任何 public static 方法上添加 [McpTool("description")]。描述告诉 AI 代理该工具的用途。


[McpTool("Spawn an enemy at position")]
public static string SpawnEnemy(
    [McpParam("Prefab name")] string prefab,
    [McpParam("X position")] float x,
    [McpParam("Z position")] float z)
{
    // Your Unity code here - runs on main thread
    return ToolHelpers.Ok("Enemy spawned");
}

McpParam

在参数上添加 [McpParam("description")],为 AI 代理提供关于应提供什么值的上下文。可选参数需要默认值。


[McpTool("Set weather")]
public static string SetWeather(
    [McpParam("Weather type: sunny, rainy, cloudy")] string weather,
    [McpParam("Wind speed in m/s")] float windSpeed = 0f)
{
    // windSpeed is optional, defaults to 0
    return ToolHelpers.Ok($"Weather set to {weather}");
}

规则

  • 方法必须是 public static 且返回 string(JSON)
  • 工具名称自动从 PascalCase 转换为 snake_case(SpawnEnemyspawn_enemy
  • 方法可以在任何类中、在任何程序集中——通过反射找到
  • 所有工具方法在 Unity主线程上运行
  • 返回 JSON字符串——使用 ToolHelpers.Ok()ToolHelpers.Error() 获取标准响应

辅助工具

ToolHelpers 类提供常见模式:


// 按层级路径查找 GameObject
var go = ToolHelpers.FindGameObject("Robot/Arm/Gripper");

// 返回成功
return ToolHelpers.Ok("Operation completed");

// 返回带数据的成功
return ToolHelpers.Ok(new { position = transform.position });

// 返回错误
return ToolHelpers.Error("GameObject not found");

示例:自定义传感器工具


using realvirtual.MCP;
using UnityEngine;

public static class FactoryTools
{
    [McpTool("Get temperature from all sensors in the factory")]
    public static string GetTemperatures()
    {
        var sensors = Object.FindObjectsByType<TemperatureSensor>(
            FindObjectsSortMode.None);

        var results = sensors.Select(s => new {
            name = s.gameObject.name,
            temperature = s.CurrentTemperature,
            unit = "celsius"
        }).ToArray();

        return JsonUtility.ToJson(new { sensors = results });
    }
}

重新编译后,AI 代理可以调用 get_temperatures 并接收场景中所有温度传感器的结构化数据。