Advanced

gengine's system architecture — C++ modules, MCP wire format, REST API endpoints, task queue states, and the SSE event broadcaster.

Architecture

gengine is a multi-module Unreal Engine plugin with a companion Node.js bridge. This page describes how the components fit together, how data flows from an AI tool call to the editor and back, and what each C++ module is responsible for.

System Diagram

┌─────────────────────────────────────────────────────────────────┐
│  AI Client (Claude CLI / OpenAI / Ollama / Web Chat Panel)      │
└────────────────────────┬────────────────────────────────────────┘
                         │  MCP wire protocol (stdio or HTTP+SSE)
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│  MCP Bridge  (Node.js — Resources/mcp-bridge/)                  │
│  ┌─────────────────┐  ┌──────────────────┐  ┌───────────────┐  │
│  │  Skill Router   │  │  Tool Cache      │  │ Context Loader│  │
│  │  routes ops to  │  │  caches tool     │  │ injects UE    │  │
│  │  REST endpoints │  │  definitions     │  │ context docs  │  │
│  └────────┬────────┘  └──────────────────┘  └───────────────┘  │
└───────────┼─────────────────────────────────────────────────────┘
            │  HTTP REST (localhost:8080)
            ▼
┌─────────────────────────────────────────────────────────────────┐
│  Unreal Engine Plugin  (C++)                                     │
│                                                                  │
│  ┌──────────────────┐   ┌─────────────────────────────────────┐ │
│  │ GengineMCPServer │   │ GengineSubsystem                    │ │
│  │ HTTP listener    │──▶│ lifecycle, settings, licensing      │ │
│  │ request routing  │   └─────────────────────────────────────┘ │
│  └────────┬─────────┘                                           │
│           │                                                      │
│           ▼                                                      │
│  ┌──────────────────┐   ┌──────────────────────────────────────┐│
│  │ MCPAutoRouter    │   │ MCPParamValidator                    ││
│  │ dispatches ops   │──▶│ type checks, path traversal,        ││
│  │ to tool handlers │   │ numeric validation, blocklists      ││
│  └────────┬─────────┘   └──────────────────────────────────────┘│
│           │                                                      │
│           ▼                                                      │
│  ┌──────────────────┐   ┌──────────────────────────────────────┐│
│  │ MCPTaskQueue     │   │ MCPToolRegistry                      ││
│  │ async dispatch   │   │ FMCPToolBase registry,               ││
│  │ max 4 concurrent │   │ tool discovery, annotation cache     ││
│  └────────┬─────────┘   └──────────────────────────────────────┘│
│           │                                                      │
│           ▼                                                      │
│  ┌──────────────────────────────────────────────────────────────┐│
│  │  Tool Handlers  (Source/Gengine/Private/MCP/Tools/)          ││
│  │  MCPTool_World  MCPTool_Assets  MCPTool_Blueprints           ││
│  │  MCPTool_Animation  MCPTool_Character  MCPTool_InputMat      ││
│  │  MCPTool_Status  MCPTool_Context  MCPTool_Nativize           ││
│  └────────┬─────────────────────────────────────────────────────┘│
│           │                                                      │
│           ▼                                                      │
│  ┌──────────────────┐   ┌──────────────────────────────────────┐│
│  │ MCPOutputSanitiz │   │ SSE Event Broadcaster                ││
│  │ strips injection │   │ pushes task progress to              ││
│  │ patterns, paths  │   │ connected HTTP+SSE clients           ││
│  └──────────────────┘   └──────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

C++ Module Reference

gengine is split into 4 C++ modules for compile-time dependency isolation:

ModuleBuild TargetResponsibility
GengineRuntimeCore MCP server, tool registry, task queue, auto-router, validators, all tool handlers
GengineAutonomyRuntimeCheckpoint system, shadow git manager, autonomous task recovery
GengineChatGatewayRuntimeChat provider abstraction layer — Anthropic, OpenAI, Ollama adapters
GengineMCPStreamableRuntimeHTTP+SSE transport — SSE handler, streamable MCP endpoint, event broadcaster

Module dependencies

GengineMCPStreamable
    └── Gengine
            └── GengineAutonomy

GengineChatGateway
    └── (standalone — no plugin-internal deps)

GengineChatGateway is intentionally isolated so provider adapters can be updated without touching the MCP layer.

MCP Wire Format

gengine implements MCP 1.0. Messages are JSON-RPC 2.0 envelopes:

Tool call (client → server)

{
  "jsonrpc": "2.0",
  "id": "req-42",
  "method": "tools/call",
  "params": {
    "name": "unreal_assets",
    "arguments": {
      "operation": "search",
      "params": {
        "query": "BP_Enemy",
        "asset_type": "Blueprint"
      }
    }
  }
}

Tool result (server → client)

