Using the Kanzi Monitor MCP server

The Kanzi Monitor MCP server is a Python tool that exposes Kanzi Monitor console commands — the Overwatch, Capture, Debug, NodeTree and Resource services — as structured tools for AI assistants such as Claude Code and Claude Desktop. It connects to the Kanzi Monitor console over TCP or serial and enables AI agents to inspect and control a running Kanzi application through the Model Context Protocol.

You can find the tool in tools/monitor-mcp-server/. See tools/monitor-mcp-server/README.md for the full reference.

How the Kanzi Monitor MCP server works

Claude Code/Desktop  ──(stdio)──>  MCP Server (Python)  ──(TCP or Serial)──>  Monitor Console  ──>  Kanzi App

The MCP server runs as a subprocess of the AI assistant. It receives tool calls over standard I/O using the Model Context Protocol and forwards them as Kanzi Monitor console commands, such as overwatch.*, nodetree.*, resource.*, debug.* and capture.*, to the Kanzi Monitor console. The MCP server returns JSON responses from Kanzi Monitor to the AI assistant as structured tool results. Large responses such as images and big JSON payloads are saved to temporary files to reduce context window consumption.

Requirements

  • Python 3.10 or later

  • mcp package: pip install "mcp>=1.0.0"

  • For serial connections: pyserial-asyncio-fast: pip install pyserial-asyncio-fast

  • A running Kanzi application with Kanzi Monitor and ServiceOverwatchEnabled=1

Setting up the Kanzi Monitor MCP server

Setting up with Claude Code

The examples below assume that Kanzi Monitor is installed to the default location in your Kanzi workspace: Engine/plugins/monitor/.

Create a .mcp.json file in the root of your Kanzi application project:

{
  "mcpServers": {
    "kanzi-monitor": {
      "command": "python",
      "args": ["../../Engine/plugins/monitor/tools/monitor-mcp-server/kanzi_monitor_mcp.py"],
      "env": {
        "KANZI_MONITOR_HOST": "127.0.0.1",
        "KANZI_MONITOR_PORT": "56000"
      }
    }
  }
}

Setting up with Claude Desktop

To set up the Kanzi Monitor MCP server with Claude Desktop:

  1. Open the Claude Desktop MCP settings file (claude_desktop_config.json).

  2. Add the following entry:

    {
      "mcpServers": {
        "kanzi-monitor": {
          "command": "python",
          "args": ["C:/KanziWorkspace/Engine/plugins/monitor/tools/monitor-mcp-server/kanzi_monitor_mcp.py"],
          "env": {
            "KANZI_MONITOR_HOST": "127.0.0.1",
            "KANZI_MONITOR_PORT": "56000"
          }
        }
      }
    }
    
  3. Replace C:/KanziWorkspace with the actual path to your Kanzi workspace.

Configuring the connection

All configuration uses environment variables in the MCP server configuration.

Variable

Default

Description

KANZI_MONITOR_HOST

127.0.0.1

Monitor TCP host.

KANZI_MONITOR_PORT

56000

Monitor TCP port.

KANZI_MONITOR_TIMEOUT

30 (TCP) / 120 (serial)

Command timeout in seconds.

KANZI_MONITOR_SERIAL_PORT

(empty)

Serial device path, for example COM3 or /dev/ttyUSB0. When you set this variable, the server uses serial instead of TCP.

KANZI_MONITOR_BAUD_RATE

115200

Serial baud rate. Used only with KANZI_MONITOR_SERIAL_PORT.

To connect over serial instead of TCP, set KANZI_MONITOR_SERIAL_PORT in the environment:

{
  "mcpServers": {
    "kanzi-monitor": {
      "command": "python",
      "args": ["../../Engine/plugins/monitor/tools/monitor-mcp-server/kanzi_monitor_mcp.py"],
      "env": {
        "KANZI_MONITOR_SERIAL_PORT": "COM3",
        "KANZI_MONITOR_BAUD_RATE": "115200"
      }
    }
  }
}

Available tools

