Commit e740df3
authored
refactor(mcp): align Prefab UI emission with MCP Apps spec (SEP-1865) (#51)
Mirrors the post-#422 pattern from katana-openapi-client@ca986527 —
removing the markdown-template rendering layer entirely and routing
Prefab UI through the canonical MCP Apps resource path that fastmcp
3.x and prefab-ui already implement end-to-end.
### What changed
**`make_tool_result` simplified** to a minimal two-line helper:
- `content` is now `response.model_dump_json(indent=2)` (the LLM's
view of the structured response — per spec, `structuredContent` is
"not added to model context")
- `structured_content` is the PrefabApp when `ui=` is provided (FastMCP
auto-detects via `_prefab_to_json`); otherwise `response.model_dump()`
- Removed `template_name` and `**template_vars` parameters — every
call site in this codebase passed `ui=`, so the markdown rendering
path was always going to be discarded
**Templates module deleted** — all 11 Jinja templates and
`templates/__init__.py`. Reference MCP servers
(`modelcontextprotocol/ext-apps/examples/customer-segmentation`,
`system-monitor`, etc.) all emit raw JSON content for the same reason.
**Tool sites cleaned up** — every `make_tool_result(...)` call across
`tools/orders.py` and `tools/statuses.py` collapsed to its essential
form: `make_tool_result(response, ui=app)`. Dropped:
- `format_md_table` calls and the per-tool table-row pre-computation
- comment_block / validity_block / order_label / *_range string-building
- per-call `outcome=...`, `http_status=...`, `message_line=...` template
variables that the result templates consumed
- The `format_md_table` helper itself (no remaining callers)
**`fastmcp>=2.13.0` floor bumped to `>=3.0`** — the `_maybe_apply_prefab_ui`
auto-wiring lives in fastmcp 3.0+ (lockfile already at 3.2.4, so this
is a documentation pin, not a forced upgrade).
**New `tests/test_mcp_apps_integration.py`** — parameterizes over all
8 UI-marked tools and asserts:
- Each tool's `meta.ui.resourceUri` points at a registered prefab
renderer (`ui://prefab/tool/<hash>/renderer.html`)
- `resources/list` exposes one renderer per UI tool with mime-type
`text/html;profile=mcp-app`
- The URI in tool meta exists in resources — a 404 on fetch would
break the iframe silently in the host
**`test_tool_result_utils.py` rewrite** — drops the obsolete
`template_name` arg from each call; new test pinning that `content`
emits the JSON dump (not formatted markdown).
### Why
Tools previously built nested PrefabApp component trees AND rendered
Jinja markdown for every call, with `make_tool_result` returning both.
The markdown was strictly worse on tokens than JSON content with no
upside (Claude Desktop and other MCP Apps hosts render the iframe; non-UI
hosts read the JSON directly). Removing the dual path simplifies the
flow and matches what the rest of the ecosystem is doing.
Net diff: ~13 templates + per-tool template-var dicts deleted; ~700 LoC
removed. 272 tests pass (was 261; +10 new for MCP Apps integration, +1
for JSON content shape).
Reference: `katana-openapi-client@ca986527`.1 parent 0368ce9 commit e740df3
19 files changed
Lines changed: 242 additions & 500 deletions
File tree
- statuspro_mcp_server
- src/statuspro_mcp
- templates
- tools
- tests
- tools
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 0 additions & 5 deletions
This file was deleted.
0 commit comments