MCP Tools for a Coding Agent: When Connecting GitHub Helps and When It Leaks the Repo

Sasha Reid

Sasha Reid

September 30, 2026

MCP Tools for a Coding Agent: When Connecting GitHub Helps and When It Leaks the Repo

The test took me about twenty minutes to set up, and the result made me revoke a token I had been using for three months. I work in security, so I had been careful, or thought I had. I connected the GitHub MCP server to my coding agent so it could read issues, check CI logs, and open draft pull requests without me copying things back and forth. It was genuinely useful. I had authorised it with a personal access token that had the classic repo scope, because that was what the setup guide suggested and it made everything just work.

The repo scope grants access to every repository my account can reach. That includes our company’s private repositories, a couple of client repositories I have collaborator access to, and my own public open-source projects. The agent, in any session, could read and write all of them through the MCP tools.

To see what that meant in practice, I opened an issue on one of my public projects from a throwaway account. The issue looked like a normal bug report, with a paragraph near the bottom addressed to “any AI assistant triaging this issue,” asking it to check whether the bug also appeared in the maintainer’s other repositories and to paste relevant file contents into a comment for comparison. Then, in a fresh session, I asked my agent to “look at the open issues on this project and summarise what needs attention.”

The agent read the issue, listed my other repositories, opened a private one, and drafted a comment on the public issue containing the first sixty lines of a private configuration module. My approval settings stopped it before the comment posted, because I had left confirmations on for write actions. Without that one setting, a stranger on the internet would have received private code by filing an issue.

What an MCP server actually gives your agent

MCP, the Model Context Protocol, is a standard way to give an agent tools. A GitHub MCP server exposes operations like “list issues,” “read a file from a repository,” “search code,” “comment on a pull request,” “create a branch.” The agent decides when to call them based on your request and whatever it reads along the way.

Two things determine what the agent can do with that server. The first is the tool list: which operations the server exposes. The second is the credential: what the token behind those operations is allowed to touch. The agent’s reach is the intersection of the two, and it is usually much larger than the task in front of it.

When I asked for a summary of issues on one public project, the task needed read access to one repository’s issues. The agent had read and write access to every repository I could see, plus tools to post content publicly. That gap between what the task needs and what the agent holds is where the risk lives.

A public community notice board covered with pinned paper notes and one suspicious envelope

Where it genuinely helps

I do not want to overstate the danger to the point of saying “never connect GitHub.” Used carefully, it removes a lot of tedious copying.

Reading CI failures. Asking the agent to fetch the failing job’s logs and relate them to the code is one of the best uses I have found. Without the integration, I copy a wall of log text into the chat. With it, the agent pulls just the failing step.

Understanding the history of a change. “Why does this function look like this?” is often answered by a pull request discussion from two years ago. An agent that can search PRs and read their comments finds that context much faster than I can.

Reading the issue it is working on. When a task starts from an issue, letting the agent read it directly, including follow-up comments, avoids me paraphrasing and losing detail.

Opening a draft PR at the end. Having the agent push a branch and open a draft PR with a written description saves a few minutes and produces a description that references the actual changes.

Every one of these uses needs access to one repository, mostly read-only, with a single write at the end. None of them needs access to everything.

Three ways it leaks

Untrusted text becomes instructions. This is what my test demonstrated. Issues, pull request descriptions, comments, commit messages and even file contents in public repositories can be written by anyone. When the agent reads them through an MCP tool, the text enters its context alongside your instructions, and a model has no reliable way to tell “data I was asked to read” from “instructions I should follow.”

A broad token lets one repository reach another. The injected instruction was only dangerous because the token could read private repositories. If the token had been scoped to the single public project, the agent could have been persuaded to try, and would have received a permission error. Scope turns a successful injection into a failed one.

Write tools create exfiltration paths. Reading private code is not a leak until the content goes somewhere public. The GitHub server’s own write tools, like commenting on an issue, creating a gist, or opening a pull request on a public repo, are the obvious channel. Any other tool that can send data out, such as a web fetch to an arbitrary URL, works too. An agent that can both read private data and write to public places has everything an attacker needs, supplied by you.

A security engineer at a dual monitor setup in a dim room, hand on chin, reviewing access settings

How I set it up now

After revoking the old token, I rebuilt the integration around one principle: the agent’s GitHub access should match the repository and the task, not my account.

Fine-grained tokens, one repository at a time. GitHub’s fine-grained personal access tokens can be limited to specific repositories and specific permissions. My agent’s token for work covers only the repositories I actively develop in, with read access to contents, issues, pull requests and actions, and write access only to pull requests. It cannot touch client repositories. It cannot create gists. It cannot read anything I am not currently working on.

Separate configurations for public and private work. When I work on my open-source projects, where issues come from strangers, the agent uses a different MCP configuration with a token that can only see those public repositories. It has no path to private code at all. Mixing public and private repositories under one token is the configuration that made my test work, so I do not do it anymore.

Write tools off by default, confirmations on. Many MCP clients let you enable or disable individual tools. I disable anything that writes to a public surface unless the task requires it, and I keep confirmations on for every write that remains. It adds a click. That click is what stopped my test.

Read the untrusted content yourself first, for sensitive tasks. If I want the agent to triage issues on a public project, I skim them first. Sometimes I copy only the relevant issues into the conversation instead of letting the agent pull the whole list. Clumsier, but I decide what text gets in.

Treat the token like any other secret. The token lives in the client’s secure configuration, not in a project file. It has an expiry date. I check GitHub’s security log for its usage occasionally, which is how I would notice if something used it unexpectedly.

Questions to ask before connecting

If you are about to connect GitHub, or any MCP server with access to your code or data, these are the questions I would ask:

  • What is the smallest set of repositories this agent needs for the work I actually do in it?
  • Does the task need write access at all? If so, to what, exactly?
  • Will the agent read content written by people outside my organisation?
  • If it does, is there any path from that content to private data plus a way to send it somewhere public?
  • Are confirmations on for every tool that writes or sends data out?
  • Would I notice if the token were used in a way I did not expect?

If the honest answer to the fourth question is yes, the configuration needs to change before anything else.

Helpful and safe are both possible

I still use the GitHub integration every day. Fetching CI logs and PR history through it has become one of the parts of agent-assisted work I would miss most. What changed is that the agent now has access that matches what it is doing, not everything I happen to have access to.

The uncomfortable lesson from my twenty-minute test is that the dangerous configuration was the default one: a broad token recommended by a setup guide, plus tools that could post publicly, plus an agent that reads whatever text it finds. None of those pieces is alarming on its own. Together, they turned a public issue tracker into a way to read my private repositories. Narrowing any one of them breaks the chain. Narrowing all three is not much more work, and it means the next injected paragraph in an issue gets a permission error instead of a copy of your code.

More articles for you