This topic ties together everything from Topics 1 through 5 into one continuous workflow: an issue comes in, gets triaged, becomes a PR with an AI-generated description, gets an AI first-pass review, and lands with a clear audit trail of what the agent did versus what a human approved. The example uses Claude Code CLI syntax since it has the most granular permission model, but every step maps directly onto OpenCode, Gemini CLI, or Cursor using the patterns from their respective topics — swap the confirmation mechanics, keep the prompts.
Assume: github-mcp-server connected with GITHUB_TOOLSETS=repos,issues,pull_requests, a fine-grained PAT scoped to one repo (acme/webapp), and .claude/settings.json set up per Topic 2 (reads auto-allowed, writes prompted, merge_pull_request excluded from allow entirely).
Workflow Overview: From Issue Creation to PR Merge Using AI
The end-to-end shape:
- Triage — an untriaged issue gets labeled, prioritized, and checked for duplicates (AI-assisted, human-approved in batch).
- Implementation — a developer (or a separate agent session) writes the fix on a branch — out of scope for this topic, covered by the code-editing workflows elsewhere in this course.
- PR description generation — AI drafts a structured PR description from the actual diff and commit history, grounded in the linked issue.
- AI code review — AI posts a first-pass review as inline comments before a human reviewer looks at it, catching the mechanical stuff (missing tests, weakened error handling, unaddressed TODO) so the human reviewer's time goes to design and correctness judgment instead.
- Human review and merge — a human approves or requests changes;
merge_pull_requestnever runs without explicit human confirmation regardless of client.
The point of AI involvement at steps 1, 3, and 4 isn't to remove the human from the loop — it's to remove the mechanical, low-judgment parts of those steps (reading a wall of issue comments, remembering to check if the description mentions rollback steps, scanning a diff for an obviously missing test) so the human's review time concentrates on the parts that actually need judgment.
claude mcp list
Tips
- Treat AI involvement in this workflow as compressing the mechanical parts of triage and review, not replacing the human decision points — merge approval and final triage-batch application stay manual by design.
- Run this workflow end-to-end on a low-stakes repo first (a personal project, a docs repo) before trusting it on anything customer-facing — the failure modes (bad label, mis-scoped PR description, a review comment that misreads the diff) are each individually cheap, but you want to see them happen once before they happen on something that matters.
- Keep the same PAT/toolset scoping discipline from Topic 1 throughout this whole workflow — nothing about chaining these steps together justifies widening the token's blast radius.
Step 1: Using AI to Triage and Label GitHub Issues via MCP
Start narrow — a single day's or week's worth of new issues, not the entire backlog:
> list issues in acme/webapp opened in the last 7 days with no labels.
For each: read the full body, search open and closed issues for likely
duplicates, and propose one label from [bug, feature, question, docs]
and one priority from [P0, P1, P2]. Show a table: issue number, title,
proposed label, proposed priority, duplicate candidate (if any). Don't
apply anything yet.
Expect output like:
#512 "Export button does nothing on Safari" bug P1 —
#513 "Add dark mode toggle" feature P2 —
#514 "Confused about rate limit headers" question P2 —
#515 "Export button broken on mobile Safari" bug P1 dup of #512
Review the table, then apply selectively:
> apply labels and priority for #512, #513, #514.
For #515, close as duplicate of #512 with a comment linking it —
don't apply a separate label since it'll be closed.
Claude Code will call update_issue (labels), then a second update_issue (priority, if you're tracking it as a label or custom field), then for #515: add_issue_comment followed by update_issue with state: closed.
Tips
- Process triage in small, recent batches (last 7 days, not the whole backlog) — smaller batches are easier to sanity-check in one read and limit the blast radius of a bad label being applied at scale.
- Always route duplicate-closure through an explicit comment linking the canonical issue — never a silent close, since the reporter deserves to see why.
- If your repo uses priority as a custom field (GitHub Projects) rather than a label, note that this MCP toolset doesn't cover Projects (Topic 1) — track priority as a label instead, or handle that field manually.
Step 2: Auto-Generating a Pull Request Description from Commit History
Once the fix for #512 (Safari export bug) is implemented on branch fix/safari-export-blob-url, generate the PR description grounded in both the diff and the originating issue — linking back to the issue gives the description context a diff alone can't provide:
> I'm opening a PR from fix/safari-export-blob-url into main, fixing issue #512.
Get the diff between these branches and the issue body for #512.
Draft a PR description with:
- Summary (what broke and why, referencing the issue)
- What Changed (bullet list grounded in the actual diff)
- Testing (what to verify manually, including the Safari-specific repro
from the issue)
- "Fixes #512" as the last line so GitHub auto-links and auto-closes it
A realistic generated body:
## Summary
Safari's Blob URL handling requires the anchor element to be attached to
the DOM before `.click()` is called, unlike Chrome/Firefox. The export
button used a detached anchor, which Safari silently ignores. Fixes #512.
## What Changed
- `src/export/downloadCsv.ts`: append the anchor element to `document.body`
before triggering `.click()`, remove it immediately after
- `tests/export/downloadCsv.test.ts`: added a jsdom-based test asserting
the anchor is attached during the click and removed after
## Testing
- Verified locally in Safari 17 on macOS: export now triggers a download
- Verified no regression in Chrome 126 and Firefox 127
- Ran the new unit test, confirms the anchor lifecycle
Fixes #512
> create the PR using that description, with title
"Fix CSV export failing silently in Safari"
The Fixes #512 line matters beyond documentation — GitHub auto-closes the issue when this PR merges, which is the one piece of housekeeping in this whole workflow you get for free without an extra tool call.
Tips
- Always ask for the issue's original repro steps to be folded into the Testing section — it closes the loop for whoever filed the issue and gives the human reviewer a concrete manual check.
- Use GitHub's auto-close syntax (Fixes #N,Closes #N) in every generated PR description tied to an issue — free automation, no reason to skip it.
- Spot-check the generated "What Changed" bullets against the actual diff before opening the PR — a model occasionally describes intent from the issue rather than the literal code change, which reads fine but can misdescribe an edge case the fix doesn't actually handle.
Step 3: Posting AI Code Review Comments via GitHub MCP
Before a human reviewer looks at it, run an AI first pass — read-only analysis first, then a separate approved step to post:
> review the diff for the PR fixing #512. Check specifically for:
- missing or inadequate test coverage for the change
- browser-specific edge cases not handled (this is a Safari-specific bug,
check if other WebKit quirks in this file are still unaddressed)
- any error handling removed or weakened
List findings with file:line references. Don't post anything yet.
Suppose it comes back with one substantive finding:
src/export/downloadCsv.ts:34 — the anchor removal happens synchronously
right after .click(), but Safari's download can be async for large blobs;
if removal races the download start, this could reintroduce a variant of
the original bug for large files. Consider a setTimeout or requestIdleCallback
before removing the anchor.
Review that finding — it's the kind of subtle, browser-timing-specific catch that's genuinely useful and not just a filler comment. Approve posting it:
> post that as an inline review comment on the PR at the specified file and line,
and submit the review as "Comment" (not "Request changes" — it's a suggestion,
not a blocker)
Claude Code calls create_pull_request_review with a single inline comment and event: COMMENT. The human reviewer then sees this comment already sitting on the PR when they open it — either they agree and ask for the fix before merge, or they judge the race condition unlikely enough to merge as-is and follow up separately. Either way, they're starting their review from "here's one specific thing already flagged" instead of a blank diff.
> now show me the full PR summary — description, this review comment,
and current check status — so I can decide whether to request the
setTimeout change before I approve
Merge stays a manual, human-triggered action:
gh pr merge fix/safari-export-blob-url --squash
Tips
- Split "analyze and list findings" from "post as review comments" into two separate confirmed steps — an AI review comment posted without a human glance first is exactly the kind of automation that erodes a team's trust in the whole workflow after one bad take.
- Choose the review event type (COMMENTvsREQUEST_CHANGES) deliberately per finding severity, and say so explicitly in your prompt — don't let the model default to whichever feels more assertive.
- Keepmerge_pull_requestout of every client's auto-approve list, permanently, across every workflow you build on this stack — it's the one step in this entire pipeline with no acceptable failure mode for "the agent did it without asking."
Tips
Tips
- Chain triage → PR description → review as three separately-approved stages, never as one uninterrupted automated pipeline — each stage has a different risk profile and deserves its own checkpoint.
- Ground every AI output in this workflow in real data pulled via MCP (the actual diff, the actual issue body) rather than letting the model infer from titles or your prompt alone — it's the difference between a useful first pass and confident-sounding noise.
- Pilot the full workflow on a low-stakes repo before trusting it on production code, and keepmerge_pull_requesta manual, human-triggered step permanently, regardless of how much you come to trust the earlier stages.