Skip to content

Velloo documentation

Markdown for LLMs ↗

MCP: discovery

Read operations. List and fetch screens, boards, the component and snippet catalogue, canvas fidelity, the preview entry, the theme, annotations, notes, and comment threads, and query a screen tree with find_nodes.

Discovery operations are reads. With one exception they never mutate the design folder, and they are the recommended first calls of any session: list_components (index mode), get_theme, and list_boards, plus component_status before claiming an app component renders exactly. In a folder whose app has components of its own, preview_status comes first of all.

The exception is set_preview_entry, documented here beside the preview_status check it reruns rather than on the mutations page.

list_screens

List every screen in the design folder.

ArgTypeRequiredDescription
includeTreebooleannoEmbed each screen’s full tree: one round-trip instead of list_screens plus N get_screen calls. Default false

Returns { screens: [{ id, name, tree? }] }.

get_screen

Return the JSON for a single screen.

ArgTypeRequiredDescription
screenIdstringyes
modestringno"full" (default) returns the complete screen. "outline" returns { id, name, tree } where each node is stripped to ref (or snippet, or param), $id when present, a classSnippet of its className capped at 40 characters, and children

Use mode: "outline" to scan a large screen before drilling in with inspect or @id locators. An unknown id returns ScreenNotFound.

list_boards

List the folder’s boards in sidebar order.

ArgTypeRequiredDescription
includeFramesbooleannoEmbed each board’s frames and groups lists in one round-trip. Default false
includeArchivedbooleannoAlso list archived boards. Default false; archived boards are hidden

Returns { boards: [{ id, name, frameCount, group?, archivedAt?, frames?, groups? }] }. group is the name of the sidebar group the board is filed under (absent means ungrouped); archivedAt appears only on archived boards.

get_board

Return one board’s full JSON: frames (placements of screens at chosen sizes) and groups.

ArgTypeRequiredDescription
boardIdstringyes

An unknown id returns BoardNotFound.

list_components

List the tag namespace that compose resolves: the app’s own components, library components, registered extensions, and snippets.

ArgTypeRequiredDescription
filterstringnoCase-insensitive substring match on ids (for snippets, the PascalCase tag)
modestringno"index" (default), "summary", or "full"
kindstringno"repo", "library", "extension", or "snippet" narrows the result
unusedOnlybooleannoList only snippets no screen reaches, directly or through another snippet. Implies kind: "snippet"

The three modes trade size for detail:

  • index returns families on shelves: { snapshotVersion, groups: [{ group, label, families: [{ id, pieces?, designModeNotes? }] }], totals: { components, families } }. A family’s sub-components are folded into pieces (Field lists FieldLabel, FieldDescription, FieldError), and extensions and snippets each get a shelf of their own. Status is reported only as exceptions: unavailableInDesign and notInstalledInApp list the ids that differ from the norm. Read this first.
  • summary: { snapshotVersion, components: [...] }, one entry per component with id, category, source, props (names only), designModeNotes, kind, availableInDesign, installedInApp, and importPath where known.
  • full: complete descriptors with prop types, enum values, and a working example. A prop that enumerates a huge value set (for example Icon.name, roughly 4,000 lucide names) is truncated to 40 values plus an enumValuesTruncated count.

Repo entries are your app’s own components, shelved first and grouped by source — Repo · this app's components, Repo · @mantine/core. Each carries importPath, exportName, member for a compound part, extracted props (with an inheritedProps count when some were folded away), acceptsChildren, styleProps, preview states, parts, and provenance naming where the app uses it. When a component reads data for itself, dataSources lists the hooks — props alone won’t fill a component that reads a store. An id that would collide with a provider component is qualified (Mantine.Button), and designModeNotes says why. In index mode a repo note reports each app’s preview-entry state, so check it before trusting the shelves.

