ai icon indicating copy to clipboard operation
ai copied to clipboard

Oauth Dynamic Client Registration should be optional

Open dylang opened this issue 1 month ago • 3 comments

Description

Currently, it seems like our MCP client oauth implementation requires dynamic client registration (DCR): https://github.com/vercel/ai/blob/233e9b295e14acf2a000f3cbabfdb5d29575634f/packages/mcp/src/tool/oauth.ts#L797-L802

While DCR is a frequent choice for public server implementations, it is optional according to the MCP specification, and not ideal for some secure enterprise situations, as well as legacy systems that do not support DCR.

According to the MCP spec, pre-registered clients must be supported, and that's what I believe we are currently missing support for.

https://modelcontextprotocol.io/docs/tutorials/security/authorization

AI SDK Version

@ai-sdk/[email protected]

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

dylang avatar Nov 07 '25 01:11 dylang

Hi @dylang , thanks for opening this issue! I will look into how we can support non DCR servers.

Just a couple of questions to understand your use-case:

  • is there any specific mcp server you had in mind? will make it easier to iterate on.
  • when using the AI SDK's experimental_MCPClient you're basically creating a new MCP client every time. So then how do we expect that client to be preregistered with the server? Maybe I'm missing something. Do you mean to pass something like the OAuth token directly to the server via some configuration?

aayush-kapoor avatar Nov 10 '25 21:11 aayush-kapoor

Hi @aayush-kapoor - right now it's just our internally created enterprise MCP servers.

The way it works without dynamic registration is by providing a known pre-registered client id.

dylang avatar Nov 10 '25 22:11 dylang

@dylang so if you refer the example in https://github.com/vercel/ai/blob/145523f00f2a98e5dee2c2ab42de62a457287b2e/examples/mcp/src/mcp-with-auth/client.ts#L27-L30

you should be able modify the InMemoryOAuthClientProvider (that you have implemented for your app) to be able to hardcode the _clientInformation by doing something like this:

private _clientInformation: OAuthClientInformation = {
    client_id: process.env.CLIENT_ID || 'your-pre-registered-client-id',
    client_secret: process.env.CLIENT_SECRET, // Optional for public clients
  };

aayush-kapoor avatar Nov 13 '25 22:11 aayush-kapoor