Skip to main content

Clerk Changelog

MCP Server Support for Next.js

Category
Product
Published

Build an MCP service into your application with Clerk and Next.js in 5 minutes

We're excited to announce server-side support for the Model Context Protocol (MCP) in Next.js applications using Clerk authentication. This enables your users to securely grant AI applications like Claude, Cursor, and others access to their data within your app.

What is MCP?

MCP is an open standard that allows AI applications to request permission to access users' private information that would normally require authentication — like emails, private repositories, or application-specific data. This creates new possibilities for AI-powered workflows while keeping users in control of their data access.

If you are building an application using Clerk and would like for your users to be able to grant access to their data to AI applications, you can now do so with Clerk's MCP support 🎉.

Getting Started

Setting up an MCP server in your Next.js app is straightforward with Clerk's modern OAuth provider implementation. Here's an example of how the MCP route handler might look in your Next.js app:

// app/[transport]/route.ts
import { verifyClerkToken } from '@clerk/mcp-tools/next'
import { clerkClient } from '@clerk/nextjs/server'
import { createMcpHandler, experimental_withMcpAuth as withMcpAuth } from '@vercel/mcp-adapter'

const clerk = await clerkClient()

const handler = createMcpHandler((server) => {
  server.tool(
    'get-clerk-user-data',
    'Gets data about the Clerk user that authorized this request',
    {},
    async (_, { authInfo }) => {
      const userId = authInfo!.extra!.userId! as string
      const userData = await clerk.users.getUser(userId)
      return {
        content: [{ type: 'text', text: JSON.stringify(userData) }],
      }
    },
  )
})

const authHandler = withMcpAuth(
  handler,
  async (_, token) => {
    const clerkAuth = await auth({ acceptsToken: 'oauth_token' })
    return verifyClerkToken(clerkAuth, token)
  },
  {
    required: true,
    resourceMetadataPath: '/.well-known/oauth-protected-resource/mcp',
  },
)

export { authHandler as GET, authHandler as POST }

Implementation Details

Our MCP implementation is built on the current specification draft, ensuring compatibility with the latest protocol standards and authentication flows. We've worked closely with the MCP community and contributed to the specification and SDK to ensure robust, secure integrations.

Rather than requiring separate MCP servers with their own authentication protocols, our approach allows you to add MCP capabilities directly to your existing application through a single API endpoint. This eliminates the overhead of deploying and managing additional services - you can expose your app's functionality to AI tools without architectural complexity.

For legacy clients that use outdated implementations of the MCP protocol and/or do not support authentication, tools like mcp-remote can bridge the gap.

We are also grateful to Vercel for their fantastic work on the MCP Adapter, which this implementation leverages heavily. We've thoroughly enjoyed collaborating with their team on this project.

Connecting AI Tools

Once your MCP server is running, connecting it to AI tools is straightforward. For example, with Cursor, you can add this configuration:

{
  "mcpServers": {
    "clerk-mcp-example": {
      "url": "http://localhost:3000/mcp"
    }
  }
}

That's it — no stdio tools, command execution, or additional software installation required. Just provide the URL and authentication is handled automatically through the MCP protocol.

For a complete guide on testing your MCP server with various AI clients, check out our MCP client integration guide.

Customer Implementations

We've been developing MCP tooling publicly for the past few months and have been impressed by our customers' enthusiasm for building with this technology. The extensive testing and feedback we've received has been invaluable in shaping and stabilizing this release.

We'd like to highlight a couple of examples of customers who have deployed MCP servers with Clerk authentication to production:

These customers have been exceptional development partners, and their engineering teams are working hard to build innovative products and ensure that their users can integrate their products with MCP as easily as possible. We're proud to have them as part of the Clerk community and encourage you to explore their products as well as their new MCP integrations!

What's Next

This initial release focuses on Next.js support, with additional framework support coming soon. We're also working on expanded tooling and utilities to make MCP integration even more straightforward across different development environments.

Beyond server-side tooling, we're also building client-side tools to help AI applications connect with MCP endpoints more easily. If you're interested in early access for any of these features, please reach out to our support team, and we'll get you set up!

Check out our step-by-step MCP implementation guide in the documentation to get started with your first MCP-enabled endpoint.

We're excited to see what new AI-powered experiences you'll build with MCP and Clerk. If you have feedback or questions, we'd love to hear from you!

Contributor
Jeff Escalante

Share this article

Enterprise SSO connections now support multiple domains, making it easier to manage authentication across different subdomains and domains within your organization.

You can now add multiple domains to a single SSO connection directly from the Clerk Dashboard, eliminating the need to create separate connections for each domain or subdomain.

Contributor
Nicolas Lopes

Share this article

Tailwind CSS v4 support

Category
Product
Published

Introducing the cssLayerName option for compatibility with Tailwind CSS v4, allowing Clerk styles to be wrapped in a dedicated CSS cascade layer.

To ensure compatibility with Tailwind CSS v4 and its use of native CSS layers, and to provide more granular control over CSS specificity, Clerk now accepts a new cssLayerName option. This new option allows Clerk's component styles to be integrated into the native CSS layering system. When you provide a layer name, Clerk will automatically wrap all of its styles within that CSS layer.

