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

# AgentSocketServer

> The server half of the agent socket protocol — attach WebSockets, authorize sessions, dispatch RPC, and broadcast state, messages, and events.

`AgentSocketServer` is the server half of the agent socket protocol — it drives every
WebSocket an agent holds. Construct one per actor instance and delegate the actor's
`webSocket(ws, req)` to `attach()`. The server sends each admitted connection a state
snapshot followed by `hello`, dispatches inbound RPC frames to the actor's
[`@rpc()`](/docs/agent-sdk/api-reference/agent/rpc)-decorated methods, and pushes
incremental updates through the `broadcast*` methods as the agent's data changes.

```ts theme={null}
import { Agent, type Env, type MergePatch } from "@telnyx/edge-runtime";
import { AgentSocketServer, type AgentServerSocket } from "@telnyx/edge-runtime/agent-socket";

interface ConvState extends Record<string, unknown> {
  status: string;
}

export class Conversation extends Agent<Env, ConvState> {
  private desk = new AgentSocketServer<ConvState>(this, {
    getState: () => this.getState(),
    getMessages: () => this.messages.all(),
    // token → claims; throw to reject; `undefined` = anonymous client
    authorize: (token) => (token === undefined ? ["read"] : ["read", "rpc"]),
  });

  async webSocket(ws: AgentServerSocket, req: Request): Promise<void> {
    await this.desk.attach(ws, req);
  }

  protected override async setState(patch: MergePatch<ConvState>): Promise<ConvState> {
    const next = await super.setState(patch);
    this.desk.broadcastPatch(patch); // incremental push to every client
    return next;
  }
}
```

With an `authorize` hook configured, every connection becomes an authorized session:
a client that opens with an `attach` frame presents its token, `authorize(token)` maps
it to claims, and per-stream subscriptions are negotiated; a client that never
attaches is authorized as anonymous — `authorize(undefined)` — so admit it with
limited claims, or throw to reject. RPC `call` frames require the `"rpc"` claim,
which is what lets read-only watchers and fully privileged operators share one socket
endpoint.

## attach()

<Attach />

## broadcastPatch()

<BroadcastPatch />

## broadcastSnapshot()

<BroadcastSnapshot />

## broadcastMessages()

<BroadcastMessages />

## broadcastEvent()

<BroadcastEvent />

## watcherCount

<WatcherCount />

## close()

<CloseMethod />

## handleCall()

<HandleCall />

## authorizeEnabled

<AuthorizeEnabled />

## AgentSocketServerOptions

<AgentSocketServerOptionsType />

## AgentServerSocket

<AgentServerSocketType />

## AgentConnectContext

<AgentConnectContextType />

## HandleCallOptions

<HandleCallOptionsType />

## HandleCallResult

<HandleCallResultType />