Snippet entries use the snippet’s PascalCase tag as id and carry the persisted kebab-case id as snippetId. In full mode their props are the declared params, each with a derived required flag (true when the param has no default and isn’t optional). A snippet nothing reaches carries unused: true, and its designModeNotes say so in every mode.

installedInApp describes the host app only; false never blocks design. There is no install operation: emit_code returns componentsToInstall for the implementation handoff. Snippets have no separate listing either; they are the kind: "snippet" entries here, and get_snippet returns one definition.

component_status

Compile-check components for the browser canvas and report how each one actually renders, so a fidelity claim rests on a check rather than an assumption. Pass screen or ids.

ArgTypeRequiredDescription
screenstringone of the twoScreen id: check the components that screen uses and whether it mounts
idsstring[]one of the twoComponent ids, as list_components returns them. Repo catalog ids are accepted
librarystringnoWith ids: the library to check. Default: the folder’s default library. A screen names its own

Each diagnostic carries the component id, a status, usually a note, and — when the status isn’t exact — a code and a remedy:

StatusMeaning
exactRendered from the app’s own source
adaptedRendered with a named canvas-safe adaptation
unstyledRendered, but its stylesheet wasn’t loaded, so it can’t be reported exact
proxyCouldn’t render; the snippet named in $repo.proxy stands in
fallbackRendered from Velloo’s bundled components instead of the app’s
unavailableCouldn’t render and has no proxy; a labelled frame stands in
unknownNot a component this library or catalog has

The codes are stable: missing-provider, render-threw, missing-export, compile-failed, server-only, resolve-failed, unstyled. missing-provider almost always means the preview entry needs another wrapper.

With screen, returns { library, screen, mounted, note?, diagnostics, errors }. Two different mount behaviours apply, and the difference matters:

  • Library components mount all-or-nothing. When one can’t compile, the whole screen — and every capture of it — renders from Velloo’s bundled components whatever the others report, and note says why.
  • Repository components fall back individually. A screen using the app’s own components always mounts; each one that can’t render becomes its proxy snippet or a labelled frame on its own, leaving the rest real. For such a screen the report also merges what the mounted frame found at runtime (render-threw, missing-provider, unstyled, missing-export) and sets runtimeChecked.

A screen whose library renders server-side only, or that uses no components, returns { screen, mounted: false, note, diagnostics: [], errors: [] }.

With ids, returns { library, usable, diagnostics, errors }. An id neither the library nor the repo catalog has is reported with status: "unknown" rather than as a canvas failure. A provider without repo-backed canvas mounting reports each recognized id as fallback.

Passing neither argument returns BadRequest; an unknown screen returns ScreenNotFound.

preview_status

Check the preview entry your app’s own components render inside on the canvas: the providers and global stylesheets they need. It proves the answer by mounting a real component in a headless browser rather than inspecting the file. Run it once per folder before the first screen.

ArgTypeRequiredDescription
appstringnoconfig.hostApps key; the default app when omitted
componentstringnoCatalog id to probe. Default: the first one the app uses, preferring one with recorded props
probebooleannoMount a component to verify. Default true

Returns { state, preview, recipes, appWrappers, appStylesheets, components, probe?, suggestedPreviewEntry?, warnings?, next }.

  • state is absent (no entry and components need one), valid (a component mounted cleanly), or failing (the probe found a problem).
  • preview describes what’s in force: kind is file (your preview.tsx, with its path), recipe (a built-in wrapper for a known library), or none.
  • appWrappers and appStylesheets are what the app’s own entry point uses — the raw material for writing an entry. codeProps flags a wrapper prop that was an expression rather than a literal.
  • probe reports the mount: component, mounted, status, code, note, remedy, plus previewError when the entry itself threw and up to five consoleErrors.
  • suggestedPreviewEntry is a draft to adapt, present whenever the current entry isn’t a verified file.
  • next is the concrete step to take from this state.

set_preview_entry

Write the design folder’s preview entry and verify it by mounting a real component. Returns the same report as preview_status.

