rokojori_action_library/Tools/mcp/McpProtocolHandler.cs

86 lines
2.5 KiB
C#
Raw Normal View History

2026-10-03 12:15:58 +00:00
#if TOOLS
namespace Rokojori.Tools
{
using Rokojori;
// Pure protocol logic - no Godot API access except inside ExecuteTool's route calls,
// which is why only tools/call needs to cross onto the main thread (see McpServer).
public class McpProtocolHandler
{
public JSONObject Initialize( JSONData id, JSONObject paramsObj )
{
var requestedVersion = JsonUtil.GetStringOrNull( paramsObj, "protocolVersion" );
var protocolVersion = string.IsNullOrEmpty( requestedVersion ) ? "2025-06-18" : requestedVersion;
var capabilities = new JSONObject();
capabilities.Set( "tools", new JSONObject() );
var serverInfo = new JSONObject();
serverInfo.Set( "name", "godot-mcp" );
serverInfo.Set( "version", "0.1.0" );
var result = new JSONObject();
result.Set( "protocolVersion", protocolVersion );
result.Set( "capabilities", capabilities );
result.Set( "serverInfo", serverInfo );
return JsonRpc.BuildResult( id, result );
}
public JSONObject ToolsList( JSONData id )
{
var tools = new JSONArray();
tools.Push( ReadResourceRoute.ToolDefinition() );
tools.Push( WriteResourceRoute.ToolDefinition() );
tools.Push( ReadSceneFragmentRoute.ToolDefinition() );
tools.Push( WriteSceneFragmentRoute.ToolDefinition() );
var result = new JSONObject();
result.Set( "tools", tools );
return JsonRpc.BuildResult( id, result );
}
public JSONObject ToolCallResult( JSONData id, ToolCallOutcome outcome )
{
var item = new JSONObject();
item.Set( "type", "text" );
item.Set( "text", outcome.text );
var content = new JSONArray();
content.Push( item );
var result = new JSONObject();
result.Set( "content", content );
result.Set( "isError", outcome.isError );
return JsonRpc.BuildResult( id, result );
}
// Runs on the main thread, dequeued from McpServer's pending-call queue.
public ToolCallOutcome ExecuteTool( string toolName, JSONObject arguments )
{
switch ( toolName )
{
case "read_resource":
return ReadResourceRoute.Execute( arguments );
case "write_resource":
return WriteResourceRoute.Execute( arguments );
case "read_scene_fragment":
return ReadSceneFragmentRoute.Execute( arguments );
case "write_scene_fragment":
return WriteSceneFragmentRoute.Execute( arguments );
default:
return ToolCallOutcome.Error( "Unknown tool: " + toolName );
}
}
}
}
#endif