com.IvanMurzak.Brutal.MCP 0.2.1

dotnet add package com.IvanMurzak.Brutal.MCP --version 0.2.1
                    
NuGet\Install-Package com.IvanMurzak.Brutal.MCP -Version 0.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="com.IvanMurzak.Brutal.MCP" Version="0.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="com.IvanMurzak.Brutal.MCP" Version="0.2.1" />
                    
Directory.Packages.props
<PackageReference Include="com.IvanMurzak.Brutal.MCP" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add com.IvanMurzak.Brutal.MCP --version 0.2.1
                    
#r "nuget: com.IvanMurzak.Brutal.MCP, 0.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package com.IvanMurzak.Brutal.MCP@0.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=com.IvanMurzak.Brutal.MCP&version=0.2.1
                    
Install as a Cake Addin
#tool nuget:?package=com.IvanMurzak.Brutal.MCP&version=0.2.1
                    
Install as a Cake Tool

Brutal-MCP

AI Game Developer integration for games built on the BRUTAL C# framework. Brutal-MCP is a NuGet package (com.IvanMurzak.Brutal.MCP) that runs inside your game process and connects it to AI agents (Claude Code, Codex, Cursor …) through the AI Game Developer App and the shared MCP server. Agents can then inspect and change the running game with RQL — one query language instead of hundreds of tools — read its logs, and learn how to write BRUTAL code from generated skills.

BRUTAL has no editor, no scene graph and no renderer, so there is no in-game UI either: the plugin starts itself in Debug builds and is configured through the App or environment variables.

Install

With the AI Game Developer App (recommended). Open your BRUTAL game project in the App and enable the BRUTAL integration: the App adds the package to your .csproj, writes .ai-game-dev/brutal-mcp.json, generates the agent skills and launches the game with the right BRUTAL_MCP_* environment variables. Sign-in is shared with the App.

Manually.

dotnet add package com.IvanMurzak.Brutal.MCP

That is all for Debug builds: the package's build targets add a module initializer that calls BrutalMcp.AutoStart(...) before Main. Release builds do not include it unless you opt in:

<PropertyGroup>
  <BrutalMcpAutoStart>true</BrutalMcpAutoStart>   
</PropertyGroup>

Two lines in your game

using com.IvanMurzak.Brutal.MCP;

BrutalMcp.Register(world, "World");          // make objects visible to agents (any C# object)
BrutalMcp.Register(scheduler, "Simulation");

while (!window.ShouldClose && !BrutalMcp.QuitRequested)
{
    Glfw.PollEvents();
    Update();
    BrutalMcp.Tick();                        // once per frame: agents' main-thread work runs here
}
  • BrutalMcp.Tick(TimeSpan? budget = null) drains the main-thread queue within a small time budget (default 4 ms). Changes made by agents (rql-mutate) run there, between your frames. Without Tick, reads still work and writes fail after 5 s with an explanation.
  • BrutalMcp.Register(obj, name) / Unregister(obj) choose what agents see. Static fields and properties of your game assembly are visible without registration. Value types (BRUTAL handle structs such as a Jolt PhysicsSystem) are compared by value: registering a copy again renames the one registration instead of adding another.
  • BrutalMcp.QuitRequested / BrutalMcp.QuitRequestedEvent: an agent asked the game to quit (game-quit). The plugin never kills your process.
  • Mark methods agents may invoke with [Rql.RqlCallable("what it does")].
  • Manual control: BrutalMcp.Start(new BrutalMcpOptions { ProjectRoot = ..., GameAssembly = ... }), BrutalMcp.Stop(), BrutalMcp.IsRunning, BrutalMcp.IsConnected.

No Brutal-MCP call throws into your game; problems are written to stderr as [Brutal-MCP] … (level: BRUTAL_MCP_LOG_LEVEL).

Configuration

