Skip to main content
reference

SDK client reference

EthosClient is the typed RPC client for the Ethos control-plane API. It wraps an oRPC link so every call is validated against the shared contract at compile time and at runtime.

Source​

Defined in packages/sdk/src/client.ts. Re-exported from @ethosagent/sdk.

Installation​

pnpm add @ethosagent/sdk

Constructor​

import { EthosClient } from '@ethosagent/sdk';

const client = new EthosClient({
baseUrl: 'http://localhost:2400',
apiKey: 'esk_...',
});

EthosClientOptions​

FieldTypeRequiredDescription
baseUrlstringyesOrigin of the Ethos web-api server. Trailing slashes are stripped automatically.
apiKeystringnoBearer token created via the apiKeys admin namespace. When set, every request includes an Authorization: Bearer <apiKey> header.
fetchtypeof globalThis.fetchnoCustom fetch implementation. Useful for testing or environments without a global fetch. Defaults to globalThis.fetch.

When apiKey is omitted the client falls into cookie-auth mode -- requests are sent with credentials: 'include' so the browser's session cookie authenticates instead. See Cookie-auth mode below.

RPC property​

client.rpc.sessions.list({ limit: 10 });

client.rpc is a ContractRouterClient<Contract> -- a fully typed proxy where each namespace and method maps one-to-one to the contract defined in @ethosagent/web-contracts. Calls are sent as HTTP POST requests to <baseUrl>/rpc.

Stable namespaces​

These namespaces are committed to semver stability. Breaking changes require a major version bump.

sessions​

MethodInputOutputDescription
list{ q?, limit?, cursor?, personalityId? }{ sessions, nextCursor }Paginated session list with optional FTS5 search.
get{ id, withMessages? }{ session, messages, cards }Single session with full message history. withMessages: false skips the history: messages and cards are then [], meaning "not requested".
messages{ id, before?, turns? }{ messages, cards, nextCursor }One page of history, newest turns first. See Paged history.
fork{ id, personalityId? }{ session }Fork an existing session into a new one.
delete{ id }{ ok: true }Delete a session.
update{ id, title }{ session }Rename a session. Pass null to clear.

Paged history​

sessions.messages returns up to turns (1–100, default 20) whole turns. A turn starts at a user message and is never split across pages; rows before the first user message come with the page that reaches the start of the session. A page also stops adding older turns at about 500 KB of message content, but always carries at least one turn. cards holds only the cards whose tool call is in the page.

Pass nextCursor back as before to get the next-older page. It is null once the page reaches the start. The cursor is opaque and stays valid while new messages arrive. A cursor that does not decode, or that belongs to another session, fails with INVALID_INPUT; an unknown session fails with SESSION_NOT_FOUND.

let page = await client.rpc.sessions.messages({ id: sessionId, turns: 20 });
while (page.nextCursor) {
page = await client.rpc.sessions.messages({ id: sessionId, before: page.nextCursor });
}

chat​

MethodInputOutputDescription
send{ sessionId?, clientId, text, personalityId? }{ sessionId, turnId }Start a turn. The response streams over SSE, not this RPC.
abort{ sessionId }{ ok: true }Cancel the running turn for a session.

personalities​

MethodInputOutputDescription
list--{ personalities, defaultId }All loaded personalities.
get{ id }{ personality, soulMd }Single personality with its SOUL.md body.
characterSheet{ id }{ markdown }Rendered character sheet.
create{ id, name, ... }{ personality }Create a new personality.
update{ id, name?, ... }{ personality }Patch an existing personality.
delete{ id }{ ok: true }Delete a user-created personality.
duplicate{ id, newId }{ personality }Clone a personality under a new id.
skillsList{ personalityId }{ skills }List per-personality skills.
skillsGet{ personalityId, skillId }{ skill }Get a single personality skill.
skillsCreate{ personalityId, skillId, body }{ skill }Create a personality skill.
skillsUpdate{ personalityId, skillId, body }{ skill }Update a personality skill body.
skillsDelete{ personalityId, skillId }{ ok: true }Delete a personality skill.
skillsImportGlobal{ personalityId, skillIds }{ imported }Copy global skills into a personality.

memory​

MethodInputOutputDescription
list--{ files }Both MEMORY.md and USER.md entries.
get{ store }{ file }One store: 'memory' or 'user'.
write{ store, content }{ file }Overwrite a memory store.

meta​

MethodInputOutputDescription
capabilities--{ capabilities }Server capability flags (Record<string, boolean>).

Experimental namespaces​

These namespaces may change without a major version bump. See the stability tier table for the full list.

  • tools -- approve, deny (tool approval workflow)
  • clarify -- respond (answer a mid-turn clarification)
  • onboarding -- state, validateProvider, complete
  • config -- get, update
  • cron -- list, get, create, delete, pause, resume, runNow, history
  • skills -- list, get, create, update, delete
  • evolver -- configGet, configUpdate, pendingList, pendingApprove, pendingReject, history
  • mesh -- list, routeTest
  • plugins -- list
  • platforms -- list, set, clear, plus multi-bot CRUD for Telegram and Slack
  • batch -- list, start, get, output
  • eval -- list, start, get, output
  • kanban -- list, getBoard, updateStatus
  • apiKeys -- create, list, revoke (cookie-auth only)

When no apiKey is provided, EthosClient sends every request with credentials: 'include'. This lets browser-based Mission Controls authenticate via the same session cookie the Ethos web UI uses -- no API key required.

Cookie-auth is the only mode that can access the apiKeys admin namespace. Bearer-token auth is rejected there to prevent privilege escalation.

// Browser-side -- cookie handles auth
const client = new EthosClient({
baseUrl: 'http://localhost:2400',
});

Types re-exported from the SDK​

The package re-exports key types so consumers do not need to depend on @ethosagent/web-contracts directly:

  • EthosClient, EthosClientOptions -- client class and constructor options
  • EventStream, EventStreamOptions, EventStreamSubscription -- SSE streaming
  • Contract, SseEvent, ApiKeyScope, ApiKeyMetadata -- shared contract types