DorkOS
Guides

Agent Coordination

Let your agents message each other and hand off work, instead of copying context between chat windows yourself

Coordinating Multiple Agents

If you run one agent per project, DorkOS lets those agents talk to each other directly. Your backend agent finishes an endpoint and tells your frontend agent to build the UI for it, without you copying the details over by hand.

Three pieces make this work: Mesh finds your agents and gives each one an address, Relay carries messages between them, and Tasks can trigger a message on a schedule instead of waiting for you to ask.

This is a shipped capability we are still hardening end to end. Multi-agent messaging works in the setups we've tested, but treat it as early: watch what an agent actually does with a handoff before you trust it with something you can't easily undo.

Quick win: send one message between two agents

  1. Turn on Relay and start DorkOS pointed at the folder that holds your projects:

    export DORKOS_RELAY_ENABLED=true
    dorkos --dir /path/to/projects
  2. Open the Mesh panel and run a discovery scan. Mesh walks your project folders looking for agent markers (things like a .claude/ folder or a .dork/agent.json file) and lists each project it finds as a candidate. Approve the ones you want; deny the rest. If the scan comes back empty, check that --dir points at the parent folder that actually contains your projects, not a project itself.

  3. Pick two approved agents in the same project family (they land in the same namespace, a label Mesh derives from where the project sits on disk) and ask one to message the other:

    Use relay_send to tell the frontend agent about the new /users endpoint.

  4. Watch the message arrive: DorkOS starts (or resumes) a session for the receiving agent and hands it your message as a prompt, the same way a person would type it in.

That is the whole loop: discover, approve, send, watch it land. Everything past this point is reference material for when you want to control access rules, chain agents into pipelines, or see exactly what's on the wire.

What this looks like in practice

A monorepo with one agent per app

Say you have apps/api, apps/web, and packages/shared. Register each folder as an agent through Mesh discovery. Because they share a monorepo root, they land in the same namespace automatically, so they can message each other with no extra setup.

Ask the API agent to add an endpoint, and in a working setup it implements the route, then messages the web agent to build the matching frontend hook. If a shared type needs to change, either agent can flag it to the other instead of reaching into a codebase it doesn't own.

Agents across separate repositories

When your backend and frontend live in different repositories, each gets its own namespace, so cross-namespace messaging needs an explicit access rule (see Access rules below).

In this setup, the backend agent can publish an updated API spec to Relay, the frontend agent picks it up and regenerates its client code, and once both report green, either one can notify a deployment agent to ship. That's the intended workflow: verify it against your own agents before you let it run unattended.

Approving decisions from your phone

If you connect a Telegram adapter, agents can send you a message outside the DorkOS UI and wait for your reply before continuing, useful for anything you'd rather approve by hand.

Picture a nightly task that checks for risky database migrations. It finds one that would drop a column with real data in it, so instead of running it, it messages your Telegram chat and waits. You reply "approved" from your phone, and the agent picks up where it left off. Nice way to keep the final call human without opening a laptop.

Reference

The rest of this page is for the curious: exact API calls, priority numbers, and message formats. Skim it once, then come back when you need a specific detail.

Registering agents

Once a discovery scan approves a project, each agent gets:

  • A unique ID in the Mesh registry
  • A Relay address (a subject, the string a message is sent to) shaped like relay.agent.{namespace}.{agentId}
  • A namespace derived from where it sits on disk

For example, scanning /home/user/projects might produce:

/home/user/projects/backend/api/      -> namespace: backend, agent: api
/home/user/projects/backend/worker/   -> namespace: backend, agent: worker
/home/user/projects/frontend/web/     -> namespace: frontend, agent: web

Access rules

Mesh checks every cross-agent message against a priority-ordered list of rules:

PriorityRuleEffect
200System-agent allowThe system agent (DorkBot) can always reach any namespace
100Same-namespace allowAgents in the same namespace talk freely by default
50Cross-namespace allowExplicit rules you add
10Cross-namespace denyThe catch-all: blocks anything not explicitly allowed

Agents in the same namespace (say, backend) need no configuration. Cross-namespace traffic (backend to frontend) needs an explicit allow rule:

# Allow backend agents to message frontend agents
curl -X PUT http://localhost:4242/api/mesh/topology/access \
  -H 'Content-Type: application/json' \
  -d '{"sourceNamespace": "backend", "targetNamespace": "frontend", "action": "allow"}'

Rules are one-directional. For two-way communication, add a second rule with the namespaces swapped.

Direct messaging

Every Claude session an agent runs has an MCP tool server injected into it (MCP is the standard that lets AI tools call functions like this one). That's what exposes relay_send:

Agent "api" notifies "web" about an API change:

> Use relay_send to tell the frontend agent about the new /users endpoint.
> Subject: relay.agent.frontend.web
> Content: "I added a GET /users endpoint that returns { id, name, email }.
>           Please update the UserList component to fetch from this endpoint."

DorkOS starts (or resumes) a session in the web agent's working directory and passes the content as a prompt, so the web agent replies with the same working-directory context it always has.

Request-reply

To get a response back, set replyTo to your own subject:

Agent "api" asks "web" a question:

> Use relay_send with replyTo set to relay.agent.backend.api
> Subject: relay.agent.frontend.web
> Content: "What TypeScript interface do you use for the User type?
>           I want to make sure the API response matches your expectations."

The web agent's reply routes back to relay.agent.backend.api on its own; you don't have to wire that up.

Every message carries a budget: a default limit of 5 hops and a 1-hour TTL (time to live, how long a message stays valid before it expires). That budget keeps a chain of agents from looping forever or running up API costs.

Scheduling messages with Tasks

Tasks can trigger a message instead of waiting for a person to ask. When Relay is on, a scheduled task dispatches through Relay, so it follows the same access rules and budget limits as a message you send by hand.

A task is a SKILL.md file (a small text file with a YAML header) with a name, a cron schedule, a timezone, and a prompt written below the header:

---
name: nightly-review
display-name: Nightly Code Review
description: Review the day's changes and flag anything risky
cron: '0 2 * * *'
timezone: America/New_York
enabled: true
---
Review all files changed today. Check for missing error handling,
untested code paths, and inconsistent naming. Create a summary report.

Creating a task from the Tasks panel (or via POST /api/tasks with name, description, prompt, cron, timezone, and a target agent) writes exactly this file to disk; DorkOS never asks you to hand-edit JSON. Set the cron for the middle of the night and you wake up to a report, not a fire.

Chaining tasks and messages

Combine a scheduled trigger with agent-to-agent messages for a multi-step pipeline. A deployment pipeline might look like:

  1. Tasks triggers a test run on the backend agent at 6 AM.
  2. Backend agent runs the suite. If it's green, it uses relay_send to notify the infrastructure agent.
  3. Infrastructure agent builds the image and deploys to staging.
  4. Infrastructure agent notifies every other agent that staging is updated.

Each step runs in the right working directory because Mesh already told DorkOS where each agent lives.

Next steps