> ## 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.

# Hooks Reference

> Complete API reference for all @frontmcp/react hooks

Most data hooks support multi-server targeting via an `options.server` parameter. When omitted, they use the provider's default server. Low-level hooks like `useServer` and `useResolvedServer` accept a server name directly as an argument instead.

## useCallTool

Call an MCP tool with typed input/output.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const [callTool, state, reset] = useCallTool<InputType, OutputType>(toolName, options?);
```

### Parameters

| Parameter                   | Type              | Description                                           |
| --------------------------- | ----------------- | ----------------------------------------------------- |
| `toolName`                  | `string`          | Name of the MCP tool                                  |
| `options.server`            | `string`          | Target a named server                                 |
| `options.onSuccess`         | `(data) => void`  | Success callback                                      |
| `options.onError`           | `(error) => void` | Error callback                                        |
| `options.resetOnToolChange` | `boolean`         | Reset state when `toolName` changes (default: `true`) |

### Return Value

| Index | Type                                         | Description                        |
| ----- | -------------------------------------------- | ---------------------------------- |
| `[0]` | `(args: TInput) => Promise<TOutput \| null>` | Call function                      |
| `[1]` | `ToolState<TOutput>`                         | `{ data, loading, error, called }` |
| `[2]` | `() => void`                                 | Reset state                        |

### Example

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function SearchTool() {
  const [search, { data, loading, error, called }, reset] = useCallTool('search');

  return (
    <div>
      <button onClick={() => search({ query: 'react' })}>Search</button>
      <button onClick={reset}>Reset</button>
      {loading && <p>Searching...</p>}
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
}
```

***

## useReadResource

Dual-mode resource reading — lazy or auto-fetch.

### Lazy Mode

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const [readFn, state] = useReadResource(options?);
```

Returns a `[read, state]` tuple. Call `read(uri)` on demand.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function LazyReader() {
  const [read, { data, loading }] = useReadResource();

  return <button onClick={() => read('app://config')}>Load Config</button>;
}
```

### Auto-Fetch Mode

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const { data, loading, error, refetch } = useReadResource(uri, options?);
```

Fetches automatically when connected. Call `refetch()` to re-read.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function AutoReader() {
  const { data, loading, refetch } = useReadResource('app://status');

  return (
    <div>
      {loading ? 'Loading...' : JSON.stringify(data)}
      <button onClick={refetch}>Refresh</button>
    </div>
  );
}
```

***

## useGetPrompt

Fetch an MCP prompt by name.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const [getPrompt, state] = useGetPrompt(promptName, options?);
```

### Example

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function PromptFetcher() {
  const [getPrompt, { data, loading }] = useGetPrompt('summarize');

  return (
    <button onClick={() => getPrompt({ topic: 'AI safety' })}>
      {loading ? 'Loading...' : 'Get Prompt'}
    </button>
  );
}
```

***

## useListTools

Reactive tool list from the registry.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const tools: ToolInfo[] = useListTools(options?);
```

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function ToolList() {
  const tools = useListTools();
  return (
    <ul>
      {tools.map((t) => <li key={t.name}>{t.name} — {t.description}</li>)}
    </ul>
  );
}
```

***

## useListResources

Reactive resource and resource template lists.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const { resources, resourceTemplates } = useListResources(options?);
```

***

## useListPrompts

Reactive prompt list.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const prompts: PromptInfo[] = useListPrompts(options?);
```

***

## useStoreResource

Subscribe to a `state://` URI with live updates via MCP resource subscriptions.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const { data, loading, error, refetch } = useStoreResource(uri, options?);
```

When the server sends `notifications/resources/updated`, the hook automatically re-fetches the resource. Content is JSON-parsed when possible.

### Example

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
function LiveCounter() {
  const { data, loading } = useStoreResource('state://counter');

  if (loading) return <p>Loading...</p>;
  return <p>Count: {String(data)}</p>;
}
```

***

## useServer

Low-level hook to access a raw `ServerEntry` from the registry.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const entry: ServerEntry | undefined = useServer(name?);
```

Uses `useSyncExternalStore` for tear-free reads.

***

## useResolvedServer

Internal hook that resolves a server entry with context fallback.

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const { entry, name, registry, connect } = useResolvedServer(serverName?);
```

This is the shared foundation for all other hooks. You typically don't need to use it directly.

***

## useDynamicTool

Register an MCP tool on mount, unregister on unmount. See [Dynamic Tools](/frontmcp/react/dynamic-tools) for full details.

