Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/agents/llms.txt

Use this file to discover all available pages before exploring further.

Overview

AgentClient is a WebSocket client for connecting to Agents from browsers and Node.js. It provides RPC method calls, state synchronization, and identity management.
import { AgentClient } from "agents/client";

const client = new AgentClient<{ count: number }>({
  host: "localhost:1999",
  agent: "CounterAgent",
  name: "room-123",
  onStateUpdate: (state) => {
    console.log("State:", state);
  }
});

await client.call("increment");

Constructor

options
AgentClientOptions<State>
required
host
string
required
WebSocket host (e.g., “localhost:1999” or “agent.example.com”)
agent
string
required
Name of the agent class (kebab-case, e.g., “my-agent”)
name
string
default:"default"
Name of the specific Agent instance
basePath
string
Full URL path - bypasses agent/name URL construction. When set, connects to this path directly. Server must handle routing manually (e.g., with getAgentByName).
path
string
Additional path to append to the URL. Works with both standard routing and basePath.
onStateUpdate
(state: State, source: 'server' | 'client') => void
Called when the Agent’s state is updated
onStateUpdateError
(error: string) => void
Called when a state update fails (e.g., connection is readonly)
onIdentity
(name: string, agent: string) => void
Called when the server sends the agent’s identity on connect
onIdentityChange
(oldName: string, newName: string, oldAgent: string, newAgent: string) => void
Called when identity changes on reconnect (different instance than before)

Standard Routing

const client = new AgentClient({
  host: "localhost:1999",
  agent: "chat-agent",
  name: "room-123"
});
// Connects to: ws://localhost:1999/agents/chat-agent/room-123

Custom Routing with basePath

const client = new AgentClient({
  host: "agent.example.com",
  basePath: "user", // Server routes based on auth
  onIdentity: (name, agent) => {
    console.log("Connected to:", agent, name);
  }
});
// Connects to: wss://agent.example.com/user

With Path Suffix

const client = new AgentClient({
  host: "localhost:1999",
  agent: "my-agent",
  name: "room",
  path: "settings"
});
// Connects to: ws://localhost:1999/agents/my-agent/room/settings

Properties

agent

agent
string
required
The agent class name (kebab-case). Updated when identity message is received.

name

name
string
required
The agent instance name. Updated when identity message is received.

identified

identified
boolean
required
Whether the client has received identity from the server. Becomes true after the first identity message, resets to false on connection close.

ready

ready
Promise<void>
required
Promise that resolves when identity has been received from the server. Useful for waiting before making calls that depend on knowing the instance. Resets on connection close.
await client.ready;
console.log("Connected to:", client.name);

Methods

call()

Call a method on the Agent.
method
string
required
Name of the method to call
args
unknown[]
Arguments to pass to the method
options
CallOptions
timeout
number
Timeout in milliseconds. If the call doesn’t complete within this time, it will be rejected.
stream
StreamOptions
onChunk
(chunk: unknown) => void
Called when a chunk of data is received
onDone
(finalChunk: unknown) => void
Called when the stream ends
onError
(error: string) => void
Called when an error occurs
Returns: Promise<T> - Promise that resolves with the method’s return value

Basic Call

const result = await client.call("increment");
console.log("Result:", result);

With Arguments

const sum = await client.call("add", [5, 3]);
console.log("Sum:", sum);

With Timeout

try {
  const result = await client.call("slowMethod", [], {
    timeout: 5000 // 5 seconds
  });
} catch (error) {
  console.error("Timeout or error:", error);
}

Streaming Call

const chunks: string[] = [];

await client.call("generateText", ["Hello"], {
  stream: {
    onChunk: (chunk) => {
      chunks.push(chunk.text);
    },
    onDone: (final) => {
      console.log("Stream complete:", final);
    },
    onError: (error) => {
      console.error("Stream error:", error);
    }
  }
});

setState()

Update the Agent’s state from the client.
state
State
required
New state to set
client.setState({ count: 42 });
If the connection is readonly, the server will respond with a state update error.

close()

Close the connection and immediately reject all pending RPC calls.
code
number
WebSocket close code
reason
string
Close reason
client.close(1000, "User closed connection");

Events

AgentClient extends PartySocket, so all PartySocket events are available:

onopen

const client = new AgentClient({
  agent: "MyAgent",
  name: "default",
  onOpen: () => {
    console.log("Connected!");
  }
});

onmessage

Internal protocol messages are handled automatically. Override to handle custom messages:
const client = new AgentClient({
  agent: "MyAgent",
  name: "default",
  onMessage: (event) => {
    // Custom message handling
    console.log("Message:", event.data);
  }
});

onclose

const client = new AgentClient({
  agent: "MyAgent",
  name: "default",
  onClose: (event) => {
    console.log("Disconnected:", event.code, event.reason);
  }
});

onerror

const client = new AgentClient({
  agent: "MyAgent",
  name: "default",
  onError: (event) => {
    console.error("Error:", event);
  }
});

Identity Management

The server sends an identity message on connect:
{
  "type": "cf_agent_identity",
  "name": "room-123",
  "agent": "chat-agent"
}
This is useful when using basePath for custom routing:
const client = new AgentClient({
  host: "agent.example.com",
  basePath: "user",
  onIdentity: (name, agent) => {
    console.log("Connected to instance:", name);
    console.log("Agent class:", agent);
  }
});

Identity Changes

If the server routes to a different instance on reconnect:
const client = new AgentClient({
  host: "agent.example.com",
  basePath: "user",
  onIdentityChange: (oldName, newName, oldAgent, newAgent) => {
    console.warn(`Reconnected to different instance: ${oldName}${newName}`);
  }
});

State Synchronization

The client automatically receives state updates:
const client = new AgentClient<{ count: number }>({
  host: "localhost:1999",
  agent: "counter-agent",
  name: "default",
  onStateUpdate: (state, source) => {
    console.log(`State updated from ${source}:`, state.count);
  }
});

// Update from client
client.setState({ count: 10 });
// Triggers: onStateUpdate({ count: 10 }, "client")

// Server updates state
// Triggers: onStateUpdate({ count: 11 }, "server")

Readonly Connections

If the connection is readonly, state updates will fail:
const client = new AgentClient({
  host: "localhost:1999",
  agent: "my-agent",
  name: "viewer",
  onStateUpdateError: (error) => {
    console.error("State update failed:", error);
    // "Connection is readonly"
  }
});

client.setState({ data: "test" });
// Triggers onStateUpdateError

Best Practices

Wait for Ready

const client = new AgentClient({
  agent: "MyAgent",
  name: "default"
});

// Wait for identity before making calls
await client.ready;
console.log("Connected to:", client.name);

const result = await client.call("method");

Handle Errors

try {
  const result = await client.call("riskyMethod", [data]);
} catch (error) {
  if (error.message === "Connection closed") {
    // Handle disconnect
  } else {
    // Handle RPC error
  }
}

Clean Up

// Close connection when done
client.close(1000, "Done");

Build docs developers (and LLMs) love