{"id":"7d4919d9-af31-43a1-85c0-c0fa6784c2dc","shortId":"hn9vra","kind":"skill","title":"manage-pull-requests","tagline":">-","description":"# Manage Pull Requests\n\nManage Harness Code pull requests, reviewers, comments, checks, and activity via MCP.\n\n## MCP Tools Used\n\n| Tool | Resource Type | Purpose |\n|------|---------------|---------|\n| `harness_list` | `pull_request` | List PRs in a repo, filter by state |\n| `harness_get` | `pull_request` | Get PR details by number |\n| `harness_create` | `pull_request` | Open a new PR |\n| `harness_update` | `pull_request` | Update PR title / description / state |\n| `harness_execute` (action: `merge`) | `pull_request` | Merge a PR (merge/squash/rebase/fast-forward) |\n| `harness_list` | `pr_reviewer` | List reviewers on a PR |\n| `harness_create` | `pr_reviewer` | Add a reviewer to a PR |\n| `harness_execute` (action: `submit_review`) | `pr_reviewer` | Submit an `approved` or `changereq` review |\n| `harness_create` | `pr_comment` | Post a top-level or inline code comment |\n| `harness_update` | `pr_comment` | Edit a comment |\n| `harness_delete` | `pr_comment` | Delete a comment |\n| `harness_list` | `pr_activity` | Read the discussion timeline — **the only way to READ comments** |\n| `harness_list` | `pr_check` | List CI status checks on a PR |\n| `harness_schema` | any of the above | Exact JSON Schema for `create` / `update` body fields |\n\nAll pull-request resources are **repo-scoped**. Every call needs `repo_id` and `pr_number` (except `harness_list` for `pull_request`, which only needs `repo_id`). `org_id` / `project_id` are optional (the server infers them from the repo).\n\n**URL shortcut:** the MCP server auto-extracts `repo_id` and `pr_number` if you pass a Harness PR URL via the `url` parameter — e.g. `harness_get(resource_type=\"pull_request\", url=\"https://app.harness.io/ng/account/.../pulls/42\")`.\n\n## Instructions\n\n### Step 1: List or find the PR\n\n```\nCall MCP tool: harness_list\nParameters:\n  resource_type: \"pull_request\"\n  repo_id: \"<repository_identifier>\"\n  state: \"open\"        # optional: open | closed | merged\n  query: \"<keyword>\"   # optional: full-text search\n```\n\nOr fetch a specific PR:\n\n```\nCall MCP tool: harness_get\nParameters:\n  resource_type: \"pull_request\"\n  repo_id: \"<repository_identifier>\"\n  pr_number: <number>\n```\n\n### Step 2: Open a PR\n\n```\nCall MCP tool: harness_create\nParameters:\n  resource_type: \"pull_request\"\n  repo_id: \"<repository_identifier>\"\n  body:\n    title: \"Fix race condition in scheduler\"\n    source_branch: \"fix/scheduler-race\"\n    target_branch: \"main\"\n    description: \"Resolves HAR-1234. Adds mutex around queue access.\"\n```\n\n`title`, `source_branch`, `target_branch` are required. `description` supports markdown.\n\n### Step 3: Update PR metadata\n\n```\nCall MCP tool: harness_update\nParameters:\n  resource_type: \"pull_request\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    title: \"Updated title\"\n    description: \"Updated description\"\n    state: \"closed\"     # optional: open | closed\n```\n\nAll body fields are optional — only include what you want to change.\n\n### Step 4: Add reviewers\n\n```\nCall MCP tool: harness_create\nParameters:\n  resource_type: \"pr_reviewer\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    reviewer_id: <numeric_user_id>\n```\n\nList current reviewers with `harness_list(resource_type=\"pr_reviewer\", repo_id, pr_number)`.\n\n### Step 5: Submit a review decision\n\n```\nCall MCP tool: harness_execute\nParameters:\n  resource_type: \"pr_reviewer\"\n  action: \"submit_review\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    decision: \"approved\"          # approved | changereq\n    commit_sha: \"<sha>\"           # optional — the commit you reviewed\n```\n\n### Step 6: Post a comment\n\n**Top-level comment:**\n\n```\nCall MCP tool: harness_create\nParameters:\n  resource_type: \"pr_comment\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    text: \"LGTM with one nit — see inline.\"\n```\n\n**Inline code comment:**\n\n```\nCall MCP tool: harness_create\nParameters:\n  resource_type: \"pr_comment\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    text: \"This loop can leak if the context is cancelled.\"\n    path: \"scheduler/queue.go\"\n    line_new: 142\n    source_commit_sha: \"<source_sha>\"\n    target_commit_sha: \"<target_sha>\"\n```\n\nUse `line_old` for comments on removed lines.\n\n### Step 7: Read comments — use `pr_activity`, not `pr_comment`\n\nThe Harness Code API does **not** expose `GET` on `/comments`. To read the discussion, list PR activity filtered by kind:\n\n```\nCall MCP tool: harness_list\nParameters:\n  resource_type: \"pr_activity\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  kind: \"comment\"        # just comments (general + code)\n  # or type: \"code-comment\" for inline code review comments only\n```\n\nOther useful `type` filters: `review-submit`, `reviewer-add`, `state-change`, `merge`, `title-change`.\n\n### Step 8: Edit or delete a comment\n\n```\nCall MCP tool: harness_update\nParameters:\n  resource_type: \"pr_comment\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  comment_id: <numeric_comment_id>\n  body:\n    text: \"Updated comment body\"\n```\n\n```\nCall MCP tool: harness_delete\nParameters:\n  resource_type: \"pr_comment\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  comment_id: <numeric_comment_id>\n```\n\n### Step 9: Inspect CI checks\n\n```\nCall MCP tool: harness_list\nParameters:\n  resource_type: \"pr_check\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n```\n\nReturns the status of each status check (pipeline, test run, external check) associated with the PR head commit. Use this before merging to confirm required checks are green.\n\n### Step 10: Merge\n\n```\nCall MCP tool: harness_execute\nParameters:\n  resource_type: \"pull_request\"\n  action: \"merge\"\n  repo_id: \"<repo>\"\n  pr_number: <number>\n  body:\n    method: \"squash\"               # merge | squash | rebase | fast-forward\n    delete_source_branch: true\n    dry_run: false\n    source_sha: \"<expected_sha>\"   # optional optimistic lock\n```\n\nSet `dry_run: true` first to preview the merge without executing — useful before destructive merges.\n\n## Examples\n\n### Open a PR and request a review\n\n```\n/manage-pull-requests\nOpen a PR from feat/new-auth into main titled \"Add OAuth device flow\" on repo platformUI,\nand add user 12345 as a reviewer.\n```\n\n### Read all unresolved comments on a PR\n\n```\n/manage-pull-requests\nShow me every inline code comment on PR 182 in repo harness-core so I can address them.\n```\n\n### Approve and merge\n\n```\n/manage-pull-requests\nApprove PR 47 in repo mcp-server with a \"LGTM\" comment, then squash-merge it and delete the branch.\n```\n\n### Check CI before merging\n\n```\n/manage-pull-requests\nList the checks on PR 99 in repo harness-cli. If they're all green, merge it with a squash.\n```\n\n### Close a stale PR\n\n```\n/manage-pull-requests\nClose PR 22 in repo harness-skills with a comment explaining we're going in a different direction.\n```\n\n## Performance Notes\n\n- **Always pass `repo_id` + `pr_number` together** except for `harness_list(pull_request)` which only needs `repo_id`. Missing `pr_number` on per-PR calls returns a helpful 400 from the server.\n- **Read comments via `pr_activity`, never `pr_comment`.** The comments endpoint is POST-only. Use `kind=comment` for all discussion, `type=code-comment` for inline only.\n- **Use `dry_run: true` on merge** before destructive squash/rebase merges — especially on main branches with required checks.\n- **Prefer the URL shortcut** when the user pastes a PR link. `url=\"<PR URL>\"` auto-extracts `org_id`, `project_id`, `repo_id`, and `pr_number` — fewer args to get wrong.\n- **`pr_reviewer.submit_review`** records a review independently of the reviewer list. You don't need to call `harness_create(pr_reviewer)` first to submit a review — any user with access can review.\n- **Cross-scope search**: `harness_search(query=\"<text>\", resource_types=[\"pull_request\"])` finds PRs across repos when you don't know which repo contains it.\n\n## Troubleshooting\n\n### \"repo_id is required\"\n\nAll PR operations are repo-scoped. Pass the repo identifier (not the repo name) — list repos first with `harness_list(resource_type=\"repository\")` if you're unsure.\n\n### Comments don't show up when I list them\n\n`pr_comment` has no `list`/`get` operations. Use `harness_list(resource_type=\"pr_activity\", kind=\"comment\")` to read the discussion timeline.\n\n### \"GET /comments not found\" / 404 on reading a comment\n\nSame cause as above — the Harness Code API is POST-only for `/comments`. Read via `pr_activity`.\n\n### Review decision rejected\n\nCheck the `decision` value — it must be exactly `\"approved\"` or `\"changereq\"`. The API does not accept `\"approve\"` (no `d`) or `\"request_changes\"`.\n\n### Merge fails with \"source SHA mismatch\"\n\nYou passed `source_sha` and it no longer matches the branch head (someone pushed after you computed it). Drop `source_sha` or re-fetch the PR to get the current `source_sha`.\n\n### Inline comment has no diff context\n\nInline code comments need both `source_commit_sha` and `target_commit_sha` in the body — without them the comment appears as a top-level comment. Get the SHAs from `harness_get(pull_request)` → `source_sha` / `target_sha`.\n\n### Required checks aren't passing but merge succeeded anyway\n\n`harness_execute(action=merge)` bypasses branch protection if the caller has admin rights. Use `harness_list(resource_type=\"pr_check\")` first and fail fast in automation if any check is not `success`.","tags":["manage","pull","requests","harness","skills","agent-skills","agents"],"capabilities":["skill","source-harness","skill-manage-pull-requests","topic-agent-skills","topic-agents"],"categories":["harness-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/harness/harness-skills/manage-pull-requests","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add harness/harness-skills","source_repo":"https://github.com/harness/harness-skills","install_from":"skills.sh"}},"qualityScore":"0.457","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 15 github stars · SKILL.md body (9,242 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:06:30.597Z","embedding":null,"createdAt":"2026-05-09T01:05:29.262Z","updatedAt":"2026-05-18T19:06:30.597Z","lastSeenAt":"2026-05-18T19:06:30.597Z","tsv":"'-1234':333 '/comments':559,1125,1146 '/manage-pull-requests':772,802,825,851,877 '/ng/account/.../pulls/42':248 '1':251 '10':710 '12345':791 '142':525 '182':811 '2':301 '22':880 '3':350 '4':393 '400':928 '404':1128 '47':828 '5':428 '6':463 '7':541 '8':619 '9':663 '99':857 'accept':1169 'access':338,1034 'across':1050 'action':67,96,443,722,1270 'activ':17,137,546,566,579,936,1116,1150 'add':88,334,394,610,781,789 'address':820 'admin':1279 'alway':899 'anyway':1267 'api':553,1140,1166 'app.harness.io':247 'app.harness.io/ng/account/.../pulls/42':246 'appear':1240 'approv':103,452,453,822,826,1162,1170 'aren':1261 'arg':1002 'around':336 'associ':693 'auto':220,990 'auto-extract':219,989 'autom':1293 'bodi':171,317,368,381,410,450,485,510,641,645,728,1235 'branch':325,328,341,343,739,846,973,1192,1273 'bypass':1272 'call':183,257,286,305,354,396,433,471,496,570,625,646,667,712,924,1021 'caller':1277 'cancel':520 'caus':1134 'chang':391,613,617,1175 'changereq':105,454,1164 'check':15,151,155,666,676,687,692,706,847,854,976,1154,1260,1287,1296 'ci':153,665,848 'cli':862 'close':273,376,379,873,878 'code':10,118,494,552,589,593,597,807,955,1139,1222 'code-com':592,954 'comment':14,110,119,123,126,130,133,147,466,470,480,495,505,536,543,549,585,587,594,599,624,634,639,644,655,660,798,808,837,888,933,939,941,949,956,1094,1104,1118,1132,1216,1223,1239,1246 'commit':455,459,527,530,698,1227,1231 'comput':1198 'condit':321 'confirm':704 'contain':1059 'context':518,1220 'core':816 'creat':49,85,108,169,309,400,475,500,1023 'cross':1038 'cross-scop':1037 'current':414,1212 'd':1172 'decis':432,451,1152,1156 'delet':128,131,622,650,737,844 'descript':63,330,346,372,374 'destruct':762,967 'detail':45 'devic':783 'diff':1219 'differ':895 'direct':896 'discuss':140,563,952,1122 'dri':741,750,961 'drop':1200 'e.g':238 'edit':124,620 'endpoint':942 'especi':970 'everi':182,805 'exact':165,1161 'exampl':764 'except':190,906 'execut':66,95,437,716,759,1269 'explain':889 'expos':556 'extern':691 'extract':221,991 'fail':1177,1290 'fals':743 'fast':735,1291 'fast-forward':734 'feat/new-auth':777 'fetch':282,1206 'fewer':1001 'field':172,382 'filter':36,567,604 'find':254,1048 'first':753,1026,1083,1288 'fix':319 'fix/scheduler-race':326 'flow':784 'forward':736 'found':1127 'full':278 'full-text':277 'general':588 'get':40,43,240,290,557,1004,1108,1124,1210,1247,1252 'go':892 'green':708,867 'har':9,27,39,48,56,65,75,84,94,107,120,127,134,148,159,191,231,239,260,289,308,332,357,399,417,436,474,499,551,573,628,649,670,715,815,861,884,908,1022,1041,1085,1111,1138,1251,1268,1282 'harness-c':860 'harness-cor':814 'harness-skil':883 'head':697,1193 'help':927 'id':186,200,202,204,223,268,297,316,365,407,412,424,447,482,507,581,636,640,657,661,678,725,902,916,993,995,997,1063 'identifi':1076 'includ':386 'independ':1011 'infer':209 'inlin':117,492,493,596,806,958,1215,1221 'inspect':664 'instruct':249 'json':166 'kind':569,584,948,1117 'know':1056 'leak':515 'level':115,469,1245 'lgtm':487,836 'line':523,533,539 'link':987 'list':28,31,76,79,135,149,152,192,252,261,413,418,564,574,671,852,909,1015,1081,1086,1101,1107,1112,1283 'lock':748 'longer':1189 'loop':513 'main':329,779,972 'manag':2,5,8 'manage-pull-request':1 'markdown':348 'match':1190 'mcp':19,20,217,258,287,306,355,397,434,472,497,571,626,647,668,713,832 'mcp-server':831 'merg':68,71,274,614,702,711,723,731,757,763,824,841,850,868,965,969,1176,1265,1271 'merge/squash/rebase/fast-forward':74 'metadata':353 'method':729 'mismatch':1181 'miss':917 'must':1159 'mutex':335 'name':1080 'need':184,198,914,1019,1224 'never':937 'new':54,524 'nit':490 'note':898 'number':47,189,226,299,367,409,426,449,484,509,583,638,659,680,727,904,919,1000 'oauth':782 'old':534 'one':489 'open':52,270,272,302,378,765,773 'oper':1068,1109 'optimist':747 'option':206,271,276,377,384,457,746 'org':201,992 'paramet':237,262,291,310,359,401,438,476,501,575,630,651,672,717 'pass':229,900,1073,1183,1263 'past':984 'path':521 'per':922 'per-pr':921 'perform':897 'pipelin':688 'platformui':787 'post':111,464,945,1143 'post-on':944,1142 'pr':44,55,61,73,77,83,86,93,99,109,122,129,136,150,158,188,225,232,256,285,298,304,352,366,404,408,421,425,441,448,479,483,504,508,545,548,565,578,582,633,637,654,658,675,679,696,726,767,775,801,810,827,856,876,879,903,918,923,935,938,986,999,1024,1067,1103,1115,1149,1208,1286 'pr_reviewer.submit':1006 'prefer':977 'preview':755 'project':203,994 'protect':1274 'prs':32,1049 'pull':3,6,11,29,41,50,58,69,175,194,243,265,294,313,362,720,910,1046,1253 'pull-request':174 'purpos':26 'push':1195 'queri':275,1043 'queue':337 'race':320 're':865,891,1092,1205 're-fetch':1204 'read':138,146,542,561,795,932,1120,1130,1147 'rebas':733 'record':1008 'reject':1153 'remov':538 'repo':35,180,185,199,213,222,267,296,315,364,406,423,446,481,506,580,635,656,677,724,786,813,830,859,882,901,915,996,1051,1058,1062,1071,1075,1079,1082 'repo-scop':179,1070 'repositori':1089 'request':4,7,12,30,42,51,59,70,176,195,244,266,295,314,363,721,769,911,1047,1174,1254 'requir':345,705,975,1065,1259 'resolv':331 'resourc':24,177,241,263,292,311,360,402,419,439,477,502,576,631,652,673,718,1044,1087,1113,1284 'return':681,925 'review':13,78,80,87,90,98,100,106,395,405,411,415,422,431,442,445,461,598,606,609,771,794,1007,1010,1014,1025,1030,1036,1151 'review-submit':605 'reviewer-add':608 'right':1280 'run':690,742,751,962 'schedul':323 'scheduler/queue.go':522 'schema':160,167 'scope':181,1039,1072 'search':280,1040,1042 'see':491 'server':208,218,833,931 'set':749 'sha':456,528,531,745,1180,1185,1202,1214,1228,1232,1256,1258 'shas':1249 'shortcut':215,980 'show':803,1097 'skill':885 'skill-manage-pull-requests' 'someon':1194 'sourc':324,340,526,738,744,1179,1184,1201,1213,1226,1255 'source-harness' 'specif':284 'squash':730,732,840,872 'squash-merg':839 'squash/rebase':968 'stale':875 'state':38,64,269,375,612 'state-chang':611 'status':154,683,686 'step':250,300,349,392,427,462,540,618,662,709 'submit':97,101,429,444,607,1028 'succeed':1266 'success':1299 'support':347 'target':327,342,529,1230,1257 'test':689 'text':279,486,511,642 'timelin':141,1123 'titl':62,318,339,369,371,616,780 'title-chang':615 'togeth':905 'tool':21,23,259,288,307,356,398,435,473,498,572,627,648,669,714 'top':114,468,1244 'top-level':113,467,1243 'topic-agent-skills' 'topic-agents' 'troubleshoot':1061 'true':740,752,963 'type':25,242,264,293,312,361,403,420,440,478,503,577,591,603,632,653,674,719,953,1045,1088,1114,1285 'unresolv':797 'unsur':1093 'updat':57,60,121,170,351,358,370,373,629,643 'url':214,233,236,245,979,988 'use':22,532,544,602,699,760,947,960,1110,1281 'user':790,983,1032 'valu':1157 'via':18,234,934,1148 'want':389 'way':144 'without':758,1236 'wrong':1005","prices":[{"id":"37c84429-ddc8-47ac-ba9e-5839a683f735","listingId":"7d4919d9-af31-43a1-85c0-c0fa6784c2dc","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"harness","category":"harness-skills","install_from":"skills.sh"},"createdAt":"2026-05-09T01:05:29.262Z"}],"sources":[{"listingId":"7d4919d9-af31-43a1-85c0-c0fa6784c2dc","source":"github","sourceId":"harness/harness-skills/manage-pull-requests","sourceUrl":"https://github.com/harness/harness-skills/tree/main/skills/manage-pull-requests","isPrimary":false,"firstSeenAt":"2026-05-09T01:05:29.262Z","lastSeenAt":"2026-05-18T19:06:30.597Z"}],"details":{"listingId":"7d4919d9-af31-43a1-85c0-c0fa6784c2dc","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"harness","slug":"manage-pull-requests","github":{"repo":"harness/harness-skills","stars":15,"topics":["agent-skills","agents"],"license":"apache-2.0","html_url":"https://github.com/harness/harness-skills","pushed_at":"2026-05-13T01:28:28Z","description":"A collection of structured AI agent skills that   enable Claude Code, Cursor, GitHub Copilot, and   other AI coding assistants to create, operate,   debug, and govern Harness CI/CD workflows through   natural language.","skill_md_sha":"660383d3a3a6acc40be9b4eb8809f6ded8b818af","skill_md_path":"skills/manage-pull-requests/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/harness/harness-skills/tree/main/skills/manage-pull-requests"},"layout":"multi","source":"github","category":"harness-skills","frontmatter":{"name":"manage-pull-requests","license":"Apache-2.0","description":">-","compatibility":"Requires Harness MCP server (harness-mcp-v2)"},"skills_sh_url":"https://skills.sh/harness/harness-skills/manage-pull-requests"},"updatedAt":"2026-05-18T19:06:30.597Z"}}