Troubleshooting
Common issues with the Brand Stack MCP connector, from OAuth flow failures to scope errors and tool errors, and how to recover.
“No eligible workspaces” on the consent screen
You’re signed in but you aren’t an admin of any Brand Stack workspace. Ask a workspace admin to either:
- Promote you to admin, or
- Authorize the MCP connection on their own account (the token is workspace-scoped, not user-scoped: once authorized, anyone using the same client gets the same workspace’s data).
Members can still use the MCP connector on shared infrastructure once an admin has connected; what they can’t do is initiate a new connection from scratch.
“redirect_uri is not registered for this client”
Your AI client tried to use a redirect URI that wasn’t included when it registered with Brand Stack. This usually means the client re-registered against a different redirect_uri than the one it’s now passing.
Fix: remove the connection in your client (claude mcp remove brandstack, delete the entry in mcp.json, etc.), then add it again. Dynamic Client Registration creates a fresh client_id with the right URIs.
“PKCE verifier mismatch”
The authorization code was redeemed with the wrong PKCE verifier. This is usually a client-side bug or a stale tab. Close any extra browser tabs running the OAuth flow and try again from the AI client.
“Insufficient credits”
Your workspace doesn’t have enough credits for the action. Check the balance:
“Get the credits for this workspace.”
Or top up at Settings → Subscription → Plans; the rejection message itself carries a direct link to that page, and so does every get_credits response (manageCreditsUrl). Purchases happen in the browser, not through the connection. The generation tools (create_mockup, create_scene) consume credits at the same rate as the in-app studio; capture and uploads are always free, and a newly connected workspace starts with 10 free mockups.
“This token does not have the mcp scope”
Your client requested only mcp:read during the consent flow. Reconnect to grant write scope as well, or skip the write tools.
“Brand profile not found” right after adopt_repo
You are almost certainly querying the wrong entity by the right id — or
running a server version from before get_brand resolved brand stacks.
adopt_repo creates a brand stack; get_brand accepts a brand
stack’s id or slug and answers with its generation status
(queued | generating | ready | failed | needs_input), progress, and —
once ready — the stack’s productId and personas. Poll it every
15–20 seconds; generation typically takes 60–90 seconds. A stack that
is still generating is never reported as “not found.”
list_brands also returns both kinds (brand_stack and
brand_profile entries, newest first), so the stack you just adopted
is the first row.
“That URL cannot be captured”
capture_screenshot runs on Brand Stack’s servers, so it can only reach
public addresses. A local dev server (localhost, 127.0.0.1, private
network ranges) is only visible from your own machine. Capture those
where they live:
npx playwright screenshot http://localhost:3000/dashboard ./shot.png
npx @brandstack/cli upload ./shot.png
No API key handy? The agent can move the file without one: call
create_upload_link and POST the bytes to the uploadEndpoint it
returns. The CLI command above is the one-step version for shells that
do have a key (API keys).
If a public page times out instead, it loaded too slowly or renders only after interaction; the same client-side capture is the fallback there too.
The POST to uploadEndpoint fails with a 403 or policy error
The tool calls all work, but curl to the upload endpoint (or any
direct request to brandstack.dev) is rejected by a proxy. That is a
sandboxed agent runtime: environments like Claude Code on the web send
MCP traffic through a dedicated channel but route general HTTP through
an egress allowlist, and brandstack.dev is not on it.
Either add brandstack.dev to the environment’s network allowlist, or
fall back to upload_screenshot, which carries the image
base64-encoded inside the tool call itself. Compress the screenshot
first (JPEG or WebP around quality 80; the inline route costs context
tokens per kilobyte and caps at 3MB decoded). See
Screenshots → mockups for the full flow.
“This upload link is invalid or has expired”
Upload links from create_upload_link live for 30 minutes. Ask the
agent for a fresh one; it takes a second and costs nothing.
Mockup or scene generation hangs / times out
Generation has a 120-second hard cap. If a single call hits the cap:
- Drop
image_sizeto1K(cheaper, faster). - Remove reference images (
character_reference_url,style_reference_url); they each add a fetch step. - Try again; model latency varies with load.
If the call returns an error after generation started, the workspace is not charged: credits are refunded on every failure path, and the mockup/scene row is marked failed in the studio.
Revoking a connection
To revoke server-side (kills every active access + refresh token immediately):
- Open Settings → Developer in Brand Stack.
- Find the client under Authorized clients.
- Click Revoke.
The next request from that client gets a 401 and the user has to reconnect to restore access.
To remove the connection client-side (without revoking the tokens):
- Claude Code:
claude mcp remove brandstack - Claude.ai web: Settings → Connectors → click the connector → Disconnect
- Cursor / Codex: delete the entry from
mcp.json/config.toml
Refresh token reuse
If a client tries to use a refresh token that has already been rotated, Brand Stack revokes the entire grant immediately. This is by design: refresh-token reuse usually indicates token theft. The legitimate client will get invalid_grant on its next refresh and trigger a fresh OAuth flow.
If you see this happen unexpectedly, check whether two copies of the same client (e.g. two Claude Code installs sharing the same config) are competing for the same grant.
Still stuck?
Open an issue with the request id (returned in error response headers) and we’ll look into it. Don’t paste tokens; Brand Stack support can find the grant from the request id alone.