CLAUDE.md, AGENTS.md, system prompt — whatever your harness uses) so the agent actually takes advantage of Skillscript instead of ignoring it.
Skillscript gives your agent a way to capture a routine once as a durable, compiled, auditable skill and run it many times — instead of re-reasoning the same workflow from scratch on every session, burning tokens and drifting a little each time. But an agent only uses skills if its instructions tell it to look. This guide is the minimum wiring to make that happen.
1. The runtime tells your agent how to use it
You probably don’t need to paste anything. The MCP server ships the usage contract as itsinstructions field — most MCP hosts surface that to the model at session start, so a connecting agent already knows to skill_list() first, preflight before composing, author-when-repeated, and never assume a backend. Quick check: after wiring the MCP, ask your agent “what do you know about skillscript?” — if it describes the workflow, you’re done, and your CLAUDE.md / AGENTS.md needs nothing about Skillscript.
If your host doesn’t surface server instructions (some don’t), paste the block below into your agent file. It mirrors what the server delivers — the authoritative copy is the runtime’s instructions field, so keep this in sync rather than diverging from it.
What your agent file should carry instead
Now that the runtime delivers the universal how-to, your agent file gets thinner — it should hold only what the runtime can’t know:- Who the operator is. The usage block says “ask the operator to wire what’s missing” — but not who. Name them and the channel to ask on.
- Which skills are this agent’s to maintain. A skill’s
headlesscategory (inskill_list) flags it as cron/event-fired, but “this one is yours to keep correct” is an ownership fact the universal block can’t carry. Note the autonomous skills the agent is responsible for. - The agent’s role and behavioral context. Who it is, how it should work. Never Skillscript’s to provide; always yours.
2. Best practices
Discover before you build
The single highest-value instruction is “runskill_list() at session start.” Agents that don’t enumerate their skills silently re-derive workflows that already exist as skills — the exact waste Skillscript removes. Make discovery a reflex, not an afterthought.
Prefer a skill over re-reasoning
A compiled skill runs the same way every time because the procedure is the source of record, not a prompt to be re-interpreted. When a routine exists as a skill, executing it is cheaper, more reliable, and auditable. Reserve fresh reasoning for the work that genuinely needs it.Write descriptions as trigger conditions, not summaries
When the agent picks among skills, it reads each# Description:. “Handles errors” is useless for selection. “If a downstream API returns non-200, run this” fires the skill at the right moment. Describe when to invoke, not what the skill does. This is what makes skill_list() actionable once you have more than a handful of skills.
Two kinds of skill, two postures
- Skills you invoke — you call them when relevant (
execute_skill). - Skills you own but never invoke — autonomous skills fired by a
cronoreventtrigger. Your job is to keep them correct, not to run them by hand. (They show up underheadlessinskill_list.)
Trust the approval gate
Every skill has aDraft → Approved → Disabled lifecycle, and only Approved skills run. In secured mode (SKILLSCRIPT_SECURED_MODE=true — the recommended posture for any agent-authored or multi-author deployment) approval is an operator’s Ed25519 signature: a skill an agent skill_writes lands Draft, a naked # Status: Approved is forced to Draft, and only a human holding the operator key can sign it into a runnable state. That’s the real safety boundary — an agent can write a skill, but a human decides whether it ever runs. In unsecured mode the status flag alone gates execution (a bare # Status: Approved runs, unkeyed) — convenient for a single trusted author, but it means a skill you write as Approved is immediately runnable. Either way, tell your agent to treat a freshly-written skill as not-yet-runnable until a human has approved it.
Author against discovered capability, not assumptions
Before writing a skill that needs a data store, a model, or an external tool, checkruntime_capabilities(). A skill that assumes a connector that isn’t wired fails at dispatch with a clear error — but it’s better to author against what’s actually present. Use # Requires: <connector>.<feature> in a skill to fail-fast at compile time when a needed capability is missing.
Keep deterministic work in tools, not skill bodies
Skills are orchestration. A fixed API call, a fixed parse, a fixed shell pipeline belongs in an MCP tool the skill invokes ($ <connector> ...), not hardcoded into the skill. This keeps skills portable across substrates and resistant to drift.
3. MCP tool reference
The tools your agent has when a Skillscript runtime is wired:| Tool | Use |
|---|---|
skill_list({ filter? }) | Discover skills, grouped by category. Filter by status / trigger_kind / name_prefix / author. Each entry carries the full contract (vars / returns / requires / effectful footprint) + approval state. |
skill_preflight({ name }) | Pre-execution contract check for one skill: what it takes / returns / requires / touches (effectful footprint) + approval-gate state + version. Call before invoking or composing. |
skill_read({ name }) | Read a skill’s source body. |
compile_skill({ name | source, inputs? }) | Render the compiled plan + surface errors. Read-only — safe to preview. |
lint_skill({ name | source }) | Static diagnostics (tier-1 errors / tier-2 warnings / tier-3 advisories). |
execute_skill({ name | source, inputs? }) | Run a skill. name runs a stored, approved skill; source runs ad-hoc inline (bypasses the store — for one-offs). |
skill_write({ name, source, overwrite? }) | Store a skill. Lands Draft unless approved. |
skill_status({ name, new_state }) | Transition Draft / Approved / Disabled. |
help({ topic? }) | Language reference — quickstart, plus ops, frontmatter, connectors, lint-codes, examples, composition. |
runtime_capabilities() | What’s actually wired — connectors, models, shell mode. |
register_trigger / list_triggers / unregister_trigger | Inspect/manage autonomous dispatch (cron / event). |
4. A minimal worked example
The smallest useful loop, from the agent’s point of view:5. What not to put in your agent file
- Don’t reference a specific backend. No “query the X store” / “call the Y model” by product name. Skills name connectors by role; the operator maps roles to backends in config. Your agent reads roles via
runtime_capabilities(). - Don’t tell the agent a freshly-authored skill is runnable. In secured mode (the recommended posture) it lands Draft until a human approves; have the agent treat anything it just wrote as not-yet-runnable regardless.
- Don’t have the agent manually fire autonomous skills. Cron/event skills fire themselves; the agent maintains them.
- Don’t hardcode tool/endpoint details into skill bodies. That’s tool territory; skills orchestrate, tools execute.