npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@contextableai/clawg-ui

v0.2.6

Published

AG-UI protocol channel plugin for OpenClaw — connect CopilotKit and AG-UI clients to your OpenClaw gateway

Readme

clawg-ui

Banner

An OpenClaw channel plugin that exposes the gateway as an AG-UI protocol-compatible HTTP endpoint. AG-UI clients such as CopilotKit UIs and @ag-ui/client HttpAgent instances can connect to OpenClaw and receive streamed responses.

Installation

npm install @contextableai/clawg-ui

Or with the OpenClaw plugin CLI:

openclaw plugins install @contextableai/clawg-ui

Then restart the gateway. The plugin auto-registers the /v1/clawg-ui endpoint and the clawg-ui channel.

How it works

The plugin registers as an OpenClaw channel and adds an HTTP route at /v1/clawg-ui. When an AG-UI client POSTs a RunAgentInput payload, the plugin:

  1. Authenticates the request using device pairing (see Authentication)
  2. Parses the AG-UI messages into an OpenClaw inbound context
  3. Routes to the appropriate agent via the gateway's standard routing
  4. Dispatches the message through the reply pipeline (same path as Telegram, Teams, etc.)
  5. Streams the agent's response back as AG-UI SSE events
AG-UI Client                        OpenClaw Gateway
    |                                      |
    |  POST /v1/clawg-ui (RunAgentInput)   |
    |------------------------------------->|
    |                                      |  Auth (device token)
    |                                      |  Route to agent
    |                                      |  Dispatch inbound message
    |                                      |
    |  SSE: RUN_STARTED                    |
    |<-------------------------------------|
    |  SSE: TEXT_MESSAGE_START             |
    |<-------------------------------------|
    |  SSE: TEXT_MESSAGE_CONTENT (delta)   |
    |<-------------------------------------|  (streamed chunks)
    |  SSE: TEXT_MESSAGE_CONTENT (delta)   |
    |<-------------------------------------|
    |  SSE: TOOL_CALL_START               |
    |<-------------------------------------|  (if agent uses tools)
    |  SSE: TOOL_CALL_END                 |
    |<-------------------------------------|
    |  SSE: TEXT_MESSAGE_END              |
    |<-------------------------------------|
    |  SSE: RUN_FINISHED                  |
    |<-------------------------------------|

Usage

Prerequisites

  • OpenClaw gateway running (openclaw gateway run)
  • A paired device token (see Authentication)

curl

# Using your device token (obtained through pairing)
curl -N -X POST http://localhost:18789/v1/clawg-ui \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -H "Authorization: Bearer $CLAWG_UI_DEVICE_TOKEN" \
  -d '{
    "threadId": "thread-1",
    "runId": "run-1",
    "messages": [
      {"role": "user", "content": "What is the weather in San Francisco?"}
    ]
  }'

@ag-ui/client HttpAgent

import { HttpAgent } from "@ag-ui/client";

// Device token obtained through the pairing flow
const deviceToken = process.env.CLAWG_UI_DEVICE_TOKEN;

const agent = new HttpAgent({
  url: "http://localhost:18789/v1/clawg-ui",
  headers: {
    Authorization: `Bearer ${deviceToken}`,
  },
});

const stream = agent.run({
  threadId: "thread-1",
  runId: "run-1",
  messages: [
    { role: "user", content: "Hello from CLAWG-UI" },
  ],
});

for await (const event of stream) {
  console.log(event.type, event);
}

CopilotKit

import { CopilotKit } from "@copilotkit/react-core";

// Device token obtained through the pairing flow
const deviceToken = process.env.CLAWG_UI_DEVICE_TOKEN;

function App() {
  return (
    <CopilotKit
      runtimeUrl="http://localhost:18789/v1/clawg-ui"
      headers={{
        Authorization: `Bearer ${deviceToken}`,
      }}
    >
      {/* your app */}
    </CopilotKit>
  );
}

Request format

The endpoint accepts a POST with a JSON body matching the AG-UI RunAgentInput schema:

| Field | Type | Required | Description | |---|---|---|---| | threadId | string | no | Conversation thread ID. Auto-generated if omitted. | | runId | string | no | Unique run ID. Auto-generated if omitted. | | messages | Message[] | yes | Array of messages. At least one user message required. | | tools | Tool[] | no | Client-side tool definitions (reserved for future use). | | state | object | no | Client state (reserved for future use). |

Message format

{
  "role": "user",
  "content": "Hello"
}

Supported roles: user, assistant, system, tool.

Response format

The response is an SSE stream. Each event is a data: line containing a JSON object with a type field from the AG-UI EventType enum:

