poetry-agent
The agent-interop gem: every surface through which an agent reaches the component contract, projected from the one registry the other gems build.
What it is
Two surfaces ship today. The MCP server is for
coding agents in your editor: boot-free, read-only, ten tools that
query and verify against what your app actually ships. The
WebMCP runtime is for the person's own browser
agent: rendered components' declared tools, registered with
document.modelContext when an instance opts in. Both
read the committed registries; neither is a second source.
Install
gem "poetry-agent"
Loading the gem is the integration: the engine registers its
controllers manifest with poetry-core (so webmcp:
roots validate at render), pins @poetry/agent in the
importmap, and mounts the origin-trial middleware.
The MCP server
poetry-agent speaks newline-delimited JSON-RPC over
stdio with no SDK dependency. Wire it into Claude Code, Cursor, VS
Code, Zed, or RubyMine with bin/rails g poetry:editor;
the MCP guide covers the ten tools and
the verify loop they close.
bundle exec poetry-agent # the stdio MCP server; run it from your app directory
The WebMCP runtime
Register the runtime beside Poetry's controllers and any component that declares tools can opt in per instance. The WebMCP guide shows the two paths - components and declarative forms - live.
import { registerPoetryAgent } from "@poetry/agent"
registerPoetryAgent(application)
The AG-UI relay
AG-UI is the event protocol agent frameworks speak to user-facing
applications: a run streams text deltas, tool calls, shared state,
activities, and interrupts. Poetry::Agent::AGUI is the
Rails side of that connection - a client, not a server. Its
Transcript folds the stream into chat-shaped messages,
its Relay renders every change as a versioned Turbo
Stream through your own row partial, and a rendered component's
declared tools are advertised as the agent's frontend tools and
executed in the browser by the same registrar WebMCP uses. The
AG-UI Relay demo runs a scripted
agent through the whole loop: streamed rows, a tool call the tabs
component executes, the result reported back, an interrupt answered.
The AG-UI Relay guide is the host recipe.
The A2UI catalog and renderer
A2UI is the declarative generative-UI format: an agent emits a flat
component list against a catalog the client owns. Poetry's registry is
that catalog once projected -
Poetry::Agent::A2UI::Catalog.from_registry writes the v1.0
JSON Schema document (style axes as enums, options as typed
properties, slots as child references, the content block as
text or children), and this site serves it at
/a2ui/catalog.json for any agent
or middleware that reads catalogs by URL.
The renderer is the other half. Poetry::Agent::A2UI::Session
folds the envelope (createSurface, updateComponents,
updateDataModel, deleteSurface) into surfaces and
answers what it cannot honor with the spec's renderer-to-agent errors;
Renderer renders a surface through your view context - the
spec's basic catalog mapped onto Poetry's components, or Poetry's own
catalog rendered straight from the registry - and Streams
delivers every change as a versioned Turbo Stream. A surface is a form:
bound inputs are named by their data-model pointer, every agent action is
a submit button, and Session#action turns the submitted form
into the spec's action message, so two-way binding syncs on
the action exactly as the spec asks. The
A2UI Surface demo renders both
catalogs, streams a third surface progressively, and shows the message
each submission produces. The
A2UI Surfaces guide is the host recipe.
The catalog's functions run on the server: formatString
interpolation, the formatters, the validators behind checks,
the combinators, openUrl. A failing check rejects the action
with its failures rendered under their controls, and the same rules run
in the browser as the user types (poetry--agent--a2ui-surface):
a button whose checks fail is disabled, an input's error slot fills. Every
rendered component carries a render-stable key, and a surface's updates
arrive as morphing replaces, so typed text, a selected tab, and an open
dialog survive the agent's next message. A function a catalog marks
rendererOrAgent answers an agent's
callRendererFunction with a response. In the
AG-UI Relay demo the agent paints a
surface mid-stream as an a2ui-surface activity and its form
posts back into the next run as forwardedProps.a2uiAction.
What's in the gem
| Piece | What it does |
|---|---|
Poetry::Agent::MCP::Server | the MCP server; #handle is a pure request-to-response function, #serve the stdio loop |
exe/poetry-agent | the one executable (bundle exec poetry-agent); skills, helpers, and recipes ride along when poetry-ui is bundled |
poetry--agent--webmcp | the registrar controller: registers an opted-in instance's tools on connect, aborts them on disconnect, dispatches calls to the component's own action |
poetry--agent--webmcp-form | the declarative-form controller: an agent-invoked submit answers through SubmitEvent.respondWith instead of navigating |
@poetry/agent adapter | the one file that knows the document.modelContext surface, so spec churn stays a one-file fix |
Poetry::Agent::WebMCP::OriginTrial | Rack middleware serving origin-trial tokens on HTML responses; a pass-through with none configured |
Poetry::Agent.configure | origin_trial_tokens and the per-document registration_budget |
Poetry::Agent::AGUI | Client, SSE, RunInput, JsonPatch, Transcript, Relay, TurboStream - the AG-UI client and its Turbo Stream relay |
poetry--agent--agui-client-tool | the bridge controller: executes an agent's frontend tool call through the registrar and POSTs the result to the continue URL |
Poetry::Agent::A2UI::Catalog | the registry projected as an A2UI v1.0 catalog document (to_h, inline, to_json) |
Poetry::Agent::A2UI::Session | the envelope consumer: surfaces, data models, renderer-to-agent errors, and #action (a submitted surface form as the spec's action message) |
Poetry::Agent::A2UI::Renderer | renders a surface through a view context as a form of pointer-named inputs and action buttons; never raises for an agent's mistake (warnings) |
Poetry::Agent::A2UI::Catalogs | Basic (the spec's catalog mapped onto Poetry's components) and Native (Poetry's catalog rendered from the registry, no hand mapping) |
Poetry::Agent::A2UI::Streams | every surface change as a versioned Turbo Stream (append on first appearance, a morphing vreplace after, remove on delete) |
Poetry::Agent::A2UI::Functions | the function registry and the basic catalog's set (Functions.basic); Expression parses formatString, Evaluator resolves values in scope, Checks runs a component's rules |
poetry--agent--a2ui-surface | the client side of a surface's checks: evaluates the rendered program as the user types, disables failing buttons, fills error slots |