The MCP server exposes Kanzi Monitor console commands as structured tools, covering the Overwatch, Capture, Debug, NodeTree and Resource services.

Tool

Description

get_scene_tree

Gets the node tree as JSON. Accepts an optional depth limit.

get_node_properties

Gets a node’s locally-set property values, each with its precedence. Values from a style, a class default, or an ancestor are counted rather than listed. See Understanding what overwatch.props reports.

set_node_property

Sets a property value on a node.

dispatch_message

Dispatches a message from a node. Takes the arguments as a dictionary of argument name to value, each value formatted as for set_node_property. Reports the routing, the declared arguments left at their default, and the handled flag. The first tool with a dictionary parameter. See Dispatching a message.

get_resources

Lists the resources that have a URL, with memory usage. The count and memory totals cover every resource, so they can exceed the entries listed. See Which resource list to use.

get_all_resources

Lists every resource the ResourceManager holds, including those without a URL, each with registered. Use it for memory accounting. See Which resource list to use.

get_resource_info

Gets detailed metadata for a resource, by handle (preferred), URL or index. For textures, this includes type, face count, slice count, and a cubemap flag.

get_texture_preview

Gets a preview of a texture. Saves as a temporary PNG file. Accepts an optional face argument (0–5) to preview a single cubemap face.

purge_resources

Purges unused resources.

set_memory_strategy

Sets the ResourceManager default memory strategy, KeepInMemory or OptimizeMemory, for resources acquired from now on. get_status reports the current value as resourceMemoryStrategy.

acquire_resource

Forces a resource into existence by URL, reporting whether it still exists afterwards.

unregister_resource

Drops the URL association so the next acquire rebuilds the resource. Not a delete; the way to pick up an edited file:// asset.

create_resource

Creates a resource of any concrete class, sets its properties and registers it under a URL, or none, and returns its handle. Resource service, see Using the Resource service.

destroy_resource

Drops a created resource and its URL, and reports whether that destroyed it.

destroy_created_resources

Drops every resource created in this session.

list_created_resources

Lists the created resources Monitor keeps alive, with their handles and references.

get_resource_kinds

Lists the builders with their arguments, and which resource classes can be created.

add_font_face

Adds a face of another weight or style to any font family.

add_font_fallback

Appends a fallback family to any font family, the application’s own included, for the glyphs its fonts lack: CJK, emoji.

create_node

Creates a node of a metaclass under a parent node, and returns its handle and path; an application override of the metaclass applies. NodeTree service, see Using the NodeTree service.

instantiate_prefab

Instantiates a prefab 1 to 10000 times under a parent node, and reports every copy’s handle and path.

destroy_node

Takes any node out of the tree, by path or handle, and reports whether it was destroyed.

detach_node

Takes any node out of the tree without destroying it, and returns its handle, by which reattach_node puts it back.

reattach_node

Puts a detached node back under its parent at the index it was taken from.

reattach_all_nodes

Puts every detached node back, the most recently detached first, which restores the original order.

attach_node

Puts a detached node, or one created without a parent, anywhere in the tree.

move_node

Moves any node to another parent, or to another position among its siblings, in one step.

list_held_nodes

Lists the nodes the NodeTree service tracks, attached or detached: handle, state, origin, current path and, for a detached node, its home.

destroy_created_nodes

Destroys every node created in this session, and removes every node component Monitor added, from created and application nodes alike.

add_node_component

Adds a node component of any class to a node, its properties (a dictionary of name to value) written before it attaches. See Adding node components.

list_node_components

Lists a node’s components, with whether Monitor added each, whether it is attached, and a trigger’s action and condition counts.

remove_node_component

Removes a named component from a node, whoever added it.

set_node_component_property

Sets a property of a node’s named component. An Animation Player applies most of its properties at the next Play or Resume.

get_resource_directory

Reports Kanzi’s base resource directory, which decides what a relative resource path means.

set_resource_directory

Sets that directory. Mainly for Android, where resources otherwise come from inside the APK.

get_framebuffers

