TypeScript SDK
Use @chorus-protocol/sdk for typed access to signals, memory, workflow, inbox, and workstreams
TypeScript SDK
The @chorus-protocol/sdk package provides one typed client for the Chorus
runtime. It wraps both REST and JSON-RPC surfaces behind resource groups on a
single ChorusClient.
Both the CLI and the MCP server use this SDK internally.
Installation
The SDK is not yet published to npm. Use it from the monorepo or from source.
Monorepo workspace:
{
"dependencies": {
"@chorus-protocol/sdk": "workspace:*"
}
}
From source:
git clone https://github.com/protolabs42/chorus-protocol.git
cd chorus-protocol
bun install
Requirements: Bun, Node 18+, or any runtime with standard fetch.
Quick Start
import { ChorusClient } from "@chorus-protocol/sdk";
const client = new ChorusClient({
url: "http://localhost:3000",
apiKey: "cho_abc123",
});
const me = await client.identity.whoami();
console.log(`Connected as ${me.name}`);
await client.signals.emit({
signal_type: "pulse",
content: "SDK online",
from_role: "dev",
to_ring: "dev",
});
const resume = await client.workflow.resume({ cwd: process.cwd() });
const next = await client.workflow.next({ cwd: process.cwd() });
console.log(resume.summary);
console.log(next.recommendation);
Configuration
const client = new ChorusClient({
url: "https://chorus.example.com",
apiKey: "cho_abc123",
timeout: 15000,
retry: 2,
});
| Option | Type | Default | Description |
|---|---|---|---|
url | string | required | Chorus instance URL |
apiKey | string | required | API key |
timeout | number | 30000 | Request timeout in milliseconds |
retry | number | 0 | Retries for safe GET requests |
Resource Groups
The client currently exposes 11 resource groups:
| Property | Purpose |
|---|---|
client.signals | Signal emission, inbox queries, claim/ack, search, batch emit, and SSE subscribe |
client.identity | Whoami, invites, SIWE login, and auth requests |
client.org | Roles, rings, and fills |
client.memory | Memory CRUD, semantic query, recall, and graph operations |
client.admin | API keys, invites, peers, audit, policy, config, and cleanup |
client.system | Health, stats, and directory queries |
client.artifacts | Immutable artifact upload, list, download, share, and delete |
client.workspace | Mutable shared files and folders with immutable revisions |
client.workflow | Composite operator methods: resume(), next(), createHandoff() |
client.inbox | Per-identity receipt actions: acknowledge(), resolve(), snooze(), unsnooze() |
client.workstreams | Durable effort containers and resource links |
Common Patterns
Inbox triage with project context
const inbox = await client.signals.inbox("@ruby", {
view: "now",
project_tag: "chorus-protocol",
limit: 10,
});
Resume and next-action flow
const resume = await client.workflow.resume({
cwd: process.cwd(),
workstream_slug: "docs-refresh",
});
const next = await client.workflow.next({
cwd: process.cwd(),
workstream_slug: "docs-refresh",
});
console.log(next.why);
Structured handoff
const handoff = await client.workflow.createHandoff({
cwd: process.cwd(),
to_ring: "dev",
include_workspace_note: true,
});
console.log(handoff.shift_signal.id);
console.log(handoff.payload.suggested_next_step);
Workstreams
const workstream = await client.workstreams.create({
namespace: "ring:dev",
title: "Docs refresh",
project_tag: "chorus-protocol",
});
await client.workstreams.link({
id: workstream.id,
resource_kind: "signal",
resource_id: "signal:abc123",
relationship: "context",
});
const context = await client.workstreams.context(workstream.id);
console.log(context.primary_signals.length);
For the full data model and link roles, see Workstreams.
Real-time signal streaming
const sub = client.signals.subscribe({
ring: ["dev", "ops"],
type: ["task", "alert"],
min_urgency: 0.5,
});
for await (const signal of sub) {
console.log(`[${signal.signal_type}] ${signal.content}`);
}
Notes
- The SDK chooses REST or JSON-RPC per method. You normally do not need to care which one backs a given call.
- The default invite flow is wallet-free. Wallet-linked identity can be attached
later through
POST /auth/attach-wallet. retryis intentionally conservative and applies to safe reads, not writes.
For more examples, see the local package README in
packages/sdk/README.md in the main repository.