feat: collapse web + gateway into a single public origin - #226
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
next.config.mjs resolves its types directly in TS 5.6; the suppression is no longer needed and now fails typecheck with TS2578.
- .env.example: drop the MCP_PUBLIC_URL override block — ADR 0009 is the canonical reference now, .env.example stays minimal. - next.config.mjs: update allowedDevOrigins from holo-app.maakle.com to holo.maakle.com to match the new single-origin tunnel hostname.
This was referenced Jun 1, 2026
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
Collapse the two-host deployment (web on one hostname, gateway on another) into a single public origin via Next.js
rewrites(). Self-hosters now need one DNS record, TLS cert, and tunnel/proxy. ngrok free is sufficient for contributors testing OAuth/MCP flows.apps/web/next.config.mjsreverse-proxies/mcp,/mcp/*,/v1/*,/openapi.json,/docs,/docs/*,/slack/*,/teams-bot/*,/google-chat-app/*, and/.well-known/oauth-protected-resourceto the gateway viaGATEWAY_INTERNAL_URL(defaulthttp://localhost:8080, set tohttp://gateway:8080in compose).MCP_PUBLIC_URLis now optional inpackages/env— derives fromWEB_PUBLIC_URL→BETTER_AUTH_URL. Two-origin operators can still publish the gateway separately by setting it explicitly; gateway code is unchanged.docker-compose.ymlwiresGATEWAY_INTERNAL_URL=http://gateway:8080and addsdepends_on: gatewayto the web service so the proxy target is reachable on boot.@holo/cli initdropsMCP_PUBLIC_URLfrom the generated.env(no longer needed)./.well-known/oauth-authorization-serveris intentionally NOT proxied — the web has its own canonical handler that derives the issuer fromWEB_PUBLIC_URL. The catch-all rewrite reaches it correctly. Comment added innext.config.mjs.Design rationale and migration steps for existing two-host operators:
docs/decisions/0009-single-origin-gateway.md.Test plan
pnpm -F @holo/env test— 10 tests pass (new tests coverGATEWAY_INTERNAL_URLdefault andMCP_PUBLIC_URLderivation including two-origin override)pnpm -F @holo/cli test— 23 tests pass (init wizard no longer emitsMCP_PUBLIC_URL)pnpm -F @holo/web test— 59 tests pass (new rewrite-presence + ordering tests)pnpm -F @holo/web -F @holo/gateway -F @holo/env -F @holo/cli typecheck— cleanpnpm verify:gateway— HTTP smoke (operator-runnable) verifies/v1/health,/openapi.json, and/mcp401 +WWW-Authenticateheader points at the single origin${WEB_PUBLIC_URL}/mcp. Required before relying on this in production. See ADR 0009 "Verification" section for the procedure and the cloudflared path-routing fallback if SSE proxying breaks.Migration for existing two-host deployments
Order matters — see ADR 0009 § "Migration notes for existing deployments":
GATEWAY_INTERNAL_URLon the web service pointing at the gateway's internal address.MCP_PUBLIC_URL=$WEB_PUBLIC_URLon gateway/worker (or unset on web — derivation takes over).The README's Railway section now has an inline "Migrating from a two-host deployment" subsection with the same checklist.
Files
16 commits, ~1500 LOC across:
packages/env/src/index.ts+ tests (schema)apps/web/next.config.mjs+ new test (rewrites)apps/web/src/app/__tests__/gateway-rewrites.test.ts(regression test)docker-compose.yml(compose wiring)packages/cli/src/commands/init.ts+ tests (CLI wizard)scripts/verify-mcp-sse.mjs+package.json(HTTP smoke)docs/decisions/0009-single-origin-gateway.md(ADR)docs/superpowers/plans/2026-06-01-single-origin-mcp-gateway.md(implementation plan)README.md,CONTRIBUTING.md,.env.example(docs)🤖 Generated with Claude Code