Skip to content

Fix a ticket end-to-end

This page walks through one ticket from the moment Claude picks it up to the moment it lands in In Review. The pattern generalizes: every fix Claude does follows the same shape, and most skills are just this loop with different selection criteria.

The shape of a fix

SELECT a ticket from a column
READ its full context (capture, DevTools, comments, annotations)
DECIDE whether you can fix it (or whether to ask)
START WORK (record a branch name, signal "in progress")
EDIT code locally
VERIFY (build, type-check, run tests)
COMMIT and push
COMMENT on the ticket with what you did
MOVE the ticket forward (To Do → In Review, or → Done)

Every step maps to one or two MCP tools.

Step by step

1. Select

Most often Claude is told “work the top of To Do” or “fix ticket t-abc123”. For the queue case:

list_tickets(project_id, column_id=todo_id, limit=1)
→ pick the first item, ticket_id = t-abc123

For the explicit case, skip straight to the next step.

2. Read context

Always pull the full ticket payload. Use include to make intent explicit even though the server returns everything:

get_ticket(ticket_id='t-abc123', include=['capture','comments','annotations'])

The response includes:

  • title, description, source_url
  • capture.console, capture.network, capture.errors, capture.performance
  • comments (in chronological order, oldest first)
  • annotations (vector shapes drawn on the screenshot)
  • attachments (any extra images uploaded by the reporter)

Read the comments before you act. If the previous MCP run already attempted a fix and the user pushed back, that history is in comments. Skipping it leads to repeating a rejected approach.

If you need the rendered screenshot (with the user’s annotations baked in):

get_capture_asset(ticket_id='t-abc123', asset='screenshot_with_annotations')
→ { url: 'https://...presigned...' }

Fetch that URL directly. No extra auth headers; the URL is presigned.

If you need to reason about what the user circled or arrowed (not just see the flattened image), prefer get_annotations, which returns the structured shapes with image-pixel coordinates.

3. Decide

Three useful triage lanes:

  • Fix it. The bug is clear, the fix is in your codebase, you can ship.
  • Ask. Something is unclear: which page? which user? “I do not know what ‘Acme’ refers to in the description.” Post a comment, leave the ticket in To Do.
  • Reject. This is not a bug, or it is out of scope. Comment with the reasoning, move to Done or to a “won’t fix” column if your project has one.

The choice is yours. Toado does not enforce a workflow.

4. Start work

Record the branch name on the ticket so other agents and humans can see what is in flight:

start_work_on_ticket(ticket_ids=['t-abc123'])
→ { branch_name: 't-abc123-fix-checkout-button-overflow', tickets: [...] }

start_work_on_ticket slugs the title into a branch name automatically when you pass one ticket. For a bundle, pass an explicit branch_name:

start_work_on_ticket(ticket_ids=['t-abc123','t-def456'], branch_name='t-bundle-checkout-fixes')

Then locally:

Terminal window
git checkout -b t-abc123-fix-checkout-button-overflow

5. Edit code

This is the part Toado does not do. Read the captured DevTools data, look at the screenshot and annotations, find the relevant file in your repo, and make the change.

The capture context is the leverage. Network errors, console traces, and performance notes are usually enough to localize the bug to a specific file or function without further investigation.

6. Verify

Run whatever your project’s local verification step is (typecheck, test, lint, build). Catching a regression here is much cheaper than catching it after you have moved the ticket.

7. Commit

Terminal window
git add -p
git commit -m "Fix checkout button overflow on narrow viewports
Toado: t-abc123"
git push -u origin HEAD

The Toado: t-abc123 line is convention. It makes the link explicit when someone reads git log later.

8. Comment

Post what you did:

add_comment(
ticket_id='t-abc123',
body='Fixed by clamping the button to `max-width: 100%` and removing the redundant `padding-right` on `.checkout-row`. Branch: `t-abc123-fix-checkout-button-overflow`. Commit: `abc1234`.'
)

The comment shows up with an MCP badge so reviewers can tell at a glance it came from an agent. Include enough detail that the reviewer can understand the change without opening the diff.

9. Move

Move the ticket forward:

list_columns(project_id) → find in_review_id
move_ticket(ticket_id='t-abc123', target_column_id=in_review_id)

Most teams send fixes to In Review for human eyes. Some skills move them straight to Done if the change is trivial and already merged.

Putting it together

A skill that does this end-to-end loop is the toado-triage skill. It is the canonical example of this pattern at work and the easiest way to start.

Failure modes worth handling

  • No tickets in the column: stop, do not loop forever.
  • Ticket has no capture data (description-only ticket created via create_ticket): skip the get_capture_asset step.
  • Branch already exists locally: pick a fresh suffix or work on the existing one.
  • Tests fail: do not move the ticket. Comment with the failure, leave it in To Do or move to a blocked column.
  • forbidden from move_ticket: the ticket is in another company; cross-company moves are rejected.