Skip to content

Multi-Agent

Moneypenny supports running multiple agents as independent workers under a shared gateway. Agents can delegate tasks to each other, share knowledge through CRDT sync, and maintain independent conversation histories.

Because Moneypenny exposes its entire surface area via MCP (Model Context Protocol), every operation below can be performed either through the CLI or by asking any MCP-compatible client (Claude Desktop, Cursor, etc.) in natural language.

Creating Multiple Agents

Start by initializing and creating agents:

Terminal window
mp init
mp agent create research
mp agent create ops-bot

Configure each agent in moneypenny.toml:

[[agents]]
name = "main"
trust_level = "standard"
persona = "You are a helpful engineering assistant."
[[agents]]
name = "research"
trust_level = "standard"
persona = "You are a research analyst. You focus on deep investigation."
[[agents]]
name = "ops-bot"
trust_level = "elevated"
persona = "You are an SRE bot. You monitor systems and triage incidents."

Running the Gateway

When you start the gateway, each agent runs as a separate worker process:

Terminal window
mp start
Gateway
├── Worker: main (mp-data/main.db)
├── Worker: research (mp-data/research.db)
└── Worker: ops-bot (mp-data/ops-bot.db)

The gateway routes messages to the correct worker. Channel adapters (HTTP, Slack, Discord, Telegram) specify which agent receives messages by default.

Delegation

Agents can delegate tasks to other agents. Delegation is a governed channel — policy controls who can delegate, to whom, and with what depth limits.

Delegation depth is capped at 3 levels by default to prevent infinite recursion. Each level runs its own full agent loop (context assembly, policy, LLM call, tool execution, extraction).

Governing Delegation

Terminal window
# Allow main to delegate to research
mp policy add \
--name "main-can-delegate-research" \
--effect allow \
--actor "main" \
--action "delegate" \
--resource "research"
# Block ops-bot from delegating to anyone
mp policy add \
--name "ops-no-delegate" \
--effect deny \
--actor "ops-bot" \
--action "delegate" \
--resource "*"

Knowledge Sharing via Sync

By default, each agent’s facts are private. To share knowledge across agents:

1. Promote facts to shared scope:

Terminal window
mp facts promote <fact-id> --scope shared

2. Configure sync peers:

[sync]
tables = ["facts", "fact_links", "skills", "policies"]
peers = ["research", "ops-bot"]
interval_secs = 300

3. Trigger sync:

Terminal window
mp sync now

After sync, shared facts are visible to all agents. Protected facts require elevated trust. Private facts remain invisible.

What Syncs and What Doesn’t

DataSyncsReason
FactsYesShared knowledge is the primary use case
Fact linksYesGraph relationships travel with facts
SkillsYesProcedures propagate fleet-wide
PoliciesYesGovernance rules are fleet-wide
JobsYesScheduled tasks propagate
ConversationsNoChat history is agent-specific
ScratchNoSession working memory is ephemeral

Targeting Agents from Channels

HTTP API

Specify the target agent in the request body:

Terminal window
curl -X POST http://localhost:4821/v1/chat \
-H "Content-Type: application/json" \
-d '{"agent":"research","message":"What are the latest findings?"}'

CLI

Terminal window
mp send research "Investigate the Q4 performance regression"
mp chat research

Slack / Discord / Telegram

Each channel adapter has a default agent. Configure per-channel routing in moneypenny.toml:

[channels.slack]
bot_token = "xoxb-..."
agent = "ops-bot"
[channels.discord]
application_id = "..."
public_key = "..."
bot_token = "..."
agent = "main"

Inspecting Agents

Terminal window
mp agent list # list all registered agents
mp agent status # summary for all agents
mp agent status research # detailed status for one agent

Status includes: fact count, session count, document count, skill count, and sync status.