Skip to content

lukewo/github-cli

v2.0.0MIT

GitHub and git integration driven by the GitHub CLI (gh) and git. Runs a local MCP server for the full pull request review lifecycle from both sides - as a reviewer (read diffs, reviews and threads, list review requests, approve/request-changes/comment, inline comments, replies, resolve threads) and as an author (create/edit PRs, request reviewers, mark ready, check CI, merge) - plus read tools for issues and PRs, and local git operations (status, log, diff, branch, add, commit, push, pull, fetch, merge, stash, checkout) against the open workspace repo. Uses your existing gh authentication (no tokens stored by the power). Reads and writes, with two safety boundaries: a command allow-list and a deny check that refuses history rewrites (force push), destructive local loss (reset --hard, clean, branch -D), gh auth/config changes, and merges without explicit confirmation.

GitHub CLI Power (reviews + git)

Drive the full GitHub pull request review lifecycle and your local git workflow from Kiro, through the GitHub CLI (gh) and git. It runs a small local MCP server that shells out to gh and git, reusing your existing gh login - no tokens are stored by the power and there is no config file to fill in.

This power reads and writes. It replaces the earlier read-only version: it can now submit reviews, post comments, create and edit PRs, merge (with confirmation), and run local git operations - not just fetch context.

What it can do

Read (issues, PRs, context)

ToolWhat it does
get_issueFetch one issue by number and save it to .github-items/ as Markdown with comments. Runs gh issue view.
get_pull_requestFetch one PR (state, branches, diff stats, review decision, merge state, body, comments), saved the same way. Runs gh pr view.
search_issuesSearch issues and PRs with GitHub search syntax. Runs gh search issues.
list_pull_requestsList a repo's PRs by state. Runs gh pr list.
get_issue_commentsFetch an issue's or PR's comments as plain text.
get_pr_diffFetch a PR's unified diff (capped for large PRs). Runs gh pr diff.
get_pr_filesList a PR's changed files with per-file additions/deletions and change type. Runs gh pr view --json files.
get_pr_reviewsFetch submitted reviews plus inline review threads with resolved/outdated state and each thread's comments. Runs gh api graphql.
get_pr_checksCI/status checks for a PR with a pass/fail/pending rollup. Runs gh pr checks.
list_review_requestsOpen PRs awaiting your review (the reviewer inbox). Runs gh search prs review-requested:@me.
get_repoRepository metadata: default branch, description, visibility, URLs. Runs gh repo view.

Review a PR (reviewer perspective) - writes

ToolWhat it does
create_pr_reviewApprove, request changes, or comment on a PR (body required for the latter two). Runs gh pr review.
add_pr_review_commentPost an inline comment on a specific file/line of the diff. Runs gh api.
reply_to_review_commentReply to an existing inline comment thread by comment id. Runs gh api.
resolve_review_threadMark an inline review thread resolved by its thread id. Runs gh api graphql.
add_issue_commentPost a top-level (non-inline) comment on an issue or PR. Runs gh issue comment / gh pr comment.

Author a PR (author perspective) - writes

ToolWhat it does
create_prOpen a new PR (title, body, base, head, draft). Runs gh pr create.
update_prEdit title/body/base and/or mark ready for review. Runs gh pr edit / gh pr ready.
request_reviewersRequest reviewers by login or org/team. Runs gh pr edit --add-reviewer.
merge_prMerge a PR (merge/squash/rebase). Only runs with confirm: true. Runs gh pr merge.

resolve_review_thread and the read tools work from either perspective - an author replying to feedback uses the same reply_to_review_comment and resolve_review_thread a reviewer uses.

Bridge review and local code

ToolWhat it does
pr_checkoutCheck out a PR's branch into the local workspace repo, so its code can be run and inspected. Writes a local branch (reversible). Runs gh pr checkout.

Local git - reads and writes

Operating on the git repository in your open workspace (or an explicit repoDir):

