
Role Creator
- 1.2k installs
- 1k repo stars
- Updated July 14, 2026
- am-will/codex-skills
Role Creator is a CLI skill that enables developers to author, validate, and deploy custom Codex agents as standalone TOML configuration files with required behavior definitions and optional runtime settings.
About
Role Creator enables developers to define and update custom Codex agents through standalone TOML files stored globally (~/.codex/agents/<name>.toml) or per-project (<project>/.codex/agents/<name>.toml). The skill enforces a strict input-collection workflow: confirm name, description, developer_instructions, model, reasoning_effort, scope, and output path before writing. Generated files contain required keys (name, description, developer_instructions) plus optional fields (nickname_candidates, model, sandbox_mode, web_search, mcp_servers). Validation occurs post-write; ready-to-run JSON payloads are returned for immediate agent spawning.
- Standalone TOML files serve as agent source of truth; no separate registration required
- Mandatory input confirmation prevents inference errors and ensures explicit developer intent
- Minimal default policy - optional keys omitted unless explicitly requested
- Author and maintain custom Codex agents via standalone TOML configuration files
- Author and maintain custom Codex agents via standalone TOML configuration files
Role Creator by the numbers
- 1,152 all-time installs (skills.sh)
- Ranked #938 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 3, 2026 (Skillselion catalog sync)
role-creator capabilities & compatibility
- Capabilities
- agent scaffolding · toml generation · configuration validation · role definition
- Use cases
- code review · orchestration
- Runs
- Runs locally
- Pricing
- Free
npx skills add https://github.com/am-will/codex-skills --skill role-creatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.2k |
|---|---|
| repo stars | ★ 1k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 14, 2026 |
| Repository | am-will/codex-skills ↗ |
What it does
Author and maintain custom Codex agents via standalone TOML configuration files
Who is it for?
Developers building reusable Codex agents with narrowly scoped instructions and custom models; teams managing per-project or global agent libraries.
Skip if: Rapid ad-hoc agent testing; modifying core Codex runtime behavior; managing ~/.codex/config.toml global settings (threads, limits).
When should I use this skill?
Creating a new custom agent, updating agent behavior/instructions, validating agent TOML syntax, or deploying agents across global or project scopes.
What you get
A valid, scope-appropriate TOML agent file ready for immediate spawning via agent_type identifier.
- Validated TOML agent configuration file
- Ready-to-run JSON spawn payload (agent_type + message)
- Syntax validation report
By the numbers
- Three required keys: name, description, developer_instructions
- Nickname_candidates must be non-empty list with unique ASCII-safe values when present
- Two scopes supported: global (~/.codex/agents/) and project (<project>/.codex/agents/)
Files
Role Creator
Overview
Use this skill to author, update, or troubleshoot custom Codex agents as standalone TOML files.
Current behavior:
- Each custom agent is defined by one file:
- Global:
~/.codex/agents/<agent-name>.toml - Project:
<project>/.codex/agents/<agent-name>.toml - The agent file is the role source of truth.
~/.codex/config.tomlis only for global/runtime settings (for example[agents]thread limits), not per-role registration.
Non-Negotiable Inputs
Step 1 is required before writing files:
name(role identifier used byagent_type)description(short, human-readable purpose)developer_instructionsmodel(recommendgpt-5.3-codexunless requested)model_reasoning_effort(none|minimal|low|medium|high|xhigh)- role scope (
globalorproject) - output TOML path (canonical absolute path preferred)
- whether to include
nickname_candidatesand exact values
Execution rule:
- Do not infer required values.
- Do not write until required inputs are explicitly confirmed.
Role file contract (current)
From Codex custom agent docs (/codex/subagents):
- Required keys:
name,description,developer_instructions. - Optional keys:
nickname_candidates,model,model_reasoning_effort,sandbox_mode,web_search,mcp_servers,skills.config, etc. nameis the spawn identifier and source of truth.description+developer_instructionsdefine behavior and usage boundaries.nickname_candidatesis optional and used only for display.
nickname_candidates requirements:
- Must be a non-empty list of unique values when present.
- Allowed characters: ASCII letters, digits, spaces, hyphens, underscores.
Default policy for optional settings
- Do not add sandboxing/MCP/web-search/model extras unless requested.
- Keep generated files minimal by default.
- If the user says "inherit defaults", omit optional keys instead of setting explicit values.
Workflow
1. Collect and confirm required inputs. 2. Resolve output path:
global→~/.codex/agents/<name>.tomlproject→<project>/.codex/agents/<name>.toml
3. Create or update the file directly with required keys. 4. Validate TOML parse and required keys. 5. Return a ready-to-run example call:
{"agent_type":"<name>","message":"<task>"}Commands
# 1) Write a standalone custom-agent file
/home/willr/Applications/skills/skills/role-creator/scripts/write_role_config.sh \
--output ~/.codex/agents/reviewer.toml \
--role-name reviewer \
--description "PR reviewer focused on correctness, security, and risk." \
--model gpt-5.4 \
--reasoning high \
--developer-instructions "Review code like an owner. Lead with concrete findings and residual risks."
# Optional: include nickname candidates for display
/home/willr/Applications/skills/skills/role-creator/scripts/write_role_config.sh \
--output ~/.codex/agents/reviewer.toml \
--role-name reviewer \
--description "PR reviewer focused on correctness, security, and risk." \
--model gpt-5.4 \
--reasoning high \
--developer-instructions "Review code like an owner. Lead with concrete findings and residual risks." \
--nickname-candidates "Atlas,Delta,Echo" \
--sandbox-mode read-only \
--web-search disabledGuardrails
- If runtime returns
unknown agent_type, verify the active scope and confirm the file exists at the expected path. - Check syntax first with
tomlqortomlq -C. - Keep role instructions operational and narrowly scoped to avoid drift.
References
- Codex subagents docs:
https://developers.openai.com/codex/subagents - Display nicknames:
https://developers.openai.com/codex/subagents#display-nicknames - Reusable templates:
templates/
Role Config Reference
Canonical Sources In This Repo
codex-rs/core/src/config/mod.rscodex-rs/core/src/agent/role.rscodex-rs/core/src/tools/handlers/multi_agents.rscodex-rs/core/config.schema.json
Role Declaration Shape (~/.codex/config.toml)
[agents.researcher]
description = "Read-only researcher role"
config_file = "~/.codex/agents/researcher.toml"Supported keys under [agents.<role>]
descriptionconfig_file
Anything else under [agents.<role>] is unsupported.
Role config_file Shape
Role config_file is parsed as a full ConfigToml layer. Top-level keys must be valid top-level keys from codex-rs/core/config.schema.json.
Minimum policy for this skill
Require these fields in every role config:
modelmodel_reasoning_effortdeveloper_instructions
Do not add optional keys (sandbox, web_search, mcp_servers, or others) unless explicitly requested by the user.
Recommended default profile (when user does not specify):
model = "gpt-5.3-codex"model_reasoning_effort = "medium"
Useful enums
model_reasoning_effort:none|minimal|low|medium|high|xhighsandbox_mode:read-only|workspace-write|danger-full-accessweb_search:disabled|cached|live
Runtime Merge Notes
- Spawn starts from parent turn config.
- Role config file is merged as a config layer.
- Spawn then forces
approval_policy = never. - Collab depth limits still apply.
Practical implication: role config can tune model/sandbox/tools/etc., but spawn-time enforced overrides still win.
Configuration Categories With Examples
These are common categories users ask for when building custom roles.
1) Minimal role (recommended default)
model = "gpt-5.3-codex"
model_reasoning_effort = "medium"
developer_instructions = """
You are a focused implementation assistant.
Work only in requested files, validate changes, and report exact evidence.
"""2) Model/reasoning/style knobs
model = "gpt-5.3-codex"
model_reasoning_effort = "high"
model_reasoning_summary = "detailed"
model_verbosity = "high"
personality = "pragmatic"
developer_instructions = "..."3) Sandboxing and workspace controls
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true
writable_roots = ["/path/to/repo"]4) Search and feature toggles
web_search = "cached"
[features]
memory_tool = false
shell_tool = false5) MCP server controls (basic and rich)
Basic enable/disable:
[mcp_servers.linear]
enabled = true
required = falseRich server definition:
[mcp_servers.linear]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-linear"]
env_vars = ["LINEAR_API_KEY"]
enabled = true
required = false6) App connector toggles
[apps.notion]
enabled = true
[apps.monday]
enabled = false7) Skill-aware role instructions
developer_instructions = """
Use the $frontend-design skill for UI/UX work.
Build mobile-first, accessible, and production-grade interfaces.
"""Inheritance Rule Of Thumb
- Configure only what must differ from parent.
- Leave everything else omitted to inherit.
- Prefer minimal role config unless user explicitly requests stronger constraints.
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
Usage:
install_role.sh --role-name NAME --description TEXT --role-config-file PATH [options]
Options:
--config PATH Target config.toml (default: ~/.codex/config.toml)
--update-existing Allow updating an existing [agents.<role>] definition
--disable-multi-agent Do not force features.multi_agent=true
-h, --help Show this help
USAGE
}
config_path="${HOME}/.codex/config.toml"
role_name=""
role_description=""
role_config_file=""
set_multi_agent="true"
update_existing="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--config)
config_path="$2"; shift 2 ;;
--role-name)
role_name="$2"; shift 2 ;;
--description)
role_description="$2"; shift 2 ;;
--role-config-file)
role_config_file="$2"; shift 2 ;;
--update-existing)
update_existing="true"; shift ;;
--disable-multi-agent)
set_multi_agent="false"; shift ;;
-h|--help)
usage; exit 0 ;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1 ;;
esac
done
if [[ -z "$role_name" || -z "$role_description" || -z "$role_config_file" ]]; then
echo "Missing required arguments." >&2
usage
exit 1
fi
mkdir -p "$(dirname "$config_path")"
if [[ ! -f "$config_path" ]]; then
: > "$config_path"
fi
role_exists="$(tomlq -r --arg role_name "$role_name" '.agents[$role_name] != null' "$config_path" 2>/dev/null || printf 'false')"
if [[ "$role_exists" == "true" && "$update_existing" != "true" ]]; then
echo "Role '$role_name' already exists in $config_path. Re-run with --update-existing to modify it." >&2
exit 1
fi
expr='.agents[$role_name].description = $role_description |
.agents[$role_name].config_file = $role_config_file'
if [[ "$set_multi_agent" == "true" ]]; then
expr+=' | .features.multi_agent = true'
fi
backup_path="${config_path}.bak.$(date +%Y%m%d%H%M%S)"
cp "$config_path" "$backup_path"
tmp_file="$(mktemp)"
tomlq -t \
--arg role_name "$role_name" \
--arg role_description "$role_description" \
--arg role_config_file "$role_config_file" \
"$expr" \
"$config_path" > "$tmp_file"
mv "$tmp_file" "$config_path"
echo "Installed role '$role_name' in $config_path"
echo "Role config file: $role_config_file"
echo "Backup created at: $backup_path"
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
Usage:
validate_role.sh --role-name NAME --config PATH --role-config PATH --schema PATH
USAGE
}
role_name=""
config_path=""
role_config_path=""
schema_path=""
while [[ $# -gt 0 ]]; do
case "$1" in
--role-name)
role_name="$2"; shift 2 ;;
--config)
config_path="$2"; shift 2 ;;
--role-config)
role_config_path="$2"; shift 2 ;;
--schema)
schema_path="$2"; shift 2 ;;
-h|--help)
usage; exit 0 ;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1 ;;
esac
done
if [[ -z "$role_name" || -z "$config_path" || -z "$role_config_path" || -z "$schema_path" ]]; then
echo "Missing required arguments." >&2
usage
exit 1
fi
for path in "$config_path" "$role_config_path" "$schema_path"; do
if [[ ! -f "$path" ]]; then
echo "Missing file: $path" >&2
exit 1
fi
done
allowed_decl='["description","config_file"]'
decl_keys="$(tomlq --arg role_name "$role_name" '.agents[$role_name] // {} | keys' "$config_path")"
unsupported_decl="$(jq -n --argjson have "$decl_keys" --argjson allowed "$allowed_decl" '$have - $allowed')"
if [[ "$unsupported_decl" != "[]" ]]; then
echo "Unsupported keys under [agents.$role_name]: $unsupported_decl" >&2
exit 1
fi
required_decl_present="$(tomlq -r --arg role_name "$role_name" '.agents[$role_name].description != null and .agents[$role_name].config_file != null' "$config_path")"
if [[ "$required_decl_present" != "true" ]]; then
echo "Role declaration must include description and config_file under [agents.$role_name]" >&2
exit 1
fi
allowed_top_keys="$(jq -c '.properties | keys' "$schema_path")"
role_top_keys="$(tomlq 'keys' "$role_config_path")"
unsupported_top="$(jq -n --argjson have "$role_top_keys" --argjson allowed "$allowed_top_keys" '$have - $allowed')"
if [[ "$unsupported_top" != "[]" ]]; then
echo "Unsupported top-level keys in role config: $unsupported_top" >&2
exit 1
fi
for required_key in model model_reasoning_effort developer_instructions; do
present="$(tomlq -r --arg required_key "$required_key" '.[$required_key] != null and .[$required_key] != ""' "$role_config_path")"
if [[ "$present" != "true" ]]; then
echo "Missing required role config key: $required_key" >&2
exit 1
fi
done
echo "Role validation passed for '$role_name'."
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
Usage:
write_role_config.sh --output PATH --role-name NAME --description DESC --model MODEL --reasoning EFFORT [options]
Required:
--output PATH
--role-name NAME
--description DESC
--model MODEL
--reasoning none|minimal|low|medium|high|xhigh
Developer instructions (choose one):
--developer-instructions TEXT
--developer-instructions-file PATH
Optional:
--nickname-candidates "Atlas,Delta,Echo"
--sandbox-mode read-only|workspace-write|danger-full-access
--network-access true|false (for workspace-write)
--writable-roots path1,path2 (for workspace-write)
--web-search disabled|cached|live
--mcp-clear (set mcp_servers = {})
--mcp-enable name1,name2 (set mcp_servers.<name>.enabled = true)
--mcp-disable name1,name2 (set mcp_servers.<name>.enabled = false)
-h, --help
USAGE
}
output_path=""
role_name=""
role_description=""
model=""
reasoning=""
developer_instructions=""
developer_instructions_file=""
nickname_candidates_csv=""
sandbox_mode=""
network_access=""
writable_roots_csv=""
writable_roots_json="[]"
web_search=""
mcp_clear="false"
mcp_enable_csv=""
mcp_disable_csv=""
while [[ $# -gt 0 ]]; do
case "$1" in
--output)
output_path="$2"; shift 2 ;;
--role-name)
role_name="$2"; shift 2 ;;
--description)
role_description="$2"; shift 2 ;;
--model)
model="$2"; shift 2 ;;
--reasoning)
reasoning="$2"; shift 2 ;;
--developer-instructions)
developer_instructions="$2"; shift 2 ;;
--developer-instructions-file)
developer_instructions_file="$2"; shift 2 ;;
--nickname-candidates)
nickname_candidates_csv="$2"; shift 2 ;;
--sandbox-mode)
sandbox_mode="$2"; shift 2 ;;
--network-access)
network_access="$2"; shift 2 ;;
--writable-roots)
writable_roots_csv="$2"; shift 2 ;;
--web-search)
web_search="$2"; shift 2 ;;
--mcp-clear)
mcp_clear="true"; shift ;;
--mcp-enable)
mcp_enable_csv="$2"; shift 2 ;;
--mcp-disable)
mcp_disable_csv="$2"; shift 2 ;;
-h|--help)
usage; exit 0 ;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1 ;;
esac
done
if [[ -z "$output_path" || -z "$role_name" || -z "$role_description" || -z "$model" || -z "$reasoning" ]]; then
echo "Missing required arguments." >&2
usage
exit 1
fi
case "$reasoning" in
none|minimal|low|medium|high|xhigh) ;;
*)
echo "Invalid reasoning effort: $reasoning" >&2
exit 1 ;;
esac
if [[ -n "$sandbox_mode" ]]; then
case "$sandbox_mode" in
read-only|workspace-write|danger-full-access) ;;
*)
echo "Invalid sandbox mode: $sandbox_mode" >&2
exit 1 ;;
esac
fi
if [[ -n "$web_search" ]]; then
case "$web_search" in
disabled|cached|live) ;;
*)
echo "Invalid web_search mode: $web_search" >&2
exit 1 ;;
esac
fi
if [[ -n "$network_access" ]]; then
case "$network_access" in
true|false) ;;
*)
echo "Invalid --network-access value: $network_access" >&2
exit 1 ;;
esac
fi
if [[ -n "$developer_instructions" && -n "$developer_instructions_file" ]]; then
echo "Use only one of --developer-instructions or --developer-instructions-file" >&2
exit 1
fi
if [[ -n "$developer_instructions_file" ]]; then
if [[ ! -f "$developer_instructions_file" ]]; then
echo "Developer instructions file not found: $developer_instructions_file" >&2
exit 1
fi
developer_instructions="$(cat "$developer_instructions_file")"
fi
if [[ -z "$developer_instructions" ]]; then
developer_instructions="You are the ${role_name} role.
Own the assigned task end-to-end.
State assumptions clearly, fail fast on invalid inputs, and report concrete evidence for results.
Stay within scope and do not modify unrelated files."
fi
mkdir -p "$(dirname "$output_path")"
nickname_json="[]"
if [[ -n "$nickname_candidates_csv" ]]; then
nickname_json="$(printf '%s' "$nickname_candidates_csv" | jq -Rc 'split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0)) | unique')"
fi
expr='.name = $ROLE_NAME |
.description = $DESCRIPTION |
.model = $MODEL |
.model_reasoning_effort = $REASONING |
.developer_instructions = $DEVELOPER_INSTRUCTIONS'
if [[ -n "$sandbox_mode" ]]; then
expr+=$' | .sandbox_mode = $SANDBOX_MODE'
fi
if [[ -n "$network_access" ]]; then
expr+=$' | .sandbox_workspace_write.network_access = ($NETWORK_ACCESS == "true")'
fi
if [[ -n "$writable_roots_csv" ]]; then
writable_roots_json="$(printf '%s' "$writable_roots_csv" | jq -Rc 'split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0))')"
expr+=$' | .sandbox_workspace_write.writable_roots = ($WRITABLE_ROOTS_JSON | fromjson)'
fi
if [[ -n "$web_search" ]]; then
expr+=$' | .web_search = $WEB_SEARCH'
fi
if [[ "$mcp_clear" == "true" ]]; then
expr+=$' | .mcp_servers = {}'
fi
if [[ -n "$mcp_enable_csv" ]]; then
IFS=',' read -r -a mcp_enable_arr <<< "$mcp_enable_csv"
for name in "${mcp_enable_arr[@]}"; do
trimmed="$(printf '%s' "$name" | xargs)"
if [[ -n "$trimmed" ]]; then
expr+=" | .mcp_servers[\"$trimmed\"].enabled = true"
fi
done
fi
if [[ -n "$mcp_disable_csv" ]]; then
IFS=',' read -r -a mcp_disable_arr <<< "$mcp_disable_csv"
for name in "${mcp_disable_arr[@]}"; do
trimmed="$(printf '%s' "$name" | xargs)"
if [[ -n "$trimmed" ]]; then
expr+=" | .mcp_servers[\"$trimmed\"].enabled = false"
fi
done
fi
if [[ -n "$nickname_candidates_csv" ]]; then
expr+=$' | .nickname_candidates = ($NICKNAME_JSON | fromjson)'
fi
tomlq -n -t \
--arg ROLE_NAME "$role_name" \
--arg DESCRIPTION "$role_description" \
--arg MODEL "$model" \
--arg REASONING "$reasoning" \
--arg DEVELOPER_INSTRUCTIONS "$developer_instructions" \
--arg SANDBOX_MODE "$sandbox_mode" \
--arg NETWORK_ACCESS "$network_access" \
--arg WRITABLE_ROOTS_JSON "$writable_roots_json" \
--arg WEB_SEARCH "$web_search" \
--arg NICKNAME_JSON "$nickname_json" \
"$expr" > "$output_path"
echo "Wrote role config to $output_path"
# Example role that explicitly calls a skill.
model = "gpt-5.3-codex"
model_reasoning_effort = "high"
model_reasoning_summary = "detailed"
developer_instructions = """
Use the $frontend-design skill for UI/UX work.
Build with a mobile-first approach.
Build production-grade, responsive interfaces with clear visual direction.
Prioritize accessibility, performance, and maintainable component structure.
"""
# Full-surface example. Demonstrates advanced knobs.
# Do not apply wholesale unless the user asks for each category.
model = "gpt-5.3-codex"
model_reasoning_effort = "high"
model_reasoning_summary = "detailed"
model_verbosity = "high"
personality = "pragmatic"
developer_instructions = """
You are a senior Product Analyst focused on turning ambiguous goals into
executable requirements and acceptance criteria.
"""
sandbox_mode = "workspace-write"
web_search = "cached"
[sandbox_workspace_write]
network_access = true
writable_roots = ["/path/to/repo"]
[features]
memory_tool = false
shell_tool = true
[mcp_servers.linear]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-linear"]
env_vars = ["LINEAR_API_KEY"]
enabled = true
required = false
[apps.notion]
enabled = true
[apps.monday]
enabled = false
# Minimal role config (recommended default).
# Omitted keys inherit from parent config.
model = "gpt-5.3-codex"
model_reasoning_effort = "medium"
developer_instructions = """
You are a focused implementation assistant.
Work only in requested files, validate changes, and report exact evidence.
"""
# Constrained role profile. Use only when user explicitly requests restrictions.
model = "gpt-5.3-codex"
model_reasoning_effort = "medium"
developer_instructions = """
You are a read-focused analyst.
Do not modify files. Return concise findings with file:line evidence.
"""
sandbox_mode = "workspace-write"
web_search = "disabled"
[sandbox_workspace_write]
network_access = false
writable_roots = ["/path/to/repo"]
[features]
memory_tool = false
shell_tool = true
Related skills
How it compares
Pick role-creator over generic agent-prompt skills when you need schema-valid Codex TOML role wiring rather than ad-hoc system prompts.
FAQ
What inputs must I confirm before writing an agent file?
You must explicitly confirm: name (role identifier), description (human-readable purpose), developer_instructions, model (recommend gpt-5.3-codex), model_reasoning_effort (none|minimal|low|medium|high|xhigh), role scope (global or project), output TOML path, and whether to includ
Where are custom agent files stored?
Global agents: ~/.codex/agents/<agent-name>.toml. Project agents: <project>/.codex/agents/<agent-name>.toml. The agent TOML file is the sole source of truth; ~/.codex/config.toml is reserved for runtime settings only (e.g., thread limits).
What happens if the agent file is not found at runtime?
The runtime returns 'unknown agent_type'. Verify the active scope (global vs. project), confirm the file exists at the expected path, and check TOML syntax with tomlq or tomlq -C.
Is Role Creator safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.