Repository navigation
feat(mcp): switch to the dev environment with X-Crystallize-Environment - #30
Merged
Merged
Conversation
The server used to hardcode api.crystallize.com / shop-api.crystallize.com in eight tool files, never passed `origin` to the js-api-client, and verified bearer tokens against a fixed production JWKS. A request can now flip to dev the way the js-api-client's `shopApiStaging` switch works: the caller sends `X-Crystallize-Environment: dev`, never a hostname. The dev origin suffix lives only in the `CRYSTALLIZE_DEV_API_ORIGIN` secret, so it never appears in the repo (tests and docs use `-dev.example.test`). - `src/core/api-origin.ts`: resolve the header into a js-api-client origin suffix. No header / `production` -> `.crystallize.com`; `dev` -> the secret (400 when unset, 500 when not a valid suffix); anything else -> 400. - `authMiddleware` resolves it first, stores it on the auth context as `origin`, uses it for the `me` call and keeps one remote JWKS per environment. - Every tool passes `origin: authContext.origin` to `createClient`, and every hand-built URL (schema introspection, Shop API token exchange) comes from `apiBaseUrl(prefix, origin)`. - The product-overview panel's CSP gains the dev parent-domain wildcard on read. - The dev bridge forwards the header from `CRYSTALLIZE_ENVIRONMENT`. - AGENTS.md documents the header, the secret and the rule for new tools.
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.
What
The MCP server hardcoded
api.crystallize.com/shop-api.crystallize.comin eight tool files, never passedoriginto the js-api-client, and verified bearer tokens against a fixed production JWKS.A request can now switch to the dev environment the way the js-api-client's
shopApiStagingswitch works: the caller flips a switch, never types a hostname.X-Crystallize-Environment: dev. Absent, blank orproduction→ production (unchanged behaviour). Any other value → 400.CRYSTALLIZE_DEV_API_ORIGINholds the dev js-api-client origin suffix. It is a Wrangler secret (or a.envline locally), so the dev hostname never appears in the repo. Tests and docs use the fake-dev.example.test.devwith the secret unset → 400; a secret that is not a valid suffix → 500.How
src/core/api-origin.tsresolves the header into an origin suffix and builds API hosts from it (apiBaseUrl).authMiddlewareresolves it first, stores it on the auth context asorigin, uses it for themecall and keeps one remote JWKS per environment (cached per isolate). The secret is only read when a request asks for dev, so a bad secret can never affect production traffic.origin: authContext.origintocreateClient; every hand-built URL (schema introspection, the Shop API/auth/tokenexchange) comes fromapiBaseUrl.grep crystallize.com srcnow only hits the resolver, the landing page and the product panel's static CSP.bin/dev-bridge.tsforwards the header fromCRYSTALLIZE_ENVIRONMENT.Tests
bun test: 211 pass (was 184). New coverage: the resolver, the middleware (header resolution, production default, 400 / 500 paths, per-environment JWKS and its caching), thequery-coreandquery-shop-carttools, the Core schema tool's introspection URL, and the CSP helper.bun type-check,bun lintandbun run buildare clean.Rollout
wrangler secret put CRYSTALLIZE_DEV_API_ORIGINwith the dev suffix (must start with.or-, lowercase host fragment).CRYSTALLIZE_DEV_API_ORIGIN=<suffix>to.env; optionallyCRYSTALLIZE_ENVIRONMENT=devfor the dev bridge.--header "X-Crystallize-Environment: dev"next to the token headers.