Skip to content

Conversation

@tadasant
Copy link
Member

@tadasant tadasant commented Dec 5, 2025

Written by Claude Code, reviewed by me.

Summary

Fixes @claude to work on external fork PRs by:

  1. Restricting triggers to modelcontextprotocol org members only
  2. Properly checking out fork PR code via refs/pull/N/head

Background

The @claude GitHub app was failing on external forks (example) because the action tried to fetch branches by name, which doesn't work for forks.

Changes

Org membership check

  • Fetches the member list from modelcontextprotocol/access repo's users.ts
  • Only org members can trigger @claude (prevents strangers from using it)
  • Uses github.triggering_actor so the person commenting must be an org member

Fork PR checkout fix

  • Detects when a comment is on a fork PR
  • Uses refs/pull/{number}/head to checkout fork code (instead of branch name)
  • This works because GitHub exposes all PRs via special refs on the base repo

How it works

  1. Org member comments @claude on a fork PR
  2. Workflow checks if commenter is in the modelcontextprotocol/access member list
  3. Workflow detects it's a fork PR and checks out via refs/pull/N/head
  4. Claude runs with access to the fork's code

🤖 Generated with Claude Code

tadasant and others added 5 commits December 5, 2025 08:29
Add a maintainer check to the Claude workflow to ensure only registry
maintainers can trigger @claude. This enables the bot to work on
external fork PRs when triggered by maintainers, while preventing
unauthorized usage.

Also adds maintainer onboarding documentation covering the full
checklist for adding/removing maintainers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace the hardcoded maintainer list with a dynamic GitHub API check
for modelcontextprotocol org membership. This allows any org member
to trigger @claude without needing to update the workflow file.

Requires adding an ORG_MEMBERSHIP_TOKEN secret with read:org scope.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Parse the users.ts file from modelcontextprotocol/access to get the
list of org members. This avoids needing a PAT with read:org scope.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Remove id-token: write (not needed for API key auth, causes issues on forks)
- Add write permissions for contents/pull-requests/issues
- Detect fork PRs and checkout via refs/pull/N/head instead of branch name
- This allows @claude to work on external fork PRs when triggered by org members

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The claude-code-action uses its own GitHub App token for write
operations, so the workflow token only needs read permissions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@tadasant tadasant marked this pull request as ready for review December 5, 2025 17:46
@tadasant tadasant requested a review from a team December 5, 2025 17:46
@tadasant tadasant changed the title Restrict @claude bot to maintainers only Restrict @claude bot to maintainers only, fix fork behavior Dec 5, 2025
@tadasant tadasant changed the title Restrict @claude bot to maintainers only, fix fork behavior Restrict @claude bot to mcp org only, fix fork behavior Dec 5, 2025
@domdomegg
Copy link
Member

tldr: username matching logic seems safe, although looks spooky

I was initially concerned about the username matching logic. If there's an approved user called something, could someone with a GitHub account somet accidentally pass the check? I (well, Claude and I 😄) traced through the code and think it's safe. grep -qxF "$ACTOR" has -x which requires the pattern to match the entire line. And -F treats the pattern as a fixed string (no regex). So each extracted username ends up on its own line, and -xF ensures only exact matches pass.

@domdomegg domdomegg merged commit 3704533 into main Dec 8, 2025
6 checks passed
@domdomegg domdomegg deleted the fix/claude-maintainer-only-access branch December 8, 2025 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants