Interact with GitHub repositories, pull requests, issues, and workflows using the GITHUB_TOKEN environment variable and GitHub CLI...
Use authenticated GitHub MCP tools first when they are available in the agent's environment. Detect this by tool availability, without depending on a particular MCP server name. Use the token and direct API instructions below only when GitHub MCP tools are unavailable or when raw API or curl access is explicitly needed.
You have access to an environment variable, GITHUB_TOKEN, which allows you to interact with
the GitHub API.
Windows PowerShell equivalents for the multi-line shell snippets below are in references/windows.md.
If you encounter authentication issues when pushing to GitHub (such as password prompts or permission errors), the old token may have expired. In such case, update the remote URL to include the current token: git remote set-url origin https://${GITHUB_TOKEN}@github.com/username/repo.git
Here are some instructions for pushing, but ONLY do this if the user asks you to:
main or master branchopenhands-workspace. Create a new branch with a better name before pushing.create_pr tool to create a pull request, if you haven't alreadygit remote -v && git branch # to find the current org, repo and branch
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
Use the show-me skill when writing or updating a PR description. If it is not
available: pick the smallest visual that makes the change clear instead of requiring
the user to reconstruct it from prose or the raw diff.
IMPORTANT: Only merge if the user asks you to, without ambiguity.
GitHub released an async merge API in October 2026; it is now the
recommended way to merge PRs programmatically, and the only merge API that supports stacked PRs. It can also add a PR to a merge queue.
Prefer it over PUT .../pulls/{n}/merge and the GraphQL mergePullRequest mutation.
A GitHub MCP merge tool may still use the older synchronous endpoint; for stacked PRs or merge queues, use the calls below.
Docs: https://docs.github.com/en/rest/pulls/pulls#merge-a-pull-request-asynchronously
merge_action: default uses the merge queue if the branch has one, else merges directly; or direct_merge / merge_queue). merge_method, commit_title and commit_message apply only to direct merges:gh api -X PUT repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/merge-async -f merge_method=squash -f sha=<HEAD_SHA>
202 returns details.uuid; poll it every few seconds until status is no longer pending:gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/merge-async/<UUID>
Final status is merged, enqueued (added to the merge queue, NOT merged yet), or failed (see details.message).
A 200 on the PUT means the PR is already merged or queued; a 409 means a merge request is already pending (its UUID is returned).
To resolve existing review threads programmatically:
<OWNER>, <REPO>, <PR_NUMBER>):gh api graphql -f query='
{
repository(owner: "<OWNER>", name: "<REPO>") {
pullRequest(number: <PR_NUMBER>) {
reviewThreads(first: 20) {
nodes {
id
isResolved
comments(first: 1) {
nodes { body }
}
}
}
}
}
}'
gh api graphql -f query='
mutation {
addPullRequestReviewThreadReply(input: {
pullRequestReviewThreadId: "<THREAD_ID>"
body: "Fixed in <COMMIT_SHA>"
}) {
comment { id }
}
}'
gh api graphql -f query='
mutation {
resolveReviewThread(input: {threadId: "<THREAD_ID>"}) {
thread { isResolved }
}
}'
# Find the run ID from the failed check URL, or use:
gh run list --repo <OWNER>/<REPO> --branch <BRANCH> --limit 5
# Rerun failed jobs
gh run rerun <RUN_ID> --repo <OWNER>/<REPO> --failed