> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Components

> Agent-driven UI components for @frontmcp/react

Agent components are React components that register MCP tools automatically. Agents interact with these components by calling tools — pushing data into the UI or receiving UI state.

## mcpComponent

The recommended way to create agent-driven components. `mcpComponent()` is a factory that wraps a React component + zod schema into an MCP-registered component with full type safety.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { mcpComponent } from '@frontmcp/react';
import { z } from '@frontmcp/sdk';

const WeatherCard = mcpComponent(
  ({ city, temp }) => (
    <div className="weather-card">
      <h2>{city}</h2>
      <p>{temp}°</p>
    </div>
  ),
  {
    name: 'show_weather',
    description: 'Display weather data for a city',
    schema: z.object({
      city: z.string(),
      temp: z.number(),
    }),
    fallback: <p>Waiting for weather data...</p>,
  },
);

// Use it like a normal component
function App() {
  return <WeatherCard />;
}
```

### How It Works

1. On mount, `mcpComponent` registers an MCP tool with the given `name` and zod `schema`
2. Input is validated against the zod schema before reaching your component
3. Before any agent invocation, the `fallback` is rendered
4. When an agent calls the tool, the validated data is passed as typed props
5. The tool returns a success response to the agent

### Options

| Option        | Type             | Default | Description                                  |
| ------------- | ---------------- | ------- | -------------------------------------------- |
| `name`        | `string`         | —       | **Required.** MCP tool name agents will call |
| `description` | `string`         | `name`  | Tool description for agents                  |
| `schema`      | `z.ZodObject`    | —       | **Required.** Zod schema for type-safe input |
| `fallback`    | `ReactNode`      | `null`  | Shown before first invocation                |
| `server`      | `string`         | —       | Target a named server                        |
| `columns`     | `McpColumnDef[]` | —       | Table mode column definitions                |

### Static Properties

The returned component has a `.toolName` property:

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const WeatherCard = mcpComponent(WeatherCardImpl, { name: 'show_weather', schema });
console.log(WeatherCard.toolName); // 'show_weather'
```

### Patterns

#### Wrapping Existing Components

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { WeatherCardImpl } from './WeatherCard';

const WeatherCard = mcpComponent(WeatherCardImpl, {
  name: 'show_weather',
  description: 'Display weather data',
  schema: z.object({ city: z.string(), temp: z.number() }),
  fallback: <Skeleton />,
});
```

#### Inline Components

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const MetricsCard = mcpComponent(
  ({ cpu, memory }) => (
    <div>
      <span>CPU: {cpu}%</span>
      <span>Memory: {memory}%</span>
    </div>
  ),
  {
    name: 'show_metrics',
    schema: z.object({ cpu: z.number(), memory: z.number() }),
  },
);
```

#### Lazy Loading

Wrap dynamic `import()` factories with `mcpLazy()` so `mcpComponent` can distinguish them from zero-arg components:

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { mcpComponent, mcpLazy } from '@frontmcp/react';

const HeavyChart = mcpComponent(
  mcpLazy(() => import('./HeavyChart')),
  {
    name: 'show_chart',
    schema: z.object({ data: z.array(z.number()), label: z.string() }),
    fallback: <p>Loading chart...</p>,
  },
);
```

#### Dashboard Widgets

Use multiple `mcpComponent` instances to build agent-controlled dashboards:

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function AgentDashboard() {
  return (
    <div className="grid grid-cols-2 gap-4">
      <MetricsCard />
      <WeatherCard />
      <OrderTable />
    </div>
  );
}
```

#### Direct Props

The returned component accepts partial props directly, which merge with agent-provided data:

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
<WeatherCard city="Default City" />
```

***

## Table Mode

When `component` is `null` and `columns` is provided, `mcpComponent` renders a default `<table>`. The tool schema is automatically wrapped in `{ rows: z.array(schema) }`.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { mcpComponent } from '@frontmcp/react';
import { z } from '@frontmcp/sdk';

const OrderTable = mcpComponent(null, {
  name: 'show_orders',
  description: 'Display order data as a table',
  schema: z.object({
    id: z.string(),
    product: z.string(),
    price: z.number(),
  }),
  columns: [
    { key: 'id', header: 'Order ID' },
    { key: 'product', header: 'Product' },
    { key: 'price', header: 'Price', render: (v) => `$${v}` },
  ],
});
```

### McpColumnDef

| Field    | Type                   | Description                    |
| -------- | ---------------------- | ------------------------------ |
| `key`    | `string`               | Property key in the row object |
| `header` | `string`               | Column header text             |
| `render` | `(value) => ReactNode` | Optional custom cell renderer  |

### How Table Mode Works

1. The agent calls the tool with `{ rows: [...] }`
2. Each row is validated against the zod schema
3. The table renders with the specified columns
4. Custom `render` functions allow formatting (e.g., currency, dates)

***

## Legacy Components

### AgentContent

<Warning>
  `AgentContent` is deprecated. Use `mcpComponent()` instead for type-safe schemas.
</Warning>

A component that registers itself as an MCP tool using raw JSON Schema.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { AgentContent } from '@frontmcp/react';

<AgentContent
  name="show_weather"
  description="Display weather data"
  inputSchema={{
    type: 'object',
    properties: {
      city: { type: 'string' },
      temp: { type: 'number' },
    },
  }}
  render={(data) => (
    <div>
      <h2>{String(data.city)}</h2>
      <p>{String(data.temp)}°</p>
    </div>
  )}
  fallback={<p>Waiting for weather data...</p>}
/>
```

### AgentSearch

<Warning>
  `AgentSearch` is deprecated. Use `mcpComponent()` with the `columns` option for table-based result rendering.
</Warning>

A headless search component that registers an MCP tool for search execution.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { AgentSearch } from '@frontmcp/react';

<AgentSearch
  toolName="product_search"
  description="Search products"
  placeholder="Search..."
  onResults={(results) => setSearchResults(results)}
/>
```

### Migration Guide

**AgentContent → mcpComponent:**

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Before
<AgentContent
  name="show_weather"
  description="Display weather"
  inputSchema={{ type: 'object', properties: { city: { type: 'string' } } }}
  render={(data) => <div>{String(data.city)}</div>}
  fallback={<p>Loading...</p>}
/>

// After
const WeatherCard = mcpComponent(
  ({ city }) => <div>{city}</div>,
  {
    name: 'show_weather',
    description: 'Display weather',
    schema: z.object({ city: z.string() }),
    fallback: <p>Loading...</p>,
  },
);
// Then use: <WeatherCard />
```

**AgentSearch → mcpComponent table mode:**

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Before
<AgentSearch
  toolName="product_search"
  description="Search products"
  onResults={(results) => setResults(results)}
/>

// After
const ProductTable = mcpComponent(null, {
  name: 'product_search',
  description: 'Search products',
  schema: z.object({ name: z.string(), price: z.number() }),
  columns: [
    { key: 'name', header: 'Product' },
    { key: 'price', header: 'Price', render: (v) => `$${v}` },
  ],
});
// Then use: <ProductTable />
```