ArgTypeRequiredDescription
sourcestringyesTSX/JSX module source, up to 100,000 bytes
appstringnoconfig.hostApps key. Writes preview.<app>.tsx; omitted writes preview.tsx

The module’s default export receives { children, colorScheme, theme, recipeTheme } and returns the providers and fixtures your components need, with the app’s global stylesheets imported at the top. Source without a default export is rejected with BadRequest, as is an unknown app.

Keep the entry free of network calls and credentials: it runs in your local browser during design, and it’s a fixture rather than a bootstrap of the real app.

get_snippet

Return the full JSON for a single snippet: id, name, params (each with the derived required flag), and the body tree.

ArgTypeRequiredDescription
snippetIdstringyesThe kebab-case snippet id

An unknown id returns SnippetNotFound.

get_theme

Return a theme’s token tree.

ArgTypeRequiredDescription
themestringnoNamed theme to read. Default "default"

Returns the theme’s tokens plus two derived fields: typeScale, what the default typeset computes to per type role, and customCss, the folder’s custom CSS. Edit through the theme operations, not per-node sizes.

list_annotations

List annotations on a screen: designer-authored guidance plus any the agent pinned.

ArgTypeRequiredDescription
screenIdstringyes

Returns { annotations }. Each carries an author, a target: { locator }, a markdown body, and a resolved path, null when the targeted node has since been removed (treat dangling annotations as low-priority; the note is stale). User-authored annotations are read-only to the agent. Agent annotations are written with the operations on the Lifecycle page.

list_notes

List the markdown notes on one board.

ArgTypeRequiredDescription
boardIdstringyes

Returns { notes }. Free notes live in board coordinates (the same space as frame x/y); an attached note carries attachment: { frameId, screenId, locator } naming the node it anchors to. Writable via add_note / update_note / remove_note on the Lifecycle page.

list_comment_threads

List visual feedback threads. Every open thread is a change the user expects.

ArgTypeRequiredDescription
boardIdstringnoNarrow to one board. Default: every board in the folder
statusstringno"open" (default), "resolved", or "all"
scopestringno"local", "shared" (threads left on a published link), or "all" (default)

Returns { threads }. A thread’s anchor reports its attached path, or that it is stale when the original node is gone.

get_comment_thread

Read one complete thread, including its anchor and replies.

ArgTypeRequiredDescription
threadIdstring (UUID)yes

Returns { thread }.

update_comment_thread

Act on a thread. Pass reply, status, or both; replying with what changed and resolving in one call is the normal close-out.

ArgTypeRequiredDescription
threadIdstring (UUID)yes
replystringnoAgent message to post, 1–4000 characters. Posted before any status change
statusstringno"resolved", "open", or "deleted". Deletion is permanent; only on the user’s explicit request

Returns { thread }. Passing neither reply nor status returns BadRequest; comment-store failures return CommentStore with a code. The full loop is in the velloo://guide/comments resource.

find_nodes

Query a screen tree for matching nodes. All filters AND together. Accepts snippet:<id> to search a snippet body.

ArgTypeRequiredDescription
screenIdstringyes
refstringnoExact component $ref, e.g. "Button"
snippetIdstringnoExact $snippet id for snippet instances
idstringnoExact $id anchor
classContainsstringnoSubstring of props.className
propstringnoProp key that must be present
propValueanynoWith prop: strict-equal value match
limitnumbernoMax matches; default 50
{ "screenId": "home", "ref": "Icon", "prop": "name", "propValue": "Github" }

Returns { matches: [{ path, kind, ref?, id?, className?, textPreview?, childCount }], total }. kind is component, snippet, or param, and total counts matches before limit. Use it to locate targets for the path-accepting operations without fetching and walking the whole tree.

Assets and captures

list_assets lists the files in the folder’s assets/ directory, and list_captures / get_capture read page captures recorded by start_capture_session. Both families are documented with the rest of the visual tooling on Visual, assets, and batch.