Claude Code MCP Permissions Model & Best Practices: GitHub / CodeGraph / API Least-Privilege Guide

How to configure Claude Code MCP permissions, minimize GitHub PAT scope, and keep CodeGraph and API MCP read-only by default. Includes data flows, trust boundaries, and an auditable policy matrix for security reviews and team onboarding.

2026.06.05  ·  ~15 min  ·  Prerequisite: MCP overview (architecture)

Claude Code MCP permissions and minimal token exposure

Prerequisite: MCP triple-connect overview (connect first, then lock down permissions); setup walkthrough in progress. For quick jumps, use the problem map below; for the full spec, read the entire article—this is the MCP permissions authoritative spec (v1.0), not a connectivity tutorial.

Problem map (search entry · jump to section)

Need a 5-minute setup? A lightweight how-to page (L4-Q08) will cover copy-paste steps; this article keeps architecture and security-review depth.

Reading path (~15 min · full spec): Problem map → One-line summary → System model → Trust boundary and data flow → Policy matrix and control plane → Config snippets → Attack chain. Suitable as team SOP or security-review attachment.

One-line security model

MCP permission safety means splitting what the Agent can see from what it can write, and defaulting everything to read-only. Writes, production reach, and CI credentials must sit outside the trust boundary—or be explicitly enabled in a separate config profile.

3
MCP roles in stack
1
Policy matrix
4
Incident paths
Read-only
Default policy

Default principle

Index and context are read-only; write access must be explicitly isolated (separate MCP service / token / environment). Code changes go through local git; production API and Runner credentials do not belong in Claude MCP config.

Scope: authoritative spec (problems + auditability)

The problem map above ties search intent to concrete sections; from here we enter the security architecture spec. Connectivity acceptance checks whether tools are registered (mcp__github__*); permission acceptance checks reach at call time: paths, APIs, GitHub resources, and secret scope.

When Claude Code, CodeGraph, and GitHub Runner share a Cloud Mac host, MCP tokens and Runner secrets must be separate accounts—never share a GitHub App private key or place production DATABASE_URL in the Agent workspace (remote Mac context: Cloud Mac vs local Mac).

Layer 1 · System model (anchor before the matrix)

Triple-connect MCP splits into three roles—each with a distinct read/write risk boundary, not three “plug and forget” extensions (architecture: MCP overview):

Claude Code session
    │
    ├─ GitHub MCP     →  intent   (where work comes from: issue / PR / comment)
    ├─ CodeGraph MCP  →  context  (what to change: impact / symbols / deps)
    └─ API MCP        →  truth    (is it correct: staging data / contracts)

Risk axis: intent-layer writes hit collaboration surfaces;
           context-layer writes corrupt index or source;
           truth-layer writes mix staging and production data.

Deployment cross-reference: CodeGraph in five minutes covers “graph is available”; this article covers “graph and API default to read-only in front of the Agent.” Series part 1: architecture / triple-connect; part 3 planned: MCP threat model (STRIDE · attack surface · credential flow).

Trust boundary

For architecture reviews, cite this diagram: the Agent session sits in the inner zone; MCP is the sole gateway to external systems. Any call that crosses production, a writable filesystem, or CI credentials is a boundary violation.

┌─────────────────────────────────────────────────────────┐
│  Trust zone A · Claude Code session (user / Agent)      │
│                                                         │
│   ┌──────────────── MCP layer ─────────────────┐      │
│   │  GitHub MCP (intent)   ──► external collab   │      │
│   │  CodeGraph MCP (ctx)   ──► local index/graph│      │
│   │  API MCP (truth)       ──► staging database  │      │
│   └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘
         │                    │                    │
         ▼                    ▼                    ▼
   [ GitHub API ]      [ .codegraph/ ]      [ staging API ]
   external · collab    local · read-only     non-production

Trust boundary (must not cross by default):
  ✗ Production database / production API URL
  ✗ Writable filesystem (whole repo / monorepo root)
  ✗ CI / Runner credentials (GITHUB_TOKEN · App private key)
  ✗ .env.production · adjacent project secrets

Matrix mapping: rows “production = deny” and “CI/Runner = do not attach to MCP” operationalize the boundaries above.

Data flow

Permission problems are really about how data moves between Agent → MCP → external systems and where side effects appear. The boundary diagram answers “may it cross?”; data flow answers “what happens after it crosses?”

User prompt
   ↓
Claude Code (Agent state · conversation context)
   ↓
MCP tool call (GitHub / CodeGraph / API)
   ↓
External response (issue body · graph JSON · staging rowset)
   ↓
Agent interpretation (plan · PR description · next tool args)
   ↓
Side effects (PR comment · DB INSERT · .codegraph/ rewrite · CI trigger)

Control points (policy matrix rows):
  · Before MCP call  → read-only MCP service / minimal scope
  · Before re-inject → PII redaction · no production fields
  · Before side effect → write service disabled → tool chain should fail

The attack-chain walkthrough below (§ Misconfiguration attack chain) follows this flow step by step: which hop’s response the Agent misuses, and which PR / table / index side effect results.

Common permission incident paths (how Agents mis-operate)

