Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Portable artifacts

Artifacts let an AI client save a small, durable page in your Stackyapper workspace. Stackyapper hosts the page, keeps immutable revisions, and applies the current viewer’s permissions every time a control runs.
Artifact hosting is a beta, currently limited to allowlisted Business workspaces. If a workspace leaves Business, artifact owners retain an owner-only catalog for opening, exporting, and deleting their existing artifacts. Creating, editing, sharing, importing, running controls, and AI client discovery remain unavailable until Business is active again.

Create an artifact with your AI client

Your AI client can read the built-in artifact-authoring skill, listed with Stackyapper's other skills. It guides the client through planning, checking, and saving an artifact. An owner or admin can turn the skill off like any other built-in skill. The skill is guidance only: it does not make artifacts available in your workspace, grant access to an app, or run any action.
  1. Describe what you need. Say who will read the artifact and what they should do with it, for example "a one-page quarterly service report for the leadership team" or "a calculator that estimates onboarding hours". The skill points the client to a starting example for the kind of artifact you asked for: a report, a calculator or simulation, a dashboard, a process diagram, a brand prototype, or a plan or design comparison.
  2. Supply real material. Give the client the brand colors, figures, and images to use. The client should not invent brand colors, trends, or images, and it labels proposals, assumptions, and sample data as such. For live data, it finds the app tools you can use and declares each one the artifact needs.
  3. Check the draft. Before saving, the client runs stackyapper_validate_artifact. See Checking a draft.
  4. Save and open it. The client saves the artifact as a new revision and opens it. Look at the result yourself, including a narrow window and any empty, loading, or error states, before you rely on it or share it.
Ask for changes in the same way. The client reads the current source, edits it, checks it again, and saves a new revision.

Build your own MCP app

In an approved Business workspace, ask your agent to build an interactive MCP app using the mcp-app-authoring skill. These apps are saved as artifacts and use the same hosting, revisions, and access controls described on this page. For example:
Build a project estimate MCP app with an hours input, a $100 hourly rate, a calculated total, and a reset button. Use no connected data. Validate it, save it, and open it so I can try the controls.
The skill includes a small calculator the agent can adapt. For a connected app, describe the system to read and the controls you need; the agent must discover the available tools and declare those dependencies before saving. If your system needs a new connector, start with Build a custom connector. Activated private connector read tools can be declared manually using their exact discovered names. Calls use the current viewer's access and request confirmation when required. Imported writes and unattended refresh are unavailable through artifact controls.
A compatible MCP Apps client can display the saved app inside your conversation. Other clients receive an authenticated portal link. Check the app in your actual client before sharing it. Editing the app creates another revision of the same artifact.
Local inputs last while the view is open; saving the app does not save entered values. This workflow does not provide a private app database, an arbitrary hosted server, or public app distribution. Controls that change a connected system still require your current access and any required confirmation.

Checking a draft

stackyapper_validate_artifact checks the complete source and its declared tools without saving anything. For a React component, it also renders the draft once, as it first appears, and reports each unsupported element, property, or style, or an error, along with where it occurs in the page.
The check never calls your apps, loads data, copies to the clipboard, or starts timers, and it does not click or type in the page. Its result says how much it covered:
ResultWhat it means
passedThe first view rendered with no issues. Later states after a click or input were not checked.
passed_initial_stateThe first view rendered, but the page reads app data, uses the clipboard, or starts a timer when it opens. Anything that depends on those results was not checked.
failedRendering stopped at the first issue. Fix it and check again to find any later issue.
skippedThe source has other problems to fix first, so it was not rendered.
unavailableThe render check could not run. Only the source checks ran, so the rendered page is unchecked.
not_applicableThe source is a JSON document or backup-only content, which is not rendered.
A passing check is not a review of the finished artifact. It does not show how the page looks in a browser, test the viewer's permissions, or prove that the data is complete. Open the saved artifact to confirm those.

Browse saved artifacts

Open Artifacts → Library to search titles and descriptions, filter by access, and sort saved work. Grid view shows previews; list view shows the owner, access, and the date the artifact changed. Updated describes the artifact itself, not the freshness of its source data. Owners can use Manage to change an artifact’s visibility or download a backup.

Rotate artifacts on a display

In an approved Business workspace, use Artifacts → Displays to rotate saved artifacts on a screen:
  1. Choose Create playlist and enter a name.
  2. Select Add artifacts, choose the artifacts you want, then confirm the selection. You can keep selecting while you search or change pages.
  3. Use the up and down buttons to set the rotation order.
  4. Set the time on each artifact and how often to refresh the artifact on screen.
  5. Choose Save playlist, then Start display. Use Fullscreen for a larger view.
