Summary
When using @storybook/addon-mcp with a private Chromatic-hosted Storybook, the MCP OAuth flow fails when connecting via Claude Code CLI or claude.ai Cowork. The browser opens for authentication but lands on an authentication error page.
Environment
@storybook/addon-mcp: 0.4.2
- MCP client: Claude Code CLI / claude.ai Cowork
- Storybook hosted on Chromatic (private, OAuth-protected)
Steps to reproduce
- Set up
@storybook/addon-mcp on a private Chromatic-hosted Storybook
- Add the MCP server to a Claude Code project (
.mcp.json):
{
"mcpServers": {
"my-storybook": {
"type": "http",
"url": "https://<your-storybook>.chromatic.com/mcp"
}
}
}
- Run
/mcp in Claude Code CLI to trigger authentication
- A browser window opens to
claude.ai/api/organizations/.../mcp/start-auth/...
- Authentication fails — browser lands on
claude.ai/settings/mcp/auth_error with:
"An unknown error occurred during authentication."
What the OAuth discovery looks like
GET /.well-known/oauth-protected-resource returns:
{
"resource": "https://<storybook-url>/mcp",
"authorization_servers": ["https://www.chromatic.com"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["storybook:read", "project:read"]
}
GET https://www.chromatic.com/.well-known/oauth-authorization-server returns:
{
"issuer": "https://www.chromatic.com",
"authorization_endpoint": "https://www.chromatic.com/authorize",
"token_endpoint": "https://www.chromatic.com/token",
"client_id_metadata_document_supported": true,
"code_challenge_methods_supported": ["S256"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"scopes_supported": ["storybook:read", "project:read"],
"response_types_supported": ["code"]
}
Analysis
The Chromatic authorization server advertises client_id_metadata_document_supported: true (per the MCP OAuth spec), which means it should accept URL-based client IDs and fetch redirect URIs from the client's metadata document.
However, there is no registration_endpoint in the server metadata, meaning dynamic client registration (RFC 7591) is not supported.
When Claude Code CLI initiates the OAuth flow, it routes through claude.ai as the OAuth intermediary. Chromatic's authorization server appears to reject claude.ai's client ID, resulting in "An unknown error occurred during authentication."
Attempted workaround: Adding a hardcoded oauth.clientId (a Chromatic-issued client ID) to the MCP config does not resolve the issue — the same error occurs because the redirect URI for that client ID is registered for CLI/localhost use, not for claude.ai.
Expected behavior
The OAuth flow should complete successfully, redirecting back to the MCP client (Claude Code CLI or claude.ai) with a valid token for storybook:read access.
Possible root cause
Chromatic's OAuth server may not be correctly implementing the client_id_metadata_document_supported flow for external MCP clients. Specifically, it may not be fetching the client metadata document from claude.ai to validate the redirect URI, instead failing with an opaque "unknown error".
Workaround
None known at this time. Using a static bearer token via Authorization header in the MCP config works, but requires each user to manually manage their Chromatic token.
Reference
Summary
When using
@storybook/addon-mcpwith a private Chromatic-hosted Storybook, the MCP OAuth flow fails when connecting via Claude Code CLI or claude.ai Cowork. The browser opens for authentication but lands on an authentication error page.Environment
@storybook/addon-mcp: 0.4.2Steps to reproduce
@storybook/addon-mcpon a private Chromatic-hosted Storybook.mcp.json):{ "mcpServers": { "my-storybook": { "type": "http", "url": "https://<your-storybook>.chromatic.com/mcp" } } }/mcpin Claude Code CLI to trigger authenticationclaude.ai/api/organizations/.../mcp/start-auth/...claude.ai/settings/mcp/auth_errorwith:What the OAuth discovery looks like
GET /.well-known/oauth-protected-resourcereturns:{ "resource": "https://<storybook-url>/mcp", "authorization_servers": ["https://www.chromatic.com"], "bearer_methods_supported": ["header"], "scopes_supported": ["storybook:read", "project:read"] }GET https://www.chromatic.com/.well-known/oauth-authorization-serverreturns:{ "issuer": "https://www.chromatic.com", "authorization_endpoint": "https://www.chromatic.com/authorize", "token_endpoint": "https://www.chromatic.com/token", "client_id_metadata_document_supported": true, "code_challenge_methods_supported": ["S256"], "grant_types_supported": ["authorization_code", "refresh_token"], "scopes_supported": ["storybook:read", "project:read"], "response_types_supported": ["code"] }Analysis
The Chromatic authorization server advertises
client_id_metadata_document_supported: true(per the MCP OAuth spec), which means it should accept URL-based client IDs and fetch redirect URIs from the client's metadata document.However, there is no
registration_endpointin the server metadata, meaning dynamic client registration (RFC 7591) is not supported.When Claude Code CLI initiates the OAuth flow, it routes through
claude.aias the OAuth intermediary. Chromatic's authorization server appears to rejectclaude.ai's client ID, resulting in "An unknown error occurred during authentication."Attempted workaround: Adding a hardcoded
oauth.clientId(a Chromatic-issued client ID) to the MCP config does not resolve the issue — the same error occurs because the redirect URI for that client ID is registered for CLI/localhost use, not forclaude.ai.Expected behavior
The OAuth flow should complete successfully, redirecting back to the MCP client (Claude Code CLI or claude.ai) with a valid token for
storybook:readaccess.Possible root cause
Chromatic's OAuth server may not be correctly implementing the
client_id_metadata_document_supportedflow for external MCP clients. Specifically, it may not be fetching the client metadata document fromclaude.aito validate the redirect URI, instead failing with an opaque "unknown error".Workaround
None known at this time. Using a static bearer token via
Authorizationheader in the MCP config works, but requires each user to manually manage their Chromatic token.Reference