These happen even when config “looks reasonable”—use as code-review and security-review checklist items:

  • GitHub MCP writes comments / labels → triggers CI bots or auto-merge rules that depend on comments, advancing the pipeline without human confirmation.
  • CodeGraph or filesystem MCP with repo write access → Agent fixing an issue rewrites .codegraph/ or adjacent subproject config; index is poisoned and codegraph_impact is untrustworthy.
  • API MCP with staging write access → test rows mix with production mock fields; Agent treats wrong schema as “truth” in the PR description.
  • Filesystem MCP reads workspace root → scans .env.production or adjacent monorepo secrets into conversation context or issue comments.

Layer 2 · Default policy principles (conclusions before the matrix)

The matrix answers “how to configure each row”; this section keeps three team-policy conclusions (without re-defining the three MCP roles):

  1. Claude sessions default to read-only MCP services (*-ro naming); any write needs a short-lived token plus an explicitly enabled second MCP service.
  2. CI / Runner is not exposed through MCP; nightly index rebuilds and integration-test writes run in workflows, not from chat.
  3. Production is invisible to the Agent: no production URL, no DATABASE_URL, no merge/push PAT permanently in ~/.claude.json.

Policy matrix (recommended default rows)

Designed for machine execution and review: beyond resource and default policy, columns mark Claude auto-call, CI trigger, and production reach for policy-as-code or onboarding checklists. Write needs require PR justification and expiry.

MCP / resourceStack roleDefault policyClaude sessionCI / RunnerProductionCommon misconfig
GitHub repo Intent PAT read + issues (as needed); short-lived token for PR/push writes Allow (read-only service) Do not attach MCP; use App / GITHUB_TOKEN Deny production-branch writes Full repo write permanently in ~/.claude.json
CodeGraph .codegraph/ Context Process read-only; tools limited to query / impact Allow (read-only) Allow nightly index rebuild job N/A Whole repo writable via MCP
API / database Truth Staging read-only account; SELECT-only tools Allow api-ro Integration tests may use separate api-rw schema Deny Production DATABASE_URL in Claude workspace
Local .env* Not exposed via MCP; docs + .env.example Deny full-directory filesystem scan Secrets only in Runner vault Deny reading .env.production Workspace at monorepo root scans neighbor projects
Runner / CI secrets Do not enter mcpServers Deny Allow (Runner only) Deny sharing with MCP Shared GitHub App private key

Control plane (who enforces policy)

The matrix answers “what should we do?”; this section answers “who enforces it at which layer”—turning best practices into enforceable tiers.

Policy enforcement points:

  1. MCP service config (~/.claude.json · static scopes · read-only default)
  2. OS / filesystem (repo and .codegraph/ read-only mount · workspace isolation)
  3. GitHub App / PAT console (fine-grained · single repo · expiring write tokens)
  4. CI pipeline (production URL gate · secret scan · ban PAT in repo)
  5. Runner vault (CI creds separate from MCP env · not in mcpServers)

Maps to matrix columns:
  · Claude session  → ①②
  · CI / Runner     → ④⑤
  · Production      → ③④ (reject prod endpoints / permanent full-write PAT)

A printable checklist will be single-paged (planned MCP best-practices checklist, see § Further reading); connectivity errors go to the planned MCP troubleshooting page—separate from this permissions spec.

GitHub MCP · PAT and scopes

Goal: let Claude Code read issues and cite them in comments, without permanently handing “merge PR” capability to the conversational Agent.

Recommended tiers

  • Daily development (read-heavy): repo (private repo read), read:org (if multi-repo under org); add issues for issue-driven flow.
  • Automated writes (short-lived): separate fine-grained PAT, single repo, Contents/Issues write checked, 7–30 day expiry, remove from mcpServers when done.

Token storage: environment variables (e.g. GITHUB_MCP_TOKEN) preferred—never commit to repo; on Cloud Mac use instance-level secrets, on local Mac inject via Keychain / 1Password.

# Example: scope intent only—verify against current GitHub PAT UI
# Fine-grained · single repo · Contents read + Issues read/write

CodeGraph · read-only index practice

CodeGraph’s value is querying the graph, not letting MCP mutate index files. Recommendations:

  1. After codegraph init at repo root, treat .codegraph/ as build output (gitignore or separate backup).
  2. MCP process is read-only on source; rebuild index via human or CI script, not chat.
  3. If Agent reports empty codegraph_impact, check index and working directory first (overview problem table)—do not grant write access first.

Large-repo context: CodeGraph and AI coding agents; permission policy unchanged: graph stays read-only.

API MCP · staging read-only

API MCP aligns “what real data looks like.” Least-privilege approach:

  • Configure staging base URL only; production URL never appears in mcpServers env block.
  • DB account SELECT only; for writes use another MCP service name (e.g. api-staging-rw), disabled in Claude config by default.
  • If responses contain PII, redact at MCP layer or forbid pasting raw JSON into issue comments.

~/.claude.json minimal example (structure)

Field names may vary by version; the point is split MCP services, split env vars, minimize default enabled set.

