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

# UI Kit

> About Nuwa UI Kit

[`@nuwa-ai/ui-kit`](https://github.com/nuwa-protocol/nuwa/tree/main/nuwa-kit/typescript/packages/ui-kit) provides a `NuwaClient` class and a set of React hooks to help you build interactive UI for your Cap.

## Example

```tsx theme={null}
import { NuwaProvider, useNuwa } from '@nuwa-ai/ui-kit';

function MyCapUI() {
  const { nuwa, connected } = useNuwa();
  return <button onClick={() => nuwa.sendPrompt('Analyze selections')} disabled={!connected}>Run</button>;
}

export default () => (
  <NuwaProvider autoHeight debug>
    <MyCapUI />
  </NuwaProvider>
);
```

## Install

```bash theme={null}
pnpm add @nuwa-ai/ui-kit
```

## NuwaClient

`NuwaClient` is the main class that you can use to interact with the Nuwa Client. It provides a set of methods that you can use to interact with the Nuwa Client.

You can initialize a `NuwaClient` instance directly, or [use the `useNuwa` hook](#React-Helpers) to get a `NuwaClient` instance.

### constructor

Create a NuwaClient for parent iframe communication.

```ts theme={null}
const nuwaClient = new NuwaClient(options); // initialize a NuwaClient instance

nuwaClient.connect(); // connect to the Nuwa Client
```

**Inputs**

Construct-time options

<ResponseField name="options" type="object?">
  <Expandable title="options">
    <ResponseField name="allowedOrigins" type="string[]?" default="[*]" />

    <ResponseField name="timeout" type="number?" default="2000">Connection timeout</ResponseField>

    <ResponseField name="debug" type="boolean?" />

    <ResponseField name="methodTimeout(s)" type="number? | record?">Per-call overrides</ResponseField>
    <ResponseField name="methodRetries(map)" type="number? | record?">Retry overrides</ResponseField>

    <ResponseField name="streamTimeout" type="number?" default="30000" />

    <ResponseField name="streamRetries" type="number?" default="0" />
  </Expandable>
</ResponseField>

**Returns**

<ResponseField name="client" type="NuwaClient">Configured client instance</ResponseField>

### sendPrompt

Send a message to the parent client chat.

**Inputs**

<ResponseField name="prompt" type="string" required>Text message to send</ResponseField>

**Returns**

<ResponseField name="result" type="Promise<void>">Resolves when sent</ResponseField>

### setHeight

Set the UI iframe height in the Nuwa Client.

**Inputs**

<ResponseField name="height" type="string | number" required>CSS size or number</ResponseField>

**Returns**

<ResponseField name="result" type="Promise<void>">Resolves when applied</ResponseField>

### addSelection

Add a selection (label + message) to parent UI.
**Inputs**

<ResponseField name="label" type="string" required>Selection title. This will be displayed as a badge in the user's input.</ResponseField>
<ResponseField name="message" type="string | object" required>Payload message. This will be provided to the AI as part of the system prompt.</ResponseField>

**Returns**

<ResponseField name="result" type="Promise<void>">Resolves when added</ResponseField>

### saveState

Save state to the Nuwa Client.

**Inputs**

<ResponseField name="state" type="any">State to save</ResponseField>

**Returns**

<ResponseField name="result" type="Promise<void>">Resolves when applied</ResponseField>

### getState

Retrieve the state from the Nuwa Client.

**Inputs**

<ResponseField name="state" type="any?">Retrieve the state</ResponseField>

**Returns**

<ResponseField name="result" type="Promise<any>">Resolves when applied</ResponseField>

### createAIStream

Start a LLM stream controlled by nuwa client.

**Inputs**

Streaming request

<ResponseField name="request" type="object" required>
  <Expandable title="request">
    <ResponseField name="prompt" type="string" required>Prompt to stream</ResponseField>
  </Expandable>
</ResponseField>

**Returns**

<ResponseField name="handle" type="StreamHandle">Control/observe the stream</ResponseField>

#### StreamHandle.execute / abort

Run the stream and observe live chunks/errors.

**Inputs**

Optional callbacks

<ResponseField name="options" type="object?">
  <Expandable title="options">
    <ResponseField name="onChunk" type="function?">Receive live content/error frames</ResponseField>
    <ResponseField name="onError" type="function?">Receive immediate error</ResponseField>
  </Expandable>
</ResponseField>

**Returns**

<ResponseField name="execute" type="Promise">Final stream result and error (object with `result` and `error`)</ResponseField>
<ResponseField name="abort" type="void">Cancel the stream</ResponseField>

## React Helpers

### NuwaProvider

Wrap your app and auto-manage connection and resizing.

**Inputs**

Provider properties

<ResponseField name="props" type="object">
  <Expandable title="props">
    <ResponseField name="autoHeight" type="boolean?" default="true" />

    <ResponseField name="allowedOrigins" type="string[]?" />

    <ResponseField name="timeout" type="number?" />

    <ResponseField name="debug" type="boolean?" />

    <ResponseField name="methodTimeout(s)/Retries(map)" type="number? | record?">Overrides</ResponseField>
    <ResponseField name="streamTimeout/streamRetries" type="number?">Streaming</ResponseField>

    <ResponseField name="onConnected" type="function?" />

    <ResponseField name="onError" type="function?" />

    <ResponseField name="className/style" type="string | object?" />
  </Expandable>
</ResponseField>

**Returns**

<ResponseField name="element" type="ReactElement">Rendered provider element</ResponseField>

### useNuwa

Access the client, theme, and connection status.

**Inputs**

<ResponseField name="(none)" type="void">Hook takes no parameters</ResponseField>

**Returns**

<ResponseField name="nuwa" type="NuwaClient">Client instance</ResponseField>
<ResponseField name="theme" type="&#x22;light&#x22;|&#x22;dark&#x22;">Current theme</ResponseField>
<ResponseField name="connected" type="boolean">Connection state</ResponseField>

## MCP Transport

### PostMessageMCPTransport (constructor)

A Transport for official MCP SDK over postMessage.

**Inputs**

Constructor options

<ResponseField name="options" type="object?">
  <Expandable title="options">
    <ResponseField name="targetWindow" type="Window?" />

    <ResponseField name="targetOrigin" type="string?" default="*" />

    <ResponseField name="allowedOrigins" type="string[]?" default="[*]" />

    <ResponseField name="timeout" type="number?" default="30000" />

    <ResponseField name="debug" type="boolean?" />

    <ResponseField name="securityPolicy" type="object?">Fields: enforceOriginValidation?, maxMessageSize?, rateLimits?</ResponseField>
  </Expandable>
</ResponseField>

**Returns**

<ResponseField name="transport" type="PostMessageMCPTransport">Configured transport</ResponseField>

### start / send / connect / disconnect

Transport lifecycle and messaging.

**Inputs**

<ResponseField name="(varies)" type="-">See individual methods</ResponseField>

**Returns**

<ResponseField name="start" type="Promise<void>">Begin listening</ResponseField>
<ResponseField name="send" type="Promise<void>">Send JSON-RPC message</ResponseField>
<ResponseField name="connect" type="Promise<void>">Connect to window</ResponseField>
<ResponseField name="disconnect" type="void">Tear down transport</ResponseField>
<ResponseField name="connected/ready" type="boolean">Current status flags</ResponseField>

### UI Helpers

Return UI resources from MCP tools.

**Inputs**

<ResponseField name="path" type="string" required>Path relative to artifact origin</ResponseField>
<ResponseField name="name/description/uiType" type="string?">Optional metadata</ResponseField>

**Returns**

<ResponseField name="resource" type="UIResource">Result for createUIResource</ResponseField>
<ResponseField name="toolResult" type="UIToolResult">Result for createUIToolResult</ResponseField>
