Connecting GitHub
This page assumes you have read MCP servers, which covers adding a server, approving it and what a server can reach.
GitHub publishes an MCP server (MIT, described in its repository as "GitHub's official MCP Server"). This recipe runs the released binary of that server, checks it against a digest so no package manager runs, and lets the session read issues and pull requests and nothing else.
It does not use the other two ways GitHub documents:
- The hosted server at
api.githubcopilot.comneeds anAuthorizationheader, andbravebot mcp add --httpsends none. - The Docker image cannot be used, because a confined server does not reach the Docker daemon.
The server is a Go binary, so nothing else has to be installed. Windows is not covered, because bravebot does not start a server there.
-
Download release v1.12.2 into a directory of its own, check the digest, and unpack it there. Pick the asset for your machine:
Asset sha256 github-mcp-server_Darwin_arm64.tar.gz7e6c5aec43f26b82d3580e77a4ee26872bcd34b48c9a08d0eaef48b5d0563904github-mcp-server_Darwin_x86_64.tar.gz6e73f5c9738050e44318d37aa919cb8ed2e29453d6341e942dc9c40c9c7ced5bgithub-mcp-server_Linux_arm64.tar.gz2b30f9fcc061b57456cbe38ddc0f13c88863bad49557508a9196f2d1c4cb17a5github-mcp-server_Linux_x86_64.tar.gz95843162759da2c31dde082dd145be35db82164594796c294414b69790c2290eASSET=github-mcp-server_Darwin_arm64.tar.gzDIGEST=7e6c5aec43f26b82d3580e77a4ee26872bcd34b48c9a08d0eaef48b5d0563904mkdir -p ~/github-mcp-server && cd ~/github-mcp-servercurl -fLO "https://github.com/github/github-mcp-server/releases/download/v1.12.2/$ASSET"echo "$DIGEST $ASSET" | shasum -a 256 -c # sha256sum -c on Linuxtar -xzf "$ASSET" && rm "$ASSET" -
Create a fine-grained token that can read what you want the session to read and nothing more. Choose Only select repositories and name the repositories, set an expiry, and give it these repository permissions, all Read-only: Issues, Pull requests, and Metadata (GitHub adds that one). Leave every other permission at no access.
-
Declare the server with the token.
read -rskeeps the token out of your shell history and off the screen:read -rs GITHUB_TOKEN_VALUE # paste the token, press Enterbravebot mcp add github -s user \-e GITHUB_PERSONAL_ACCESS_TOKEN="$GITHUB_TOKEN_VALUE" \-- ~/github-mcp-server/github-mcp-server stdio \--read-only --lockdown-mode --toolsets issues,pull_requestsunset GITHUB_TOKEN_VALUEgithub stdio /Users/you/github-mcp-server/github-mcp-server stdio --read-only --lockdown-mode --toolsets issues,pull_requestsvariables: GITHUB_PERSONAL_ACCESS_TOKEN (stored)It then asks whether to use the server, and shows a digest line under these. Answer yes once the lines above are what you expect. The token is stored in
~/.bravebot/mcp.jsonand is shown by its name and never as itself.-s userasks for the server in every session once you answer yes.The three flags are part of what you approve, so they show at the question:
--read-onlyleaves out every tool that writes.--toolsets issues,pull_requestsoffers those two groups of tools and not the server's defaults, which also read repository contents and users.--lockdown-modeis described below.
-
Refuse the tools that write, in
~/.bravebot/settings.json:{"permissions": {"deny": ["Mcp(github:add_comment_to_pending_review)","Mcp(github:add_issue_comment)","Mcp(github:add_reply_to_pull_request_comment)","Mcp(github:create_pull_request)","Mcp(github:issue_write)","Mcp(github:merge_pull_request)","Mcp(github:pull_request_review_write)","Mcp(github:sub_issue_write)","Mcp(github:update_issue_comment)","Mcp(github:update_pull_request)","Mcp(github:update_pull_request_branch)"]}}With
--read-onlythe server does not offer any of them, so these rules matter on the day someone edits the declaration and drops the flag.pull_request_review_writeandmerge_pull_requestare the two that can approve or merge a pull request. Adenyrule holds where no question is asked, answer 2 and--dangerously-skip-permissionsincluded.
The session then offers github:issue_read, github:list_issues, github:search_issues,
github:list_pull_requests, github:pull_request_read, github:search_pull_requests,
github:get_label, github:list_issue_fields and github:list_issue_types. What they return is
private and quarantined, so the model reads an issue or a pull request only through a processor or
after you let it out of quarantine (see vetting).
What you have handed over
- The token reads the issues and pull requests of the repositories you named. It cannot
comment, review, merge, or change anything. Taking it back is deleting it in your
GitHub token settings, and removing the
server with
bravebot mcp remove github. - The token sits in
~/.bravebot/mcp.json. Anything that can read that file as you can use the token until it expires. - Other people write what it reads. On a public repository anyone with an account can file an
issue or comment on one, and the session reads it.
--lockdown-modemakes the server return content on a public repository only from authors who have push access to it. GitHub describes it as a best-effort filter and not a security boundary, and it does not limit what the token can read. - Lockdown needs push access. The server asks GitHub whether each author has push access, and
GitHub answers only a person who has it themselves. Without push access to a repository, a read
of another author's issue fails with
403 Must have push access to view collaborator permission. For a repository you cannot push to, drop--lockdown-modeand accept that the session reads text from strangers, or leave the repository out. git cloneandgit pushare not covered. The server has no tool for either. This recipe offers no tool that reads a repository's files, though a pull request's changed files and diff can be read.- You update it yourself. The directory holds the release you checked. A newer release is
downloaded and checked the same way, against the digest in its own
checksums.txt.