{
  "mcpServers": {
    "github-readonly": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_MCP_TOKEN_READONLY}"
      }
    },
    "codegraph": {
      "command": "codegraph",
      "args": ["mcp"],
      "env": {
        "CODEGRAPH_READ_ONLY": "1"
      }
    }
  }
}

Note: CODEGRAPH_READ_ONLY is illustrative—check your CodeGraph / MCP implementation; if no switch exists, use OS permissions (read-only mount) for the same effect.

Pre-launch checklist (summary · full page planned)

  • □ Is GitHub PAT minimum scope and not committed to git?
  • □ Is there an API MCP service that writes production? If yes, is it disabled by default?
  • □ Does CodeGraph expose only impact/query tools?
  • □ On Cloud Mac, does the Claude workspace point to a single repo, avoiding neighbor .env files?
  • □ Is the Runner registration token separate from the MCP token?
  • □ Do team members know which doc to update after tightening permissions? (this article + overview)

Misconfiguration attack chain walkthrough

Based on common real-world combos: config looks “efficient” on the surface, but chained Agent calls exceed permission intent.

1. Initial config (looks reasonable)

  • Single mcpServers profile: GitHub MCP (repo write) + filesystem + CodeGraph in one process.
  • CodeGraph writable at monorepo root; API MCP points to staging but account has INSERT.
  • Claude workspace = repo root, no .env* exclusion.

2. Agent trigger

User: “Fix bug from issue #42 and update reproduction steps in the PR description.” Agent calls GitHub read issue → CodeGraph impact → API sample from staging → filesystem config change.

3. Permission escalation path

  1. Filesystem writes config in adjacent subproject (not the issue target path).
  2. CodeGraph rewrites .codegraph/ under write access; impact results drift.
  3. API tool INSERTs test row; field names match production mock; Agent copies into PR body.
  4. GitHub MCP posts comment with write scope; label rule fires; CI auto-queues.

4. Data / code impact

  • Wrong config lands in PR; staging DB has dirty rows; untrustworthy index causes follow-on Agent sessions to misjudge.
  • If PR description contains staging DATABASE_URL fragment, secret scan alerts (still a leak event).

5. Post-incident fix (not connectivity)

  1. Revoke PAT → fine-grained read-only, single repo, 7–30 day write token in separate profile.
  2. CodeGraph read-only mount; index rebuild only via Runner nightly job.
  3. Split API into api-ro / api-rw; Claude defaults to api-ro only.
  4. Runner secret scan + forbid MCP and CI sharing App private key.

Series further reading (layered · on blog roadmap)

This page = Page 1 · authoritative spec (architecture + policy + review). Lighter pages below handle how-to and troubleshooting—cross-linked, so one page does not try to be both encyclopedia and cheat sheet:

LayerPageqidPlanSearch intent
Page 1 MCP permissions spec (this article) L4-Q04 Permission model · best practices · security spec
Page 2 How to configure Claude Code MCP permissions (how-to) L4-Q08 6/11 5-minute steps · copy-paste · verify
Page 3 MCP troubleshooting L4-Q07 6/12 Common errors · permission/connectivity symptoms
Extended MCP threat model L4-Q05 6/10 STRIDE · credential flow · attack surface
Extended Best-practices checklist (single page) L4-Q06 6/13 Printable checklist · team onboarding

Planned slugs (zh): mcp-quanxian-zenme-peizhi (how-to) · mcp-changjian-guzhang-paichang (troubleshooting) · mcp-weixie-moxing-stride-gongji-mian (threat model).

Evolution: policy as code

This policy matrix is already an auditable table; the next series phase can materialize row rules as executable artifacts—for example JSON policy (mcpServers allow-list), MCP permission DSL, CI gates (ban production URLs / full-write PAT in repo). After the threat model (③) is final, open a separate enforcement runbook—do not mix with this permissions spec.

FAQ

Can CodeGraph be read-only?
Yes—and recommended. Update index via CI or manual process; conversation layer queries only.

Does GitHub MCP need write access?
Issue comments / labels: yes; merge and push: short-lived token + human confirmation, not 24/7 in Claude config.

Can I share secrets with Runner?
No. MCP serves interactive Agents; Runner serves CI—different exposure and rotation cadence.

MCP not working after install?
Connectivity symptoms: overview problem map; planned MCP troubleshooting (L4-Q07) will collect common errors and permission misconfigs.

Version: AI Agent permissions security spec v1.0 (stable). Series: Cloud Mac AI Stack · L4 security specMCP permissions model and threat control.

PartDocumentCore outputStatus
MCP architecture Intent / context / truth Overview
MCP permissions model Policy · data flow · control plane This article ✅
MCP threat model STRIDE · credential flow L4-Q05 · 6/10
How-to (how to configure permissions) Lightweight steps page L4-Q08 · 6/11
Troubleshooting Error index L4-Q07 · 6/12
Checklist Single-page checklist L4-Q06 · 6/13

Cloud Mac AI Stack · L4 security spec

MCP permissions model and threat control

Architecture  ·  ② Permissions model (this article)  ·  ③ Threat model (planned)  ·  CodeGraph in five minutes

Back to blog · full series
MCPCloud Mac pricing