feat(github): migrate to cloudflare workers#396
Merged
viktormarinho merged 9 commits intomainfrom Apr 23, 2026
Merged
Conversation
Moves the github MCP off kubernetes-bun and onto CF Workers via `wrangler deploy`. Removes it from deploy.json / the shared `deco deploy` pipeline and adds a dedicated `deploy-github.yml` workflow. Key changes to make it isolate-safe: - Installation map + trigger state migrated from in-memory / Mesh StudioKV to a Workers KV binding (`INSTALLATIONS`) with `installation:` and `triggers:` prefixes - All module-level `process.env` reads moved into lazy closures (Workers doesn't populate `process.env` at module init) - Upstream MCP tool discovery deferred to first request (previously a top-level `await`) and runtime construction cached per isolate - Webhook + OAuth closures now pull secrets per-request Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Emits [Webhook] log lines on ingress, on signature failure, on skip (no installation / no mapping), and on successful notify — keyed by x-github-delivery so a single event can be traced end to end in Cloudflare observability. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cf-worker-check # Conflicts: # github/server/main.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
triggers.notify() is fire-and-forget — on Workers the internal fetch to Mesh got cancelled as soon as we returned the HTTP response, silently dropping events. Replaced with a direct Mesh callback delivery that reads trigger credentials from KV and returns an awaitable Promise, which we hand to ctx.waitUntil so Workers keeps the isolate alive until the POST completes. Threads ExecutionContext through handle() → webhook handler. Also logs every success / failure per delivery id. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…owner If two users share a GitHub App installation, the second OAuth would overwrite installation:<id> but leave the first user's connection:<oldConn>:<id> entry behind. A later removeByConnection(oldConn) then deleted the live forward mapping for the new owner. set() now reads the current owner first and cleans up its reverse- index entry in the same batch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cf-worker-check # Conflicts: # github/server/main.ts
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves the github MCP off kubernetes-bun and onto Cloudflare Workers via
wrangler deploy. Removes it fromdeploy.json/ the shareddeco deploypipeline and adds a dedicateddeploy-github.ymlworkflow that mirrors the slide-maker / site-diagnostics pattern.What changed to make it isolate-safe
Map) / Mesh StudioKV to a single Workers KV binding (INSTALLATIONS), multiplexed byinstallation:andtriggers:prefixes.process.envreads moved into lazy closures — Workers doesn't populateprocess.envat module-init time undernodejs_compat.await, is now deferred to the first request and the resultingwithRuntimeis cached per isolate (reset on failure so retries work).export default { fetch }; webhook + OAuth closures read secrets per-request.Test plan
cd github && bun run check— typecheck passes at pre-existing baseline (1 unrelated runtime type error inmcp-proxy.ts).bunx wrangler deploy --dry-run --outdir=dist— bundles successfully (~372 KB gzip) and shows theINSTALLATIONSKV binding.CLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_IDrepo secrets, set app secrets viawrangler secret bulk .secrets.json, then merge to main and confirm theDeploy GitHub MCPworkflow succeeds./mcpendpoint via an MCP client and confirm tool discovery works and at least one tool call succeeds./webhooks/githubverifies the signature and reachestriggers.notify.🤖 Generated with Claude Code
Summary by cubic
Migrates the GitHub MCP to Cloudflare Workers with KV-backed state, isolate-safe lazy runtime, and reliable webhook delivery via
ctx.waitUntil. Adds a dedicated deploy workflow and serves at https://github-mcp.decocms.com.Refactors
INSTALLATIONSwithinstallation:*andtriggers:*prefixes; maintain reverse index and evict stale entries on reassignment (in-memory fallback for local dev).export default { fetch }; proxy MCP resources before runtime; read secrets per request.x-github-delivery, and deliver to Mesh via KV-backed callback withctx.waitUntilto avoid dropped events.wrangler.toml, switch scripts tobunx wrangler, add@cloudflare/workers-typesandwrangler, route custom domain, updategithub/app.jsonURL, adddeploy-github.yml.Migration
INSTALLATIONSinwrangler.toml.CLOUDFLARE_API_TOKEN,CLOUDFLARE_ACCOUNT_ID; set Worker secrets viawrangler secret bulk .secrets.json(GITHUB_APP_ID,GITHUB_PRIVATE_KEY,GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET,GITHUB_WEBHOOK_SECRET).bunx wrangler deploy.Written for commit fa2aaca. Summary will update on new commits.