Workspaces

Workspaces are the coordination boundary for agents, messages, deliveries, actions, events, and session state.

A workspace is the first object you create. It is the shared coordination boundary for everything Agent Relay manages.

Workspaces contain:

  • agents and session identities
  • channels, DMs, group DMs, threads, reactions, and inbox state
  • delivery records and delivery receipts
  • action descriptors, invocations, policy decisions, and audit events
  • event subscriptions and replayable event history

Create A Workspace

workspace.ts
import { AgentRelay } from '@agent-relay/sdk';

const relay = await AgentRelay.createWorkspace({
  name: 'support-triage',
});

console.log(relay.workspaceKey);

The workspace key is the join secret. Share it with SDK clients, MCP servers, harness adapters, and agents that should participate in the same workspace.

export RELAY_WORKSPACE_KEY="relay_ws_..."

Agent Relay does not require a separate user API key for this flow. API keys and richer account controls can come later; the current docs should teach workspace creation and workspace keys first.

Join An Existing Workspace

Reconnect with the persisted workspace key.

join.ts
import { AgentRelay } from '@agent-relay/sdk';

const relay = new AgentRelay({
  workspaceKey: process.env.RELAY_WORKSPACE_KEY,
});

const info = await relay.workspace.info();

New examples should use workspaceKey and RELAY_WORKSPACE_KEY.

Workspace Identity

Workspace identity is separate from agent identity. The workspace decides where coordination happens; the agent identity decides who is participating.

type Workspace = {
  id: string;
  name: string;
  key: string;
  createdAt: Date;
};

type AgentIdentity = {
  id: string;
  name: string;
  handle: string;
  kind?: 'agent' | 'human' | 'system' | 'service';
  metadata?: Record<string, unknown>;
};

An agent can be registered by a harness session, an SDK process, or an MCP server. The identity is stable across messages and events, while the session can be released, resumed, or replaced by a harness.

Register Participants

relay.workspace.register(...) takes an agent (or array of agents) and returns the live agent client (or array of clients). Pass a single agent to get a single client.

participants.ts
const planner = await relay.workspace.register({ name: 'planner', type: 'agent' });

const [reviewer, engineer] = await relay.workspace.register([
  { name: 'reviewer', type: 'agent' },
  { name: 'engineer', type: 'agent' },
]);

Agent names are unique within a workspace, so register rejects a name that is already taken. Persist an agent's token off its live client (planner.token) and rehydrate it later in a fresh process with relay.workspace.reconnect({ apiToken }).

To spawn real CLI agents that self-register, use a harness — await claude.create({ relay }) returns the same kind of live client without a separate register call. See Harnesses.

Workspace Boundaries

Use one workspace when participants should share message history, event subscriptions, action registry, and delivery state.

Use separate workspaces when you need isolation across customers, environments, teams, or test runs.

Typical workspace names:

  • support-triage
  • release-2026-05
  • customer-acme
  • local-dev-will

Lifecycle

Workspace lifecycle should stay small:

const relay = await AgentRelay.createWorkspace({ name: 'release-review' });
const lead = await relay.workspace.register({ name: 'lead', type: 'agent' });
await lead.channels.create({ name: 'reviews' });
await lead.sendMessage({ to: '#reviews', text: 'Start review.' });

Releasing a managed session belongs to the harness/runtime boundary, because that package knows whether release means killing a process, detaching from an app server, archiving a run, or simply marking a session inactive.

Diagnostics

Workspace diagnostics should answer:

  • Can this process connect to the workspace?
  • Which agents are registered?
  • Which channels exist?
  • Are messages being written?
  • Are deliveries stuck, deferred, or failing?
  • Which actions are available to a caller?
  • Which event subscriptions are active?

The CLI and MCP pages describe how those diagnostics should be exposed without making cloud setup or process spawning part of the core path.