> ## Documentation Index
> Fetch the complete documentation index at: https://stytch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate with MCP servers on Vercel

> Create a remote MCP server with Stytch authentication on Vercel.

In this guide, we'll walk through the creation of a Remote Model Context Protocol (MCP) server which manages authentication as a Stytch Connected App. We will be examining a simple application that manages a list of tasks (TODO app) ([GitHub project](https://github.com/stytchauth/vercel-mcp-example)). The web app is managed as a single page app hosted with Vercel, and additionally the server implements the MCP protocol to become accessible to a Large Language Model (LLM) MCP client. This app can be run locally and can also be deployed on Vercel, but the basic concepts we'll cover here generalize to any cloud platform capable of hosting an MCP server.

## Pre-requisites

In order to complete this guide, you'll need:

* A Stytch project. If you don't have one already, or would like to create a new one, in the [**Dashboard**](https://stytch.com/dashboard), click on your existing project name in the top left corner of the Dashboard, click **Create Project**, and then select Consumer Authentication.
* The [MCP Inspector](https://github.com/modelcontextprotocol/inspector). This is a tool that will help us ensure that our MCP server is exposing the correct interface, is running properly, and allows us to explore the features of the MCP protocol in a web-based tool.

## Create a remote MCP server

<Steps>
  <Step title="Configure Stytch for our example app">
    Navigate to "Project Settings" to note your "Project ID" and "Public token". You will need these values later.

    <img src="https://mintcdn.com/stytch-34ca0595/FB84jLh1Rx_Ls_jG/images/connected-apps/guides/remote-mcp-server-step-1.png?fit=max&auto=format&n=FB84jLh1Rx_Ls_jG&q=85&s=f7e77da6774e7757589d1810d8cb3ab1" alt="Remote Mcp Server Step 1" width="3000" height="1812" data-path="images/connected-apps/guides/remote-mcp-server-step-1.png" />

    Navigate to "Frontend SDKs" to enable the Frontend SDK for `http://localhost:3000`

    <img src="https://mintcdn.com/stytch-34ca0595/FB84jLh1Rx_Ls_jG/images/connected-apps/guides/remote-mcp-server-step-2.png?fit=max&auto=format&n=FB84jLh1Rx_Ls_jG&q=85&s=d9a72cff2e3ba48c642b0b71490252d3" alt="Remote Mcp Server Step 2" width="3000" height="1500" data-path="images/connected-apps/guides/remote-mcp-server-step-2.png" />

    Navigate to "Connected Apps" and enable "Allow dynamic client registration".

    <Note>
      [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) is a protocol that allows applications to register themselves with Stytch as a Connected App client. We will dive more into how Dynamic Client Registration works later in this guide.
    </Note>

    <img src="https://mintcdn.com/stytch-34ca0595/FB84jLh1Rx_Ls_jG/images/connected-apps/guides/remote-mcp-server-step-3.png?fit=max&auto=format&n=FB84jLh1Rx_Ls_jG&q=85&s=d8973abdb807ee5e3616d3bb57a6a350" alt="Remote Mcp Server Step 3" width="3000" height="1500" data-path="images/connected-apps/guides/remote-mcp-server-step-3.png" />
  </Step>

  <Step title="Clone the GitHub repository for this guide">
    The companion repository for this guide is located [in GitHub](https://github.com/stytchauth/vercel-mcp-example). Go to that repository, clone it, and follow the README to get the TODO app up and running on your local machine.

    Once you have the example up and running, explore its functionality and start to get a sense of how the app is structured, then return here for a tour of the app's implementation.
  </Step>

  <Step title="Examine how the app manages data">
    This demo is structured as a lightweight single page app / MCP server that uses Stytch's frontend SDKs both to manage auth and also implement the todo list functionality. This is done using Stytch's `untrusted_metadata` field on the `user` object to store the list data itself rather than a dedicated database--although the architecture operates in such a way that a [different data layer](https://github.com/stytchauth/vercel-mcp-example/blob/a78f87aa19c449f046d15b5067b4c09dfeaa3876/src/services/TodoService.ts#L15) can be used.)
  </Step>

  <Step title="Learn how the MCP server is defined">
    The [MCP Core architecture documentation](https://modelcontextprotocol.io/docs/concepts/architecture) is a good reference for understanding how an MCP server is implemented.

    <Accordion title="Summary of relevant concepts">
      MCP servers use a protocol based on JSON-RPC 2.0 for message passing between the remote MCP server (what we're building) and the client, which is the LLM that is integrating with the server. The RPC protocol uses POST requests to the MCP server which either return a JSON payload or uses Server-Sent Events to pass messages back and forth between the server and client. There are a few core primitives (Resources, Prompts, Tools, etc...) defined by the MCP specification that describe the schema of the messages in this protocol and what behaviors can be expected.

      This is a structurally different protocol than vanilla HTTP requests, so implementing a Remote MCP server is more nuanced than a typical HTTP request/response flow. Thankfully there are libraries to assist in implementing MCP servers. Our example uses [@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk) and [@vercel/mcp-adapter](https://www.npmjs.com/package/@vercel/mcp-adapter) to handle the specifics of conforming with the MCP protocol.

      The details of how exactly an MCP server defines its components are implementation-dependent, but for the purposes of this walkthrough the key concept is that MCP defines a protocol for our server to implement in order to establish communications with an LLM client. This protocol can coexist with an HTTP server or stand on its own, but the fundamentals of establishing authentication and access control are similar for each.

      The implementation for the MCP server in this example can be found in [TodoMCP.ts](https://github.com/stytchauth/vercel-mcp-example/blob/a78f87aa19c449f046d15b5067b4c09dfeaa3876/src/services/TodoMCP.ts#L16)
    </Accordion>

    We'll dive more deeply into how authentication is implemented in the next step.
  </Step>

  <Step title="Learn how authentication and authorization with Stytch is implemented">
    <AccordionGroup>
      <Accordion title="Dynamic Client Registration">
        [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) is an OAuth standard for allowing a client to automatically register itself with an Identity Provider (IDP) server and is included as part of the Remote MCP protocol.

        MCP servers should implement the Oauth 2.0 [Protected Resource Metadata](https://datatracker.ietf.org/doc/html/rfc9728) standard. The first time the MCP Inspector attempts to access our TODO app (the protected resource) without credentials it will receive a `401 Unauthorized` response with a `WWW-Authenticate` header. This header points to a server which has authorization metadata, which is also this app. In the app there is a route at `/.well-known/oauth-protected-resource` which returns metadata about where to find its authorization server (the Stytch subdomain for your project). Once this location is known, Stytch and the MCP Inspector will handle the rest of the Dynamic Client Registration process to create a new [Connected Apps](/connected-apps/overview) client.
      </Accordion>

      <Accordion title="Connected Apps authorization">
        All dynamically registered clients are Third Party Public apps and will show up in the Stytch Dashboard when registration is complete.

        <img src="https://mintcdn.com/stytch-34ca0595/FB84jLh1Rx_Ls_jG/images/connected-apps/guides/remote-mcp-server-step-5.png?fit=max&auto=format&n=FB84jLh1Rx_Ls_jG&q=85&s=87fb40323ff89d7532fff2c365b151f0" alt="Remote Mcp Server Step 5" width="3000" height="1500" data-path="images/connected-apps/guides/remote-mcp-server-step-5.png" />

        Now that the MCP Inspector is registered as a client app the flow continues through the standard Connected Apps authorization process. As the MCP Inspector is a "Third Party" app, this includes showing an access request dialog for the user to allow the MCP Inspector to access data in our app. Upon completion of this flow the MCP inspector should show a successful connection and allow access to the data managed by our TODO app.
      </Accordion>

      <Accordion title="Authentication">
        In the web client, the app wraps its components in a [parent component](https://github.com/stytchauth/vercel-mcp-example/blob/a78f87aa19c449f046d15b5067b4c09dfeaa3876/src/components/Auth.tsx#L21) that enforces authentication. This component verifies that there is a current Stytch user logged in before rendering its child component. If no user is logged in, it redirects to the login page.

        For the MCP server we use Stytch's [headless frontend SDK to authenticate](https://github.com/stytchauth/vercel-mcp-example/blob/a78f87aa19c449f046d15b5067b4c09dfeaa3876/src/services/TodoMCP.ts#L11). This retains user information from when we authorized the app connecting to our MCP server and uses this to make requests to Stytch's API.
      </Accordion>

      <Accordion title="Authorization">
        Rather than implementing specific authorization logic, the use of user-scoped `untrusted_metadata` means that each user will only see their own data.

        If you would be interested to see how to implement more nuanced authorization rules with a Stytch B2C project, read [this guide](/api-reference/consumer/api/rbac/get-rbac-policy) on how this can be achieved with Stytch metadata. Additionally, a more robust authentication implementation with Stytch Role-Based Access Control can be found in our [B2B MCP Server example app](/connected-apps/guides/remote-mcp-servers).
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Deploying to Vercel">
    Vercel naturally supports deploying by linking a Github repository; just note, after the deploy, the location of the server will have changed away from `localhost`, which requires additional configuration in Stytch. Once you have the URL for your Vercel app, repeat the process in Step 1 to add this URL as an "Authorized Application" in the "Frontend SDK" settings.
  </Step>
</Steps>

## What's next

* View our guide on our [B2B MCP Server example app](/connected-apps/guides/remote-mcp-servers) to see a similar app using B2B Authentication with OAuth scopes and Role-Based Access Control
* View a similar walkthrough for deploying and MCP server as a [Cloudflare Worker](/connected-apps/guides/mcp-servers-cloudflare)
* Familiarize yourself with [Stytch's B2B SDKs](/api-reference/b2b/api/sdks) and [Consumer SDKs](/api-reference/consumer/api/sdks) for a deeper dive on how to integrate your MCP server with Stytch.
* Browse the [Model Context Protocol](https://modelcontextprotocol.io/introduction) documentation for more information about Remote MCP Servers.
