이 페이지는 영어에서 기계 번역되었습니다. 영어 원문 읽기.

사용자 지정 도구

C#로 나만의 Godot MCP 도구를 작성하고, 메인 스레드에서 Godot API를 호출하며, 실행 중인 Godot 게임에서 도구와 프롬프트, 리소스를 노출하세요.

2026년 11월 4일 업데이트 Markdown으로 보기

프로젝트 안에서 순수 C#으로 Godot MCP에 자신만의 MCP 도구를 추가할 수 있습니다. 사용자 지정 도구는 AI 에이전트가 호출할 수 있는 메서드이며, 설명을 통해 모델이 그 도구가 무엇을 하는지 알 수 있습니다. 이 페이지에서는 에디터 도구, 메인 스레드 규칙, 그리고 에이전트가 실행 중인 게임과 대화할 수 있게 해주는 옵트인 런타임을 다룹니다.

에디터 도구 작성하기

도구 패밀리는 [AiToolType]이 붙은 partial class입니다. 각 도구는 [AiTool("tool-name")]이 붙은 메서드이며, 메서드와 모든 매개변수에 [Description]을 붙여 모델이 언제 어떻게 호출해야 하는지 알 수 있게 합니다.

using System.ComponentModel;
using com.IvanMurzak.McpPlugin;           // [AiToolType], [AiTool]
using com.IvanMurzak.ReflectorNet.Utils;  // MainThread

[AiToolType]
public partial class Tool_MyFeature
{
    [AiTool("my-custom-task", Title = "Do a custom task")]
    [Description("Explain to the LLM what this does and when to call it.")]
    public string CustomTask
    (
        [Description("Explain to the LLM what this parameter is.")]
        string inputData
    )
    {
        // Work that does not touch the Godot API can run here, on a background thread.

        return MainThread.Instance.Run(() =>
        {
            // Touch EditorInterface, Node or Resource here, on the main thread.
            return "[Success] Operation completed.";
        });
    }
}

C# 프로젝트를 빌드하세요(에디터의 Build 버튼, godot-cli build, 또는 에이전트에게 script-build 실행 요청). Godot이 어셈블리를 다시 로드하고 애드온이 재연결되면, 새 도구가 에이전트의 도구 목록과 독의 Tools 창에 나타납니다.

도구를 안정적으로 유지하는 규칙

  • Godot 객체는 메인 스레드에서만. 도구 메서드는 메인 스레드 밖에서 호출됩니다. Node, Resource, SceneTree, EditorInterface에 대한 모든 호출은 MainThread.Instance.Run(...)을 거쳐야 합니다. 백그라운드 스레드에서 이들에 접근하면 에디터가 충돌할 수 있습니다.
  • 포맷된 텍스트가 아니라 데이터를 반환하세요. 속성이 있는 클래스를 반환하거나(모델을 위해 직렬화됩니다), 부수 효과만 있는 도구라면 void를 반환하세요. 에이전트가 파싱해야 하는 값에는 직접 만든 문자열을 쓰지 마세요.
  • 선택적 매개변수를 표시하세요. 기본값이 있는 널 허용 타입을 사용하세요. 예를 들어 string? filter = null처럼 쓰면 모델이 해당 매개변수를 선택 사항으로 취급합니다.
  • 모든 것을 설명하세요. 모델이 읽는 것은 바로 이 설명입니다. 도구가 무엇을 하는지, 언제 사용해야 하는지, 각 매개변수가 무엇을 의미하는지 적으세요.
  • 에디터 전용 코드는 #if TOOLS 뒤에 두세요. 에디터 API를 사용하는 코드는 내보낸 게임에 컴파일되어서는 안 됩니다.

힌트와 대상

[AiTool]은 ReadOnlyHint = true, IdempotentHint = true 같은 선택적 힌트를 받으며, 이는 클라이언트에게 해당 도구가 아무것도 변경하지 않거나 안전하게 반복 호출할 수 있음을 알려줍니다. Target은 도구가 등록되는 위치를 결정합니다: ToolTarget.Editor(에디터 전용), ToolTarget.Runtime(게임 전용), 또는 기본값인 양쪽 모두입니다.

에이전트가 도구를 작성하게 하기

시스템 도구 godot-skill-create는 프로젝트에 새 C# 도구 파일을 작성하며, 해당 도구는 다음 빌드 후에 호출 가능해집니다. 새 도구를 작성하기 전에 RQL이 이미 그 작업을 처리하는지 확인하세요. 대부분의 에디터 데이터 접근(노드, 리소스, 파일, 프로젝트 설정)은 rql-query나 rql-mutate 한 번이면 됩니다. Tools를 참고하세요.

실행 중인 게임 속 도구