Playlists are personal to your account in the workspace and reopen on other devices you sign in to. You can save up to 20 playlists, with up to 24 artifacts in each. Access is checked again when an artifact opens.
Viewing time starts after an artifact loads. You can pause rotation, move to the previous or next artifact, refresh the current view, or exit the display. Refresh continues while paused; saved data follows its source’s own schedule. Last loaded means the view rendered successfully. Source freshness is shown separately and stays unknown when no evidence is available. Artifact actions are unavailable during display playback.
If another device changes a playlist while you are editing it, reload the saved playlists to see the latest version. You can also discard your edits.

What an artifact can include

Beyond text, tables, metrics, and charts, a component artifact can include:
  • Images. Inline PNG, JPEG, GIF, or WebP images supplied as part of the source, such as a logo the client received from you. Each image needs alt text, or must be marked as decorative. Images must be still: animated GIF, PNG, and WebP files are rejected. See Limits for sizes.
  • Process diagrams. Steps arranged in lanes for each team or role, with decisions, handoffs, and return paths. Stackyapper draws the diagram, lets the reader select a step with the keyboard to see its details, and includes a text version of the whole process. A long process is drawn top to bottom rather than shrunk to fit.
  • Sliders and date fields. Range and date inputs with optional minimum and maximum values, and a step for numbers. Dates use the YYYY-MM-DD format.
  • Captions and quotes. Figures with captions, and block quotes.
If an artifact opens in an older version of the artifact viewer, it still shows its content in a simpler form. An image becomes a labeled placeholder showing its alt text, and a decorative image is left out. A diagram becomes its numbered text version, a slider becomes a number field, and a date field becomes a text field that shows the expected format.

Not available yet

  • Image uploads or image addresses. There is no upload or shared image library, and images cannot load from a web address. Each artifact carries its own images. Without an image to supply, the skill tells the client to show a labeled placeholder rather than a made-up picture.
  • Custom chart axis ranges. Charts set their own axis scale.
  • Custom HTML, SVG drawings, and links. Use a chart for data, a diagram for a process, and an image for a picture. Web addresses can appear as text.

Delivery and compatibility

Client capabilityWhat opens
MCP Apps with text/html;profile=mcp-appAn embedded, network-isolated hosted page
MCP without that capabilityAn authenticated Stackyapper portal link
Export/import onlyA stackyapper.artifact/v1 backup package
The fallback link is part of the protocol contract: a client never needs to execute HTML or JavaScript to preserve or reopen an artifact. Support can vary by client version and admin policy.

Editing across clients

Authorized AI clients can manage an artifact’s lifecycle through Stackyapper: load metadata, read the source in bounded chunks, list revisions, and submit a replacement source document. Claude and ChatGPT are tested with the beta; other clients that follow the protocol should work but are not verified end to end.
Every update names the revision it started from. If another client has already saved a newer revision, Stackyapper rejects the stale update and tells the client to reload and merge — safe sequential synchronization, not simultaneous co-editing. Open portal pages reload the latest revision when the browser regains attention; an artifact already embedded in an AI conversation keeps what it was given until that client opens it again. Shared artifacts remain read-only; edits require the owning Stackyapper user in the owning workspace.

Authoring formats

stackyapper.ui/v1 is JSON data, not executable code. The root has exactly two keys: format and blocks. Supported block types are heading, text, status, metric, table, control, and work_queue.
The beta also accepts a React component written in JSX or TypeScript when it passes Stackyapper’s source checks and uses only the curated artifact packages: React, React Query, Lucide icons, Recharts, and Stackyapper’s artifact UI components. Your component runs sandboxed on Stackyapper’s servers — no network, no browser, no credentials, no saved connections. It returns a description of the UI, and Stackyapper’s own shell — the same versioned runtime in the standalone page and in compatible MCP Apps clients — renders that description. Arbitrary HTML, unsupported imports, and older unvalidated JSX remain inert backup source.

Example 1: status page

{ "format": "stackyapper.ui/v1", "blocks": [ { "type": "heading", "text": "Morning service check", "level": 2 }, { "type": "status", "label": "Backup", "value": "Healthy", "tone": "good" }, { "type": "metric", "label": "Open alerts", "value": "2", "detail": "Review before noon" } ] }

Example 2: table

{ "format": "stackyapper.ui/v1", "blocks": [ { "type": "table", "caption": "Devices approaching replacement", "columns": [ { "key": "device", "label": "Device" }, { "key": "age", "label": "Age" } ], "rows": [ { "device": "Laptop 014", "age": "4 years" } ] } ] }

