feat(mcp): add headless MCP server for Myra layouts#523
Open
Fuitad wants to merge 4 commits into
Open
Conversation
Summary: - Add Myra.Mcp, a stdio Model Context Protocol server (net8) that embeds Myra.PlatformAgnostic behind a no-GPU headless platform stub, so .xmmp layouts load and validate through Myra's own engine with no GraphicsDevice. - Expose five tools: validate_layout, read_layout, save_layout, list_widget_types, and describe_widget (properties, enums, defaults, attached properties, and style names). - Confine every path argument to a --root / MYRA_MCP_ROOT workspace using case-sensitive comparison and per-component symlink resolution (fail closed); serialize all engine calls under one lock over Myra's process-global state. - Add Myra.Mcp.Tests (xunit, 31 tests) including an MCP-protocol integration test and a loader-parity test that proves the catalog only advertises vocabulary Project.LoadFromXml accepts. Core Myra is untouched. Rationale: - Gives AI coding agents a real load, validate, and save loop plus widget introspection driven by Myra's engine instead of editing MML blind, with authoritative error messages and no reimplementation of MML parsing. - Myra.PlatformAgnostic (netstandard2.0, no MonoGame/XNA/Stride) is the only backend that runs headless cross-platform; the existing MonoGame test suite is Windows-only. - The loader throws on the first error, so results carry one diagnostic; save writes the raw MML verbatim and refuses invalid layouts unless forced. Tests: - dotnet test src/Myra.Mcp.Tests -> 31/31 passing - Live server driven end to end over stdio: initialize, tools/list, and validate/read/save/describe round trips
Summary: - Add stylesheetPath to the validate_layout and save_layout rows of the README tool table. - Add a note describing stylesheetPath as read-only stylesheet validation context. Rationale: - Both tools expose an optional stylesheetPath parameter, but the README table listed neither, so an agent reading the docs would not know the parameter exists or what it does. Tests: - not run (docs-only change).
…spection Summary: - Add StylesheetService that loads a stylesheet headless (default skin when no path given) and reports its named styles per widget, font ids, and atlas region names. - Expose it as the inspect_stylesheet MCP tool; register the service in the host. - Add StylesheetInfo and StyleGroup result records. - Add StylesheetInspectionTests plus a named_styles.xmms fixture (reuses the Commodore64 atlas and font) to exercise named-style enumeration. - Update the integration test to expect six tools and document inspect_stylesheet in the README. Rationale: - Codex feedback asked for read-only stylesheet and atlas inspection so an agent authoring layouts can discover which StyleName values, fonts, and atlas drawables it may reference, rather than guessing. The empty default style key is omitted because it is not referenceable by name. Tests: - dotnet test src/Myra.Mcp.Tests: 34 passed, 0 failed. - Live stdio round-trip: inspect_stylesheet returned the named "danger" Button style, the commodore-64 font, and the atlas regions for the Commodore64 fixture; the default skin returned 106 regions and two fonts.
Summary:
- Add the layout_bounds MCP tool: arranges a confined .xmmp at a viewport
(default 1280x720) and returns each widget's { id, type, x, y, width,
height, visible, zeroSize, clipped } in tree order.
- Run Myra's Measure/Arrange pass headless on Project.Root; position from
ToGlobal(Point.Empty), size from Bounds, under MyraEngine.Gate with
MyraWorkspace path confinement and non-positive-viewport rejection.
- Track effective visibility (widget and all ancestors visible); zeroSize
and clipped fire only for visible widgets, so an intentionally hidden
widget is never reported as a collapsed or clipped layout bug.
- Add WidgetBounds/LayoutBoundsResult records; extract a shared LoadProject
helper from ValidateCore.
- Document the tool in the README and bump the integration test to seven
tools with a live stdio round-trip.
Rationale:
- Lets an agent detect overlap, clipping, and collapsed widgets with no
live render. clipped is viewport-only per the request; ancestor and
ScrollViewer clipping is deferred with a documented upgrade path.
- A separate feasibility gate test confirms Measure/Arrange (including
FontStashSharp text measurement) runs with no GraphicsDevice before the
tool is built.
Tests:
- dotnet build src/Myra.Mcp (0 errors, 0 warnings)
- dotnet test src/Myra.Mcp.Tests (52/52 passed)
- Live stdio round-trip against the built server verified
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Rationale:
Tests: