Cursor With the GitHub MCP Server

How to add GitHub’s official MCP server to Cursor: the hosted server with a token read from your environment, or the local one with a browser sign-in; a read-only entry beside a read-write one; and what to ask first.

6 min read

To use GitHub from Cursor’s agent, add GitHub’s hosted MCP server, https://api.githubcopilot.com/mcp/, to ~/.cursor/mcp.json with a personal access token in the Authorization header, and have Cursor read the token from an environment variable rather than the file. GitHub’s Cursor installation guide (opens in a new tab) says the hosted server currently needs a token in Cursor, even though Cursor supports OAuth for some servers, and that Streamable HTTP needs Cursor 0.48.0 or later. If you would rather sign in through the browser, run GitHub’s server locally in Docker instead. Either way, add a second, read-only entry and keep the read-write one switched off until you want it.

This guide is about the connection in Cursor. What the server’s toolsets cover, including GitHub Projects, and how it behaves in the terminal, is in Claude and the GitHub MCP server; it is not repeated here.

The MCP server is not Cursor’s GitHub app

Cursor has its own GitHub connection, and it does a different job. Cursor’s GitHub integration (opens in a new tab) is a GitHub app that connects your repositories for Cursor’s Cloud Agents and Bugbot, which work on repositories in the cloud and review pull requests. The GitHub MCP server brings GitHub into the agent you are chatting with in the editor: it can read an issue, look up a pull request’s review comments or open a new issue while it works on your local checkout. You can have both; they do not share a credential.

Step 1: make a narrow token

Create a fine-grained personal access token. GitHub’s token documentation (opens in a new tab) recommends fine-grained tokens over classic ones wherever possible, because they can be limited to chosen repositories and given specific permissions, and it recommends an expiry on every token. For a first week, give it read access to issues, pull requests and contents on the repositories you work in, and nothing else.

The same page lists what fine-grained tokens cannot do, and one gap matters here: they cannot reach Projects owned by a user account. If you want the agent on a personal Project, you need a classic token for that, with the broader reach that comes with one.

Step 2: add it to mcp.json

Cursor’s MCP documentation (opens in a new tab) reads servers from ~/.cursor/mcp.json for every project and .cursor/mcp.json for one project, and resolves ${env:NAME} in the url and headers fields. That means the file can name the variable and your shell profile can hold the token, so the file is safe to commit and each person uses their own token.

~/.cursor/mcp.json
{
  "mcpServers": {
    "github-readonly": {
      "url": "https://api.githubcopilot.com/mcp/readonly",
      "headers": {
        "Authorization": "Bearer ${env:GITHUB_PAT}"
      }
    },
    "github": {
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer ${env:GITHUB_PAT}",
        "X-MCP-Toolsets": "context,repos,issues,pull_requests"
      }
    }
  }
}

Set GITHUB_PAT in your shell profile and restart Cursor completely so it sees the variable. Then open Customize in the sidebar, where the two servers appear, and switch github off. GitHub’s guide suggests checking the result by asking the agent to list your repositories.

Step 3: choose what it can see

The hosted server is configured by address and by header. GitHub’s remote server reference (opens in a new tab) lists the paths: /readonly for read tools only, /x/issues for a single toolset, /x/issues/readonly for that toolset read-only, and /x/all for everything. The headers do the same job for lists: X-MCP-Toolsets takes several toolsets, X-MCP-Tools names single tools, and X-MCP-Readonly: true strips write tools.

  • Keep the list short. Fewer tools means the agent picks the right one more often and spends less of its context reading tool descriptions.
  • Read-only by address is easier to audit than read-only by header: anyone reading mcp.json sees /readonly in the URL.
  • Working on public repositories where anyone can write an issue? Add X-MCP-Lockdown: true, which hides public issue content from people without push access. GitHub describes it as a filter, not a security boundary.

Approvals: what to let run

Cursor asks before it uses an MCP tool unless you have allowlisted it. Because github-readonly has no write tools, it is safe to allow all of it, and Cursor’s permissions reference (opens in a new tab) lets you pin that in a permissions.json file in ~/.cursor/ or the project’s .cursor/ folder, with server:* meaning every tool on one server.

.cursor/permissions.json
{
  "mcpAllowlist": [
    "github-readonly:*"
  ]
}