| Event | When | |---|---| | RUN_STARTED | Immediately after validation | | TEXT_MESSAGE_START | First assistant text chunk | | TEXT_MESSAGE_CONTENT | Each streamed text delta | | TEXT_MESSAGE_END | After last text chunk | | TOOL_CALL_START | Agent invokes a tool | | TOOL_CALL_END | Tool execution complete | | RUN_FINISHED | Agent run complete | | RUN_ERROR | On failure |

Authentication

clawg-ui uses device pairing to authenticate clients. This provides secure, per-device access control without exposing the gateway's master token.

Device Pairing Flow

┌─────────────────┐      ┌──────────────────┐      ┌─────────────────┐
│  Gateway Owner  │      │  OpenClaw Server │      │   AG-UI Client  │
└────────┬────────┘      └────────┬─────────┘      └────────┬────────┘
         │                        │                         │
         │                        │  1. POST (no auth)      │
         │                        │<────────────────────────│
         │                        │                         │
         │                        │  2. Return device token │
         │                        │     + pairing code      │
         │                        │────────────────────────>│
         │                        │     403 pairing_pending │
         │                        │     { pairingCode, token }
         │                        │                         │
         │              3. Share pairing code (out of band) │
         │<─────────────────────────────────────────────────│
         │                        │                         │
    4. Approve device             │                         │
         │  openclaw pairing approve clawg-ui ABCD1234      │
         │───────────────────────>│                         │
         │                        │                         │
         │                        │  5. POST with device token
         │                        │<────────────────────────│
         │                        │     Authorization: Bearer <token>
         │                        │                         │
         │                        │  6. Success - SSE stream│
         │                        │────────────────────────>│
         │                        │                         │

Step-by-Step Setup

1. Client initiates pairing

The client sends a POST request without any authorization header:

curl -X POST http://localhost:18789/v1/clawg-ui \
  -H "Content-Type: application/json" \
  -d '{}'

Response (403):

{
  "error": {
    "type": "pairing_pending",
    "message": "Device pending approval",
    "pairing": {
      "pairingCode": "ABCD1234",
      "token": "MmRlOTA0ODIt...b71d",
      "instructions": "Save this token for use as a Bearer token and ask the owner to approve: openclaw pairing approve clawg-ui ABCD1234"
    }
  }
}

The client must save the token for future requests.

2. Approve the device (gateway owner)

The client shares the pairingCode with the gateway owner, who approves it:

# List pending pairing requests
openclaw pairing list clawg-ui

# Approve the device
openclaw pairing approve clawg-ui ABCD1234

3. Client uses Bearer token

Once approved, the client uses their Bearer token for all requests:

curl -N -X POST http://localhost:18789/v1/clawg-ui \
  -H "Authorization: Bearer MmRlOTA0ODIt...b71d" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Hello"}]}'

CLI Commands

| Command | Description | |---------|-------------| | openclaw clawg-ui devices | List approved devices | | openclaw pairing list clawg-ui | List pending pairing requests awaiting approval | | openclaw pairing approve clawg-ui <code> | Approve a device by its pairing code |

Error Responses

| Status | Type | Meaning | |--------|------|---------| | 401 | unauthorized | Invalid device token | | 403 | pairing_pending | No auth (initiates pairing) or valid token but device not yet approved |

Deprecated: Direct Bearer Token

Deprecated: Previous versions (0.1.x) allowed using the gateway's master token (OPENCLAW_GATEWAY_TOKEN) directly. This approach is no longer supported. All clients must now use device pairing.

Old (deprecated):

Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN

New (required):

POST without Authorization header  # Initiates pairing
Authorization: Bearer <device-token>  # After approval

Agent routing

The plugin uses OpenClaw's standard agent routing. By default, messages route to the main agent. To target a specific agent, set the X-OpenClaw-Agent-Id header:

curl -N -X POST http://localhost:18789/v1/clawg-ui \
  -H "Authorization: Bearer $CLAWG_UI_DEVICE_TOKEN" \
  -H "X-OpenClaw-Agent-Id: my-agent" \
  -d '{"messages":[{"role":"user","content":"Hello"}]}'

Error responses

Non-streaming errors return JSON:

| Status | Type | Meaning | |---|---|---| | 400 | invalid_request_error | Invalid request (missing messages, bad JSON) | | 401 | unauthorized | Invalid device token | | 403 | pairing_pending | No auth header (initiates pairing) or valid token but device not yet approved | | 405 | — | Method not allowed (only POST accepted) |

Streaming errors emit a RUN_ERROR event and close the connection.

Development

git clone https://github.com/contextablemark/clawg-ui
cd clawg-ui
npm install
npm test

License

MIT