* feat(mcp): require auth on /mcp when client is a plugin
Plugin hosts such as Claude Code only start OAuth for servers that 401 at
connect time. Matching Exa MCP, ?client=claude-code-plugin (any client
value containing "plugin") now gates /mcp the same way /mcp/oauth does,
while anonymous access on the public URL is unchanged.
Co-authored-by: Enes Gules <enesgules@users.noreply.github.com>
* chore(mcp): drop the SDK OAuth-helpers TODO
The v2 helpers (bearerAuthChallengeResponse, oauthMetadataResponse) assume
Bearer-only OAuth on a fetch() handler. This server also accepts API keys,
mixes anonymous and required routes, returns JSON-RPC 401 bodies, and
proxies authorization-server metadata live, so they are not a drop-in.
Co-authored-by: Enes Gules <enesgules@users.noreply.github.com>
* docs: keep the plugin client auth gate out of user-facing docs
The ?client=claude-code-plugin gate stays in the server and Claude plugin
URL. OAuth docs continue to describe /mcp/oauth only.
Co-authored-by: Enes Gules <enesgules@users.noreply.github.com>
* simplify Claude plugin auth tracking
* separate plugin and client metrics
* extract plugin request detection
* simplify MCP request handling
* extract authentication policy
* use OAuth for Claude Code plugin
* support API key or OAuth in Claude plugin
* simplify Claude plugin authentication
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Enes Gules <enesgules@users.noreply.github.com>
Co-authored-by: Fahreddin Özcan <ozcanfahrettinn@gmail.com>