Skip to content

fix(mcp-agent): correct modifier key-combo normalization (Error Input Format) + cap UI-tree recursion depth#477

Open
DieBurgerSouce wants to merge 2 commits into
mediar-ai:mainfrom
DieBurgerSouce:fix/key-combo-and-tree-depth
Open

fix(mcp-agent): correct modifier key-combo normalization (Error Input Format) + cap UI-tree recursion depth#477
DieBurgerSouce wants to merge 2 commits into
mediar-ai:mainfrom
DieBurgerSouce:fix/key-combo-and-tree-depth

Conversation

@DieBurgerSouce

Copy link
Copy Markdown

Summary

Two independent fixes for the Windows MCP agent:

  1. Modifier key-combos were broken in press_key / press_key_global.
  2. The cached UI-tree walk can overflow the stack on deeply-nested windows.

1. Key-combo normalization (crates/terminator-mcp-agent/src/helpers.rs)

normalize_key wrapped the entire key string in braces when it didn't already
contain {, so the documented "Ctrl+Z" became "{Ctrl+Z}" — a single unknown
token that the uiautomation backend rejects:

-32002 "Failed to press key on focused element"
Platform-specific error: Error { code: 6, message: "Error Input Format" }

Every modifier combo (Ctrl+Z, Ctrl+A, Alt+F4, …) failed. The schema
docstrings also recommended a broken form ("{Ctrl}{V}"): a single letter
inside braces ({V}) is not a valid named key.

Fix: parse +-separated combos into valid uiautomation syntax —
modifiers → {Ctrl}/{Alt}/{Shift}/{Win}; a final single character → a
literal char held under the modifier ("{Ctrl}z"); a final named key → braced
("{Alt}{F4}"). Already-braced raw syntax and lone characters pass through
unchanged. This matches the behaviour of the existing, tested
translate_gemini_keys converter in terminator-computer-use.

Also corrects the misleading key docstrings for PressKeyArgs /
GlobalKeyArgs (src/utils.rs).

input before after
Ctrl+Z {Ctrl+Z} {Ctrl}z
Ctrl+Shift+S {Ctrl+Shift+S} {Ctrl}{Shift}s
Alt+F4 {Alt+F4} {Alt}{F4}

2. UI-tree depth cap (crates/terminator/src/platforms/windows/tree_builder.rs)

build_node_from_cached_element recurses unbounded when the caller passes no
tree_max_depth. Deeply-nested windows overflow the native stack — Windows
terminates the process with 0xC00000FD (the exit code the npm wrapper already
special-cases and restarts on). Add cap_tree_depth() / SAFE_MAX_TREE_DEPTH
(50) and apply it in build_tree_with_cache so the cached walk is always
bounded, even with no explicit depth.


Testing

  • Unit tests added for normalize_key (combos, single keys, passthrough) and
    cap_tree_depth. Verified red→green (breaking the fix fails the test).
  • cargo test -p terminator-mcp-agent --lib / -p terminator-rs --lib pass.
  • Empirical runtime check against a release build: press_key_global with
    Ctrl+N / Ctrl+A / Ctrl+W now return executed_without_error
    (key_pressed: "{Ctrl}n" etc.) where the previous build returned
    Error Input Format.

🤖 Generated with Claude Code

Firmenichgmbh and others added 2 commits June 7, 2026 02:04
…yntax

press_key / press_key_global rejected every modifier combo. normalize_key
wrapped the whole string in braces, turning "Ctrl+Z" into "{Ctrl+Z}" — a single
unknown token the uiautomation backend rejects with E_INVALIDARG ("Error Input
Format"). The documented examples ("{Ctrl}{V}") were also wrong: a single letter
inside braces ("{V}") is not a valid named key.

Parse "+"-separated combos instead: modifiers -> {Ctrl}/{Alt}/{Shift}/{Win};
a final single character -> literal held under the modifier (e.g. "{Ctrl}z");
a final named key -> braced (e.g. "{Alt}{F4}"). Already-braced raw syntax and
lone characters pass through unchanged. Mirrors the existing, tested
translate_gemini_keys converter. Adds unit tests and corrects the misleading
schema docstrings for both tools.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
build_node_from_cached_element recurses unbounded when the caller passes no
tree_max_depth. Deeply nested windows can overflow the native stack — Windows
kills the process with 0xC00000FD, which the npm wrapper detects and restarts.
Add cap_tree_depth() / SAFE_MAX_TREE_DEPTH (50) and apply it in
build_tree_with_cache so the cached tree walk is always bounded. Adds a unit test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants