git-repo-auth-mcp
This is the detailed, under-the-hood version. New here? Start with the simple one →

Credential issuance for AI agents

Your AI can build things.
This lets it save them — safely.

When you ask an AI to build something, that work has to live somewhere. Developers keep theirs on GitHub — but GitHub expects you to create and manage digital keys, and that's where most people give up.

This bridge handles the keys for you. Connect your GitHub account once. After that, every time your AI needs to save work, it gets a fresh key that opens only the one door it needs — and the key expires in an hour.

That's actually safer than what most professionals do. The common shortcut is one master key that opens everything and lasts for years. Here, there's no master key to lose — and if you ever want out, one click disconnects everything.

You never see a key. You never touch a key. You just ask, and it saves to GitHub.

https://gitauth.klappy.dev/mcp
Installation Token git-repo-auth-mcp
contents: write
klappy.dev
oddkit-steward[bot]
Time to live60:00
NO ROTATION REQUIRED EXPIRY IS THE ROTATION

Live demonstration at 60× speed — a real token lives one hour.

The problem, on the record

A personal access token is a key you can lose. This is a key that loses itself.

Hand-minted PAT Status quo

  • Lives for months. Pasted into chat transcripts, logs, and clipboards.
  • One scope for everything — the agent fixing a typo holds the same key as the deploy.
  • Rotation is a chore a human remembers to do. Or doesn't.
  • Commits show up as you. The audit log can't tell your hands from the agent's.

Minted on demand This worker

  • Lives one hour, maximum. A leaked transcript holds a corpse, not a key.
  • Down-scoped per request — name the repos, name the permissions.
  • Rotation ceases to be a task. The token rotates by dying.
  • Every commit is attributed to the App's bot identity. Provenance is built in.

How it works

Three hops. Your key never moves.

STEP 1

You connect, once

Add the MCP server to your client and log in with GitHub. The connection binds to your installation of the app — you choose which repos it covers. Then your agent calls github_token at need.

STEP 2

The worker signs

Your Cloudflare Worker signs a 10-minute JWT with your App's private key — which lives in worker secrets and never transits chat, disk, or transcript.

STEP 3

GitHub issues the pass

GitHub exchanges the JWT for a one-hour installation token, scoped exactly as requested. The agent uses it, and the clock does the rest.

No coding tool required

Ship from the chat you're already in.

Don't leave the thread

Claude, ChatGPT, any frontier model — the plain conversation, even from a phone. Append to a repo, cut a branch, open a pull request, mid-conversation. No tool switch, no lost context.

Your flow, not ours

Write straight to main if that's how you roll. Or run strict protected branches with required CI, and let the assistant bridge you into that setup. We don't determine your flow. We let you.

Tested, not theorized

Blank repository to branch protection and a working CI pipeline, set up entirely inside a chat — with Opus, and again with ChatGPT. Not their coding tools. The chat. It works.

Read this before you trust it

The security model, stated plainly.

Most credential tools bury their threat model. This one leads with it — because the people who should deploy this are exactly the people who will ask.

Your grant is the boundary

Each connection is bound by OAuth to one user, one installation — a minted token physically cannot reach another account's repositories; GitHub enforces the walls. The worker stores no GitHub tokens, ever: its only state is its own hashed grants and your quota accounting.

"No admin" ≠ "can't escalate"

The recommended grant excludes Administration — but Workflows write means a token holder can modify CI, and CI runs with the repo's own credentials. That path is accepted, not eliminated: every CI change lands in PRs and audit logs under the bot identity. Don't want the trade? Drop the Workflows permission.

Blast radius, stated

You never hand over a key — connecting means installing a GitHub App on repos you choose. If this bridge were compromised, exposure is minting over installed scopes, within the app's ceiling — never your account or credentials. Your kill switch is unilateral: uninstall the app and minting ends instantly. Want zero shared trust? Self-host the same code.

$ Reversal is two clicks. The riskiest credential in this system is the one it replaces.

The deal, stated plainly

How big is your agentic concurrency?

Tokens live one hour, and a working agent typically mints two — a read-only token to look (the secure default), then a write token to act — so every tier budgets two tokens per agent and the cards below count agents. The mix is unpoliced: two reads, two writes, a read and a write, all the same. Every tier is one human, no seats — the team is your agents, and the per-agent price falls as you climb. Every response shows remaining and window_reset_at, so the wall is never a surprise.

Free

$0

one-time trial — no card
  • Bucket of 100 mints, total
  • No decay — a clean wall, then you decide

Solo

$1

per month — $24 billed every 2 years
  • 5 agents at once
  • All 5 in the first hour, or one an hour
  • $0.20 per agent slot
Get Solo

Pro

$5

per month — $60 billed yearly
  • 30 agents at once
  • 5x the price, 6x the agents
  • $0.167 per agent slot
Get Pro

Team

$25

per month
  • 200 agents at once
  • A team of agents — one human, no seats
  • $0.125 per agent slot
Get Team

Fleet

$100

per month
  • 1,000 agents at once
  • Never think about the window again
  • $0.10 per agent slot
Get Fleet

$ Re-requesting the same scope while a token is live is always free, and a mint GitHub refuses never charges — you pay only for tokens you receive. Prices and quotas render from the governance document the server enforces. Prefer your own keys? Self-host for $0, forever — same code.

Setup

Connect in a minute. Or run your own.

Use it: add https://gitauth.klappy.dev/mcp to your MCP client and follow the GitHub login. Operate it: the script here is the self-host runbook — same code, your app, your worker. Details in the README.

Keep your existing PAT until github_token mints its first real token. Retiring the fallback before validating the replacement is how lockouts happen — the README sequences this for you.

setup.sh
# 1 — Create the GitHub App (Contents RW, PRs RW, Metadata R.
#     Workflows RW optional — see security model. No Administration.)

# 2 — GitHub ships PKCS#1; Workers WebCrypto wants PKCS#8:
openssl pkcs8 -topk8 -inform PEM \
  -in your-app.private-key.pem -nocrypt -out app-pkcs8.pem

# 3 — Enable user OAuth on the app: callback =
#     https://<worker>/callback, generate a client secret.

# 4 — Secrets (never committed, never pasted in chat):
wrangler secret put GH_APP_ID
wrangler secret put GH_APP_PRIVATE_KEY
wrangler secret put GITHUB_CLIENT_ID
wrangler secret put GITHUB_CLIENT_SECRET

# 5 — Ship it:
npm install && npm run deploy

# 6 — Point any MCP client at https://<worker>/mcp —
#     OAuth + GitHub login happen in the browser.