Files
Enes Gules 21c3dd464e feat(mcp): authenticate and track Claude Code plugin (#3028)
* 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>
2026-09-04 11:44:54 +03:00
..