Lists FBO-backed render targets.

get_render_passes

Gets the render pass tree.

get_render_pass_preview

Gets a preview of a render pass output. Saves as a temporary PNG file.

get_render_pass_properties

Gets a render pass’s locally-set property values, each with its precedence. Same shape as get_node_properties.

set_render_pass_property

Sets one property on a render pass. Same value formats as set_node_property.

get_resource_properties

Gets any resource’s locally-set property values, addressed by handle or URL, and names the resource the key reached.

set_resource_property

Sets one property on any resource, addressed by handle or URL. Same value formats as set_node_property.

take_screenshot

Captures a screenshot of the application. Polls the two-phase capture protocol internally so a single call returns the image. Saves as a temporary PNG file.

start_capture

Arms the in-RAM frame ring and records continuously until stop_capture. The ring keeps the last N frames and overwrites the oldest. every_nth captures one of every N rendered frames, so a fixed ring spans N times as long. Requires ServiceCaptureEnabled = 1.

stop_capture

Freezes the ring so the frames it holds can be fetched.

get_capture_status

Gets the capture state, frames held and capacity, per-frame readback cost, peak bytes, and rendered frames against captured.

get_capture_manifest

Gets per-frame metadata: index, frame number, source frame, timestamp, inter-frame delta and dimensions. Use sourceFrame to space playback, because frames are not contiguous when every_nth is above 1.

fetch_capture_frame

Fetches one captured frame by index. Saves as a temporary PNG file.

fetch_capture_all

Fetches every frame the ring currently holds — not every frame recorded, because the ring overwrites the oldest. Saves the frames as temporary PNG files and assembles them into a video, MP4 by default or APNG, with playback timed from the captured timestamps.

list_breakpoints

Lists every property breakpoint, each with its condition, actions, hit counters, and whether it is armed. An entry reporting "notification": false could not be armed and never fires, which usually means the property name is wrong. Requires ServiceDebugEnabled = 1.

add_breakpoint

Adds a property breakpoint that breaks, logs, captures a screenshot, or runs a console command when a node property meets a condition. Takes the node path, property name, comparison and value, with an optional hit count and a once-only flag. The condition is evaluated inside the assignment that changed the property, so with a debugger attached the break action stops on the code that wrote the value.

remove_breakpoint

Removes one breakpoint by the ID list_breakpoints reports.

enable_breakpoint

Activates or deactivates one breakpoint without removing it. Activating resets the hit count, so a breakpoint with a hit target starts counting from zero again.

set_breakpoint_command

Sets the Monitor console command a breakpoint runs when it triggers, and enables that breakpoint’s command action. The command runs with no console attached, so its output goes to the application log, readable with get_logs.

clear_breakpoints

Removes every property breakpoint.

fetch_breakpoint_screenshot

Fetches the screenshot a breakpoint’s screenshot action captured. Reports none when no capture was requested, pending while waiting for the next render, failed when the request was abandoned at its deadline because no frame rendered, and ready with the image otherwise. Saves as a temporary PNG file.

get_performance

Gets current FPS, frame times, rendering statistics, GPU object counts, and staging buffer usage.

get_app_performance

Gets frames-per-second (FPS) information from the Kanzi Domain main loop.

get_performance_info_level

Gets the PerformanceInfo logging level.

set_performance_info_level

Sets the PerformanceInfo logging level.

list_watchers

Lists active performance watchers.

add_watcher

Adds a metric watcher that triggers a command when a threshold is crossed.

remove_watcher

Removes a watcher by ID.

reset_watcher

Resets a triggered watcher to active.

clear_watchers

Removes all watchers.

list_breakpoints

Lists every property breakpoint, each with its condition, actions, hit counters, and whether it is armed. An entry reporting "notification": false could not be armed and never fires, which usually means the property name is wrong. Requires ServiceDebugEnabled = 1.

add_breakpoint

