If you already have a markdown skill (a SKILL.md file with name and
description frontmatter, optionally bundled with helper scripts), Roscoe
can convert it directly into a workflow. The converter is exposed as an
MCP tool, so the easiest path is to ask Claude Code (or any harness with
Roscoe's MCP server connected) to do it for you.
This works across any harness that follows the Agent Skills open standard: Claude Code, Codex CLI, OpenCode, Gemini CLI, Cursor, and others.
What gets converted#
The skill body is sent to the configured LLM backend along with the workflow schema and conversion guidance. The model produces a workflow that maps:
| Skill pattern | Workflow pattern |
|---|---|
| Numbered imperative steps | A chain of ai_agent / script nodes |
"Run scripts/foo.sh" |
A script node executing bash "$ROSCOE_WORKFLOW_DIR/scripts/foo.sh" via Bun.$ |
| "If X then Y, otherwise Z" | An ai_judge with an enum or boolean validator routing to the branches |
| "Ask the user to confirm" | A human node with the prompt and the available transitions |
| "Carefully check before deploying" | A consensus node (3-5 agents, quorum): reserved for high-stakes / irreversible work |
| "Verify → fix → re-verify" | A cycle with maxIterations set |
| "Based on the previous result" | Template interpolation: {{ prior-node.response }} |
Bundled scripts/ are copied into the workflow's asset directory and
reachable via $ROSCOE_WORKFLOW_DIR from script nodes.
references/, examples/, and assets/ folders are detected and
reported in the response but not bundled. Wire them up manually if needed.
Quick start (Claude Code)#
With the Roscoe MCP server connected, ask Claude Code:
"Convert the skill at
~/.claude/skills/release-cut/SKILL.mdinto a Roscoe workflow."
Claude calls convert_skill to get a converter prompt, runs it on your
Claude subscription, then calls finalize_skill_conversion to write the
workflow YAML plus any bundled scripts. (Splitting it this way keeps the
conversion on your subscription — Roscoe's server never runs the model.) By
default the workflow lands in your active project
(<repo>/.roscoe/workflows/); fall back is global
(~/.roscoe/workflows/). Pass target_source: "global" to override.
Open it in the editor at http://localhost:7777/workflows/<id> (or the
dev port if you're running bun run dev) to inspect the conversion
before kicking off a run.
Discovering skills first#
Use list_skills to enumerate skill candidates Roscoe can see, then
pick one to convert. The scanner looks in the standard skill roots
(~/.claude/skills/, ~/.agents/skills/, ~/.codex/skills/,
~/.config/opencode/skills/, ~/.gemini/skills/), the project-local
roots (.claude/skills/, .agents/skills/, .opencode/skills/), and
falls back to the full repo tree for skills in non-standard locations.
A skill is identified by content signature: any .md file with a name:
and a real prose description: (20 or more characters, and not a blog
post's title: / date: frontmatter) qualifies, regardless of filename.
After conversion: things to check#
The converter aims for a faithful translation but you should always review the result before running it for real:
- Models: every AI node gets
model:set; confirm it matches what you want. The default is whatever is configured in yourroscoe.yaml. - Template interpolation: open the editor and look for nodes whose
prompts read like "based on the previous result". The converter emits
{{ nodeId.field }}references where it can; missing references show up as red wavy underlines in the editor. - Branches and validators:
ai_judgevalidator choices and theon:map should match the skill's branching logic. - Cycles: any verify-fix loop has
maxIterationsset; raise it if 3-10 attempts isn't enough for your workload. - Human gates:
humannodes preserve the skill's wording but you may want to tighten the prompt or transition labels.
Limitations#
| Limitation | Detail |
|---|---|
| Bundled non-script folders | references/, examples/, and assets/ are not copied, only scripts/. Reference them manually if needed. |
| No round-trip yet | There is no convert_workflow going the other direction. |
| Large skills can take a while | The converter gives the LLM call up to 10 minutes (timeoutMs: 600_000); a multi-phase skill with many bundled scripts may approach that ceiling. |
| Consensus selection is judgement-driven | Not mechanical. The converter is prompted to reach for consensus on high-stakes decisions (production deploys, security severity, migration safety), but it's worth manually upgrading any ai_judge that gates an irreversible action. |
Reference#
convert_skillMCP tool — full input and output shape.list_skillsMCP tool — scanner roots and the content-signature rule.- Output chaining — the
{{ nodeId.field }}syntax the converter emits, including fallbacks and the dominance rule.