How do I manage agents and identity?
http://localhost:3001 Agents in Daemion are Claude operating in a named role. Their personality, working style, and context live in a soul.md file — separate from their system prompt — so you can evolve an agent’s identity without touching its configuration. The modes API exposes the built-in Plan/Act mode definitions so clients know what modes are available and how to label them.
How do I read the base soul?
The base soul (~/.daemion/soul.md) applies to all agents as a shared foundation. Agents that have their own soul.md extend or override it.
Read the base soul.md content. Returns an empty string if no base soul has been written yet.
curl http://localhost:3001/soul
-H “Authorization: Bearer $DAEMION_TOKEN”
Response:
{ “content”: “You care deeply about doing good work. You are curious, direct, and honest…” }
How do I write the base soul?
Write the base soul.md content. Overwrites the existing file. Creates the file if it does not exist. Max 100 KB.
| Parameter | Type | Description |
|---|---|---|
content REQUIRED | string | The full soul.md content to write. Must be a string. Max 100 KB. |
curl -X PUT http://localhost:3001/soul
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{“content”: “You care deeply about doing good work. You are curious, direct, and honest.”}’
Response:
{ “status”: “ok” }
How do I read an agent’s soul?
Each agent can have its own soul.md at ~/.daemion/agents/<name>/soul.md. This is read in addition to the base soul when that agent is active.
Read the soul.md for a named agent. Returns an empty string if the agent has no soul file yet. The name must not contain path traversal characters.
Read the soul for the “daemion” agent
curl “http://localhost:3001/agents/daemion/soul”
-H “Authorization: Bearer $DAEMION_TOKEN”
Read the soul for the “sonnet” agent
curl “http://localhost:3001/agents/sonnet/soul”
-H “Authorization: Bearer $DAEMION_TOKEN”
Response:
{ “content”: “You are the primary Daemion agent. You help Jordan think through problems…” }
How do I write an agent’s soul?
Write the soul.md for a named agent. Overwrites the existing file. Creates the file and any missing parent directories. Max 100 KB.
| Parameter | Type | Description |
|---|---|---|
content REQUIRED | string | The full soul.md content to write. Must be a string. Max 100 KB. |
curl -X PUT “http://localhost:3001/agents/daemion/soul”
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{
“content”: “You are the primary Daemion agent. You help Jordan think through problems, ship code, and stay curious. You prefer directness over hedging.”
}’
Response:
{ “status”: “ok” }
Soul changes take effect on the next conversation turn — the gateway does not need to restart. The soul file is read fresh each time an agent is invoked.
How do I list available modes?
Modes define how an agent operates: Plan mode constrains the agent to read-only exploration, Act mode gives full tool access. The /modes endpoint returns the built-in mode definitions so your client can render the correct labels, colors, and descriptions.
List all built-in agent modes. Returns an array of mode objects with name, label, color, description, allowedTools, and requiresApproval.
curl http://localhost:3001/modes
-H “Authorization: Bearer $DAEMION_TOKEN”
Response:
[ { “name”: “plan”, “label”: “Plan”, “color”: “#f59e0b”, “systemPrompt”: “You are in Plan mode. You may freely read files, search, explore, and reason. Do NOT write files, execute commands, or make changes. Present a structured plan with: steps, files affected, and expected outcome. The user will review and approve before execution.”, “allowedTools”: [“Read”, “Glob”, “Grep”, “WebFetch”, “WebSearch”], “requiresApproval”: true, “description”: “Agent explores and presents a plan. No changes until approved.” }, { “name”: “act”, “label”: “Act”, “color”: “#3b82f6”, “systemPrompt”: "", “allowedTools”: null, “description”: “Agent executes with full tool access.” } ]
The default mode is plan. If no mode is specified when starting a conversation, the agent starts in Plan mode and requires approval before executing changes.
Frequently asked questions
system.md) defines what the agent does — its role, capabilities, and rules. The soul (in soul.md) defines who the agent is — its personality, values, and working style. Keeping them separate lets you iterate on tone and character without touching functional configuration.~/.daemion/soul.md. Each agent's soul lives at ~/.daemion/agents/<name>/soul.md. The gateway creates parent directories automatically on the first write — you do not need to mkdir first..., /, or \ with a 400 invalid agent name error. Names are validated to resolve strictly inside ~/.daemion/agents/.plan and act) are defined in src/gateway/modes.ts and are not stored in the database. Custom modes are not yet supported through the API. The /modes endpoint always returns the built-in set.What can go wrong
400 {"error": "invalid agent name"} — The :name segment in /agents/:name/soul contains .., /, \, or resolves outside ~/.daemion/agents/. Use plain alphanumeric names with hyphens only.
400 {"error": "invalid JSON"} — The request body could not be parsed as JSON. Check that Content-Type: application/json is set and the body is valid JSON.
400 {"error": "content must be a string"} — The content field was missing or was not a string. Wrap the markdown text in a JSON string: "content": "...".
413 {"error": "soul content too large (max 100KB)"} — The content string exceeds 102,400 bytes. Split the content or trim it before writing.
GET /agents/:name/soul returns {"content": ""} — This is not an error. It means the agent has no soul file yet. The first PUT will create it.
What’s next?
- Extensions API — manage agent extensions and all other extension types
- Conversations API — send turns to agents and read thread history
- WebSocket events — subscribe to real-time agent events