example(math_ui): a toolkit that ships a tool and its user interface [TOO-1999] - #925
Conversation
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
Adds a runnable example of the whole path this milestone opens: a toolkit declares a static resource, the worker serves it under /worker/resources/*, and a caller reads back the bytes the toolkit shipped. SumList adds a list of numbers and resolves as Math.SumList. sum-list.html is the interface for it and resolves as ui://math/0.1.0/sum-list.html, built at registration from the toolkit's name and installed version rather than typed by the author. The mime type is text/html;profile=mcp-app, which the MCP Apps extension pins exactly. The document is self-contained with no external assets, so it renders without the content-security-policy allowlists that a resource cannot yet declare. The distribution is named arcade_math so the tool reads as Math.SumList. That shadows the published toolkit of the same name, so the README says to install it in its own environment. Examples are excluded from the release workflow. The README carries the commands end to end: install, start the worker, mint a token, call both endpoints, and read the same resource from the engine's own client. Two things the example deliberately does not do, both above this leg: the tool does not advertise its interface, because ToolDefinition has no _meta field, and nothing renders the document.
1176927 to
2755613
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…cgustin/math-sumlist-ui-demo
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
Stacked on #922, so it sits on all six of the M1 arcade-mcp PRs. Not part of an issue: this is the demo for the milestone.
A runnable example of the whole path M1 opens. A toolkit declares a static resource, the worker serves it under
/worker/resources/*, and a caller reads back the bytes the toolkit shipped.What it adds
arcade_math/tools/arithmetic.py@tool sum_list, which resolves asMath.SumListarcade_math/ui/resources.py@resource(path="sum-list.html"), which resolves asui://math/0.1.0/sum-list.htmlarcade_math/ui/sum_list.htmlThe author writes only the path. The framework builds the URI at registration from the toolkit's name and installed version. The mime type is
text/html;profile=mcp-app, which the MCP Apps extension pins exactly and the reference host compares with string equality.It runs
POST /worker/resources/list:{"resources":[{"name":"sum_list_ui","title":"Sum a list of numbers","uri":"ui://math/0.1.0/sum-list.html","description":"Interface for the SumList tool: enter numbers, see the running total.","mimeType":"text/html;profile=mcp-app"}]}POST /worker/resources/readreturns the 3072-byte document undercontents[0].textwith the same mime type. The engine's own client reads the same resource through the manual test in ArcadeAI/monorepo#3659. Full commands in the README.Two things it deliberately does not do
The tool does not advertise its interface. A host learns a tool has one by reading
_meta.ui.resourceUri, andToolDefinitionhas no_metafield, so nothing connectsMath.SumListto its URI except the two being in the same toolkit. Nothing renders the document either. Both sit above this leg.Two things building it surfaced
Resources are invisible to local-file discovery.
analyze_files_for_toolsscans for@toolonly and never callsadd_toolkit, so pointing the server at a directory of loose Python files finds the tools and silently none of the resources. Only the installed-package path registers them. That is consistent with the hosted worker, which installs packages, but a Builder iterating locally would watch a declaration disappear without a word.The URI authority is not cased like the tool name. The tool is
Math.SumListand the URI isui://math/..., because qualification usestoolkit.namewhile the tool's fully-qualified name is display-cased. Both are stable and RFC 3986 calls an authority case-insensitive, so nothing breaks. Worth a decision rather than an accident, since a gateway correlating a tool with its interface will see both spellings.Neither is fixed here. Flagging them where they were found.
Verification
uvx ruff@0.6.7 checkandformat --checkclean. Verified by running it: worker up, both endpoints answering, and the engine client reading the document back with the mime type byte-identical to the listing.Note
Low Risk
Documentation and isolated example code only; no changes to auth, worker routing, or production libraries in this diff.
Overview
Adds a new
examples/toolkits/math_uidemo package that shows a toolkit shipping both a tool and a host-renderable UI over the worker/worker/resources/*path.The
arcade_mathpackage registers@tool sum_list(Math.SumList) and@resourceforsum-list.html, which resolves toui://math/0.1.0/sum-list.htmlwith mime typetext/html;profile=mcp-app. The HTML is bundled via Hatchforce-includeand loaded at registration as in-memory text.pyproject.tomlwires monorepouveditable sources and adevextra forarcade-mcp-server.The README documents local worker startup (JWT + list/read curls) and points to the engine’s manual end-to-end resource test. The example intentionally does not link the tool to the resource via
_meta.ui.resourceUrior render the UI in-process.Reviewed by Cursor Bugbot for commit 26b6e67. Bugbot is set up for automated code reviews on this repo. Configure here.