How to use

  1. Add the cssLayerName prop to the appearance object of your ClerkProvider or Clerk options config, depending on your framework.

    layout.tsx
    import { ClerkProvider } from '@clerk/nextjs'
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <ClerkProvider
          appearance={{
            cssLayerName: 'clerk',
          }}
        >
          <html lang="en">
            <body>{children}</body>
          </html>
        </ClerkProvider>
      )
    }
  2. After specifying the cssLayerName option, you then need to specify the CSS layer order in your global stylesheet. This ensures that the layer you assigned to Clerk (e.g., "clerk") is correctly sequenced with Tailwind's layers and your custom styles:

    @layer theme, base, clerk, components, utilities;
    @import 'tailwindcss';

    This configuration ensures that Clerk styles are part of the cascade in a predictable way, playing nicely with Tailwind CSS v4's architecture and allowing you to utilize Tailwind's utility classes within Clerk's appearance object.

Contributor
Alex Carpenter

Share this article

OAuth Provider Improvements

Category
Product
Published

Expanded OAuth functionality that paves the way for MCP support

We're excited to announce a major expansion to Clerk's OAuth capabilities! This release adds the following features to Clerk:

  • OAuth tokens generated through Clerk's OAuth endpoints can now be verified through Clerk's SDKs and instantly revoked.
  • Clerk now supports authorization server metadata out of the box.
  • The OAuth authorization flow now includes a consent screen that displays the access that the user is granting and ensures that they are ok with it before completing the flow.
  • Implementing public clients (that must complete the token exchange in the browser) with Clerk's OAuth feature is now possible due to changes to our CORS handling.
  • Clerk now supports dynamic client registration for OAuth clients.
  • Clerk's OAuth implementation is compatible with all the requirements needed to implement MCP services using Clerk as an authorization service.

We have been working hard for the last few months on these features and are beyond excited to finally get them into our customers and users' hands. Many thanks to everyone who helped us to test and refine them through our early access program!

What is OAuth?

If you're a web developer, you have no doubt heard the term “OAuth” and know it's in some way related to authentication, or maybe to single sign on, but for the vast majority of engineers, this is about as far as it goes. Truth be told, OAuth is quite a confusing topic, largely because the term “OAuth” is used to refer to three entirely different features, and there is no clear way to differentiate between them. We wrote a detailed post explaining OAuth in general, as well as these three distinctions that you can read here. The key takeaway: these new features enable OAuth scoped access - allowing third-party applications to access user data with explicit permission and limited scope.

Let's recap the three OAuth use cases:

  1. OAuth Scoped Access - The features from this announcement enable this
  2. OAuth SSO - We already had support for this
  3. OAuth User Management - We do user management, but not via OAuth

With this background out of the way, let's get into an example of how these new features work!

Implementing OAuth scoped access

If you'd like to take this feature for a spin, we have a guide on how to implement OAuth scoped access into a Clerk application right here. It just takes a few minutes to configure an OAuth client in Clerk's dashboard and start using it.

Verifying OAuth access tokens with Clerk

If you are building an application that uses Clerk and would like to incorporate OAuth, you will want to ensure that, after the client gets an OAuth access token, they can use it to make authenticated requests into your app (the resource service) using the token. Let's look at an example of how this could be done on an API route with Clerk's Next.js SDK:

// app/api/example/route.ts
import { auth } from '@clerk/nextjs'

export async function GET() {
  const { userId, isAuthenticated } = await auth({
    acceptsToken: 'oauth_token',
  })

  if (!isAuthenticated) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  // pseudo-code: get user data from a database
  const userData = await getUserDataFromDatabase({ clerkUserId: userId })

  return Response.json(userData)
}

To learn more about verifying machine tokens with Clerk, check out our new OAuth documentation on the topic right here.

OAuth token verification through Clerk is currently available across most of our SDK ecosystem, making it easy to build resource servers that can authenticate requests from OAuth clients.

Fully supported:

Coming soon:

  • Astro SDK
  • Nuxt SDK
  • PHP SDK
  • Go SDK
  • Ruby SDK
  • Expo SDK
  • iOS SDK

If you're using one of the "coming soon" SDKs, you can verify OAuth tokens using Clerk's REST API directly:

curl https://api.clerk.com/oauth_applications/access_tokens/verify \
  -X POST \
  -H 'Authorization: Bearer your-clerk-api-key-here' \
  -H 'Content-Type: application/json' \
  -d '{ "access_token": "your-oauth-token-here" }'

Want to help prioritize? Let us know on our roadmap which SDK you need most!

The new OAuth consent screen ensures users understand exactly what permissions they're granting before completing the OAuth flow.

The consent screen displays:

  • The requesting application's name and logo
  • Specific scopes being requested in user-friendly language
  • Clear accept/deny options
Clerk's OAuth consent screen

