Skip to content

refactor(github): use App installation token + bot identity in mesh consumers#3196

Open
tlgimenes wants to merge 7 commits into
mainfrom
tlgimenes/github-app-scope
Open

refactor(github): use App installation token + bot identity in mesh consumers#3196
tlgimenes wants to merge 7 commits into
mainfrom
tlgimenes/github-app-scope

Conversation

@tlgimenes

@tlgimenes tlgimenes commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

What is this contribution about?

Refactors Mesh's GitHub consumer code to rely on the App installation token already stored in the mcp-github connection's downstream token, dropping all uses of the user's GitHub identity. The mcp-github connection model and storage are unchanged — only consumer call sites are touched.

Two surfaces change:

  • apps/mesh/src/shared/github-clone-info.ts no longer fetches GET /user to populate git committer name/email; it returns hardcoded bot identity (mcp-github[bot] + the matching users.noreply.github.com email). Daemon clones are now committed by the App's bot, decoupled from whoever connected GitHub.
  • apps/mesh/src/tools/github/list-user-orgs.ts swaps GET /user/installations for GET /installation/repositories and synthesizes a single-installation summary from the first repo's owner. The output schema is preserved so the existing repo-picker UI keeps working without changes.

How to Test

  1. Pull this branch and ensure the mcp-github connection is connected at the org level.
  2. Trigger a VM_START (sandbox provisioning) flow that exercises buildCloneInfo — confirm git config user.name inside the daemon shows mcp-github[bot] and git config user.email shows mcp-github[bot]@users.noreply.github.com.
  3. Open the GitHub repo picker UI: the installation-picker entry shows the App account; selecting it lists repos via the unchanged search_repositories flow.
  4. Run bun test apps/mesh/src/shared/github-clone-info.test.ts apps/mesh/src/tools/github/list-user-orgs.test.ts — 12 tests pass.

Migration Notes

No database, schema, or config migration. Hard cutover at the consumer layer: any pre-existing per-user mcp-github connection rows are inert under the new code (consumers no longer need user-scoped tokens). Org admins do not need to reconnect — the same mcp-github connection's downstream token is now interpreted as an App installation token end-to-end.

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working (new github-clone-info.test.ts + updated list-user-orgs.test.ts)
  • Documentation is updated (if needed)
  • No breaking changes (UI repo-picker output shape preserved)

Summary by cubic

Refactors GitHub consumers to use the App installation token end-to-end. Commits now use the bot identity, and org/repo selection reads from the installation’s repositories; token invalidation follows main’s refresh-and-retry behavior.

  • Refactors

    • buildCloneInfo: drops GET /user; commits use mcp-github[bot] with mcp-github[bot]@users.noreply.github.com. Proactively refreshes expired tokens and throws RECONNECT_ERROR when needed.
    • GITHUB_LIST_USER_ORGS: swaps GET /user/installations for GET /installation/repositories?per_page=1; synthesizes a single-install summary from the first repo’s owner; sets appSlug to mcp-github; preserves output shape; proactive refresh and one 401 retry; cached token deletion delegated to refreshAndStore (only on invalid_grant).
  • Bug Fixes

    • Made bot identity constants internal (non-exported) to avoid unused export warnings.

Written for commit 2872225. Summary will update on new commits.

Review in cubic

tlgimenes and others added 3 commits April 27, 2026 17:21
The mcp-github connection's downstream token is an App installation
token; calls to GET /user no longer reflect a real user. Replace the
on-the-fly fetch with hardcoded bot constants matching the App's bot
account, and add unit tests covering happy path, proactive refresh,
refresh failure, and missing-token cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ion/repositories

The downstream token is an App installation token, so /user/installations
no longer applies. Synthesize a single-installation summary from the
installation's first repo owner; preserve the output shape so the
repo-picker UI stays unchanged. Pagination is removed — the App is
bound to one installation, so one repo's owner suffices.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The throw-only fetch stub returns Promise<never>, which doesn't
structurally overlap with typeof fetch. Use double cast and match the
two-param signature used by sibling tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Benchmark

Should we run the Virtual MCP strategy benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

@github-actions

github-actions Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Release Options

Suggested: Patch (2.373.7) — based on refactor: prefix

React with an emoji to override the release type:

Reaction Type Next Version
👍 Prerelease 2.373.7-alpha.1
🎉 Patch 2.373.7
❤️ Minor 2.374.0
🚀 Major 3.0.0

Current version: 2.373.6

Note: If multiple reactions exist, the smallest bump wins. If no reactions, the suggested bump is used (default: patch).

tlgimenes and others added 4 commits April 27, 2026 17:43
knip flagged MCP_GITHUB_BOT_NAME / MCP_GITHUB_BOT_EMAIL as unused
exports. They are only consumed inside github-clone-info.ts; remove
the export keyword instead of silencing knip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…installation/repositories"

This reverts commit 6d52b28.
Resolve conflicts in the GitHub App-scope consumer refactor against main:

- github-clone-info.ts: keep bot-identity buildCloneInfo (no /user call);
  merge main's token-baking + sandbox-lifecycle docstring and keep main's
  new buildAnonymousCloneInfo for public-repo clones.
- list-user-orgs.ts: keep the /installation/repositories refactor and adopt
  main's "delete cached token only on definitive invalid_grant" behavior
  (drop explicit tokenStorage.delete on 401; delegate to refreshAndStore).
- Delete mocked-fetch tests list-user-orgs.test.ts (modify/delete: honor
  main's deliberate removal in #3501) and github-clone-info.test.ts (same
  mock.module + global.fetch pattern), per main's policy of not keeping
  mocked GitHub fetch tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant