# Quickstart

Install the SDK and make your first RPC call in under 5 minutes.

## Install

```bash
bun add moltlazy
```

The SDK exports are available from `moltlazy/sdk`:

```ts
import { createClient } from 'moltlazy/sdk';
```

## Pattern 1: Direct client calls

Use the typed RPC client when you need fine-grained control over individual gateway operations.

```ts
import { createClient } from 'moltlazy/sdk';

const client = createClient({
  baseUrl: 'http://localhost:18789',
  token: process.env.OPENCLAW_GATEWAY_TOKEN!,
});

// Read full config
const config = await client.config.get();
if (config.ok) {
  console.log(config.payload);
}

// Apply a config fragment (raw JSON string)
await client.config.set({ raw: JSON.stringify({ session: { dmScope: 'per-channel-peer' } }) });

// List agents
const agents = await client.agents.list();

// Approve a device pairing request
await client.devices.approve({ requestId: 'request-id-123' });

// Restart the gateway
await client.gateway.restart();
```

## Pattern 2: Config Module (startup patching)

The Config Module runs at container startup before the gateway starts. It generates `moltlazy.json` with all mandatory config and injects `$include: "./moltlazy.json"` into `openclaw.json`.

```bash
# In start-openclaw.sh:
moltlazy patch
```

This reads `MOLTLAZY_FEATURE_FLAGS` from the environment, generates `/home/openclaw/.openclaw/moltlazy.json`, and ensures the `$include` directive exists in `openclaw.json`.

## Auth

All RPC calls require a Bearer token matching the gateway's `gateway.auth.token` config value:

```ts
const client = createClient({
  baseUrl: 'http://localhost:18789',
  token: process.env.OPENCLAW_GATEWAY_TOKEN!,
});
```

The token is never included in RPC call parameters — it's sent as an HTTP `Authorization: Bearer` header.

## Retry behavior

The client retries on HTTP 503 (Service Unavailable) up to `maxRetries` times (default: 3) with `retryDelay` ms between attempts (default: 1000ms).

```ts
const client = createClient({
  baseUrl: 'http://localhost:18789',
  token: '...',
  timeout: 15_000, // 15s request timeout
  maxRetries: 5, // retry up to 5 times on 503
  retryDelay: 2_000, // 2s between retries
});
```

## Handling responses

Every call returns `RpcResponse<T>` — always check `ok` before using `payload`:

```ts
const result = await client.agents.list();

if (result.ok) {
  for (const agent of result.payload) {
    console.log(agent.name);
  }
} else {
  console.error(`Error ${result.error.code}: ${result.error.message}`);
}
```