Adds a property breakpoint that breaks, logs, captures a screenshot, or runs a console command when a node property meets a condition. Takes the node path, property name, comparison and value, with an optional hit count and a once-only flag. The hit count must not be negative: no change count reaches a negative target, so such a value is rejected rather than dropped, which would have armed a breakpoint that triggers on every change instead. The condition is evaluated inside the assignment that changed the property, so with a debugger attached the break action stops on the code that wrote the value.

remove_breakpoint

Removes one breakpoint by the ID list_breakpoints reports.

enable_breakpoint

Activates or deactivates one breakpoint without removing it. Activating resets the hit count, so a breakpoint with a hit target starts counting from zero again.

set_breakpoint_command

Sets the Monitor console command a breakpoint runs when it triggers, and enables that breakpoint’s command action. The command runs with no console attached, so its output goes to the application log, readable with get_logs.

clear_breakpoints

Removes every property breakpoint.

fetch_breakpoint_screenshot

Fetches the screenshot a breakpoint’s screenshot action captured. Reports none when no capture was requested, pending while waiting for the next render, failed when the request was abandoned at its deadline because no frame rendered, and ready with the image otherwise. Saves as a temporary PNG file.

capture_trace

Captures a Monitor profiling trace to file. Writes one file per active writer — .json for chrometrace, .perfetto-trace for perfetto.

clear_trace

Empties the Monitor profiling trace storage, so the next capture_trace no longer repeats what earlier traces held. See Clearing the trace storage.

fetch_trace

Fetches the most recent .json (chrometrace) Monitor profiling trace as a JSON string. Returns an error pointing at fetch_perfetto_trace if only the perfetto writer ran.

fetch_perfetto_trace

Fetches the most recent .perfetto-trace (native Perfetto protobuf) capture. The binary is transported as base64 over the line protocol, decoded by the tool, and persisted to a temp file. Returns {file, path, size} — pass path to Perfetto UI for visualisation.

capture_kztrace

Captures a kzTrace snapshot (engine-native tracing, requires Debug or Profiling build).

fetch_kztrace

Fetches the most recent kzTrace as JSON.

get_kztrace_categories

Lists the kzTrace categories the application registers, with their descriptions. Read-only, and separate from the profiling categories. See Listing the kzTrace categories.

list_writers

Lists registered trace writers with name, description, and current active state.

activate_writer

Activates a trace writer by name (e.g. chrometrace, perfetto). Use list_writers to see what is registered.

deactivate_writer

Deactivates a trace writer by name. Deactivating all writers stops trace output.

get_profiling_categories

Lists the profiling categories (not kzTrace categories) and whether each is enabled, or gets one by name. A disabled category records nothing. See Choosing which profiling categories are recorded.

set_profiling_category

Enables or disables one profiling category.

set_profiling_category_filter

Applies a category filter with the syntax of ProfilingCategoryFilter (e.g. *=off;MainLoop|MyCategory=on).

reset_profiling_categories

Returns every profiling category to its code default, then applies the startup filter again. A defined state, not an undo.

get_kzb_files

Lists the kzb files the application loaded, optionally with their entries and byte sizes.

get_property_types

Lists the registered property types, including project-authored ones. Supports filtering and paging.

get_message_types

Lists the registered message types, including project-authored ones. Supports filtering and paging.

find_message_type

Looks up one message type by exact name in the engine’s global registry. Answers what the listing cannot: whether a name that does not appear in it is unregistered, or merely unreachable from the sources the listing draws on. The name must match exactly; use get_message_types with a filter to search.

get_effective_schema

Resolves the property and message types one class declares, across its base chain and its mixed-in concepts, each entry attributed to the class that declares it. Takes an exact class name. Not everything that influences a node: see What a class declares, in one call.

get_metaclasses

Lists the registered metaclasses. Supports filtering and paging.

get_data_sources

Gets all data sources and DataObject trees.

set_data_value

Sets a value in a DataObject tree.

get_status

Gets Overwatch service status.

get_fonts

Gets all active FontRuntimes with font identity, style, glyph cache state, metrics, and node info.

get_font_glyph_cache_preview

