> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.ekanos.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed agents

> How a Source provides an agent to every team: templates and versions, skills, triggers and links, approval policy, what teams may change, and who reviews reply drafts.

A managed agent is data held by Ekanos, not code. It has instructions, a model, the tools it may use, which calls wait for a person, and its skills. You change it with the `ekanos` CLI or in the app, and nothing is deployed.

This page explains the model for Source admins and developers. [Build agents with Claude](https://sdk.ekanos.dev/guides/managed-agents.md) walks through creating one, and the [`agents` reference](https://sdk.ekanos.dev/cli/commands#agents) has every flag.

## Provided for every team, or a team's own

| | Provided for every team | A team's own |
| - | - | - |
| Built by | A Source admin, with `ekanos agents` | A team, in the app (Agents › New) |
| Stored as | An **agent template**, with numbered versions | One agent on that team |
| Who sees it | Every team in the Source, under **Agents › Provided for your team** | That team only |
| Updated by | Publishing a new version of the template | The team |

A provided agent is defined once. Each team decides whether to turn it on. Turning it on makes the team's own copy, which runs on that team's connections and as the person who turned it on. A team that hasn't connected a `required` product sees "needs setup" instead of a working agent.

> [!NOTE]
>
> Team members never see the word "Source". To them, a provided agent is
> "provided for your team". Keep Source language out of instructions, skill text
> and reply drafts a team member reads.

## The template lifecycle

A template moves through the same steps every time you change it:

1. **Apply.** `ekanos agents apply agents/<key>` stores a new numbered version. It is a **draft**: no team sees it. Either seat can apply.
2. **Review.** `ekanos agents show <key>` shows what was stored and the version history.
3. **Test.** `ekanos agents test <key> --team <slug> --prompt "…"` runs the latest, unpublished version on one team that has turned the agent on. See [Testing a draft](#testing-a-draft).
4. **Publish.** `ekanos agents publish <key> --yes` makes that version the one every following team runs. Only a Source admin publishes.
5. **Roll back.** `ekanos agents rollback <key> --to <n> --yes` publishes an earlier version to every following team.

`apply` refuses a stale file. The `baseVersion` in `agent.json` is the version you pulled; if someone stored a newer one since, `apply` stops with `invalid_state` (exit 7) so two people never overwrite each other unseen. Pull, reconcile, and apply again.

### Following and pinning

Each team's copy either **follows** the published version or is **pinned** to one. A following team moves on every publish and rollback. A pinned team stays where it is and is told when a newer version is published.

A team pins in the app. A Source admin can do it for the team with `ekanos teams agents pin <team> <key> <version>` and undo it with `ekanos teams agents unpin <team> <key>`.

When a new version needs more access than the team confirmed, such as a new product or a tool that now runs without approval, the person the agent runs as is asked to confirm again in the app. Until then the agent keeps only what needs no new confirmation.

### Testing a draft

`ekanos agents test` runs the template's latest version on one team without publishing it. The run is recorded on the team's agent and marked as a test, with the version it ran in `draftTemplateVersion`.

A test run is deliberately safer than a real one:

* **Every write waits for a person**, whatever the draft's policy says. Only `approve` overrides are kept, and handing work to another agent also waits.
* **On its own, a draft can do less, never more.** The tool executor still checks every call against the team's current agent, so a tool only the draft grants is refused.
* **To test what a draft adds, put one team on it.** `ekanos teams agents pin <team> <key> --draft`, or `enable <team> <key> --draft` for an agent the team hasn't turned on or that has never been published, puts that team's agent on the latest unpublished version. Only that team has it, only a run you start runs it (its triggers don't), every write still waits, and the next publish puts the team back to following.
* Approvals, the AI tool audit and the run's history work as in any run.

Read the result with `ekanos runs show <run-id> --team <slug> --json`. See [Test agents before you publish](https://sdk.ekanos.dev/guides/test-agents.md).

## Skills

A skill is a folder, `SKILL.md` plus optional `references/` and `assets/`, in the same format Claude Code uses. The agent sees each skill's name and description and loads one when the task calls for it, so write the description as "what it is — when to use it".

| Level | Command | Who can use it |
| - | - | - |
| **Source** (default) | `ekanos skills push <dir>` | Every team. A template may name it in `skills`. |
| **Team** | `ekanos skills push <dir> --team <slug>` | That team only. For content another team must not see. |

* **A push is live at once.** There is no draft and no publish step: every agent naming the skill reads the new version on its next run. An identical folder is `unchanged` and stores nothing.
* **Only a Source admin pushes.** A developer seat can `list`, `show` and `pull` Source skills.
* **`agents apply` pushes sibling skills.** Every `agents/<key>/skills/<slug>/` folder is pushed at Source level first and named in the agent's `skills`. `--no-skills` skips that. A developer seat applying an agent with skill folders is refused with `SOURCE_ADMIN_REQUIRED`; use `--no-skills` and ask a Source admin to push them.
* **A template names Source or platform skills only.** A team skill is attached by that team to its own agents, or to a provided agent whose `teamCustomization.skills` is on.

Limits today:

* **The agent sees the whole folder.** Loading a skill gives it the `SKILL.md` body plus a list of every other file in the folder (`references/`, `assets/` and anything else you pushed), and it opens one when the instructions point to it, the way Claude Code reads a skill's references locally. Text files are read in parts of about 12,000 characters, so a long reference is fine; a binary file (an image, a PDF) is listed but can't be read as text. Point to a file from `SKILL.md` by its path, for example `references/policy-2026.md`.
* A `scripts/` folder is refused. Executable skills need review in the app.
* Up to 100 files, 1 MB per file and 3 MB per skill.

See [`skills`](https://sdk.ekanos.dev/cli/commands#skills).

## Triggers and links

A **trigger** is what starts a run. Today triggers belong to each team: they are not part of the template, and a team adds them on its copy (Agents › the agent › Triggers) after turning it on.

| Kind | Starts a run when |
| - | - |
| Integration event | A connected integration reports an event the agent listens for, such as `zendesk.ticket_created`, `zendesk.comment_added`, `linear.mentioned` or `linear.issue_labeled`. The team fills in the event's filter (labels, tags, a group). `ekanos catalog` lists every event a product declares as `agentEvents`. |
| Schedule | A cron expression fires, in a time zone, with what to do each time. |
| Webhook | Any system calls the trigger's URL. |
| Slack | A message arrives in chosen channels or direct messages. |
| Manual | Someone clicks **Run now**, or a Source admin runs `ekanos runs start`. |

When an integration has a reply channel, the agent answers where the event happened, on the ticket or the issue.

A **link** lets one agent bring in another. Links are directional (`from → to`) and come in two kinds:

* **talk**: the caller asks a question and always waits for the answer. The asked agent runs with reads only, so talking never has side effects.
* **delegate**: the caller hands over a task. The other agent runs with its own tools, policy and approvals, so a delegation never widens what it may do. The mode is `await` (the caller waits for the result, the orchestrator pattern) or `handoff` (the caller carries on and the other agent owns the outcome).

A team sets its links in the app. A Source admin can set a team's triggers and links from the terminal with `ekanos teams triggers` and `ekanos teams links`. Linear and Slack triggers are added in the app only. See [Setting up a team's agents](https://sdk.ekanos.dev/cli/commands.md#team-agents).

## Approval policy

The template's `policy` says, for each tool the agent may call, whether a call runs on its own (`auto`) or waits for a person (`approve`):

```json theme={null}
"policy": {
  "reads": "auto",
  "writes": "approve",
  "overrides": { "zendesk_add_internal_note": "auto" }
}
```

* `reads` and `writes` set the default by the tool's effect. Reads default to `auto` and writes to `approve`.
* `overrides` sets single tools by name. An MCP server's tools are named `mcp__<server key>__<tool>`.
* **Knowledge.** `search_knowledge`, `read_knowledge_article` and `propose_knowledge_article` give an agent its team's Knowledge base and the Source's General collection (see [`ekanos knowledge`](https://sdk.ekanos.dev/cli/commands#knowledge)). Grant them by name; Ekanos picks the collection from the team the agent runs in, never from the model's arguments. A proposal is a write and waits for a person by default.
* **A tool the agent must never call is simply not granted.** Leave it out of `tools`; there is no deny list.
* **An undeclared effect counts as a write.** For an MCP server, `toolEffects` lists which tools only read; every other tool on that server is a write and follows `writes`. Teams can't change a template server's effects.

Calls that wait show up in the team's **Agents › Approvals** inbox, together with workflow approvals, and in `ekanos approvals list --team <slug>`. A decision approves, rejects, or, for a reply draft, edits the text and sends it. See [`approvals`](https://sdk.ekanos.dev/cli/commands#approvals).

A provided agent's policy is its template's. `ekanos teams agents policy <team> <key>` shows the effective policy, and refuses to change a provided agent's with `AGENT_POLICY_TEMPLATE_OWNED`. It changes the policy of a team's own agent, and a change that lets more run on its own (writes or reads set to `auto`, a tool that asked set to `auto`) drops the confirmation of the person the agent runs as, as it does for a provided agent: the agent uses only what needs no confirmation until that person confirms again. Asking for more approvals keeps it.

## What a team may change

`teamCustomization` in `agent.json` says what a team may add on top of a provided agent. Every switch is off unless you turn it on:

| Switch | Lets a team |
| - | - |
| `skills` | Attach its own skills |
| `mcpServers` | Attach its own MCP servers. Their tools wait for approval until the team marks one as read-only. |
| `integrations` | Grant more of its own connected products or tools. Needs `tools.mode: "custom"`. |
| `narrow` | Drop tools, or make more of them wait for approval. Never loosens. |

A team never changes or removes what the template set. What stays the team's own: whether the agent is on, its pinned version, its triggers and links, its connections, its run history, and whatever the switches above allow.

> [!NOTE]
>
> **New in `@ekanos/cli` 0.11.0.** Templates carry their own `triggers` and
> `links` beside `policy`, and a `teamOverrides: { policy, triggers, links }`
> switch per area. With an area's switch off, every team runs exactly the
> template's settings; with it on, a team's own differences apply on top.
> Turning a switch off keeps the team's differences but makes them inactive.
> Source admins edit these on the draft with `ekanos agents
>     policy|triggers|links|overrides <key>`, and `--publish` (or `agents
>     publish`) rolls them out.

## Reviewers and the review queue

Under an `approve` policy, a customer reply waits as a **draft**: the text exactly as it would be posted, and where it lands. A person can **Approve**, **Edit & send** (approve with their own text), or **Reject**. Every decision on a draft is recorded as a correction, and the agent's Runs tab shows how often drafts were sent as written, edited, or not sent, by version. Only a reply's text can be edited, never where it goes.

Three groups of people can decide a draft:

| Who | Decides | Where |
| - | - | - |
| A team's agent managers (`agents.manage`) | Everything that team's runs wait on | The team's Approvals inbox |
| A team's reviewers (`agents.review`) | That team's reply drafts only | The team's Approvals inbox |
| The Source's **named reviewers** | Reply drafts of provided agents, within their reach | The review queue at `/reviews` |

`agents.review` is a team permission. Owners and admins hold it by default, and a team can give it to another role; `ekanos teams roles list <team>` shows which roles hold it.

A Source admin names reviewers from the Source's own users, anyone who is a member of one of its teams, with a **reach**:

* **`source`**: drafts from every team's provided agents.
* **`team`**: one named team's drafts. The reviewer need not be a member of that team.

```bash theme={null}
ekanos reviewers add dana@acme.com --reach source
ekanos reviewers add raj@acme.com --reach team --team bank-a
```

Named reviewers are notified of each draft in their reach and decide from `/reviews`, where a Source-reach reviewer sees each draft labelled with its team. **The first decision settles a draft for everyone**: it leaves every other queue, and anyone who decides second is told it was already decided. A team's own agents stay with that team's managers and reviewers. Reviewers are also managed in the console under **People & teams › Reviewers**. See [`reviewers`](https://sdk.ekanos.dev/cli/commands#reviewers).

## Who does what

| Task | Who |
| - | - |
| Apply a template draft, read templates and skills | Either seat |
| Publish or roll back a template | Source admin |
| Test a draft on a team, run a team's agent, read its runs | Source admin (`agents test`, `runs`), or the team's agent managers in the app |
| Decide what a run waits on | The team's agent managers, its reviewers for reply drafts, named reviewers, or a Source admin with `ekanos approvals` (a team's own agent: only as one of that team's agent managers or reviewers) |
| Push skills | Source admin |
| Name reviewers | Source admin |
| Turn a provided agent on, pin it, set its triggers and links | The team in the app, or a Source admin with `ekanos teams agents\|triggers\|links` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.