Skip to main content
Many teams already define their agents in files: an AGENT.md with the instructions, an agent.yaml with the model and tools, policy files that say what needs a person, and a folder of skills. A managed agent in Ekanos is the same idea held as data, so most of it moves across directly. This guide maps each piece, then lists what doesn’t map yet. You need a seat on the Source: developer to store drafts, source_admin to push skills, test and publish. Read Sources, team accounts and integrations first if those words are new to you.

The target layout

agent.json and AGENT.md are what ekanos agents pull writes and ekanos agents apply reads. Every field and its limits are in the commands reference. Unknown fields are refused, so leave anything that doesn’t map out of the file rather than carrying it along.

How the pieces map

Policy

Most frameworks express approval as rules per tool. In Ekanos every granted tool resolves to one of two answers: auto runs on its own, approve waits for a person in the app.
  • Start from reads: auto, writes: approve, then add an auto override for each write you’re happy to let run, such as an internal note.
  • A tool’s effect comes from its integration. An MCP tool you haven’t marked as a read in toolEffects counts as a write, so it waits under writes: approve.
  • MCP tools are named mcp__<server key>__<tool> in overrides.

MCP servers

When a team turns the agent on, a team-owned server is added to that team. With auth: "none" it works straight away; otherwise the team signs in. Teams can’t change the effects you declared.

Skills

A skill is a folder in the same format Claude Code uses: SKILL.md with name and description frontmatter, plus optional references/ and assets/. Copy each of your skill folders to agents/<key>/skills/<slug>/.
ekanos agents apply agents/<key> pushes each folder as a Source skill first, then names it in the agent’s skills. Pushing needs a Source admin; with a developer seat, pass --no-skills and ask a Source admin to run ekanos skills push <dir>. A skill only one team should see is pushed with --team <slug>. The whole folder reaches the agent: it loads SKILL.md and opens the other files (references/, assets/) when the instructions point to them. Before you copy skills across, read the gaps: executable skills don’t carry over. Triggers and links can live in the template, so every team gets them: agent.json’s triggers and links, or ekanos agents triggers <key> add … and ekanos agents links <key> add …, published like any change. Where the template’s teamOverrides lets teams change them, a team adds its own on the agent’s Triggers tab, or a Source admin does from the terminal:
A talk link lets one agent ask another a question and wait for the answer; the asked agent can only read. A delegate link hands over a task: with --mode await the caller waits for the result, which is the orchestrator pattern, and with --mode handoff it carries on and the other agent owns the outcome. A delegated agent runs with its own tools and policy, never the caller’s. Map each old trigger onto the event it actually listened for. ekanos catalog <product> --source acme --json lists every event a product declares under agentEvents, with its filter keys: Linear has linear.mentioned, linear.assigned, linear.issue_labeled and linear.issue_created; Zendesk has zendesk.ticket_created and zendesk.comment_added. A label-driven agent stays label-driven (linear.issue_labeled); it does not have to become an @mention. Slack triggers, and the Linear (Agents app) trigger (Ekanos’s own Linear app, which answers @mentions and labelled issues), belong to each team rather than the template: install with ekanos teams connect <team> slack|linear-app, then ekanos teams triggers add <team> <key> slack --channel '#support' --yes or … linear [--label <name>], or use the agent’s Triggers tab in the app. The Linear integration’s events above are added from the terminal like any other event.
Coming: triggers, links and teamOverrides in agent.json, so the template sets them for every team, and ekanos agents policy|triggers|links|overrides <key> to edit them on the draft. Until that ships, set them per team as above.

Steps

  1. Set up a folder.
    agents init adds the skills and docs server Claude Code uses to build agents. If you’d rather have Claude do the mapping, open claude in the folder, point it at your old repository and ask it to migrate one agent. It follows the same table.
  2. Check what the Source has. ekanos catalog --source acme --json lists each product’s tools by the names tools and policy use, and the events triggers can start from. A tool your old agent called that isn’t in the catalog is a gap.
  3. Write the files. One agent per folder, starting with the simplest one. Move the instructions to AGENT.md, and build agent.json from the table above.
  4. Store a draft.
    apply checks every product, tool, skill and model against the Source and names each field it refuses, such as tools.tools.0. Nothing reaches a team yet.
  5. Publish the first version, then test on one team. A team can only turn on an agent that has been published once, and publishing alone changes nothing for a team until it turns the agent on. Turn it on for a test team, then run it:
    For every change after that, agents test runs your unpublished draft on the test team. See Test an agent before you publish.
  6. Roll it out. Publish each tested version. Every team that follows the latest version moves to it; ekanos agents rollback <key> --to <n> --yes takes them back.

Gaps

What doesn’t carry over today, and what to do instead:
  • Tools written as code. An agent can only call tools that a Source product or an MCP server provides. A function your framework ran in-process has to become an integration built with the SDK, or live behind a remote MCP server.
  • Local MCP servers. Only remote servers over HTTPS are supported. A server you ran over stdio needs to be hosted.
  • Conditional approval rules. Policy is auto or approve per tool. A rule that looks at arguments, such as “approve refunds over $100”, doesn’t map; choose approve for the tool, or split the action into two tools in an integration.
  • Binary skill files. The agent reads every text file in a skill’s folder, but an image or a PDF under assets/ is only listed, not read. Put what it must know in a text file.
  • Executable skills. A skill with a scripts/ folder is refused. Skills are limited to 100 files, 1 MB per file and 3 MB per skill.
  • Skill versions. A skill push is live at once, for every agent that names the skill, on its next run. It doesn’t go through apply, test and publish, so review a skill change as carefully as a publish.
  • Slack and the Ekanos Agents app for Linear in the template. Their triggers are per team (ekanos teams triggers add … slack|linear, or the app), because each team installs its own workspace and picks its channels. Every integration event, including all of Linear’s and Zendesk’s, can be in the template or per team.
  • One shared connection for every team. owner: "source" in connections works for integrations that declare a Source connection, such as Zendesk: the Source admin connects once (ekanos apps connect) and maps events to teams (ekanos routes). It is refused for other integrations and for mcpServers.
  • Secrets in config. No secret goes in agent.json, a flag or a file. Teams enter theirs in the app, and a Source admin enters an app secret at an interactive terminal.
See also: Build agents with Claude, Commands reference.