Typed command options builder (MCPToolkitCommandOptions)
The raw Dictionary parameter in registry.add() was replaced with a typed MCPToolkitCommandOptions builder class. Extension authors (and built-in commands) construct options via chained setters instead of freeform string-keyed dictionaries.
Considered Options
A. Keep the Dictionary. Zero effort, but the API accepts any key — typos like "is_readonly" silently produce wrong defaults. No autocomplete, no documentation on hover. C# usage (new Dictionary { { "is_read_only", true } }) is stringly-typed.
B. Typed class with constructor parameters. Type-safe, but GDScript lacks named parameters and method overloading — a 9-parameter constructor is unusable. C# interop through ClassDB.Instantiate can’t call GDScript constructors with arguments.
C. Typed class with builder pattern (chosen). A RefCounted class with chained setters (mark_read_only(), with_description(...)) that returns self. Builds via MCPToolkitCommandOptions.new() in GDScript or registry.Call("create_options") in C#. Internally exposes data via to_dict() — the registry validates the final state and converts to its internal format.
Option C was chosen because it gives full autocomplete and type safety in GDScript, works through Godot’s Call() interop for C#, and keeps the class itself simple (no cross-field validation, no order-dependent logic). The builder pattern is the standard GDScript workaround for the lack of named parameters.
Consequences
- Breaking change to
registry.add()— third parameter changes fromDictionarytoMCPToolkitCommandOptions. Acceptable pre-1.0 (no third-party extensions in the wild). - All ~55 built-in commands must migrate to explicit
MCPToolkitCommandOptions.new()— no null default. Built-in code becomes the reference implementation for extension authors. _force_serializeis exposed publicly asmark_exclusive_execution()on the builder. The internal-only_set_force_serialize()path was removed — all callers (includinggame.start/game.stop) use the builder method.MCPToolContextrenamed toMCPToolkitToolContextfor prefix consistency (bundled in the same commit as the builder migration).MCPToolkitExtensionOptionssubclass added with mandatorydescriptionin its constructor. Built-in tools useMCPToolkitCommandOptions(description optional viawith_description()); extension tools useMCPToolkitExtensionOptions(description required at construction). This enforces the boundary between built-in and extension tools at the type level.push_warningfor empty description was removed — enforcement moved toMCPToolkitExtensionOptionsconstructor, making it a hard error for extensions and a non-issue for built-ins.
API surface
# Value setters (return self)
with_description(description: String) -> MCPToolkitCommandOptions
with_input_schema(schema: Dictionary) -> MCPToolkitCommandOptions
with_timeout_ms(timeout: int) -> MCPToolkitCommandOptions
with_group(name: String, description: String = "", keywords: Array = []) -> MCPToolkitCommandOptions
# Boolean flags — positive-only, no arguments
mark_read_only() -> MCPToolkitCommandOptions
mark_destructive() -> MCPToolkitCommandOptions
mark_idempotent() -> MCPToolkitCommandOptions
mark_cancellable() -> MCPToolkitCommandOptions
mark_scene_independent() -> MCPToolkitCommandOptions
mark_exclusive_execution() -> MCPToolkitCommandOptions # force serialization for read-only tools with side effects
# Conversion (public — used by registry, useful for debugging)
to_dict() -> Dictionary
MCPToolkitExtensionOptions (extends MCPToolkitCommandOptions):
# Constructor — description is mandatory for extension tools
_init(description: String)
Registry additions:
create_options() -> MCPToolkitCommandOptions— factory for C# discoverabilitycreate_extension_options(description: String) -> MCPToolkitExtensionOptions— factory for extension tools (enforces mandatory description)add()signature:add(method: String, handler: Callable, options: MCPToolkitCommandOptions)
Validation (read_only + destructive contradiction, timeout clamping) stays in registry.add(), not in the class. The class stores intent; the registry validates the final state. Empty description warning removed — MCPToolkitExtensionOptions enforces at construction time.