Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt

Use this file to discover all available pages before exploring further.

A component is the BindJS code that backs a Type. A package is an immutable, semantically-versioned snapshot of all the components in a project. Together they form the pair that makes MCP Apps reproducible and rollback-safe: a Type points at a component, the component lives in a package version, and that pairing never silently changes once published.

Component shapes

Every BindJS component declares one of three shapes through a defineComponent(), defineDataSource(), or layout-component declaration. The shape determines what kind of Type the component can back.
Component shapeBacksWhat it does
Layout componentInteractive ToolDefines a tool’s input schema (via properties) plus the layout that renders the validated JSON. Allowed-children declarations let the AI compose approved view components inside the layout.
View component(Reusable building block)A reusable UI building block — a product card, a button, a chart, a media frame. View components are the building blocks layout components compose, and the candidates a layout’s allowlist permits.
Data componentData ToolDeclares typed input/output and an async handler(props, env) that runs in a V8 sandbox.
A Data Tool is just a component with a different shape — it has the same lifecycle, same package, same versioning as a layout or view component. There is no separate “Data Tool” object underneath the surface.

A component example

A view component (ProductDetail) declares what properties the AI can supply and renders the result:
export default defineComponent({
  metadata: {
    title: "Product Detail",
    description: "Image, CTA, description, features, and reviews"
  },
  properties: {
    title: { type: "string", title: "Title" },
    price: { type: "string", title: "Price" },
    asset: { type: "asset", assetTypes: ["image", "video"] },
    // ...
  },
  body: (props) => {
    return VStack({ spacing: 28 }, [
      ProductImage(props),
      ProductTitle(props),
      ProductPrice(props),
      // ...
    ]);
  }
});
A data component declares its handler and the input/output schemas it implements:
export default defineDataSource({
  metadata: {
    title: "Product Search",
    description: "Semantic product search via the Metabind Content API"
  },
  properties: {
    searchTerm: { type: "string" },
    needsImage: { type: "boolean" }
  },
  output: {
    products: PropertyArray({ /* ... */ }),
    total: PropertyNumber({})
  },
  handler: async (props, env) => {
    const res = await fetch(url, {
      headers: { "x-api-key": env.secrets.METABIND_API_KEY }
    });
    return res.json();
  }
});
For the full BindJS API, see the BindJS Reference.

Packages

A package is a frozen, semantically-versioned bundle of every component in a project, plus the asset references those components depend on. Packages are immutable: once published, version 2.1.0 is 2.1.0 forever. Why this matters:
  • Reproducible renders. A Type that pinned to package 2.1.0 always renders against 2.1.0’s component code, even after you publish 2.2.0.
  • Instant rollback. Reverting from 2.2.0 to 2.1.0 is a metadata flip, not a redeploy.
  • Predictable updates. New tool definitions and component changes ship together as a coherent unit, not as a series of partial states.
The CDN serves package bundles content-addressed by hash. Once a package is requested, every renderer (web iframe, iOS, Android) caches it at the edge.

Draft and published states

Components and packages each have three states:
StateMeaning
DraftNew, never published. Editable freely. Visible only on the project’s draft endpoint.
PublishedLive. Visible on the production endpoint.
ModifiedWas published, has unpublished edits. Production continues to serve the last published version; draft serves the working copy.
When you publish the project, modified components and Types are promoted: the package version increments, and the production endpoint switches to the new version.

Inspector and the visual builder

Components author both what they render and how the editor configures them. The inspector schema (inspector config on each property) tells MCP App Studio what controls to show — single-line fields, multi-line text, sliders, color pickers, asset pickers, dropdowns. This is what lets non-technical teams configure Tools without writing code.
properties: {
  starCount: {
    type: "number",
    title: "Star Count",
    inspector: { control: "slider", step: 1 },
    validation: { min: 0, max: 5 }
  }
}

Where components render

The BindJS authoring layer drives what Claude, ChatGPT, and every other MCP host show your users — the React renderer (@bindjs/renderer) runs in a sandboxed iframe inside each host. For embedded experiences, Metabind also provides native iOS and Android renderers and an Assistant SDK that ship as part of the Metabind SDK. See Native rendering for what runs where.

Tools and Types

How a component becomes a registered MCP tool.

Native rendering

How one component compiles to React, SwiftUI, and Jetpack Compose.

Authoring BindJS components

How-to: write components from scratch.

BindJS Reference

Full BindJS API.