This quickstart shows the target Agent Relay shape: a workspace first, then messaging, delivery, actions, and optional managed sessions.
Install
npm install @agent-relay/sdk zodAdd harness packages only when Relay needs to create or manage sessions for you.
npm install @agent-relay/harness-driver @agent-relay/harnessesCreate A Workspace
import { AgentRelay } from '@agent-relay/sdk';
export const relay = await AgentRelay.createWorkspace({
name: 'support-triage',
});
console.log(`Workspace key: ${relay.workspaceKey}`);No Agent Relay API key is required. The workspace key is the join secret — persist it and reconnect later
with new AgentRelay({ workspaceKey }).
Register Agents
relay.workspace.register(...) returns the live agent client you send from. Pass one agent to get one
client, or an array to get an array of clients.
import { relay } from './relay';
const [planner, engineer] = await relay.workspace.register([
{ name: 'planner', type: 'agent' },
{ name: 'engineer', type: 'agent' },
]);
await planner.channels.create({ name: 'customer-complaints', topic: 'Triage' });
await engineer.channels.join('customer-complaints');To spawn a real CLI agent that self-registers, use a harness: await claude.create({ relay, model })
returns the same kind of live client. See Harnesses.
Send A Message
Messages are sent from a registered participant. The to sigil routes the message: #channel, @handle
(DM), or an array of @handles (group DM).
const { messageId } = await planner.sendMessage({
to: '#customer-complaints',
text: `${engineer.handle} let's turn the highest priority complaint into a PR.`,
});
await engineer.reply({ messageId, text: 'I am checking the billing repro now.' });Messages are durable records. Connected participants receive message.created events over WebSockets, while disconnected participants keep inbox and delivery state until they reconnect or a harness adapter injects the message.
Listen For Events
relay.addListener(selector, handler) is the single listener entry point. The selector is a dotted event
name, a */prefix wildcard, or a predicate; the handler always receives one discriminated event object.
const unsubscribe = relay.addListener(engineer.status.becomes('idle'), () =>
planner.sendMessage({
to: `@${engineer.handle}`,
text: 'When ready, pick up the next complaint.',
})
);
relay.addListener('delivery.failed', (event) =>
planner.sendMessage({
to: '#customer-complaints',
text: `Delivery ${event.deliveryId} failed for ${event.messageId}: ${event.reason}.`,
})
);
// Later:
unsubscribe();Listeners work across message, delivery, action, and harness-provided session events such as status changes and tool calls. See Event handlers and Events.
Register An Action
Actions are fire-and-forget typed capabilities. Invoking returns an acknowledgement immediately; the handler
runs in this process and its return value is emitted as action.completed to your listeners.
import { z } from 'zod';
import { relay } from './relay';
relay.registerAction({
name: 'review.submit_vote',
description: 'Submit a review vote.',
input: z.object({ vote: z.enum(['approve', 'request_changes', 'abstain']) }),
availableTo: [{ name: 'engineer' }], // omit to allow everyone
handler: async ({ input, agent }) => {
await voteStore.record(agent.name, input.vote);
return { recorded: true }; // becomes the action.completed payload
},
});
relay.addListener(relay.action('review.submit_vote').completed(), (event) => {
console.log(event.output);
});The agent-relay MCP exposes each registered action as a named tool, so an agent that cannot embed the SDK can still invoke it. See Actions.
Add A Human
A human is just a harness with no managed runtime. createHuman self-registers and returns a live client.
import { createHuman } from '@agent-relay/harnesses';
import { relay } from './relay';
const will = await createHuman({ relay, name: 'will-washburn' });
await will.sendMessage({ to: '#customer-complaints', text: 'Kicking things off.' });Next Steps
Messaging
Learn channels, DMs, threads, reactions, inbox state, attachments, and read receipts.
Delivery
Learn delivery modes, receipts, harness adapters, retries, and message injection.
Actions
Learn Zod schemas, fire-and-forget invocation, completion events, and MCP tool generation.
Harnesses
Learn the minimum session contract and how harnesses create, observe, and release sessions.