Descope and Model Context Protocol (MCP)
The Model Context Protocol (MCP), an open standard developed by Anthropic, defines how AI models and agents interact with external systems in a safe, consistent way.
This guide will walk you through the different components of MCP and how to use Descope to secure and authorize MCP servers and tools.
About MCP
Think of MCP like a USB-C port for AI: just as USB-C offers a universal interface for physical devices, MCP provides a standard protocol for connecting AI applications to external resources such as APIs, tools, files, or services.
Instead of bespoke integrations for every AI system, MCP introduces a standardized plug-and-play model that works across:
- AI agents and chat interfaces
- Developer tools like IDEs and CLIs
- Local and remote APIs, SaaS apps, and data services
- Secure, multi-tenant environments with structured access control
To learn more about MCP and its authentication model, refer to:
Why Use Descope with MCP
Descope provides a full suite of capabilities to help developers secure MCP servers and tools:
- OAuth 2.1 Authorization for MCP Servers: Add fully managed OAuth support using Inbound Apps, including consent, scope validation, and modern authentication flows (passwordless, SSO, etc.).
- Token Management for Tools and APIs: Store and issue OAuth tokens and static API keys for outbound API calls made from your MCP server or agent.
- Access Control and Policy Enforcement: Define policies that tie Descope token claims (like
scope
,roles
, or verification status) to what MCP tools and APIs are accessible.
Securing Your MCP Server with Descope
The MCP authorization spec is built on OAuth 2.1, enabling secure and standardized access control for agents. With Descope Inbound Apps you can:
- Issue and validate OAuth 2.1 compliant tokens, with authorization code and client credentials flows
- Enforce strict OAuth 2.1 security measures including PKCE, precise redirect URI matching, and configurable token lifetimes for short-lived access
- Let AI agents or tools self-register with Dynamic Client Registration
- Apply time-based consent policies with end-user control
- Create custom scopes for specific MCP tools and parts of your resource server
Inbound Apps provide a fully managed OAuth provider that handles token issuance, session management, and consent flows—so you can securely expose your product and APIs through an MCP server to remote agents and MCP clients with minimal custom code or infrastructure.
Option 1: Use the MCP Express SDK
Note
Currently available for Express/Node.js. Python support is coming soon.
The @descope/mcp-express
SDK provides a fully functional OAuth provider—powered by Descope Inbound Apps—and wraps your MCP server with all the necessary endpoints, session handling, and token validation. It provides:
- Standard OAuth endpoints and token routes
- Scope-based access validation middleware
- Dynamic Client Registration (DCR)
- Built-in integration with Descope Outbound Apps
→ Get Started with the MCP Express SDK
Option 2: Use Inbound Apps Directly
For other stacks (e.g., FastAPI, Go, FastMCP), you can integrate with Descope's OAuth 2.1 endpoints directly:
- Serve your own
.well-known
discovery if needed - Use Descope for DCR, authorization, token, and consent
- Validate incoming tokens and scopes using Descope's SDKs or your own middleware
If you wish to implement our Inbound Apps directly, you can find a code example in our Netlify example.
If you're using a different MCP framework like FastMCP, you can explore our other examples here.
Dynamic Client Registration
Descope supports customizable Dynamic Client Registration (DCR) with:
- Self-service registration for AI agents and tools, through a POST request to an OAuth compliant
/dynamic
endpoint - Customizable management flows (e.g. domain whitelisting, etc.)
- Auditing for all inbound app registrations, with request and response logs
- Smart rate limiting and IP-based registrations to prevent abuse
Due to the flexible nature of the management flow used with DCR, you can implement your own hardening requirements to make the client registration process more secure.
This is particuarly important for remote MCP servers exposed to the broader internet.
Scoping with MCP Servers
Progressive scoping is not currently supported in MCP servers. This is an open PR in the MCP spec, and not merged yet.
Scopes in Descope define what a caller (such as an AI agent or user) is allowed to do. When used with Inbound Apps, scopes are issued inside OAuth tokens and can be dynamically tied to:
- User roles (e.g.,
admin
,viewer
, etc.) - User attributes (e.g.,
department
,name
, etc.)
These scopes also have modifiable descriptions that make it easier for the user in the consent flow to understand what the app is requesting access to.
It's worth noting that scopes are not mandatory for use with your MCP server or inbound apps. You can choose to allow empty scopes if you wish to not use scopes at all.
However, this option is only allowed for DCR-based inbound apps at the moment.
Why Scopes Matter for MCP and Resource Servers
In any OAuth 2.1-based system, the resource server is responsible for enforcing the permissions granted in the token. Scopes are the standard mechanism for expressing those permissions.
In the context of MCP, your MCP server is the resource server—it exposes tools and services that must be protected. Scopes therefore give your server a way to:
- Differentiate between agents with read-only vs. write access
- Prevent unauthorized access to sensitive tools
- Enforce least-privilege access across users, tenants, and applications
Without scopes, all access would be binary, and would make fine-grained access control impossible.
Why Tool-Level Scopes Are Better Than Just Reusing OAuth Scopes
While standard OAuth scopes (like email
, calendar.read
, profile
) are useful, they don't reflect the intent or behavior of the tools being accessed within MCP.
For example, consider a tool in your MCP server called generate_invoice
. That tool might:
- Read from a billing database
- Call an external document-generation API
- Log an event in a customer service platform
Each of these operations might require different downstream scopes (e.g., billing.read
, docs.write
, zendesk.log_event
), but the tool itself should only be accessible if the intent to execute it is authorized.
By defining tool-level scopes like:
exec:generate_invoice
exec:workflows:*
tools:calendar-scheduler
You can:
- Treat tool invocation as a first-class permission
- Gate execution based on both user identity and context
- Issue tokens with scopes tailored to the tool's capabilities and not just the downstream API needs
- Allow a single token to represent composite intent, even if multiple downstream APIs are involved
This is particularly valuable for AI agent use cases, where:
- You want to authorize the agent to run specific tools (not arbitrary ones)
- Each tool might internally depend on different APIs or permissions
- User intent and tool scope should be auditable and revocable
Calling External APIs from Tools (Outbound Apps)
When your MCP tools need to call external APIs—such as Google Calendar, Salesforce, or Jenkins—you can use Descope Outbound Apps to manage and store both static and dynamic tokens per user or tenant.
With Outbound Apps, you can:
- Store multiple tokens per user or tenant, each with different scopes—even for the same third-party service or MCP server.
- Upload and manage user-scoped API keys for non-OAuth APIs using a secure consent flow, including for internal tools or custom MCP servers.
- Use the same token storage and management model for MCP server connections, treating them like any other external API—so your system can access multiple MCP servers or services from a single token store.
All tokens managed by Outbound Apps are securely stored in Descope and can be retrieved by your MCP tools or agents using Descope SDKs or APIs.
Access Control Plane
Descope's Access Control Plane is the final piece of a unified system that manages identity, consent, and authorization across your entire agentic stack.
With Inbound Apps, Descope authenticates your MCP clients and users—issuing tokens that carry roles, claims, scopes, and tenant info. With Outbound Apps, Descope securely stores and refreshes the tokens your MCP server needs to call external tools (e.g., Google Workspace, Asana, internal APIs).
The Access Control Plane bridges the two—evaluating every outbound token request based on the context of the inbound token and enforcing real-time access decisions.
This means:
- Your MCP server no longer has to manage scopes, refresh logic, or custom policy enforcement.
- Authorization decisions are centralized and based on the authenticated identity, not hardcoded logic.
- If access is denied (e.g., because the user's role doesn't permit write access), the token request is blocked, and the MCP tool will return a
403
or redirect the user through re-consent. - All of this happens dynamically—so changes in user roles, group membership, or policies are reflected instantly. This also integrates with existing Descope features, like SSO and SCIM
Depending on your MCP client, it may prompt the user to reconnect and re-consent if a token is blocked, or retry the request automatically.
By using Descope as the control plane for both inbound and outbound identity, your MCP server can focus entirely on tool execution logic—while Descope handles who gets to do what, where, and when.
Example: Role-Based Authorization with Real-Time Enforcement
Imagine your inbound app uses SSO via Okta or Azure AD. A user logs in and grants consent to use your MCP-based tools. Their token includes a roles: ["viewer"]
claim, based on their membership in a Viewer group in Okta.
You define a policy in Descope stating:
Users with the
Viewer
role can only access outbound scopes likecalendar.readonly
for Google Workspace, or a read-only API key for a third-party integration.
Now, every time the MCP server receives a request to execute a tool (e.g., pushing a calendar event), it checks with Descope to retrieve the appropriate outbound token.
Because the policy blocks access to calendar.write
for viewers, the request fails with a 403 Forbidden - Insufficient Scope
.
This model enables dynamic, identity-aware, real-time authorization—where outbound tool access is fully governed by your existing identity provider's role mapping and Descope's access policies.
Example Projects
For a list of example projects, please refer to our GitHub repository.
Key Examples:
- Express MCP Server - Express.js-based MCP server with authentication using our Express SDK
- FastAPI MCP Server - Python FastAPI-based MCP server, using FastAPI-MCP
- FastMCP MCP Server - Python FastMCP-powered MCP server, using FastMCP and their built-in Bearer Auth
- Next.js Vercel MCP Server - Next.js MCP server deployed to Vercel, using the Vercel MCP Adapter
Next Steps
Explore the documentation and examples above to start integrating Descope with your MCP server.
Whether building a secure server, connecting to external APIs, or managing tokens across organizations—Descope gives you everything needed to make your MCP implementation enterprise-ready.
If you have additional questions, you can contact us or join the AuthTown community.