{
  "jsonrpc": "2.0",
  "id": "req-42",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"assets\":[{\"name\":\"BP_Enemy_Goblin\",\"path\":\"/Game/Characters/Enemies/BP_Enemy_Goblin\",\"type\":\"Blueprint\"}],\"total\":1}"
      }
    ],
    "isError": false
  }
}

Error result

{
  "jsonrpc": "2.0",
  "id": "req-42",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Validation error: parameter 'query' is required"
      }
    ],
    "isError": true
  }
}

REST API Endpoints

The gengine REST API on port 8080 is the interface between the MCP bridge and the C++ plugin:

MethodPathDescription
POST/mcp/toolExecute a tool call. Body: { name, operation, params }
GET/mcp/toolsList all registered tool definitions (JSON Schema)
GET/mcp/statusPlugin health, version, connected clients
GET/mcp/tasksList active and recent tasks with state
GET/mcp/tasks/{id}Get full detail for a specific task
DELETE/mcp/tasks/{id}Cancel a running task
GET/mcp/activityRecent tool call activity log
GET/mcp/sseSSE stream for real-time task progress events
POST/mcp/license/activateActivate a license key
GET/mcp/license/statusCurrent license tier and seat info

Tool call request body

{
  "name": "unreal_blueprints",
  "operation": "add_variable",
  "params": {
    "path": "/Game/Characters/BP_Player",
    "name": "Health",
    "type": "float",
    "default_value": 100.0
  }
}

Task Queue States

Each task in the async queue passes through these states:

Queued ──▶ Running ──▶ Completed
                  └──▶ Failed
                  └──▶ Cancelled  (via DELETE /mcp/tasks/{id})

Queued ──▶ TimedOut  (after 30s without executing)

The task queue enforces the 4-concurrent-task limit. Tasks in Queued state wait until a Running slot opens.

Task object shape

{
  "id": "task-8f3a2c",
  "tool": "unreal_blueprints",
  "operation": "add_node",
  "state": "Completed",
  "queued_at": "2025-01-15T14:32:07Z",
  "started_at": "2025-01-15T14:32:07Z",
  "completed_at": "2025-01-15T14:32:08Z",
  "duration_ms": 412,
  "result": { "node_id": "node_7", "success": true }
}

SSE Event Broadcaster

The GengineMCPStreamable module pushes real-time events to connected HTTP+SSE clients. Events are emitted for every task state transition:

event: task_queued
data: {"id":"task-8f3a2c","tool":"unreal_blueprints","operation":"add_node"}

event: task_started
data: {"id":"task-8f3a2c","queued_ms":12}

event: task_progress
data: {"id":"task-8f3a2c","message":"Locating graph 'EventGraph'","percent":40}

event: task_completed
data: {"id":"task-8f3a2c","duration_ms":412,"result":{"node_id":"node_7"}}

The Web Chat Panel subscribes to this SSE stream to show live task progress in the Tasks tab.

Key Source Directories

Source/
├── Gengine/
│   ├── Private/
│   │   ├── MCP/
│   │   │   ├── GengineMCPServer.cpp       HTTP server, request parsing
│   │   │   ├── MCPAutoRouter.cpp          Operation dispatch, safety tier enforcement
│   │   │   ├── MCPTaskQueue.cpp           Async task queue, concurrency management
│   │   │   ├── MCPToolRegistry.cpp        Tool registration, discovery endpoint
│   │   │   ├── MCPParamValidator.cpp      Input validation, injection prevention
│   │   │   ├── MCPOutputSanitizer.cpp     Response sanitization
│   │   │   └── Tools/
│   │   │       ├── MCPTool_World.cpp
│   │   │       ├── MCPTool_Assets.cpp
│   │   │       ├── MCPTool_Blueprints.cpp
│   │   │       ├── MCPTool_Animation.cpp
│   │   │       ├── MCPTool_Character.cpp
│   │   │       ├── MCPTool_InputMaterials.cpp
│   │   │       ├── MCPTool_Status.cpp
│   │   │       ├── MCPTool_Context.cpp
│   │   │       └── MCPTool_Nativize.cpp
│   │   └── GengineSubsystem.cpp           Plugin lifecycle, settings, licensing
│   └── Public/
│       ├── GengineSettings.h
│       └── GengineConstants.h
├── GengineAutonomy/
│   └── Private/Checkpoint/
│       └── ShadowGitManager.cpp
├── GengineChatGateway/
│   └── Private/ChatGatewayProvider.cpp
└── GengineMCPStreamable/
    ├── Private/MCPSSEHandler.cpp
    └── Private/MCPStreamableHandler.cpp

Resources/
└── mcp-bridge/
    ├── src/
    │   ├── index.ts           Entry point, transport setup
    │   ├── router.ts          Skill tree router
    │   ├── toolCache.ts       Tool definition cache
    │   └── contextLoader.ts   UE context doc injector
    └── dist/                  Compiled JS output