Guides and Tutorials/Model Context Protocol (MCP)

MCP Express SDK

The MCP Express SDK is a TypeScript-based Express library that leverages Descope auth and user management capabilities to allow you to easily add Model Context Protocol (MCP) Specification compliant-Authorization to your MCP Server. It implements the provider side of the OAuth 2.1 protocol with PKCE support, Dynamic Client Registration, and Authorization Server Metadata.

Prerequisites

Before you begin, ensure you have:

  • An existing Descope project
  • An existing Express application
  • Node.js version 18.x or higher

Installation

npm install @descope/mcp-express

Quick Start

  1. Get your credentials from the Descope Console

  2. Create a .env file in your project root:

DESCOPE_PROJECT_ID=<your_project_id>
DESCOPE_MANAGEMENT_KEY=<your_management_key>
SERVER_URL=<your_mcp_server_url>

Note

The SERVER_URL is the URL of your MCP Server. eg. http://localhost:3000 or https://mcp.example.com

  1. Ensure that the environment variables are loaded, for example by using dotenv:
npm install dotenv
  1. Then, you can use the SDK as follows:
import "dotenv/config";
import express from "express";
import {
  descopeMcpAuthRouter,
  descopeMcpBearerAuth,
} from "@descope/mcp-express";
 
const app = express();
 
app.use(descopeMcpAuthRouter());
 
app.use(["/sse", "/message"], descopeMcpBearerAuth());
 
app.listen(3000);

The descopeMcpAuthRouter() function adds the metadata and route handlers (eg. dynamic client registration) to the server while the descopeMcpBearerAuth() function checks the request's headers for a Bearer token and, if found, attaches the Auth object to the request object under the auth key.

  1. TypeScript Support (Optional)

If you're using TypeScript, you can add a type declaration to get proper type checking for the auth property that gets attached to the Express request object. Create a new file (e.g., types/globals.d.ts) and add:

declare module "express-serve-static-core" {
  interface Request {
    /**
     * Information about the validated access token, if the `descopeMcpBearerAuth` middleware was used.
     * Contains user information and token details after successful authentication.
     */
    auth?: AuthInfo;
  }
}

This type declaration will:

  • Enable TypeScript autocompletion for the auth property on request objects
  • Provide type safety when accessing auth-related properties
  • Help catch potential type-related errors during development

Example usage in your route handlers:

app.post("/message", async (req, res) => {
  // TypeScript now knows about req.auth
  if (req.auth) {
    // Access auth properties with full type support
    console.log(req.auth.token);
    console.log(req.auth.scopes);
  }
});

Advanced Usage

Dynamic Client Registration

You can configure dynamic client registration options when initializing the provider:

import express from "express";
import {
  descopeMcpAuthRouter,
  descopeMcpBearerAuth,
} from "@descope/mcp-express";
 
const app = express();
 
const provider = new DescopeMcpProvider({
  // The below values are defaults and can be omitted
  // if the environment variables are set and loaded
  projectId: process.env["DESCOPE_PROJECT_ID"],
  managementKey: process.env["DESCOPE_MANAGEMENT_KEY"],
  serverUrl: process.env["SERVER_URL"],
 
  dynamicClientRegistrationOptions: {
    authPageUrl: `https://api.descope.com/login/${DESCOPE_PROJECT_ID}?flow=consent`,
    permissionScopes: [
      {
        name: "get-schema",
        description: "Allow getting the SQL schema",
      },
      {
        name: "run-query",
        description: "Allow executing a SQL query",
        required: false,
      },
    ],
  },
});
 
// Add metadata and route handlers (eg. dynamic client registration)
app.use(descopeMcpAuthRouter(provider));
 
// Add bearer token validation
app.use(["/sse", "/message"], descopeMcpBearerAuth(provider));
 
app.listen(3000);

Token Verification

You can customize the token verification options by setting the verifyTokenOptions object:

import { descopeMcpBearerAuth, DescopeMcpProvider } from "@descope/mcp-express";
 
const provider = new DescopeMcpProvider({
  verifyTokenOptions: {
    requiredScopes: ["get-schema", "run-query"],
    key: "descope-public-key",
  },
});

Features

The SDK implements the Model Context Protocol Auth Specification, providing:

  • 🔐 Hosted Metadata
  • 🔑 Authorize endpoint
  • 🎫 Token endpoint
  • 🔒 Token revocation endpoint
  • 📝 Dynamic Client Registration

OAuth Implementation

This SDK implements OAuth 2.0/2.1 following these RFCs:

  • RFC 8414: OAuth 2.0 Authorization Server Metadata
  • RFC 7591: OAuth 2.0 Dynamic Client Registration
  • RFC 7009: OAuth 2.0 Token Revocation

All OAuth schemas are implemented using Zod for runtime type validation.

Was this helpful?

On this page