ToolWhat it does
git_statusCurrent branch and staged/unstaged/untracked files.
git_logRecent commits (hash, author, date, subject).
git_diffWorking-tree or staged diff, optionally by path, or --stat only.
git_branchList branches, or create/switch (create:true makes a new branch).
git_checkoutCheck out an existing branch/tag/commit (never forced).
git_addStage changes (all, or specific paths).
git_commitCommit with a message (all:true stages tracked changes first).
git_pushPush; setUpstream:true publishes a new branch with tracking.
git_pullFetch and integrate, optionally rebase.
git_fetchDownload refs without merging, optionally prune.
git_mergeMerge a ref into the current branch, optionally --no-ff.
git_stashpush (save), list, pop, apply.
git_showShow a commit (message + diff), or a file's contents at a ref.
git_blameLine-by-line authorship for a file, optionally a line range.
git_diff_refsDiff between two refs/branches (three-dot from...to).
git_repo_infoCurrent branch, upstream, origin URL, and ahead/behind counts.

Safety boundary

The write surface is deliberately bounded in two layers, enforced in code (server/src/gh-client.js and server/src/git-client.js):

  1. Command allow-list - only the specific gh and git subcommands the tools use can run at all. Anything else is refused.
  2. Deny check - even within the allow-list, these are refused with a clear reason:
    • Force push (push --force / --force-with-lease) - rewrites shared history.
    • Destructive local loss - git reset, git clean, checkout/switch --force, branch -D, stash drop/clear.
    • gh auth / gh config changes - the power never alters how you are authenticated or configured.
    • Merge without confirmation - merge_pr refuses unless you pass confirm: true.
    • DELETE via gh api and writes to user/orgs/settings/admin API endpoints.

Everything runs through execFile with an argument array (never a shell string), so repo names, branch names, queries and comment bodies cannot break out into shell execution.

If you need one of the excluded operations (a force push, a hard reset), do it yourself in a terminal - the power intentionally will not.

Which repository do git tools act on?

Git tools operate on the git repository in the workspace folder Kiro currently has open, detected from Kiro's window state. You can override this per call with repoDir (an absolute path). If no repo can be determined, or the directory is not a git work tree, the tool returns a clear error rather than guessing.

The gh tools take an optional repo as OWNER/REPO (e.g. cli/cli) or a github.com URL, validated against a strict pattern before it reaches gh. A few operations that use the API directly (inline comments, replies) require an explicit repo.

Fetched items are saved into your workspace

get_issue and get_pull_request write the fetched item into a .github-items/<OWNER-REPO-NUMBER>/ folder in the open workspace (git-ignored), as Markdown with the body and comments. The other tools do not save to disk.

Prerequisites

  • The GitHub CLI (gh) installed and on PATH (cli.github.com).
  • Authenticated: run gh auth login once (verify with gh auth status).
  • git installed and on PATH.
  • Node.js 18+ to run the bundled server.

The power ships a prebuilt, self-contained server bundle (server/dist/index.js), so there is no npm install at install time.

Setup

Nothing to configure. Once gh is installed and you have run gh auth login, install the power and reconnect the github-cli server in Kiro's MCP Servers panel. On startup the server runs gh auth status; if gh is missing or you are not logged in, it exits with a message telling you exactly what to do.

Verifying it works

  1. In the MCP Servers panel, github-cli should be connected and list the read, review, author and git_* tools.
  2. Read: "get PR 1 from cli/cli" or "show the diff of PR 1 in cli/cli".
  3. Reviewer inbox: "list PRs awaiting my review".
  4. Local git: "what's my git status" (with a git project open).

Troubleshooting

  • Server exits at startup - the message names the cause: gh not on PATH (install it), or not logged in (run gh auth login, then reconnect).
  • A git tool says "Not a git repository" - open a git project in Kiro, or pass repoDir explicitly.
  • A write was "Refused: ..." - it hit the safety boundary above. That is by design; perform the excluded operation manually if you really intend it.
  • See the real error - run the bundled server directly:
    cd server
    node dist/index.js
    
    A clean start prints [github-cli] read/write MCP server started (gh + git).

Security notes

  • The power stores no credentials. Authentication is entirely gh's, so it can only touch what your gh login already can.
  • Read/write is bounded by the allow-list and deny check described above, and all commands run via execFile argument arrays (no shell).
  • Fetched items under .github-items/ are git-ignored local cache; delete the folder any time.

Building from source (maintainers)

The power ships the prebuilt bundle at server/dist/index.js. If you change anything under server/src/, rebuild before committing:

cd server
npm install   # one-time, installs build-time dependencies
npm run build # regenerates server/dist/index.js

The build uses esbuild to produce a single self-contained ESM file.