Gets a preview of a font’s glyph cache texture. Saves as a temporary PNG file.

set_glyph_cache_size

Sets the glyph cache texture size for newly created caches. Requires OverwatchPropertyChangeEnabled.

get_graphics_info

Gets graphics backend and device information.

get_logs

Gets recent log entries.

set_log_buffer_size

Sets the log buffer size at runtime.

get_log_config

Gets the current log buffer configuration.

get_gpu_timestamps

Gets the state of the GPU timestamp dump: whether it is on, its frame interval, and the graphics backend. It does not check the values. See the GPU timestamp dump.

set_gpu_timestamps

Enables or disables the per-frame and per-render-pass GPU timestamp dump. The lines arrive in the log, so read them with get_logs.

get_log_diagnostics

Gets KanziLog trace pipeline diagnostics.

get_ui_visibility

Gets the Monitor UI overlay visibility status for each node tree.

toggle_ui

Shows or hides the on-screen UI overlay. Accepts an optional node_tree parameter to target a specific node tree.

get_basicui_screens

Lists available BasicUI overlay screens and the current selection.

set_basicui_screen

Switches to a BasicUI overlay screen by index.

get_font_scale

Gets the current BasicUI overlay font scale.

set_font_scale

Sets the BasicUI overlay font scale.

get_idle_suspend

Gets the current MainLoopScheduler SuspendWhenIdle state.

set_idle_suspend

Enables or disables MainLoopScheduler SuspendWhenIdle.

send_command

Sends a raw Kanzi Monitor command.

quit_application

Quits the Kanzi application.

Response size optimization

The MCP server automatically reduces large responses to avoid consuming the AI assistant’s context window:

  • Image responses (take_screenshot, get_texture_preview, get_render_pass_preview): Raw RGBA pixel data is converted to a temporary PNG file. A framebuffer capture is oriented from the rowOrder the plugin reports with it, so it comes out upright on any backend; a texture or render-pass preview, which carries no such report, is flipped as GPU readback data conventionally requires. The tool returns the image dimensions, file path, and any non-pixel metadata. The AI assistant can then read the PNG file when it needs to see the image.

  • Binary trace responses (fetch_perfetto_trace): .perfetto-trace files are protobuf binaries and cannot traverse the text-mode command protocol as-is. The C++ side base64-encodes the bytes inside a JSON envelope; the MCP tool decodes the base64 and writes the resulting binary to a temporary .perfetto-trace file, returning the path. The AI assistant can pass the path on to a trace analyser or open it in Perfetto UI.

  • Large text responses (get_scene_tree, get_resources, get_all_resources, fetch_trace, get_data_sources): When a response exceeds 50 KB, it is written to a temporary JSON file. The tool returns the file path and a preview of the first 200 lines.

Temporary files are written to the system temp directory and are not automatically deleted.

Troubleshooting

MCP server does not connect

  • Verify that the Kanzi application runs with the Kanzi Monitor plugin loaded.

  • Check that ServiceOverwatchEnabled=1 is set in kanzimonitor.cfg.

  • Confirm that the host and port match your kanzimonitor.cfg settings. The RemoteConsolePort setting defaults to 56000.

Tools return timeout errors

  • take_screenshot polls the two-phase capture protocol internally, so a single call returns the image. If it reports Screenshot timed out — render stage did not complete, the application is not rendering new frames. When running in Studio Preview, ensure Allow preview to update if not in focus is enabled.

  • Increase KANZI_MONITOR_TIMEOUT for slow devices or serial connections.

Serial connection fails

  • Install pyserial-asyncio-fast: pip install pyserial-asyncio-fast.

  • Verify the serial port name, for example COM3 on Windows or /dev/ttyUSB0 on Linux.

  • Ensure that SerialConsoleEnabled=1 is set in kanzimonitor.cfg.

Property changes have no effect

  • Ensure that OverwatchPropertyChangeEnabled=1 is set in kanzimonitor.cfg.

See also

Using the Overwatch service

Using the Monitor Web UI

Configuring Kanzi Monitor