Files

Workflow Artifacts as MCP Apps

OpenWork exposes Workflow results as portable, standards-based MCP Apps. A supporting MCP host can render an artifact inline; every other MCP client still receives a useful Markdown result.

Product flow

  1. Code Mode produces data and a deterministic Markdown rendering.
  2. The result can be saved as an immutable Workflow snapshot with a receipt, schema validation, result digest, and exact Workflow version.
  3. A person or an Automation may run the Workflow again. Automations only refresh the data snapshot; they do not create or execute UI code.
  4. The read-only render_workflow_artifact tool loads the latest successful snapshot, or an exact receipt when requested. render_dynamic_artifact remains as a deprecated alias for one release.
  5. MCP Apps hosts resolve the linked ui:// resource and inject the tool's structured result. Other hosts show the Markdown fallback.

This keeps execution, scheduling, data, and presentation separate:

Workflow ──run──> immutable snapshot ──read──> MCP tool result
       ▲                        ▲                          ├─ Markdown fallback
       │                        │                          └─ ui:// MCP App
   explicit run           Automation refresh

The MCP App never runs a Workflow, mutates an artifact, or introduces another scheduler. It only presents an already-authorized snapshot.

MCP Apps conformance

The agent MCP server implements the io.modelcontextprotocol/ui extension and the 2026-01-26 MCP Apps protocol:

  • server capability: extensions.io.modelcontextprotocol/ui.mimeTypes contains text/html;profile=mcp-app;
  • tool metadata: _meta.ui.resourceUri points to ui://openwork/workflow-artifact/v1/view.html (with the compatibility metadata emitted by the official MCP Apps server helpers);
  • resource delivery: resources/read returns one self-contained HTML5 document with MIME type text/html;profile=mcp-app;
  • view lifecycle: the document performs ui/initialize, sends ui/notifications/initialized, receives tool input/result/cancellation and host-context notifications, reports size changes, and acknowledges teardown;
  • data delivery: the tool returns versioned structuredContent, lightweight lineage in result _meta, and a complete text fallback;
  • security: the resource declares an empty network/frame/base-URI CSP, loads no external code, performs no network requests, and inserts artifact values with DOM text APIs rather than HTML interpolation.

The shared payload schema lives in @openwork/types/workflows so a host can validate the data contract independently of this presentation resource.

UI behavior

The self-contained view is intentionally data-first and framework-neutral. It adapts the Preview tab to common result shapes:

  • arrays of records become a bounded table;
  • flat objects become metric cards;
  • nested or irregular values fall back to formatted JSON;
  • Data always exposes the full structured result, with a rendering-size guard;
  • Lineage shows the immutable receipt, Workflow/version IDs, source, digest, renderer, and Automation run when present.

The view follows host theme/style context, uses responsive HTML, and caps large tables and rendered JSON without changing the underlying tool result.

Authorization and failure behavior

The renderer uses the same organization membership, team grants, and saved Workflow authorization path as the existing artifact APIs. It does not accept a plugin or result payload from the caller. The caller supplies only a saved Workflow ID, an optional exact receipt, and an optional freshness threshold.

Only readable, successful, non-deleted snapshots can be rendered. Missing, failed, deleted, or unauthorized results fail closed with a non-sensitive text error. A stale snapshot remains renderable and is labeled stale; a failed refresh leaves the last successful artifact available with a needs-attention state.

Next interoperable slice

The provider side is deliberately usable without an OpenWork-specific host. The next slice is a generic MCP Apps host in the desktop conversation surface: negotiate the UI extension with upstream MCP servers, preserve tool/resource metadata and structured results through the runtime, sandbox ui:// resources, and bridge the standard JSON-RPC lifecycle. That host should consume the same standard contract rather than adding a custom React artifact format.