Example 3: governed read control

{ "format": "stackyapper.ui/v1", "blocks": [ { "type": "control", "kind": "refresh", "label": "Refresh open tickets", "description": "Reads up to three open tickets with your current access.", "binding": { "role": "psa", "tool_name": "cw_search_tickets", "arguments": { "conditions": "closedFlag=false", "pageSize": 3 } } } ] }
The matching revision bindings argument declares what the control may use:
[ { "role": "psa", "service": "connectwise", "tool_names": ["cw_search_tickets"] } ]

Operational work queues

Use work_queue when a saved artifact needs to keep the shape of a dispatch board, alert queue, or task list instead of flattening it into unrelated metric cards. It must be the document’s only block: a histogram, local search and facets, filter chips, compact rows, and one optional governed query control. Every facet, histogram, and chip match key must name a declared column, and filters and chip_groups are required even when empty. Search, facets, chips, histogram selection, sorting, density, and list copying all run locally over the bounded saved rows. The query control’s fresh result is shown separately; it does not silently rewrite the saved snapshot.
{ "format": "stackyapper.ui/v1", "blocks": [ { "type": "work_queue", "item_label": "tickets", "eyebrow": "Service operations", "title": "Dispatch Console", "status": "80 open", "histogram": { "label": "Open by age", "hint": "Select a bar to filter", "items": [ { "label": "30d+", "value": "23", "tone": "warning", "match": { "key": "age_bucket", "value": "30d+" } } ] }, "filters": [{ "key": "board", "label": "All boards" }], "chip_groups": [], "columns": [ { "key": "ticket", "label": "Ticket" }, { "key": "board", "label": "Board" }, { "key": "age", "label": "Age", "kind": "age" }, { "key": "age_bucket", "label": "Age bucket", "hidden": true } ], "rows": [ { "ticket": "#42 Printer offline · Acme", "board": "Service", "age": "31d", "age_bucket": "30d+" } ], "footer": ["ConnectWise via Stackyapper"], "control": { "label": "Query latest", "binding": { "role": "psa", "tool_name": "cw_search_tickets", "arguments": { "page": 1, "pageSize": 2 } } } } ] }

Rules

  • Unknown keys or block types are rejected.
  • Every control’s role and tool must also appear in the revision’s immutable bindings argument.
  • Control arguments may contain bounded filters, but never tokens, credentials, connection IDs, or tenant selectors.
  • Controls never carry authorization. Stackyapper resolves the role against the current viewer, workspace, grants, risk policy, and saved credentials at click time; write or destructive operations still require confirmation.
  • Histogram and chip counts are whole numbers written as strings (for example "23").

Limits

  • Source: 256 KiB stored; hosted stackyapper.ui/v1 document: 64 KiB.
  • Hosted document: 100 blocks; each string: 4 KiB UTF-8.
  • Table: 12 columns and 50 rows.
  • Work queue: 16 declared columns, 50 rows, 6 facets, 4 chip groups, 6 histogram items, and 12 chip items per group.
  • Control arguments: 8 levels and 256 JSON nodes.
  • Images: 16 per page. Each image is up to about 72 KiB (96 KiB of base64 text), 4,096 pixels on its longest side, and 4 megapixels. All images on a page together are limited to about 144 KiB (192 KiB of base64 text) and 8 megapixels. Keep logos and icons to a few kilobytes.
  • Diagram: 8 lanes, 40 steps, and 80 connections; step labels up to 80 characters.
  • Backup package: 400 KiB; export is returned in bounded 4 KiB chunks.
  • Active artifacts: 250 per workspace; retained revision history: 50 revisions.

Backups

stackyapper.artifact/v1 is a deterministic, backup-only JSON package. It contains the title, description, source, and reviewed bindings. Its SHA-256 checksum detects corruption; it is not a signature and does not prove who created the package. Import validates the checksum and artifact format, removes all original identifiers, and creates a new private artifact owned by the importing viewer with “Imported copy” appended to its title.
Do not edit a package by hand. Export it again after changing the artifact.

Safe authoring checklist

  • Prefer small summaries and explicit bounded queries.
  • Include only data the intended viewers are allowed to see.
  • Declare every control tool in the revision bindings.
  • Check every draft with stackyapper_validate_artifact, then open the saved artifact and review it.
  • Use only the curated artifact packages; external packages and network imports are unavailable.
  • Never place secrets, customer payloads, or credential identifiers in source.
  • Expect controls to fail when the viewer lacks current permission.
  • Treat export as recoverability, not provenance or authorization.