multica-creating-agents
multica-ai/multica
Use 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 secrets are gated, and how skill binding behaves. Not for assigning issues to existing agents or for runtime task prompts.
...Expand allCreating Multica agents
This is the contract for Multica's agent-creation path: what the create entry
points accept, what the server validates and rejects, how each field is
persisted, and which fields the daemon actually reads at claim time. It is
not a parameter manual — it states source-traced facts, and every claim is
backed by file:line in references/creating-agents-source-map.md.
Quick start (read-only inspection)
These commands read state and have no side effects:
multica agent get --output json # full persisted agent record
multica agent skills list --output json # current skill bindings
multica agent env get --output json # plaintext env (owner/admin only, agents denied)
agent get returns the persisted agent including runtime_id, model,
thinking_level, service_tier, custom_args, has_custom_env,
custom_env_key_count, and skills. It never returns plaintext custom_env.
Core model
An agent is a workspace-scoped row (table agent). Creation is a single
POST /api/agents (multica agent create). At task claim time the daemon
re-reads the agent row and assembles the runtime payload — so the persisted
fields, not the create-time output, are what the agent runs on.
Two distinct text fields, often confused:
descriptionis a catalog summary. It is stored and shown in listings; the daemon does NOT inject it into the agent's runtime prompt. Treat it as human-facing metadata only. Capped at 255 Unicode code points.instructionsis the runtime behavior contract. The daemon reads it at claim time and ships it to the provider as the agent's durable instructions. Persona, responsibilities, boundaries, output and escalation rules go here, not indescription.
CLI / API entry points
Minimum create call (--name and --runtime-id are both required):
multica agent create --name --runtime-id \
--description "" \
--instructions "" \
--output json
runAgentCreate builds a JSON body and posts it to /api/agents. It only
adds a key when its flag was provided — description/instructions on a
non-empty value, the rest (runtime-config, custom-args, model,
thinking-level, service-tier, visibility, …) on the flag being Changed — so omitted
flags fall through to server defaults rather than sending empty strings.
The HTTP body (CreateAgentRequest) accepts: name, description,
instructions, avatar_url, runtime_id, runtime_config, custom_env,
custom_args, model, thinking_level, service_tier, visibility,
max_concurrent_tasks, mcp_config.
Field contracts
Defaults when omitted: runtime_config → {}, custom_env → {},
custom_args → [], avatar_url → a random emoji:, visibility →
private, max_concurrent_tasks → 6
(all materialized server-side before the insert). custom_args/runtime_config
are typed []string/any and marshaled as-is — the JSON-shape rejection
happens in the CLI, not the create handler.
thinking_level is validated only at the provider level: fixed-catalog
providers reject an unrecognized literal, while dynamic-catalog providers such
as Codex/OpenCode accept a syntactically safe token. A value unsupported for
the chosen model is NOT rejected here — the daemon checks its local model
catalog at execution time, logs a warning, and omits the incompatible override.
Set it from the CLI with --thinking-level on agent create and agent update, mirroring --model: the flag is a thin pass-through to the top-level
thinking_level field, and on update an empty string (--thinking-level "")
clears it back to the runtime default. The CLI deliberately does not enumerate
the valid levels — they are runtime/model-specific (Claude currently uses
low|medium|high|xhigh|max; Codex values are discovered from the runtime's
model catalog). It forwards the token, the server applies the provider's
fixed-enum or safe-token gate, and the daemon performs the exact model/level
check. A runtime whose provider has no thinking concept rejects any non-empty
value with a 400.
service_tier is the matching first-class Codex speed control. Set it with
--service-tier on create/update; use --service-tier "" on
update to clear it. The runtime model catalog owns both availability and
display copy (currently priority, shown as Fast). The server accepts safe
future Codex catalog IDs, while the daemon verifies the exact model/tier pair
before execution and omits a stale incompatible override. Agents without an
explicit model fail closed because the effective config.toml model is unknown.
model vs custom_args
model is a first-class persisted column the daemon reads directly.
custom_args are raw provider CLI args. The CLI help notes that some providers
(codex app-server, openclaw) reject --model inside custom_args — but that is
documented CLI guidance, not a server-enforced invariant; nothing in the create
handler inspects custom_args for a model flag.
Env & secrets
custom_env is secret material. The CLI offers three input channels; two keep
secrets out of shell history and the process list:
multica agent create --name --runtime-id --custom-env-stdin --output json
multica agent create --name --runtime-id --custom-env-file <0600-json> --output json
--custom-env-stdin reads the JSON object from stdin; --custom-env-file
reads it from a file (suggested mode 0600). The third channel,
--custom-env , puts the value on the command line where shell history
and ps can see it — avoid it for real secrets.
Read-side facts (these are the wrong assumptions to avoid):
- Agent resources never expose plaintext
custom_env.agent list/get/create/updateand WS events return onlyhas_custom_env(bool) andcustom_env_key_count(int). - Reading plaintext values requires the dedicated
GET /api/agents/{id}/envendpoint (multica agent env get). It is gated to workspace owner/admin members, and agent actors are denied regardless of the backing member's role — a running agent cannot read another agent's secrets. - Writing values after creation does NOT go through
agent update. The generic update handler rejects anycustom_envfield with a 400 ("use PUT /api/agents/{id}/env"). Plaintext env writes are handled byPUT /api/agents/{id}/env(multica agent env set), which is owner/admin-only and writes an audit row.
mcp_config
mcp_config is the agent's MCP server configuration (a JSON object such as
{"mcpServers": {…}}). It is also secret material — MCP entries routinely embed
API tokens — and offers the same three input channels as custom_env, on BOTH
agent create and agent update:
multica agent create --name --runtime-id --mcp-config-file <0600-json> --output json
multica agent update --mcp-config-stdin --output json
multica agent update --mcp-config 'null' # clears the config
--mcp-config-stdin / --mcp-config-file keep the value out of shell history
and ps; the inline --mcp-config does not. The CLI requires a JSON
object or the literal null; a top-level array or primitive is rejected
client-side, and empty stdin/file input errors rather than silently clearing.
Two ways mcp_config differs from custom_env:
- It IS settable through
agent update. Unlikecustom_env,mcp_confighas no dedicated audited endpoint — the genericPUT /api/agents/{id}accepts it. Tri-state per the raw request body: field omitted → no change;null→ clear; object → replace. - It is serialized on read, but redacted.
agent get/listreturnmcp_configonly to callers allowed to view agent secrets; otherwise the field isnullandmcp_config_redactedistrue. Agent actors never see it, and a workspace may force redaction for everyone.
Provider support is not uniform: Qwen Code accepts a managed mcp_config through a daemon-owned 0600 temporary JSON file passed with --mcp-config; it is removed when the run exits. Leave the field unset (null) to inherit Qwen Code native settings.
Skill binding
Creating an agent does NOT bind any workspace skill — binding is a separate call after the agent exists. Two distinct verbs:
addis additive — it merges the given ids with existing bindings (POST /api/agents/{id}/skills/add).setis replace-all — it overwrites the entire binding list with exactly the given ids (PUT /api/agents/{id}/skills);--skill-ids ''clears all.
multica agent skills add --skill-ids --output json
multica agent skills list --output json
At claim time the daemon assembles the agent's skills as workspace-bound skills
FIRST, then appends the platform built-in skills. LoadAgentSkills loads each
bound skill's content plus its supporting files; built-in skills are embedded
at compile time and loaded from SKILL.md + sibling files. Both reach the
provider as skill content — which is why capability belongs in a bound skill,
not pasted into instructions.
Side effects needing approval
Read-only (safe): agent get, agent skills list, agent env get.
State-changing (require an explicit instruction — do not run speculatively):
multica agent create— inserts a new agent row.multica agent skills add/set— mutate bindings (setis destructive: it drops bindings not in the new list).multica agent env set— overwrites the fullcustom_envmap and writes an audit row.
Common wrong assumptions
- "
descriptionis the prompt." It is not — onlyinstructionsreaches the runtime. A rich description with empty instructions yields a named shell with no operating contract. - "Create binds the agent's skills." It does not; bind explicitly afterward.
- "
agent updatecan rotate env." It cannot — it 400s oncustom_env; use the env endpoint. - "
mcp_configbehaves likecustom_envon update." It does not —mcp_configIS settable viaagent update(--mcp-config), with--mcp-config nullto clear; onlycustom_envis gated behind the dedicated env endpoint. - "
agent getshows env values." It shows onlyhas_custom_envandcustom_env_key_count. - "An invalid
thinking_level/modelcombo is caught at create." Only an unknown provider-level literal is — model-specific gaps fail at run time. - "
setandaddare interchangeable for skills."setreplaces all bindings; using it when you meantaddsilently removes capabilities.
References
references/creating-agents-source-map.md maps every contract above to its
file:line on the current tree, the runtime effect, and a safe read-only
verification command.
Creating Multica agents
This is the contract for Multica's agent-creation path: what the create entry
points accept, what the server validates and rejects, how each field is
persisted, and which fields the daemon actually reads at claim time. It is
not a parameter manual — it states source-traced facts, and every claim is
backed by file:line in references/creating-agents-source-map.md.
Quick start (read-only inspection)
These commands read state and have no side effects:
multica agent get <agent-id> --output json # full persisted agent record
multica agent skills list <agent-id> --output json # current skill bindings
multica agent env get <agent-id> --output json # plaintext env (owner/admin only, agents denied)
agent get returns the persisted agent including runtime_id, model,
thinking_level, service_tier, custom_args, has_custom_env,
custom_env_key_count, and skills. It never returns plaintext custom_env.
Core model
An agent is a workspace-scoped row (table agent). Creation is a single
POST /api/agents (multica agent create). At task claim time the daemon
re-reads the agent row and assembles the runtime payload — so the persisted
fields, not the create-time output, are what the agent runs on.
Two distinct text fields, often confused:
descriptionis a catalog summary. It is stored and shown in listings; the daemon does NOT inject it into the agent's runtime prompt. Treat it as human-facing metadata only. Capped at 255 Unicode code points.instructionsis the runtime behavior contract. The daemon reads it at claim time and ships it to the provider as the agent's durable instructions. Persona, responsibilities, boundaries, output and escalation rules go here, not indescription.
CLI / API entry points
Minimum create call (--name and --runtime-id are both required):
multica agent create --name <name> --runtime-id <runtime-id> \
--description "<short catalog summary>" \
--instructions "<runtime behavior contract>" \
--output json
runAgentCreate builds a JSON body and posts it to /api/agents. It only
adds a key when its flag was provided — description/instructions on a
non-empty value, the rest (runtime-config, custom-args, model,
thinking-level, service-tier, visibility, …) on the flag being Changed — so omitted
flags fall through to server defaults rather than sending empty strings.
The HTTP body (CreateAgentRequest) accepts: name, description,
instructions, avatar_url, runtime_id, runtime_config, custom_env,
custom_args, model, thinking_level, service_tier, visibility,
max_concurrent_tasks, mcp_config.
Field contracts
Defaults when omitted: runtime_config → {}, custom_env → {},
custom_args → [], avatar_url → a random emoji:<glyph>, visibility →
private, max_concurrent_tasks → 6
(all materialized server-side before the insert). custom_args/runtime_config
are typed []string/any and marshaled as-is — the JSON-shape rejection
happens in the CLI, not the create handler.
thinking_level is validated only at the provider level: fixed-catalog
providers reject an unrecognized literal, while dynamic-catalog providers such
as Codex/OpenCode accept a syntactically safe token. A value unsupported for
the chosen model is NOT rejected here — the daemon checks its local model
catalog at execution time, logs a warning, and omits the incompatible override.
Set it from the CLI with --thinking-level on agent create and agent update, mirroring --model: the flag is a thin pass-through to the top-level
thinking_level field, and on update an empty string (--thinking-level "")
clears it back to the runtime default. The CLI deliberately does not enumerate
the valid levels — they are runtime/model-specific (Claude currently uses
low|medium|high|xhigh|max; Codex values are discovered from the runtime's
model catalog). It forwards the token, the server applies the provider's
fixed-enum or safe-token gate, and the daemon performs the exact model/level
check. A runtime whose provider has no thinking concept rejects any non-empty
value with a 400.
service_tier is the matching first-class Codex speed control. Set it with
--service-tier <catalog-id> on create/update; use --service-tier "" on
update to clear it. The runtime model catalog owns both availability and
display copy (currently priority, shown as Fast). The server accepts safe
future Codex catalog IDs, while the daemon verifies the exact model/tier pair
before execution and omits a stale incompatible override. Agents without an
explicit model fail closed because the effective config.toml model is unknown.
model vs custom_args
model is a first-class persisted column the daemon reads directly.
custom_args are raw provider CLI args. The CLI help notes that some providers
(codex app-server, openclaw) reject --model inside custom_args — but that is
documented CLI guidance, not a server-enforced invariant; nothing in the create
handler inspects custom_args for a model flag.
Env & secrets
custom_env is secret material. The CLI offers three input channels; two keep
secrets out of shell history and the process list:
multica agent create --name <name> --runtime-id <runtime-id> --custom-env-stdin --output json
multica agent create --name <name> --runtime-id <runtime-id> --custom-env-file <0600-json> --output json
--custom-env-stdin reads the JSON object from stdin; --custom-env-file
reads it from a file (suggested mode 0600). The third channel,
--custom-env <json>, puts the value on the command line where shell history
and ps can see it — avoid it for real secrets.
Read-side facts (these are the wrong assumptions to avoid):
- Agent resources never expose plaintext
custom_env.agent list/get/create/updateand WS events return onlyhas_custom_env(bool) andcustom_env_key_count(int). - Reading plaintext values requires the dedicated
GET /api/agents/{id}/envendpoint (multica agent env get). It is gated to workspace owner/admin members, and agent actors are denied regardless of the backing member's role — a running agent cannot read another agent's secrets. - Writing values after creation does NOT go through
agent update. The generic update handler rejects anycustom_envfield with a 400 ("use PUT /api/agents/{id}/env"). Plaintext env writes are handled byPUT /api/agents/{id}/env(multica agent env set), which is owner/admin-only and writes an audit row.
mcp_config
mcp_config is the agent's MCP server configuration (a JSON object such as
{"mcpServers": {…}}). It is also secret material — MCP entries routinely embed
API tokens — and offers the same three input channels as custom_env, on BOTH
agent create and agent update:
multica agent create --name <name> --runtime-id <runtime-id> --mcp-config-file <0600-json> --output json
multica agent update <agent-id> --mcp-config-stdin --output json
multica agent update <agent-id> --mcp-config 'null' # clears the config
--mcp-config-stdin / --mcp-config-file keep the value out of shell history
and ps; the inline --mcp-config <json> does not. The CLI requires a JSON
object or the literal null; a top-level array or primitive is rejected
client-side, and empty stdin/file input errors rather than silently clearing.
Two ways mcp_config differs from custom_env:
- It IS settable through
agent update. Unlikecustom_env,mcp_confighas no dedicated audited endpoint — the genericPUT /api/agents/{id}accepts it. Tri-state per the raw request body: field omitted → no change;null→ clear; object → replace. - It is serialized on read, but redacted.
agent get/listreturnmcp_configonly to callers allowed to view agent secrets; otherwise the field isnullandmcp_config_redactedistrue. Agent actors never see it, and a workspace may force redaction for everyone.
Provider support is not uniform: Qwen Code accepts a managed mcp_config through a daemon-owned 0600 temporary JSON file passed with --mcp-config; it is removed when the run exits. Leave the field unset (null) to inherit Qwen Code native settings.
Skill binding
Creating an agent does NOT bind any workspace skill — binding is a separate call after the agent exists. Two distinct verbs:
addis additive — it merges the given ids with existing bindings (POST /api/agents/{id}/skills/add).setis replace-all — it overwrites the entire binding list with exactly the given ids (PUT /api/agents/{id}/skills);--skill-ids ''clears all.
multica agent skills add <agent-id> --skill-ids <skill-id> --output json
multica agent skills list <agent-id> --output json
At claim time the daemon assembles the agent's skills as workspace-bound skills
FIRST, then appends the platform built-in skills. LoadAgentSkills loads each
bound skill's content plus its supporting files; built-in skills are embedded
at compile time and loaded from SKILL.md + sibling files. Both reach the
provider as skill content — which is why capability belongs in a bound skill,
not pasted into instructions.
Side effects needing approval
Read-only (safe): agent get, agent skills list, agent env get.
State-changing (require an explicit instruction — do not run speculatively):
multica agent create— inserts a new agent row.multica agent skills add/set— mutate bindings (setis destructive: it drops bindings not in the new list).multica agent env set— overwrites the fullcustom_envmap and writes an audit row.
Common wrong assumptions
- "
descriptionis the prompt." It is not — onlyinstructionsreaches the runtime. A rich description with empty instructions yields a named shell with no operating contract. - "Create binds the agent's skills." It does not; bind explicitly afterward.
- "
agent updatecan rotate env." It cannot — it 400s oncustom_env; use the env endpoint. - "
mcp_configbehaves likecustom_envon update." It does not —mcp_configIS settable viaagent update(--mcp-config), with--mcp-config nullto clear; onlycustom_envis gated behind the dedicated env endpoint. - "
agent getshows env values." It shows onlyhas_custom_envandcustom_env_key_count. - "An invalid
thinking_level/modelcombo is caught at create." Only an unknown provider-level literal is — model-specific gaps fail at run time. - "
setandaddare interchangeable for skills."setreplaces all bindings; using it when you meantaddsilently removes capabilities.
References
references/creating-agents-source-map.md maps every contract above to its
file:line on the current tree, the runtime effect, and a safe read-only
verification command.
All Files
0 filesInstall multica-creating-agents
Download and extract the skill files to your .claude/skills/ directory.
Download ZIPClone the repository and copy the skill files to your project.
git clone https://github.com/multica-ai/multica/tree/main/server/internal/service/builtin_skills/multica-creating-agents # Copy the skill folder to .claude/skills/ or .codex/skills/
Copy





Home