Supports both **zod schemas** (recommended) and raw **JSON Schema** (backward compat).

### With Zod Schema (Recommended)

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

useDynamicTool({
  name: 'add_to_cart',
  description: 'Add item to cart',
  schema: z.object({
    itemId: z.string(),
    quantity: z.number().optional(),
  }),
  execute: async (args) => {
    // args is typed as { itemId: string; quantity?: number }
    addToCart(args.itemId, args.quantity ?? 1);
    return { content: [{ type: 'text', text: 'Added' }] };
  },
  enabled: isLoggedIn,
});
```

When using a zod `schema`, input is automatically validated via `safeParse` before reaching your `execute` callback. Invalid input returns an error `CallToolResult` with validation details.

### With JSON Schema (Backward Compat)

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
useDynamicTool({
  name: 'add_to_cart',
  description: 'Add item to cart',
  inputSchema: { type: 'object', properties: { itemId: { type: 'string' } } },
  execute: async (args) => {
    addToCart(args.itemId as string);
    return { content: [{ type: 'text', text: 'Added' }] };
  },
});
```

### Options

| Option        | Type                                | Default | Description                                        |
| ------------- | ----------------------------------- | ------- | -------------------------------------------------- |
| `name`        | `string`                            | —       | **Required.** Tool name                            |
| `description` | `string`                            | —       | **Required.** Description for agents               |
| `schema`      | `z.ZodObject`                       | —       | Zod schema (mutually exclusive with `inputSchema`) |
| `inputSchema` | `Record<string, unknown>`           | —       | JSON Schema (mutually exclusive with `schema`)     |
| `execute`     | `(args) => Promise<CallToolResult>` | —       | **Required.** Handler                              |
| `enabled`     | `boolean`                           | `true`  | Conditionally enable/disable                       |
| `server`      | `string`                            | —       | Target a named server                              |

***

## useDynamicResource

Register an MCP resource on mount, unregister on unmount. See [Dynamic Tools](/frontmcp/react/dynamic-tools) for full details.

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

useDynamicResource({
  uri: 'app://user-prefs',
  name: 'user-prefs',
  description: 'Current user preferences',
  mimeType: 'application/json',
  read: async () => ({
    contents: [{ uri: 'app://user-prefs', text: JSON.stringify(prefs) }],
  }),
});
```

### Options

| Option        | Type                                | Default | Description                       |
| ------------- | ----------------------------------- | ------- | --------------------------------- |
| `uri`         | `string`                            | —       | **Required.** Resource URI        |
| `name`        | `string`                            | —       | **Required.** Human-readable name |
| `description` | `string`                            | —       | Description for agents            |
| `mimeType`    | `string`                            | —       | Content MIME type                 |
| `read`        | `() => Promise<ReadResourceResult>` | —       | **Required.** Handler             |
| `enabled`     | `boolean`                           | `true`  | Conditionally enable/disable      |
| `server`      | `string`                            | —       | Target a named server             |

***

## useComponentTree

Expose the DOM subtree under a ref as a JSON MCP resource. See [Dynamic Tools](/frontmcp/react/dynamic-tools) for full details.

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

const rootRef = useRef<HTMLDivElement>(null);

useComponentTree({
  rootRef,
  uri: 'react://component-tree',
  maxDepth: 10,
  includeProps: true,
});
```

### Options

| Option         | Type                             | Default                    | Description                    |
| -------------- | -------------------------------- | -------------------------- | ------------------------------ |
| `rootRef`      | `RefObject<HTMLElement \| null>` | —                          | **Required.** Root element ref |
| `uri`          | `string`                         | `'react://component-tree'` | Resource URI                   |
| `maxDepth`     | `number`                         | `10`                       | Max traversal depth            |
| `includeProps` | `boolean`                        | `false`                    | Include `data-*` attributes    |
| `server`       | `string`                         | —                          | Target a named server          |

***

## Multi-Server Pattern

All hooks accept `{ server: 'name' }` to target a specific server:

```tsx theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Call a tool on the analytics server
const [track, state] = useCallTool('track_event', { server: 'analytics' });

// Read a resource from the config server
const { data } = useReadResource('app://settings', { server: 'config' });

// List tools from a specific server
const tools = useListTools({ server: 'analytics' });

// Subscribe to state on a specific server
const { data } = useStoreResource('state://counter', { server: 'state-server' });
```