Precedence: environment variables → code options (BrutalMcpOptions) → <project>/.ai-game-dev/brutal-mcp.json → defaults.

Env var json key Default Meaning
BRUTAL_MCP_ENABLED enabled true false disables the plugin
BRUTAL_MCP_CONNECTION_MODE connectionMode Cloud Cloud (ai-game.dev) or Custom (your own server)
BRUTAL_MCP_CLOUD_URL cloudUrl https://ai-game.dev cloud base URL (/mcp is appended)
BRUTAL_MCP_HOST host http://localhost:<project port> Custom server URL (port derived from the project path, like the App)
BRUTAL_MCP_AUTH_OPTION authOption none Custom mode: none, oauth (signed-in account; sent to a localhost server only) or token
BRUTAL_MCP_TOKEN — — bearer token for token mode (and for oauth to a non-localhost server); kept in memory, never written to disk
BRUTAL_MCP_LOG_LEVEL logLevel Warning the plugin's own diagnostics
BRUTAL_MCP_SKILLS_PATH skillsPath .claude/skills where generated skills are written
— generateSkillFiles, logBufferSize, mainThreadTimeoutMs true, 2000, 5000

Cloud mode signs in with the machine credentials shared by the App, the CLIs and the other engine plugins (~/.ai-game-dev/credentials.json): sign in once with the App.

What agents get

RQL tools — rql-query (read), rql-mutate (set / call, with dry_run), rql-schema (sources and types).

RQL source Content
game process, uptime, frame counter, main-thread pump, OS / .NET, connection, BRUTAL packages + versions, extensions
registered objects passed to BrutalMcp.Register
statics static fields / properties of your game types (read and write)
types your game types (with their statics and known instances)
console log lines captured from BRUTAL LogSystem (ring buffer)
logCategories BRUTAL LogCategory registry (mute a category with set IsCategoryEnabled = false)
jobSchedulers JobSchedulers with per-runner timings
localization LStrings (localize with call Localize("…"))
monitor BRUTAL Monitor log files, stats, recovered crash tails, dumps

Functions: brutal.registered("Name"), brutal.find("Type"), brutal.type("Type"). BRUTAL value types read and write naturally: float3 as "(1, 2, 3)", floatQuat, float4x4, int*, double*, colors as "#ff8800".

registered | select Name Type
brutal.registered("World") | get Entities | where Health < 50 | select $ref Name Position
console | where Level == "Error" | sort Sequence desc | first 5 | select Category Message
brutal.registered("World") | get Entities | where Name == "Boss" | set Health = 100, Position = "(0, 1, 0)"

Other tools — game-logs-tail (Monitor log files on disk), game-quit (graceful quit request), ping and brutal-skill-generate (system tools).

script-execute (Debug builds of the game only) — compiles and runs C# inside the game, on its main thread: plain statements whose last expression is the result, or a class with a static method. Usings for System, LINQ, Brutal.Numerics, Brutal.Logging and com.IvanMurzak.Brutal.MCP are already there, game types are imported automatically, compile errors point at the agent's own lines, and Console / LogSystem output written meanwhile comes back with the result. In a Release build the tool does not exist.

var world = (World)BrutalMcp.Registry.Get("World")!;
world.Entities.Count(e => e.Health < 50)

Skills (written to .claude/skills): brutal-rql (RQL for this game, generated from the live engine and installed extensions) and brutal-framework (how to write BRUTAL code, plus the BRUTAL packages your game loads and a table of every Brutal-MCP extension: package, required BRUTAL package, registration line, RQL sources, loaded / recommended), plus one skill per tool.

Extensions

Feature packages (ImGui, Jolt, Glfw, Fmod, Box2D, RakNet, Vulkan.Vma, RenderDoc, Sdl) get optional extension packages com.IvanMurzak.Brutal.MCP.<Feature> (catalog: extensions/manifest.json, embedded into the core and rendered into the brutal-framework skill). Each depends only on the core and its BRUTAL package. An extension is a class library that references the core and adds a public Rql.Execution.IRqlModule (sources, functions, adapters, guide); its assembly is picked up automatically when it sits next to the game. Core API for extensions:

