Summary
The ?utm_source=plugin query string appended to the MCP server URL breaks the OAuth flow in Claude Code. Authorization fails with:
Error
Authentication failed
Close this tab and try again from Claude Code.
invalid_target: The resource parameter does not match this authorization server
The plugin installs fine and its skills load, but the MCP server can never be authenticated, so none of its tools are usable.
Root cause
https://mcp.sentry.dev publishes this protected-resource metadata:
$ curl -s https://mcp.sentry.dev/.well-known/oauth-protected-resource/mcp
{
"resource": "https://mcp.sentry.dev/mcp",
"authorization_servers": ["https://mcp.sentry.dev"],
"scopes_supported": ["org:read", "project:write", "team:write", "event:write"],
"bearer_methods_supported": ["header"]
}
The canonical resource identifier is https://mcp.sentry.dev/mcp — no query component.
Claude Code derives the RFC 8707 resource parameter from the configured server URL, so it sends
resource=https://mcp.sentry.dev/mcp?utm_source=plugin. RFC 8707 requires the resource indicator to
match the protected resource identifier, and the authorization server correctly rejects the
mismatch with invalid_target.
Evidence
Two OAuth entries accumulated in the macOS keychain under Claude Code-credentials → mcpOAuth,
one per URL variant (the key is derived from the server URL):
| entry |
serverUrl |
state |
plugin:sentry:sentry|800cb29a… |
https://mcp.sentry.dev/mcp |
dynamic client registration completed (clientId + full scopes present), no token |
plugin:sentry:sentry|b328196b… |
https://mcp.sentry.dev/mcp?utm_source=plugin |
never got a clientId |
The clean URL gets through client registration; the utm_source variant fails before it.
Affected files
?utm_source=plugin appears in three distribution configs, so this affects more than the Claude Code plugin:
src/plugins/claude/plugin.json
src/plugins/agent-plugin/mcp.json
mcp.json
Reproduction
- Install the Sentry plugin in Claude Code (
sentry@claude-plugins-official, v1.3.2)
- Enable it and run
/mcp → sentry → Authenticate
- Browser tab shows the
invalid_target error above
Workaround
Edit the installed plugin manifest and strip the query string:
"mcpServers": {
"sentry": {
"type": "http",
- "url": "https://mcp.sentry.dev/mcp?utm_source=plugin"
+ "url": "https://mcp.sentry.dev/mcp"
}
}
on macOS at
~/.claude/plugins/cache/claude-plugins-official/sentry/<version>/.claude-plugin/plugin.json.
This is overwritten on the next plugin update.
Suggested fix
TELEMETRY.md documents that ?utm_source=plugin exists so distributed MCP configs are attributed
on spans, so simply deleting it would lose that signal. Two options that keep attribution intact:
- Move attribution out of the URL — carry it in a request header (e.g.
X-Sentry-Client or a
User-Agent suffix) rather than the resource URI. The URL is load-bearing for OAuth; the header
is not.
- Canonicalize
resource server-side — have the authorization server strip the query component
before comparing resource indicators. This fixes existing installs without a plugin release, but
only helps clients talking to mcp.sentry.dev.
Option 1 seems preferable — it keeps the resource identifier spec-compliant for every client, not
just ones that happen to hit a lenient server.
Environment
- Claude Code 2.1.197
- Sentry plugin 1.3.2 (
sentry@claude-plugins-official)
- macOS 26.5.1
Summary
The
?utm_source=pluginquery string appended to the MCP server URL breaks the OAuth flow in Claude Code. Authorization fails with:The plugin installs fine and its skills load, but the MCP server can never be authenticated, so none of its tools are usable.
Root cause
https://mcp.sentry.devpublishes this protected-resource metadata:The canonical resource identifier is
https://mcp.sentry.dev/mcp— no query component.Claude Code derives the RFC 8707
resourceparameter from the configured server URL, so it sendsresource=https://mcp.sentry.dev/mcp?utm_source=plugin. RFC 8707 requires the resource indicator tomatch the protected resource identifier, and the authorization server correctly rejects the
mismatch with
invalid_target.Evidence
Two OAuth entries accumulated in the macOS keychain under
Claude Code-credentials→mcpOAuth,one per URL variant (the key is derived from the server URL):
serverUrlplugin:sentry:sentry|800cb29a…https://mcp.sentry.dev/mcpclientId+ full scopes present), no tokenplugin:sentry:sentry|b328196b…https://mcp.sentry.dev/mcp?utm_source=pluginclientIdThe clean URL gets through client registration; the
utm_sourcevariant fails before it.Affected files
?utm_source=pluginappears in three distribution configs, so this affects more than the Claude Code plugin:src/plugins/claude/plugin.jsonsrc/plugins/agent-plugin/mcp.jsonmcp.jsonReproduction
sentry@claude-plugins-official, v1.3.2)/mcp→sentry→ Authenticateinvalid_targeterror aboveWorkaround
Edit the installed plugin manifest and strip the query string:
"mcpServers": { "sentry": { "type": "http", - "url": "https://mcp.sentry.dev/mcp?utm_source=plugin" + "url": "https://mcp.sentry.dev/mcp" } }on macOS at
~/.claude/plugins/cache/claude-plugins-official/sentry/<version>/.claude-plugin/plugin.json.This is overwritten on the next plugin update.
Suggested fix
TELEMETRY.mddocuments that?utm_source=pluginexists so distributed MCP configs are attributedon spans, so simply deleting it would lose that signal. Two options that keep attribution intact:
X-Sentry-Clientor aUser-Agentsuffix) rather than the resource URI. The URL is load-bearing for OAuth; the headeris not.
resourceserver-side — have the authorization server strip the query componentbefore comparing resource indicators. This fixes existing installs without a plugin release, but
only helps clients talking to
mcp.sentry.dev.Option 1 seems preferable — it keeps the resource identifier spec-compliant for every client, not
just ones that happen to hit a lenient server.
Environment
sentry@claude-plugins-official)