Agents

An agent is the unit of scope and persona in Chamade. It ties together one provider, the keys that drive it, and the platform accounts it can reach. Most users have exactly one and never think about it.

What an agent is

When you connect a platform and mint a key, Chamade groups them under an agent: a named persona that pairs a credential (and optionally an LLM provider) with the platform accounts it's allowed to see and act on. An agent driven by a key can only touch the accounts attached to it — nothing else.

Throughout these docs, agent always means this Chamade unit. The thing on your side — your code, your AI loop, your MCP client — is your app.

The mental model

One agent holds:

Every inbound event (a DM, an incoming call, a transcript line) is scoped to the agent that owns the account it arrived on, and dispatched once to that agent. Manage agents at dashboard → Agents.

Two ways to drive an agent

Pick per agent. They're not exclusive — an agent can expose keys and carry a provider — but most use one or the other.

Bring your own runtime

Your app holds the agent's chmd_* key (or an MCP OAuth bearer) and does the thinking. Chamade is a pure gateway: your app reads events and calls back to act.

  • Read events via the MCP tools, the REST API, or Push Mode.
  • Act with chamade_dm_chat, chamade_call_say, chamade_call_chat, … (or their REST equivalents).
  • Best when you already run an AI loop — Claude Code, a custom backend, any MCP client.

Inline provider

You attach an LLM provider to the agent. Chamade calls it on every scoped event, parses the reply's XML action tags (<say>, <write>, <dm>, …) and fans them out. No runtime to host — Chamade drives your model.

  • Configure in dashboard → AgentsProvider.
  • Catalog and per-provider setup: see the AI providers section in the sidebar.
  • Best when you don't want to host an agent loop at all.
Voice is orthogonal

Both models handle chat turn-based and cheap. For voice, you separately choose hosted STT/TTS (add a provider key, Chamade runs the pipeline) or raw-PCM BYO-audio on the call WebSocket — independent of how the agent is driven.

Keys & authorization

There are two kinds of chmd_* key, and the distinction is the whole point: the key an agent holds must not be able to reconfigure the account it runs under.

These map onto three authorization tiers:

TierWho can call itSurface
Control-plane Any valid key (agent or settings) Calls, DMs, inbox, files — /api/call/*, /api/dm/*, /api/inbox
Config Dashboard session or a settings key (agent keys → 403) Everything under /api/agents/*, voice providers, platform connections, bot tokens, SIP, key mint, data export
Account-owner Dashboard session only (no bearer at all) Delete account, change email / password, manage settings keys

OAuth-based platform connects (Microsoft, Google, Discord, NC Talk, and the Gemini / Foundry providers) always require a browser consent on top, whatever key you hold.

The default agent

Exactly one of your agents carries the Default badge. Its job is to receive any platform you connect next, automatically — so a casual user who connects Teams, Discord, and one key never has to think about scope.

If you stick with one key + the default, agents are invisible: that key sees every platform, exactly like single-bucket Chamade.

When to create more

Scope: what an agent sees

A bearer (key or OAuth client) can only see and act on accounts that share an agent with it. Concretely:

The no-orphan rule: every bearer and every platform account must belong to ≥1 agent, so a credential never silently sees nothing and inbound events are never dropped. You can't delete an agent if it would orphan a member, and you can't detach the last agent of a key or account — move it elsewhere first. The default is un-deletable, so there's always a safe fallback.

REST API

Every agent-shaping endpoint lives under /api/agents/* and is config tier: a dashboard session or a settings key only — agent keys, MCP OAuth, and identity tokens get 403. Full reference: REST API → Agents.