API Use
BrutalMcp.Registry.Find<T>(InstanceSources) live instances of T (class or struct) with display names: registrations, discoverers, statics (incl. T?, collections, dictionaries), fields of registered objects; distinct by reference / value
BrutalMcp.Registry.OfType<T>(), NameOf(obj) instances without names (no struct constraint); the registration name of an instance
BrutalMcp.AddInstanceDiscoverer(name, func) expose instances the plugin cannot find itself
BrutalMcp.Log.For("Feature") Debug/Info/Warn/Error, WarnOnce(key, msg): [Brutal-MCP] warn: [Feature] … on stderr, filtered by BRUTAL_MCP_LOG_LEVEL
BrutalMcp.Ticked event raised on the main thread at the end of every BrutalMcp.Tick(); handler exceptions are caught and logged
BrutalLogging.GetProviders() / CurrentFactory() the ILoggerProviders of BRUTAL LogSystem's factory (e.g. ImGui ConsoleWindow, Monitor)
BrutalMainThread.Current.Run(...) run non-thread-safe native calls on the game's main thread
BrutalPackages.Catalog / CatalogState() the extension catalog and what is loaded / recommended in this process

Extension test projects (Brutal.Mcp.<Feature>.Tests) see the core's internals: BrutalMcp.ResetForTests() clears registrations, discoverers, game assemblies, Ticked handlers and once-only log keys; RqlBrutal.Reset() rebuilds the engine.

Releasing

Maintainers: packages are published to nuget.org by a manual dispatch of the release workflow, see docs/RELEASING.md.

Licence

Brutal-MCP is licensed under the Apache License 2.0. It depends on com.IvanMurzak.Rql, licensed under the PolyForm Shield License 1.0.0, and on McpPlugin / ReflectorNet (Apache-2.0).

BRUTAL itself is licensed by Ahwoo Limited under the BRUTAL License (MIT + attribution). Its attribution duties — credits line, BRUTAL logo before gameplay, shipping NOTICE.txt, third-party notices — apply to your game, as a product built with BRUTAL, not to this package. Brutal-MCP is an independent project, not affiliated with Ahwoo.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (9)

Showing the top 5 NuGet packages that depend on com.IvanMurzak.Brutal.MCP:

Package Downloads
com.IvanMurzak.Brutal.MCP.Jolt

Brutal-MCP extension for Ahwoo.BRUTAL.Jolt: exposes live Jolt physics to AI agents through RQL.

com.IvanMurzak.Brutal.MCP.RenderDoc

Brutal-MCP extension for Ahwoo.BRUTAL.RenderDoc: RenderDoc in-application API (captures, trigger capture, replay UI), exposed to AI agents through RQL.

com.IvanMurzak.Brutal.MCP.Vma

Brutal-MCP extension for Ahwoo.BRUTAL.Vulkan.Vma: Vulkan Memory Allocator (device, heap budgets, statistics; read-only), exposed to AI agents through RQL.

com.IvanMurzak.Brutal.MCP.ImGui

Brutal-MCP extension for Ahwoo.BRUTAL.ImGui: pumps BrutalMcp.Tick() from an ImGui NewFramePre hook, exposes the ImGui context (io, style, windows), ini settings and the ConsoleWindow terminal commands to AI agents through RQL, and discovers the GLFW window behind the main viewport.

com.IvanMurzak.Brutal.MCP.Sdl

Brutal-MCP extension for Ahwoo.BRUTAL.Sdl: exposes the SDL windows of the game (title, position, size, flags) to AI agents through RQL.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 0 10/22/2026
0.2.0 74 10/20/2026
0.1.1 117 10/17/2026
0.1.0 145 10/17/2026