Leave the read-write server on ask. A request to create an issue or comment on a pull request should show you its arguments before it runs, and a merge should never be a tool call you skim past.

The local server, with a browser sign-in

GitHub’s guide gives a second route: run the same server on your machine in Docker. On github.com the official image carries its own app credentials, opens a browser sign-in on first use and keeps the token in memory, so there is nothing to create or store. It needs Docker running and a fixed callback port on loopback:

~/.cursor/mcp.json (local, OAuth)
{
  "mcpServers": {
    "github-local": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-p", "127.0.0.1:8085:8085",
               "-e", "GITHUB_OAUTH_CALLBACK_PORT",
               "ghcr.io/github/github-mcp-server"],
      "env": { "GITHUB_OAUTH_CALLBACK_PORT": "8085" }
    }
  }
}

Toolsets and read-only mode move to environment variables on the local server, such as GITHUB_TOOLSETS and GITHUB_READ_ONLY. GitHub Enterprise Server can only use the local route. Cursor also offers a Marketplace for one-click installs from Customize; whichever way you install, check which address the entry points at and how it signs in.

Sharing the setup with a team

Move the two entries into the repository’s .cursor/mcp.json and commit it. Because the file only names GITHUB_PAT, nobody’s token is in it: each person creates their own fine-grained token, limited to the repositories they work on, and sets the variable on their own machine. Changes the agent makes then carry the name of whoever was driving, which is what a reviewer expects to see. On Cursor’s Enterprise plan, admins can also decide from the Cursor dashboard which MCP servers and tools the team may run at all, so a shared read-only default can be enforced rather than only suggested.

What to try first

Start with reads that save you a browser tab while you are in the code. With github-readonly on:

  • “Read issue 412 in this repository and list the files you think the fix touches.” The agent reads the issue, then your checkout.
  • “Summarise the unresolved review comments on pull request 88 and tell me which are in files I have open.”
  • “Which open issues labelled bug mention the payments module? Oldest first.”
  • Then one write, with github switched on: “Open an issue for the TODO on line 40 of retry.ts, titled from the comment, with the bug label.” Read the arguments before you approve.

When it does not work

  • No tools appear: validate the JSON, then quit and restart Cursor, not just the window.
  • Authentication fails: the variable is empty in Cursor’s environment, or the token lacks access to that repository. Organisations can also restrict or require approval for fine-grained tokens.
  • Streamable HTTP errors: update Cursor to 0.48.0 or later.
  • A guide tells you to install @modelcontextprotocol/server-github: that npm package has not been supported since April 2025. Use GitHub’s server.

When the work is not all on GitHub

GitHub’s server works as you: a change the agent makes shows under your name, and anyone who needs to see the work needs a GitHub account and access to the repository. If the people on the work include a client or a colleague who never opens GitHub, fenbs is a simpler board Cursor connects to the same way: one URL in mcp.json, a browser sign-in, your role narrowed by the scopes you tick, and every change recorded under the assistant’s name. The code stays on GitHub; the list of features, enhancements and bugs can live where everyone can read it.

Related

fenbs in Cursor: Cursor integration. Keeping Cursor’s agent on task: Cursor rules for AI projects. The same server from the terminal: Claude and the GitHub MCP server. GitHub Projects compared: fenbs vs GitHub Projects.

Questions people ask.

Can Cursor sign in to GitHub’s hosted MCP server with OAuth?

GitHub’s Cursor guide says the hosted server currently needs a personal access token in Cursor. For a browser sign-in, run GitHub’s server locally in Docker, which opens a GitHub login on first use and keeps the token in memory.

Where should the GitHub token go?

In an environment variable set in your shell profile, referenced from mcp.json as env:GITHUB_PAT inside a dollar-brace placeholder. Cursor resolves it in the url and headers fields, so the token never sits in a file you might commit.

How do I make the GitHub MCP server read-only in Cursor?

Point the entry at https://api.githubcopilot.com/mcp/readonly, or send the header X-MCP-Readonly with the value true. On the local server, set GITHUB_READ_ONLY. A read-only token adds a second layer.

Is this the same as Cursor’s Bugbot or Cloud Agents?

No. Those use Cursor’s GitHub app to work on repositories in the cloud. The MCP server gives the agent in your editor tools to read and change GitHub while it works on your local code.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.