Godot MCP는 실행 중이거나 내보낸 게임 안에서도 동작할 수 있습니다(디버그 또는 릴리스). 이를 통해 에이전트는 실시간 게임 상태를 읽고 제어할 수 있습니다. 예를 들어 봇의 수가 LLM에서 나오는 체스 게임이 그렇습니다. 두 가지는 의도된 설계입니다:

  • 스스로 연결하지 않습니다. 연결 여부와 시점은 Connect() 호출로 여러분의 코드가 결정합니다.
  • 기본적으로 아무것도 노출하지 않습니다. 모든 도구, 프롬프트, 리소스는 직접 등록해야 합니다. 애드온의 에디터 도구는 게임 빌드에 컴파일되지 않습니다.

SceneTree가 존재한 뒤에 시작하세요. 예를 들어 오토로드의 _Ready()에서 시작할 수 있습니다:

using System.Reflection;
using com.IvanMurzak.Godot.MCP.Connection;
using com.IvanMurzak.Godot.MCP.Runtime;
using McpServerConsts = com.IvanMurzak.McpPlugin.Common.Consts.MCP.Server;
using Godot;

public partial class GameMcp : Node
{
    private GodotMcpRuntimeHandle? _mcp;

    public override async void _Ready()
    {
        _mcp = GodotMcpRuntime.Initialize(builder =>
        {
            builder.WithConfig(config =>
            {
                config.ConnectionMode = GodotMcpConnectionMode.Custom;
                config.Host = "http://localhost:8080";
                config.AuthOption = McpServerConsts.AuthOption.token;
                config.Token = "your-secret-token";
            });
            builder.WithToolsFromAssembly(Assembly.GetExecutingAssembly());
        }).Build();

        await _mcp.Connect();
    }

    public override async void _ExitTree()
    {
        if (_mcp is not null)
            await _mcp.Disconnect();
    }
}

게임 전용 도구 클래스에는 [AiToolType(Target = ToolTarget.Runtime)]을 붙이세요(com.IvanMurzak.McpPlugin.Common에서 제공). 그러면 에디터가 해당 도구를 등록하지 않으며, 에디터가 연결되어 있는 동안에도 에이전트가 게임에 접근할 수 있습니다.

빌더 옵션

호출동작 내용
WithConfig(...)코드에서 Host, Token, ConnectionMode, AuthOption을 설정합니다.
WithToolsFromAssembly(...) / WithTools(...)어셈블리에서 [AiToolType] 클래스를 등록하거나 특정 타입을 등록합니다.
WithPromptsFromAssembly(...) / WithPrompts(...)[AiPromptType] 프롬프트 클래스를 등록합니다.
WithResourcesFromAssembly(...) / WithResources(...)[AiResourceType] 리소스 클래스를 등록합니다.
WithRuntimeErrorCapture()게임 내 오류를 캡처하고 runtime-errors-get / runtime-errors-clear를 등록합니다. 기본값은 꺼짐입니다.
WithScriptExecute()게임에 script-execute를 등록합니다. 기본값은 꺼짐이며 .csproj 옵트인이 필요합니다.
ConnectWhenRunFromEditor()에디터에서 Play로 게임을 시작한 경우에도 연결합니다. 기본값은 꺼짐입니다.
WithoutMainThreadDispatcher()자동 메인 스레드 디스패처를 건너뜁니다(직접 설치한 경우에만).

Host와 토큰은 GODOT_MCP_* 환경 변수나 .env 파일에서도 가져올 수 있으며, 이 값이 코드보다 우선합니다. 게임은 에디터에 저장된 설정을 절대 읽지 않습니다.

프롬프트와 리소스

도구 외에도, 게임은 MCP 프롬프트(이름이 붙은 지시 템플릿, [AiPrompt] 메서드가 있는 [AiPromptType])와 리소스(URI로 가져오는 읽기 전용 콘텐츠, [AiResource] 메서드가 있는 [AiResourceType])를 노출할 수 있습니다. 각 종류는 선택 사항이며 도구와 동일한 방식으로 등록됩니다.

게임 내부에서 C# 실행하기

에이전트가 게임에서 C#을 실행하도록 하려면 게임의 .csproj에서 옵트인하고 WithScriptExecute()를 호출하세요:

<PropertyGroup>
  <GodotMcpCodeExecInGame>true</GodotMcpCodeExecInGame>
  <DefineConstants>$(DefineConstants);GODOT_MCP_CODE_EXEC_IN_GAME</DefineConstants>
</PropertyGroup>

이 기능은 데스크톱 CoreCLR 빌드에서만 동작하며, NativeAOT나 iOS에서는 동작하지 않습니다.

게임 빌드를 위한 보안 체크리스트

  • localhost 또는 127.0.0.1에서 AuthOption.token과 실제 토큰을 사용하는 Custom 모드를 선호하세요.
  • 필요한 도구만 등록하세요. 공격 표면은 정확히 여러분이 등록한 도구입니다.
  • 그렇게 하도록 설계하고 보안을 갖추지 않은 한, 릴리스 빌드에서 공용 네트워크 인터페이스에 연결을 노출하지 마세요.

전체 도구 목록은 Tools를, 패키징된 도구 세트는 Extensions를 참고하세요.