$npx -y skills add multica-ai/multica --skill multica-creating-agentsUse when creating, inspecting, or debugging a Multica agent through the multica agent CLI or POST /api/agents — what each field is, its persisted shape, whether it is metadata-only or consumed by the daemon at claim time, which inputs are validated/rejected, how custom_env se
| 1 | # Creating Multica agents |
| 2 | |
| 3 | This is the contract for Multica's agent-creation path: what the create entry |
| 4 | points accept, what the server validates and rejects, how each field is |
| 5 | persisted, and which fields the daemon actually reads at claim time. It is |
| 6 | not a parameter manual — it states source-traced facts, and every claim is |
| 7 | backed by `file:line` in `references/creating-agents-source-map.md`. |
| 8 | |
| 9 | ## Quick start (read-only inspection) |
| 10 | |
| 11 | These commands read state and have no side effects: |
| 12 | |
| 13 | ```bash |
| 14 | multica agent get <agent-id> --output json # full persisted agent record |
| 15 | multica agent skills list <agent-id> --output json # current skill bindings |
| 16 | multica agent env get <agent-id> --output json # plaintext env (owner/admin only, agents denied) |
| 17 | ``` |
| 18 | |
| 19 | `agent get` returns the persisted agent including `runtime_id`, `model`, |
| 20 | `thinking_level`, `custom_args`, `has_custom_env`, `custom_env_key_count`, and |
| 21 | `skills`. It never returns plaintext `custom_env`. |
| 22 | |
| 23 | ## Core model |
| 24 | |
| 25 | An agent is a workspace-scoped row (table `agent`). Creation is a single |
| 26 | `POST /api/agents` (`multica agent create`). At task claim time the daemon |
| 27 | re-reads the agent row and assembles the runtime payload — so the persisted |
| 28 | fields, not the create-time output, are what the agent runs on. |
| 29 | |
| 30 | Two distinct text fields, often confused: |
| 31 | |
| 32 | - `description` is a catalog summary. It is stored and shown in listings; the |
| 33 | daemon does NOT inject it into the agent's runtime prompt. Treat it as |
| 34 | human-facing metadata only. Capped at 255 Unicode code points. |
| 35 | - `instructions` is the runtime behavior contract. The daemon reads it at |
| 36 | claim time and ships it to the provider as the agent's durable instructions. |
| 37 | Persona, responsibilities, boundaries, output and escalation rules go here, |
| 38 | not in `description`. |
| 39 | |
| 40 | ## CLI / API entry points |
| 41 | |
| 42 | Minimum create call (`--name` and `--runtime-id` are both required): |
| 43 | |
| 44 | ```bash |
| 45 | multica agent create --name <name> --runtime-id <runtime-id> \ |
| 46 | --description "<short catalog summary>" \ |
| 47 | --instructions "<runtime behavior contract>" \ |
| 48 | --output json |
| 49 | ``` |
| 50 | |
| 51 | `runAgentCreate` builds a JSON body and posts it to `/api/agents`. It only |
| 52 | adds a key when its flag was provided — `description`/`instructions` on a |
| 53 | non-empty value, the rest (`runtime-config`, `custom-args`, `model`, |
| 54 | `thinking-level`, `visibility`, …) on the flag being `Changed` — so omitted |
| 55 | flags fall through to server defaults rather than sending empty strings. |
| 56 | |
| 57 | The HTTP body (`CreateAgentRequest`) accepts: `name`, `description`, |
| 58 | `instructions`, `avatar_url`, `runtime_id`, `runtime_config`, `custom_env`, |
| 59 | `custom_args`, `model`, `thinking_level`, `visibility`, |
| 60 | `max_concurrent_tasks`, `mcp_config`. |
| 61 | |
| 62 | ## Field contracts |
| 63 | |
| 64 | | Field | Persisted as | Validated? | Consumed by | |
| 65 | |---|---|---|---| |
| 66 | | `name` | `agent.name` | required, 400 if empty | listings, runtime payload | |
| 67 | | `description` | `agent.description` | 400 if > 255 code points | catalog/listing only — NOT the runtime prompt | |
| 68 | | `instructions` | `agent.instructions` | none | daemon → provider at claim time | |
| 69 | | `avatar_url` | `agent.avatar_url` | none; an explicit non-empty value is preserved, while omitted/empty creates a random `emoji:<glyph>` avatar | catalog/listing UI only — NOT the runtime prompt | |
| 70 | | `runtime_id` | `agent.runtime_id` | required (400) + must resolve to a runtime in this workspace | selects runtime/provider | |
| 71 | | `model` | `agent.model` (nullable) | none beyond runtime support | daemon reads; empty = runtime default | |
| 72 | | `thinking_level` | `agent.thinking_level` (nullable) | provider-level enum; unknown literal → 400 | daemon; empty = runtime default | |
| 73 | | `custom_args` | `agent.custom_args` (JSON array) | JSON shape checked CLI-side; server stores as-is | daemon (extra CLI switches); defaults to `[]` | |
| 74 | | `runtime_config` | `agent.runtime_config` (JSON) | JSON shape checked CLI-side; server stores as-is | runtime-specific config; defaults to `{}` | |
| 75 | | `custom_env` | `agent.custom_env` (JSON object) | — | daemon (process env); see Env & secrets | |
| 76 | | `mcp_config` | `agent.mcp_config` (raw JSON) | CLI checks it is a JSON object or `null`; server stores as-is. At create, literal `null` is dropped (no-op); at update, `null` clears the column | daemon → provider (provider-specific MCP handling); redacted on read | |
| 77 | | `visibility` | `agent.visibility` | — | access control; defaults to `private`; gates who can read/route a private agent (e.g. a private squad leader) — NOT the runtime prompt | |
| 78 | | `max_concurrent_tasks` | `agent.max_co |