fix: improve Hyprland 0.55 and MCP schema compatibility#45
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces schema sanitization to remove unsupported unsigned integer formats from exported tool schemas in src/server.rs, along with corresponding unit tests. It also updates window activation in src/windowing/backends/hyprland.rs to try a new Lua-based focus dispatcher before falling back to the legacy command. Feedback suggests simplifying the recursion logic in sanitize_unsigned_integer_formats by matching directly on the serde_json::Value enum to make the traversal cleaner and more robust.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| fn sanitize_unsigned_integer_formats(value: &mut serde_json::Value) { | ||
| let serde_json::Value::Object(object) = value else { | ||
| return; | ||
| }; | ||
|
|
||
| let has_unsigned_format = matches!( | ||
| object.get("format").and_then(serde_json::Value::as_str), | ||
| Some("uint" | "uint8" | "uint16" | "uint32" | "uint64" | "usize") | ||
| ); | ||
| if has_unsigned_format { | ||
| object.remove("format"); | ||
| } | ||
|
|
||
| for nested in object.values_mut() { | ||
| match nested { | ||
| serde_json::Value::Object(_) => sanitize_unsigned_integer_formats(nested), | ||
| serde_json::Value::Array(items) => { | ||
| for item in items { | ||
| sanitize_unsigned_integer_formats(item); | ||
| } | ||
| } | ||
| _ => {} | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The recursion logic in sanitize_unsigned_integer_formats can be simplified and made more robust by matching directly on the serde_json::Value enum, similar to how it is done in the test helper collect_unsigned_integer_formats. This avoids the nested match inside the loop and ensures that any nested array-of-arrays or other structures are correctly traversed.
fn sanitize_unsigned_integer_formats(value: &mut serde_json::Value) {
match value {
serde_json::Value::Object(object) => {
let has_unsigned_format = matches!(
object.get("format").and_then(serde_json::Value::as_str),
Some("uint" | "uint8" | "uint16" | "uint32" | "uint64" | "usize")
);
if has_unsigned_format {
object.remove("format");
}
for nested in object.values_mut() {
sanitize_unsigned_integer_formats(nested);
}
}
serde_json::Value::Array(items) => {
for item in items {
sanitize_unsigned_integer_formats(item);
}
}
_ => {}
}
}|
Thanks @LikelyLucid — this is a great contribution. The Lua-first/legacy-fallback focus order is exactly the right compatibility shape, and stripping the non-standard schemars uint formats at the export boundary (with regression coverage) cleans up a real annoyance for MCP clients. CI is fully green, merging. This will go out in the next release shortly. |
… schema fixes Backfills CHANGELOG entries for 0.3.0 and 0.3.1 and adds the 0.4.0 section covering the generic X11/EWMH window backend (#41), the pi coding agent extension package (#42), the Hyprland 0.55 Lua focus dispatcher with legacy fallback plus schemars unsigned-format sanitization at the MCP export boundary (#45), and the Ubuntu GNOME extension bootstrap fix (#40).
Summary
focuswindowdispatcherformatannotations from exported MCP input and output schemasMotivation
Hyprland 0.55.4 rejects the legacy command used for exact window targeting:
The supported 0.55 form is:
The Lua-first/legacy-fallback order keeps older Hyprland releases working.
Separately,
schemarsemitsuint,uint8,uint32, anduint64formats throughout tool schemas. These are not standard JSON Schema formats and produce repeated warnings in MCP clients. The export-boundary sanitizer removes only those format annotations while preserving integer types and numeric constraints.Validation
Manually validated on Hyprland 0.55.4, including cross-workspace exact focus.
Results: 134 library tests passed; MCP safety check passed for all 18 tools. The schema regression test confirms no unsupported unsigned formats remain in either input or output schemas.