Skip to content

Authoring your own skill

When the packaged skills do not fit, write your own. This page lays out the patterns and conventions that make Toado skills reliable.

Anatomy of a skill

A skill is one file: ~/.claude/skills/<name>/SKILL.md. The structure:

---
name: my-skill
description: One-line summary of what the skill does. Shows up in /help and the skill picker.
allowed-tools: ["mcp__toado__*", "Read", "Edit", "Bash"]
---
# /my-skill
[The prompt that runs when the user invokes /my-skill goes here.]

The frontmatter is metadata. The body is the prompt. Claude reads the prompt when the user types /my-skill ...args and runs whatever the prompt asks.

Naming

Prefix Toado skills with toado- so they group together in the skill picker and signal what they need. toado-triage, toado-verify, toado-dupes.

allowed-tools

The allowed-tools array gates which tools Claude is permitted to call from inside the skill. Use it to scope down. Common patterns:

  • Read-only triage: ["mcp__toado__list_*", "mcp__toado__get_*", "mcp__toado__search_*", "mcp__toado__list_*"]
  • Read plus comment: add "mcp__toado__add_comment".
  • Full triage that fixes code: include code-edit tools (Read, Edit, Write, Bash, Grep, Glob) and the write set (mcp__toado__update_ticket, mcp__toado__move_ticket, mcp__toado__start_work_on_ticket).

The wildcard mcp__toado__* allows everything in the namespace. Convenient for development; tighten before sharing.

Conventions to follow

1. Resolve ids once, use them throughout

Resolving company → project → columns at the start of the run is one round of API calls. Pass the ids through the rest of the loop instead of re-resolving by name.

list_companies → cache co_id
list_projects(co_id) → match $1 → cache proj_id
list_columns(proj_id) → cache todo_id, in_review_id, done_id

2. Read comments before acting

Every ticket may have prior MCP runs. Read those comments first. If a previous run posted “Cannot reproduce, environment-specific”, do not silently retry.

3. Comment as a receipt for every action

After every write, post an add_comment describing what you did. The comment is the audit trail. Without it, a reviewer two weeks later cannot tell what the agent meant by the move_ticket they see in history.

Useful comment template:

What changed: [1-3 sentence description of the fix]
Branch: t-abc123-fix-foo
Commit: abc1234
Verified: tests pass / build succeeds

4. Default to “ask” when unsure

If the description is ambiguous, the capture is missing data, or the proposed fix would touch more than 5 files: comment with the question, leave in place. Better to ask once than to fix the wrong thing.

5. Honor opt-out signals

If a ticket has a comment containing “do not auto-fix” or has a blocked label, skip it. Document the convention in the skill so users know how to opt a ticket out.

6. Stop on systemic failures

If three consecutive tickets fail the same way (verify step crashes, MCP returns 500), stop the run. Something is broken in the environment, and burning through 47 more tickets will not help.

7. Always summarize at the end

Even when no human reads it immediately, the run summary is what makes the audit trail tractable. Counts, branch names, commit SHAs.

When to use which MCP tool

GoalToolNotes
Discover the project treelist_companies, list_projects, list_columnsCache the results.
Find tickets matching a phrasesearch_ticketsMin 2 chars. Scope with project_id.
Fetch full ticket contextget_ticket(include=[...])Include array is advisory; server returns everything.
See what the user drew on the screenshotget_annotationsReturns vector shapes with image-pixel coords.
Get bytes of the screenshotget_capture_asset(asset='screenshot_with_annotations')Returns presigned URL. Fetch directly.
Post an action receiptadd_commentMarkdown body.
Record a branch you are about to createstart_work_on_ticketGenerates a slug for a single ticket; require an explicit name for bundles.
Move a ticket forwardmove_ticketCross-company is rejected.
Move many at oncebulk_move_ticketsCaps at 50. Sequential, partial failures reported per ticket.
Assign / unassignassign_ticket, unassign_ticket, bulk_assign_ticketsUse list_members first to get user ids.
File a new bug from the agentcreate_ticketText-only. No screenshot.
Park a ticket out of the active boardarchive_ticketReversible via restore_ticket.

Templating arguments

Skills receive the user’s invocation as numbered positional args. $1 is the first word, $2 the second, and so on. Most Toado skills use $1 for a project name or id.

Modifiers are usually parsed from the rest of the command in plain English: “stop and ask before each move”, “first 10”, “read-only”. The skill prompt should explicitly handle the most common modifiers in its body so Claude knows to honor them.

Sharing a skill with teammates

Copy the skill folder into the project repo:

Terminal window
mkdir -p .claude/skills/toado-triage
cp ~/.claude/skills/toado-triage/SKILL.md .claude/skills/toado-triage/SKILL.md

Commit and push. Teammates running Claude Code inside the project pick it up automatically.

Testing a skill

The fastest test loop:

  1. Edit SKILL.md.
  2. Restart Claude Code (or reload the skill in-session if your client supports it).
  3. Run the skill against a test project that has a few intentionally-tricky tickets.
  4. Watch the tool calls. Adjust the prompt for any decisions Claude makes that you disagree with.

Repeat until the prompt produces the behavior you want without needing in-line correction.

Where to next