This document explains skills from first principles, how they work in the OpenClaw runtime (~/openclaw), and how OpenClaw Studio currently exposes them in UX.
It is intended as design context for rethinking the Skills UX.
Skills are the mechanism OpenClaw uses to give agents reusable operational know-how without hardcoding that know-how into core runtime logic.
At a product level, a skill is:
- A unit of capability guidance (
SKILL.md) that teaches an agent how to perform a job. - A gated unit of readiness (only available when required binaries/env/config/OS are satisfied).
- A portable package format compatible with AgentSkills (
agentskills.io) so skill content can be authored and shared outside a single product.
Without skills, every workflow instruction would need to live in prompts, app code, or ad hoc user messages. Skills create a middle layer: structured capability packs that are discoverable, filterable, and enforceable.
OpenClaw intentionally uses AgentSkills-compatible SKILL.md structure and semantics.
Why this matters:
- Interoperability: skills can move between ecosystems that understand AgentSkills.
- Community/network effects: external skill ecosystems (for OpenClaw specifically, ClawHub) can be leveraged instead of reinventing proprietary formats.
- UX consistency: users can reason about “a skill folder with
SKILL.md+ metadata gates” instead of app-specific abstractions.
OpenClaw adds product-specific metadata under metadata.openclaw (install specs, gating fields, primary env key, etc.) while keeping the base skill shape compatible.
A skill is loaded from a directory containing SKILL.md with frontmatter.
Minimum frontmatter:
namedescription
Important optional fields used by OpenClaw:
metadata.openclaw.alwaysmetadata.openclaw.skillKeymetadata.openclaw.primaryEnvmetadata.openclaw.osmetadata.openclaw.requires.{bins, anyBins, env, config}metadata.openclaw.install[]user-invocabledisable-model-invocationcommand-dispatch,command-tool,command-arg-mode
In runtime, this becomes a normalized SkillEntry:
- Raw skill (
name,description,source, file paths) - Parsed frontmatter
- Resolved OpenClaw metadata
- Invocation policy flags
OpenClaw merges multiple sources into one effective skill set.
Current merge precedence in code (lowest -> highest):
skills.load.extraDirsand plugin-contributed skill dirs (source: openclaw-extra)- Bundled skills (
openclaw-bundled) - Managed/global local skills (
~/.openclaw/skills,openclaw-managed) - Personal agents skills (
~/.agents/skills,agents-skills-personal) - Project agents skills (
<workspace>/.agents/skills,agents-skills-project) - Workspace skills (
<workspace>/skills,openclaw-workspace)
Name conflicts are resolved by “last writer wins” according to this order.
Eligibility is not just “is this skill installed.” It is computed every load/snapshot using:
- Per-skill disable (
skills.entries.<skillKey>.enabled === false) - Bundled allowlist (
skills.allowBundled) for bundled skills only - Runtime requirements:
requires.bins(all required)requires.anyBins(at least one)requires.envrequires.configos
- Remote node eligibility (macOS node bin probing can satisfy certain requirements)
always: trueshort-circuiting requirement failures
Status output carries:
eligible/blocked- structured
missingreasons configCheckswith{ path, satisfied }(not secret values)- install options derived from metadata
OpenClaw has a separate per-agent skill filter via agents.list[].skills:
- Missing
skillskey: all discovered skills are allowed skills: []: no skills allowedskills: ["a", "b"]: allowlist mode
This filter is normalized and passed into snapshot generation as skillFilter.
In practice this is the key UX distinction:
- Discovery/readiness is global + workspace-derived.
- “Can this specific agent use it?” is per-agent allowlist.
Skills are snapshotted into session state (skillsSnapshot) to avoid re-scanning every turn.
Snapshot contains:
- prebuilt prompt block
- lightweight skill metadata (
name,primaryEnv, required env names) - normalized
skillFilter - resolved skills list
- version
Lifecycle:
- First turn/new session builds snapshot.
- File watcher / remote-node events bump snapshot version.
- Later turns refresh snapshot only if version is newer.
- Prompt injection uses snapshot prompt when present.
Watcher scope includes:
- workspace
skills/ - workspace
.agents/skills ~/.openclaw/skills~/.agents/skills- configured extra dirs
- plugin skill dirs
Watcher monitors SKILL.md patterns (not entire trees) and debounces changes.
During an agent run:
- Skill env overrides are applied (
skills.entries.*.env+apiKeymapping toprimaryEnv). - Overrides are sanitized/guarded (dangerous host env keys blocked).
- Skills prompt is injected.
- Environment is restored after run.
Invocation behavior:
disable-model-invocation: truekeeps skill out of model prompt.user-invocable: trueexposes slash commands.- Optional direct tool dispatch can bypass model routing.
Sandbox nuance:
- For non-
rwsandbox workspaces, OpenClaw syncs skills into sandbox workspace (best-effort) so skill files remain accessible.
Core RPC methods:
skills.status-> returnsSkillStatusReportfor an agent workspace.skills.install-> installs dependencies for a skill install option.skills.update-> updatesskills.entries.<skillKey>config (enabled,apiKey,env).skills.bins-> aggregates required bins across agent workspaces.
Important scope behavior:
skills.installis executed against the default agent workspace (not arbitrary selected agent workspace).skills.updatewrites gateway config (openclaw.json) and is gateway-wide state mutation.
Security detail:
skills.statusexposes config check satisfaction, not raw secret config values.
Studio settings currently live on root route with a query-driven settings mode:
- Canonical settings state is
/?settingsAgentId=<agentId>. /agents/[agentId]/settingscurrently redirects to that query route.
Left nav tabs in settings mode:
- Behavior
- Capabilities
- Skills
- Automations
- Advanced
When either Skills or System setup tab is active and connected, Studio:
- Calls
skills.status. - Reads current per-agent allowlist from gateway config (
agents.list[].skills). - Renders two distinct settings surfaces:
Skills tab (agent-scoped):
- Shows one list focused on “what this agent can use”.
- Per-skill allow toggle (
Skill <name>switch) for agent access only. - Simplified status chips (
Ready,Setup required,Not supported). - Search + status filters for scanning.
- Non-ready rows provide
Open System Setupinstead of inline setup actions.
System setup tab (gateway-scoped):
- Explicitly states that setup actions affect all agents.
- Shows setup queue and full readiness details.
- Per-skill
Configuremodal with setup/lifecycle actions:- install dependencies (
skills.install) - save API key (
skills.updatewithapiKey) - global enable/disable (
skills.updatewithenabled) - remove removable skill directories via Studio remove route
- install dependencies (
- Supports transition handoff from agent row to preselected skill setup context.
Per-agent access mutations:
updateGatewayAgentSkillsAllowlistin Studio writesconfig.setwith retry-on-stale-hash behavior.- Agent toggles continue to rely on allowlist semantics (
undefinedmeans all, explicit array means selected-only).
System setup mutations:
- Install ->
skills.install - API key save ->
skills.update - Remove files -> Studio route
/api/gateway/skills/remove(local fs or SSH helper)
Removal has strict guards:
- Only specific sources removable (
openclaw-managed,openclaw-workspace). - Must stay inside allowed root.
- Cannot remove skills root directory.
- Must look like a real skill dir (
SKILL.mdexists).
Studio computes the default agent id and passes install-scope context into the system setup surface.
Current scope copy behavior:
Skillstab copy states controls apply to the current agent.System setuptab copy states actions apply to all agents.- Install target caveat (default-agent workspace behavior) is shown in system setup context and setup modal context, where install actions actually occur.
This keeps scope and install-target warnings accurate while minimizing noise in the agent access flow.
Sorted by most recent creation time in openclaw-studio/.agent/done, the latest items are mostly bugfix exec plans (streaming, proxy auth, stale config, cron rollback, etc.).
The most recent plan with explicit skills direction is:
ui-execplan-stuff.md(2026-02-20 create time), which intentionally scoped skills as coming-soon during that IA pass.
Additional files with incidental skill mentions:
simplify-agent-creation-starter-kits.mdux-zero-agent-layout-consolidation.md
Interpretation:
- The current Studio code now has a real Skills tab and mutation flow, but the older IA/doc language still contains “coming soon” assumptions in places.
- For redesign, trust current code behavior over older plan phrasing.
Any redesign should preserve these distinctions:
- Three separate scopes:
- Agent allowlist scope (
agents.list[].skills) - Gateway setup scope (
skills.entries.*, installs) - Source/discovery scope (workspace/managed/bundled/extra/plugin)
- Eligibility vs enablement:
- A skill can be enabled by allowlist but still blocked by missing requirements.
- A skill can be eligible but disabled by agent allowlist.
- Session-snapshot behavior:
- Skills changes may not appear mid-turn; they apply on next turn/snapshot refresh.
- Install target caveat:
- Install currently targets default agent workspace context in gateway path.
- Security posture:
- Secret values should never be exposed in status surfaces.
- Removal must stay bounded to allowed roots and verified skill dirs.
If you hand a screenshot to another LLM for UX feedback, ask it to evaluate on three axes:
- Scope clarity
- Can a user tell what is per-agent vs gateway-wide?
- Readiness clarity
- Can a user tell blocked vs eligible and why?
- Action safety
- Are destructive/setup actions clearly separated from allowlist toggles?
If a design fails any of those axes, users will misconfigure skills even if controls are technically correct.