In order to avoid breaking changes and security issues, we have implemented the following settings with respect to the consent screen

  • New OAuth applications: Consent screen enabled by default
  • Existing OAuth applications: Disabled by default (to avoid breaking changes), but we strongly recommend enabling it
  • OAuth applications with dynamic client registration enabled: Consent screen automatically enforced and cannot be disabled

You can toggle the consent screen in the settings for any individual OAuth application on the Clerk dashboard.

A screenshot of the OAuth "consent screen" setting in the Clerk dashboard

We strongly recommend enabling the consent screen for all OAuth applications. Without a consent screen, any logged-in user who visits an OAuth authorization URL automatically grants access to any requested scopes. The consent screen acts as a critical security checkpoint, preventing malicious applications from silently gaining access to user accounts.

Dynamic client registration

Clerk now supports dynamic client registration, allowing OAuth clients to be created programmatically via API in addition to manually through the dashboard.

You can enable this feature through a toggle in your OAuth applications settings:

A screenshot of the "enable dynamic client registration" setting in the Clerk dashboard

What is dynamic client registration? If you're unfamiliar with this OAuth extension, we cover it in detail (including real-world use cases and security considerations) in our comprehensive OAuth guide, and our documentation.

Building an MCP service using Clerk's OAuth server

We've heard loud and clear from our users about the interest in leveraging OAuth to support MCP integrations. With this set of improvements to our OAuth capabilities, building MCP services that use Clerk as their authorization server becomes possible.

MCP services often need to access user data from various sources on behalf of AI applications. This requires robust OAuth flows with proper consent management, token verification, and security controls - exactly what Clerk's enhanced OAuth features provide. The combination of dynamic client registration (for registering MCP servers programmatically), the consent screen (for secure user authorization), and comprehensive SDK support makes Clerk an ideal authorization server for MCP implementations.

Imagine the following example of a real-world use case. Say you've built a project management tool using Clerk for authentication. With Clerk's OAuth server, you can easily expose an MCP endpoint that allows AI applications like Cursor, ChatGPT, Claude, or Windsurf to securely access your users' project data. Your users can authorize these AI tools through Clerk's consent screen, and the AI applications can then help with tasks like generating project summaries, suggesting optimizations, or automating workflows - all while maintaining secure, user-controlled access to your application's data.

We will have another post coming soon that goes into detailed implementation of building MCP services using Clerk's OAuth server. In the meantime, if you'd like to peek behind the curtains, we have a reference implementation of an MCP service using next.js and Clerk right here.

Custom scopes: coming soon

We don't yet have support for adding custom OAuth scopes, we wanted to get these new OAuth features into our users' hands as quickly as they were usable and stable, which we feel like they are now. Next on our list is implementing a way that custom scopes can be added, accepted, and checked through our SDKs. We'll have another update coming your way soon when this feature is available!

If you're interested in getting involved with early access for custom OAuth scopes, please add a vote and/or feedback to the item on our roadmap here and we'll be in touch soon!

Aside: didn't Clerk already have OAuth support?

Sort of - while Clerk previously had endpoints for OAuth, and docs for how to configure it for SSO, this implementation was built specifically for SSO integration with Shopify and was lacking several critical features that are necessary for broad usage:

  • The OAuth access token returned was not accepted by any of Clerk's SDKs and did not have a method for verifying its authenticity, making it not very useful as an access token.
  • There was no OAuth consent page implemented, meaning that users going through the OAuth flow would not get the chance to review and accept scopes being requested by the third party. As long as the user was signed in, and visited an authorize link, the access request would be automatically accepted. There are some cases when only limited scopes are available and the flow is only being used for SSO where this can make sense (which was the case with the previous implementation), but outside of that it's a substantial security risk.
  • While PKCE was previously implemented in order to support public clients, Clerk's API would reject any requests to the token endpoint made from a browser due to incomplete CORS configuration, making the public client flow for most use cases non-functional.
  • The OAuth applications page in Clerk's dashboard had no pagination, so any more than 10 applications were not displayed and unable to be accessed at all.
  • There was no support for dynamic client registration, an OAuth protocol extension that is a frequent requirement for use with MCP services.
  • There was no way to create custom scopes and add them to OAuth requests

With the current release, all of these points (outside of the custom scopes, but that's coming very soon) are now resolved, and we feel confident that this is a feature-complete release of a built-in OAuth server for OAuth scoped access.

Contributors
Jeff Escalante
Ben Werner
Robert Soriano
Brandon Romano

Share this article

Billing MRR Report

Category
Dashboard
Published

View Monthly Recurring Revenue trends with a new interactive chart.

We've added a new MRR chart to the Subscriptions tab, making it easier to track revenue growth over time.

Contributors
Iago Dahlem
Maurício Antunes

Share this article

Improved Invoices

Category
Product
Published

We've improved the invoice format to make things easier to read.

Before, all line items showed up with the same label, even if they referred to different features of the same product. That made it hard to tell what each charge was for.

Now, items are grouped by their feature name. It's a much clearer view of what you're paying for.

Invoice Preview

This is already live. No action needed. Next invoice should look a lot nicer.

Contributor
Clerk

Share this article