--secret-phrase "$CEF_VAULT_SECRET_PHRASE"
```
The vault checks your write access on the scope and writes its own registry bucket. The agent’s alias is bound to the scope it is first published from. Authenticate with your wallet’s phrase or with `--vault-token` (`$CEF_VAULT_TOKEN`). `--bucket`, `--access-token`, and the network flags are refused with `--vault`.
## Remove someone
For an organization service, remove people on the organization’s page. People still on the service’s own member list are shown on **Settings** → **People**, each with **Remove**.
## Related
* [Next: Install the CLI](/get-started/install/)
* [Your Agent Service](/get-started/agent-service/)
* [Vault members](/vaults/members/)
* [Push and deploy](/agents/ship/push-and-deploy/)
* [CLI reference](/reference/cli/#cef-push)
# Agent SDK (@cef-ai/agent-sdk)
> Reference for @cef-ai/agent-sdk 5.8.0: decorators, the Context surface, defineAgent, defineWorkflow, isWorkflow, and the workflow runner entry.
```bash
npm install @cef-ai/agent-sdk@5.8.0
```
| Import | Contains | Used in |
| ----------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------- |
| `@cef-ai/agent-sdk` | Decorators and types (`Context`, `Event`, …). | Agent source. |
| `@cef-ai/agent-sdk/config` | `defineAgent`, `defineWorkflow`, `isWorkflow`, config types. | `cef.config.ts`. |
| `@cef-ai/agent-sdk/workflow` | The workflow engine: `WorkflowRunner`, graph helpers, `WORKFLOW_RUNNER_ENTRY`. | Tools that inspect or test workflows. |
| `@cef-ai/agent-sdk/workflow/runner` | The runner module itself; the default entry of every workflow. | `defineWorkflow({ runner })`. |
| `@cef-ai/agent-sdk/runtime` | The in-bundle implementation of `ctx`. | Wired in by `cef build`; never imported by agents. |
Decorators need `"experimentalDecorators": true` in `tsconfig.json`.
## Decorators
| Decorator | Target | Signature / effect |
| --------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@Engagement({ id, goal })` | class | Names an engagement. |
| `@OnEvent(type)` | method | `(event: Event, ctx: Context) => Promise`. `type` must be a string literal. A second handler for the same type is ignored with a warning. |
| `@OnStart` / `@OnStart()` | method | Runs once when the Job starts. |
| `@OnClose` / `@OnClose()` | method | `(ctx: Context, reason: OnCloseReason)`. |
| `@Condition(expr)` | class | CEL selection expression. Repeatable; ANDed. |
| `@Priority(n)` | class | Lower value wins. Last application wins. |
| `@Weight(n)` | class | Split within a priority tier. |
| `@Limit(n, per)` | class | `per`: `"day"`, `"connection/day"`, `"connection/month"`. |
| `@Params(values)` | class | Param values for the engagement; repeated applications merge. |
`OnCloseReason` is `"revoked" | "idle_timeout" | "closed_by_agent" | "failed"`.
## `Event`
| Field | Type | Notes |
| ----------- | ------------------------------- | ------------------------------ |
| `type` | `string` | |
| `payload` | `P` | |
| `timestamp` | `string` | ISO 8601, set by the vault. |
| `context` | `string` | The stream key. |
| `role` | `"source" \| "user" \| "agent"` | |
| `from` | `string?` | Publisher identity. |
| `eventId` | `string?` | |
| `parents` | `string[]?` | Events this one was caused by. |
## `Context`
| Member | Type |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cubby(alias, attribution?)` | `CubbyHandle`: `query(sql, params?) → Promise`, `exec(sql, params?) → Promise<{ changes, lastInsertRowid }>`. The cubby belongs to the Agent Service. `attribution.nodeId` names the workflow step making the call. |
| `models` | `KnownModels & Record`. `ModelHandle`: `infer(input: I) → Promise`, `stream(input: I) → AsyncIterable` (yields the complete output once). |
| `vault.publish(type, payload, opts?)` | `opts: PublishOptions` = `{ target?, title?, description?, correlation? }`. |
| `vault.objects` | `upload(path, data: Uint8Array, { contentType? })`, `get(path)`, `head(path)`, `presignedUrl(path, { ttlSeconds? })`, `list({ prefix? })`. No `delete`. |
| `memory` | `MemoryHandle`: `upsert(record)`, `update(id, { title?, body? })`, `setPrivacy(id, privacy)`, `delete(id)`, `relation(edge)`, `search(match, { limit? })`, `get(id)`, `neighbours(id, { limit? })`, `countByType()`. |
| `self` | `{ agentId?, vaultId?, scope?, context?, jobId?, taskId? }`, frozen. |
| `settings` | `Readonly>`. |
| `params` | `Readonly>`. |
| `close(reason?)` | `Promise`. |
`MemoryRecordInput`: `{ id, type, title?, body?, scope, privacy }`. `MemoryRelationInput`: `{ in, out, type, scope, privacy }`. `MemoryPrivacy`: `"public" | "internal" | "private" | "restricted"`, required on every write. `neighbours` returns `MemoryNeighbourRow`: `{ id, type, title, scope, privacy, edgeType }`.
`KnownEventTypes` and `KnownModels` are interfaces filled by `cef typegen` for typed `@OnEvent`, `vault.publish`, and `models`.
## `defineAgent(config)`
Returns the config unchanged, with its literal types. Fields of `AgentConfig`:
| Field | Type | Default |
| -------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `id` | `string` | required; the alias |
| `version` | `string` | required |
| `alias` | `string` | `id` |
| `agentServicePubkey` | `string` | — |
| `source` | `string` | — |
| `card` | `{ name, description, iconUrl?, capabilities? }` | — |
| `entry` | `string` | one of `entry` / `engagements` |
| `engagements` | `{ id, entry, goal?, condition?, priority?, weight?, limit?: { n, per }, params?, enabled? }[]` | |
| `requiredScopes` | `string[]` | `["default"]` |
| `idleTimeout` | duration string | `"30m"`; `"0s"` disables |
| `models` | `Record` | — |
| `params` | `Record` | — |
| `settings` | `SettingDecl[]` | — |
| `cubbies` | `CubbyDecl[]` = `{ alias, migrations? }[]` | — |
| `schedules` | `ScheduleDecl[]` | — |
| `widgets` | `WidgetDecl[]` | — |
| `eventSchemas` | `Record` | — |
| `uses` | `Record` | Peer agents, typed by `cef typegen`. |
| `agents` | `AgentConfig[]` | Several agents in one config. |
| `kind` | `"internal" \| "external" \| "workflow"` | A classification; dispatch does not depend on it. |
| Type | Shape |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ParamDecl` | `{ type: "number" \| "string" \| "boolean" \| "modelAlias", default, min?, max?, enum? }` |
| `SettingDecl` | `{ key, type: "string" \| "number" \| "boolean" \| "url" \| "secret", required?, label?, description?, default? }` |
| `ScheduleDecl` | `{ id, cron, timezone?, eventType, payload? }` |
| `WidgetDecl` | `{ id, name?, description?, cubbyAlias?, kind?, config?, queries?, events?, dir, entry }`; a query is `{ id, label?, sql?, cubby?, tool?, limit?, timeoutMs? }` |
Guides: [Write an agent](/agents/code-agents/overview/), [Build a widget](/agents/building-blocks/create-a-widget/).
## `defineWorkflow(spec)`
Declares a workflow and returns an `AgentConfig`, so a workflow builds, pushes, deploys, and connects like any agent.
```ts
import { defineWorkflow } from "@cef-ai/agent-sdk/config";
export default defineWorkflow({
id: "triage",
version: "0.1.0",
goal: "Classify incoming requests",
models: { llm: "https://cdn.ddc-dragon.com//models///model.json" },
nodes: [
{ id: "start", kind: "trigger" },
{ id: "classify", kind: "model", params: { alias: "llm", input: { prompt: "={{ $json.text }}" } } },
{ id: "done", kind: "output" },
],
edges: [
{ from: "start", to: "classify" },
{ from: "classify", to: "done" },
],
});
```
| `WorkflowSpec` field | Meaning |
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`, `version` | As for an agent. |
| `goal` | Description; also the default card description. |
| `nodes` | `WorkflowNode[]`: `{ id, kind, use?, emit?, params?, label?, question?, position? }`. |
| `edges` | `{ from, to, when?, loop? }`; `from`/`to` must be node ids (checked by the type). `when`: `{ field, op, value? }`, `op` one of `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `contains`, `exists`. `loop`: `{ max, counter, exhausted? }`. |
| `models`, `cubbies`, `schedules`, `card`, `idleTimeout` | As for an agent. `idleTimeout` defaults to `"30m"`. |
| `runner` | Runner entry. Defaults to `"@cef-ai/agent-sdk/workflow/runner"`. |
Node kinds: `trigger`, `agent`, `branch`, `join`, `publish`, `remember`, `relate`, `recall`, `transform`, `code`, `human`, `model`, `cubbyQuery`, `cubbyExec`, `action`, `output`, `split`, `aggregate`. Step semantics: [Steps](/agents/workflows/steps/).
`defineWorkflow` throws at config load (that is, at `cef build`) when two nodes share an id, a kind is unknown, an `agent` node has no `use`, a `model` node names an alias not in `models`, there is no `trigger`, an edge names an unknown node, a schedule id is not a trigger with `params.mode: "schedule"`, a non-trigger node has no incoming edge, or the runner’s own validation finds a fatal problem.
The returned config uses the runner as its entry, adds a `runs` cubby for the runner’s state, and carries the graph as the `graph` param. A deployment can override that param.
## `isWorkflow(manifest)`
Returns `true` when a manifest carries a non-empty `graph` param, which is what makes an agent a workflow. `WORKFLOW_GRAPH_PARAM` is `"graph"`.
## `@cef-ai/agent-sdk/workflow`
| Export | Use |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `WorkflowRunner` | The engine class every workflow runs. |
| `WORKFLOW_RUNNER_ENTRY` | `"@cef-ai/agent-sdk/workflow/runner"`. |
| `validate(doc)`, `isFatal(issue)` | The runner’s graph validation. |
| `readContinuation(raw)` | Which step, pass, and item an answer was for. |
| `readResultSpec`, `narrowResult`, `RESULT_TYPES` | A workflow’s declared Result, used by [evaluations](/agents/workflows/evaluate/results/). |
| `STEP_ASK_EVENT` | `"workflow.step"`. |
## Related
* [Write an agent](/agents/code-agents/overview/)
* [Workflows in code](/agents/workflows/author-in-code/)
* [CLI reference](/reference/cli/)
* [Testing reference](/reference/testing/)
# Build with AI
> Point Claude Code, Cursor, or any coding agent at Manykind's machine-readable docs so it builds with real platform APIs.
These docs are published in machine-readable form, so a coding agent has accurate, current platform context instead of guessing.
## llms.txt files
Three files are generated from this site on every build:
| File | What it is | Use it when |
| ------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------------- |
| [`/llms.txt`](/llms.txt) | An index of the documentation, with links. | The agent should discover what exists and fetch only what it needs. |
| [`/llms-full.txt`](/llms-full.txt) | The entire documentation in one Markdown file. | The agent should load the whole platform in one fetch. |
| [`/llms-small.txt`](/llms-small.txt) | A condensed version of the full file. | The agent has a smaller context budget. |
They follow the [llms.txt convention](https://llmstxt.org/) and are regenerated from the published pages, so they never drift from what you read here.
## Use it in your coding agent
```text
Read https://developers.cere.io/llms-full.txt for context on the Manykind platform,
then help me write a workflow that …
```
Give the agent the vocabulary up front: an **Agent Service** holds your agents and workflows; a customer’s **vault** holds their data, **Memory Bank**, and **connectors**; an agent or workflow runs on a vault only after the owner **connects** it.
## Scaffolded projects include agent instructions
`cef init` writes `AGENTS.md`, `CLAUDE.md`, and a `.claude/` settings folder into a new project, so a coding agent opened in it starts with the project’s conventions. Pass `--no-ai` to skip them.
## Related
* [Install the CLI](/get-started/install/)
* [Quickstart](/get-started/quickstart/)
* [How it fits together](/get-started/how-it-fits-together/)
* [Glossary](/reference/glossary/)
# CLI (@cef-ai/cli)
> Every cef command and flag in @cef-ai/cli 2.8.0: init, build, typegen, inspect, push, widget push, cubby push, deploy, dev, publish, eval, and test.
The reference section is the lookup layer: every CLI command, SDK export, limit, error code, and term. Start with the CLI.
```bash
npm install -D @cef-ai/cli@2.8.0 # or: npm i -g @cef-ai/cli
cef --version
```
| Command | Does |
| ------------------------------------- | -------------------------------------------------------------------- |
| [`cef init`](#cef-init) | Scaffold a project. |
| [`cef build`](#cef-build) | Bundle agents and write manifests. |
| [`cef typegen`](#cef-typegen) | Generate types for declared models and peers. |
| [`cef inspect`](#cef-inspect) | Check a built agent. |
| [`cef push`](#cef-push) | Upload an agent version, or register an A2A agent you run elsewhere. |
| [`cef widget push`](#cef-widget-push) | Publish a service widget. |
| [`cef cubby push`](#cef-cubby-push) | Publish the service’s cubby declarations. |
| [`cef deploy`](#cef-deploy) | Apply deployment records. |
| [`cef dev`](#cef-dev) | Serve a widget locally. |
| [`cef publish`](#cef-publish) | Send the agent card to the marketplace listing. |
| [`cef eval`](#cef-eval) | Workflow evaluations. |
| `cef test` | Not implemented; prints a notice. Run `vitest` directly. |
Any failing command prints its error and exits with code `1`.
## Environments
`--env dev|stage|prod`, or `$CEF_ENV`. Default `dev`.
| `--env` | DDC network (`--preset`) |
| ------- | ------------------------ |
| `dev` | `DEVNET` |
| `stage` | `TESTNET` |
| `prod` | `MAINNET` |
The environment also selects the platform API for `deploy`, the marketplace for `publish`, and the endpoints written into widgets. Specific flags (`--preset`, `--endpoint`, `--marketplace`) override single values.
## Credentials
| Variable | Flag | Used by |
| ------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `CEF_DDC_ACCESS_TOKEN` | `--access-token` | `push`, `widget push`, `cubby push`: a DDC token from ROC (**Settings** → **Access** → **DDC access token**). |
| `CEF_DDC_SECRET_PHRASE` | `--secret-phrase` | Same commands: the bucket owner’s sr25519 phrase, instead of a token. |
| `CEF_DDC_SUBJECT_PHRASE` | `--subject-phrase` | The phrase of the key a token was issued to, when the token names one. |
| `CEF_ACCESS_TOKEN` | `--access-token` | `deploy`, `publish`, `eval run`: the CLI access token from ROC (**Settings** → **Access** → **CLI access token**). |
| `CEF_VAULT_TOKEN` | `--vault-token` | `push --vault`. |
| `CEF_VAULT_SECRET_PHRASE` | `--secret-phrase` | `push --vault`: your wallet phrase (used as ed25519). |
| `CEF_ENDPOINT` | `--endpoint` | `deploy`: platform API base URL. |
| `CEF_MARKETPLACE_URL` | `--marketplace` | `publish`. |
Prefer environment variables to flags: a secret on the command line stays in shell history and is visible in the process list. A push needs exactly one of a phrase or a token.
## `cef init`
```bash
cef init [dir]
```
Scaffolds a hello-world agent: `cef.config.ts`, `src/agent.ts`, `migrations/`, `deployments/`, a widget, a test, and, unless `--no-ai`, `AGENTS.md`, `CLAUDE.md`, and `.claude/`.
| Flag | Default | Meaning |
| ------------------- | --------------------- | ------------------------------------ |
| `--name ` | slug of the directory | Agent alias. |
| `-y, --yes` | — | Accept all defaults. |
| `--pm ` | — | `pnpm`, `npm`, `yarn`, or `bun`. |
| `--install` | off | Install dependencies. |
| `--no-git` | — | Skip `git init`. |
| `--no-ai` | — | Skip the AI assistant files. |
| `--force` | — | Scaffold into a non-empty directory. |
| `--template ` | `hello-world` | Template. |
## `cef build`
Bundles every agent in `cef.config.ts` and writes `dist//bundle.js`, `manifest.json`, and `widgets//` (runtime vendored and manifest injected).
| Flag | Default | Meaning |
| ------------------- | --------------- | ------------------------------------------------------------- |
| `--config ` | `cef.config.ts` | Config file. |
| `--out ` | `dist` | Output directory. |
| `--env ` | `dev` | Endpoints written into widget manifests. |
| `--as-pubkey ` | — | Agent Service pubkey written into widget manifests’ agent id. |
Build checks are listed in [Write an agent](/agents/code-agents/overview/#what-cef-build-rejects).
## `cef typegen`
Fetches each declared model’s `model.json` and each peer in `uses`, then writes `.cef/generated.d.ts` and `cef.lock.json`.
| Flag | Default | Meaning |
| ----------------- | --------------- | ------------ |
| `--config ` | `cef.config.ts` | Config file. |
## `cef inspect`
```bash
cef inspect dist/
```
Prints each engagement and checks that the bundle exports every handler the manifest routes to. Exits with code `2` when a handler is missing, so you can run it in CI.
## `cef push`
Uploads the built agent in `dist/` to a bucket you can write, or through vault-api into an organization vault, or registers an A2A agent you run elsewhere (`--kind external`).
```bash
cef push --bucket --as-pubkey
cef push --vault --vault-scope
cef push --kind external --card --bucket --as-pubkey
```
| Flag | Applies to | Default | Meaning |
| --------------------------- | --------------------- | ------------------------- | ---------------------------------------------------------------------------------- |
| `--kind ` | all | `internal` | `internal` pushes the bundle in `dist/`; `external` registers an A2A agent. |
| `--bucket ` | bucket push, external | — | DDC bucket id (decimal). |
| `--as-pubkey ` | all | config value | Agent Service pubkey; forms the agent id `:`. |
| `--agent ` | internal | the only built agent | Which `dist//` to push. |
| `--out ` | internal | `dist` | Build output directory. |
| `--vault ` | internal | — | Publish into this organization vault through vault-api. Needs `--vault-scope`. |
| `--vault-scope ` | `--vault` | — | Scope to publish from. The alias is bound to the scope it is first published from. |
| `--vault-api ` | `--vault` | environment’s vault API | vault-api base URL. |
| `--vault-token ` | `--vault` | `$CEF_VAULT_TOKEN` | Wallet-api bearer token. |
| `--card ` | external (required) | — | A2A Agent Card URL. A bare origin gets `/.well-known/agent-card.json`. |
| `--alias ` | external | slug of the card name | Registry alias; no `:`. |
| `--agent-version ` | external | `1.0.0` | Version to register. |
| `--scope ` | external | `default` | Scopes the agent asks for. |
| `--idle-timeout