# MCP Servers for Coding Agents: Claude Code and Codex

> Add an MCP server to Claude Code and Codex from the docs, with a worked read-only GitHub server setup and the permissions to set.

- Source: https://www.zarifautomates.com/blog/mcp-servers-for-coding-agents
- Published: 2026-09-26
- Updated: 2026-09-26
- Pillar: Agents & AI Engineering
- Tags: Claude Code, codex, mcp, AI Coding, ai coding tools
- Author: Zarif

---

An MCP server gives a coding agent tools it doesn't ship with: read an issue, query a database, open a pull request. The protocol is the same across clients, so one server works in Claude Code, Codex, and Cursor. The setup commands and config files are not the same, and neither are the permission controls.

If MCP is new to you, read [what Model Context Protocol is](/blog/what-is-model-context-protocol-mcp) first. This page is the practical half: add one server to each tool, keep the token out of the repo, and decide what the agent may do without asking. Every command below comes from the vendor docs as of September 26, 2026.

## Adding a server to Claude Code

Claude Code has one command with two transports ([Claude Code MCP docs](https://code.claude.com/docs/en/mcp)):

```bash
# Remote server over HTTP
claude mcp add --transport http <name> <url>

# Local server started as a process; everything after -- is the server's command
claude mcp add --transport stdio <name> -- <command> [args...]
```

The `--` matters. Without it, Claude Code tries to read the server's flags as its own.

The `--scope` flag decides who gets the server:

| Scope | Stored in | Who sees it |
|---|---|---|
| `local` (default) | `~/.claude.json`, under this project | You, in this project |
| `project` | `.mcp.json` at the repo root | Everyone who clones the repo |
| `user` | `~/.claude.json` | You, in every project |

A project-scoped `.mcp.json` looks like this:

```json
{
  "mcpServers": {
    "server-name": {
      "type": "http",
      "url": "https://example.com/mcp"
    },
    "local-server": {
      "command": "npx",
      "args": ["-y", "some-mcp-server"]
    }
  }
}
```

Interactive sessions ask for approval before using a server from a project's `.mcp.json`. That prompt is the safeguard against a repo you cloned quietly wiring in a server. Note the exception from the [non-interactive docs](https://code.claude.com/docs/en/headless): a `claude -p` run connects the servers in `.mcp.json` without a prompt, even in a folder you've never trusted, unless you pass `--bare`.

Manage servers with `claude mcp list`, `claude mcp get <name>`, and `claude mcp remove <name>`. Inside a session, `/mcp` shows status and handles OAuth sign-in for servers that need it.

## Adding a server to Codex

Codex keeps servers in `config.toml`, either `~/.codex/config.toml` for you or `.codex/config.toml` in a project ([Codex MCP docs](https://developers.openai.com/codex/mcp)). The CLI writes the same entries:

```bash
codex mcp add context7 -- npx -y @upstash/context7-mcp
```

A stdio server takes `command`, `args`, and `env`. An HTTP server takes `url` and, for a bearer token, `bearer_token_env_var`, which names an environment variable rather than holding the token. For servers that use OAuth, run `codex mcp login <server-name>`.

Codex has per-server controls that Claude Code handles elsewhere:

- `enabled_tools` and `disabled_tools`: an allow list or deny list of the server's tools.
- `startup_timeout_sec` (default 10) and `tool_timeout_sec` (default 60).
- `default_tools_approval_mode`: the default approval behavior for that server's tools.

`/mcp` in the Codex TUI lists connected servers.

## Worked example: GitHub's MCP server, read-only

GitHub publishes an official server with a hosted endpoint at `https://api.githubcopilot.com/mcp/` ([github/github-mcp-server](https://github.com/github/github-mcp-server)). It's a good first server because it's public, maintained, and you already know what the data should look like.

The target: both agents can read issues and pull requests in your repositories, and neither can write anything.

**Step 1. Create a token with narrow scope.** The server's install guide recommends least privilege: add scopes only when a tool request fails for lack of permission. Its suggested minimum for a classic token starts with `repo`, which includes write access. For a read-only setup, a fine-grained token limited to the repositories you need, with read-only permissions, is the narrower choice, and read-only mode on the server backs it up.

**Step 2. Keep the token out of Git.** Put it in your shell environment or a gitignored `.env`, never in a committed config file. Both install guides say the same.

```bash
export GITHUB_PAT="github_pat_..."
```

**Step 3a. Claude Code.** The server's [Claude install guide](https://github.com/github/github-mcp-server/blob/main/docs/installation-guides/install-claude.md) gives this command for current Claude Code versions. The extra `X-MCP-Readonly` header is the server's documented switch for read-only mode on the remote endpoint:

```bash
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer '"$GITHUB_PAT"'","X-MCP-Readonly":"true"}}'
```

That stores the server at local scope with the token's value written into `~/.claude.json` on your machine, outside the repo. To share the setup with a team instead, commit a `.mcp.json` that references the variable, since the Claude Code docs support `${VAR}` expansion in that file:

```json
{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp",
      "headers": {
        "Authorization": "Bearer ${GITHUB_PAT}",
        "X-MCP-Readonly": "true"
      }
    }
  }
}
```

Each teammate sets their own `GITHUB_PAT`. The committed file never holds a secret.

**Step 3b. Codex.** The server's Codex guide gives this for `~/.codex/config.toml`, and the `http_headers` line adds the same read-only header. The [Codex config reference](https://developers.openai.com/codex/config-reference) documents `http_headers` as static headers sent with each request to an HTTP server:

```toml
[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "GITHUB_PAT_TOKEN"
http_headers = { "X-MCP-Readonly" = "true" }
```

The guide's one-line equivalent, without the header, is:

```bash
codex mcp add github --url https://api.githubcopilot.com/mcp/ --bearer-token-env-var GITHUB_PAT_TOKEN
```

Note the variable name differs between the two guides. Codex reads `GITHUB_PAT_TOKEN` here, so export the token under that name too, or change the config to match.

**Step 4. Verify.** In Claude Code, `claude mcp list` should show `github` as connected, and `/mcp` inside a session lists its tools. In Codex, `/mcp` should show the server and its tools. Then ask something you can check by eye:

```text
List the five most recently updated open issues in <owner>/<repo>, with numbers and titles.
```

Compare the answer to the Issues tab. If the list matches, the server works. Then ask the agent to add a label to one issue. The server's README describes read-only mode as restricting write operations, so the request should be refused, and a read-only token refuses it a second time on GitHub's side.

## Permissions: what the agent may do without asking

Connecting a server and approving its tools are separate decisions.

In Claude Code, MCP tools are named `mcp__<server>__<tool>`, for example `mcp__github__list_issues`. That full name works in permission rules, in a skill's `allowed-tools`, and in hook matchers. So you can let the agent read issues freely and still require a prompt for everything else from that server by adding only the read tools to your allow list. The same names work in headless runs, as the Claude Code GitHub Actions docs show with `--allowedTools "mcp__github__list_commits,mcp__github__list_issues"`.

In Codex, the equivalent levers are `enabled_tools`, `disabled_tools`, and `default_tools_approval_mode` on the server's config table.

A `PreToolUse` hook can enforce harder rules on MCP calls too, because hook matchers accept the same tool names. The [hooks page in this series](/blog/hooks-for-coding-agents) covers that.

## Risks worth taking seriously

The Claude Code docs put the main one in a warning: verify you trust each server before connecting it, because servers that fetch external content can expose you to prompt injection. An issue body is external content. A malicious issue can contain instructions aimed at your agent. A read-only token limits what those instructions can make the agent do, which is a strong reason to start read-only.

Two smaller ones:

- **Output size.** Claude Code warns when one MCP tool result passes 10,000 tokens and caps results at 25,000 by default, saving larger output to a file. `MAX_MCP_OUTPUT_TOKENS` raises the cap. Big results eat context, so ask for filtered queries.
- **Too many servers.** Every connected server adds tool descriptions to the agent's context. Connect what the current project uses, at project scope, rather than everything at user scope.

## Where to go next

If you want to build a server rather than use one, [how to build an AI agent using MCP](/blog/how-to-build-an-ai-agent-using-mcp-model-context-protocol) walks through the other side of the protocol. For servers worth trying, the [MCP servers directory](/blog/mcp-servers-for-ai-builders) lists maintained options with verification dates.

Previous in the series: [Subagents and parallel work with coding agents](/blog/subagents-and-parallel-work-with-coding-agents). Next: [Skills and reusable instructions for coding agents](/blog/skills-and-reusable-instructions-for-coding-agents).


