Dhaval Dalvadi
03/28/2026, 9:09 AMDevRev
03/28/2026, 9:10 AM# Example using Descope Python MCP SDK
from descope_mcp import DescopeMCPServer
server = DescopeMCPServer(
project_id="your-project-id",
management_key="your-management-key"
)
IP Whitelisting Options
For network-level security, Descope provides static IP addresses that you can whitelist . All outbound requests from Descope services originate from a fixed set of static IP addresses, making it straightforward to configure firewalls and access controls .
• Static IPs are available on Pro+ tier plans
• Required for regulated environments (SOC 2, HIPAA, PCI)
• Enables predictable network behavior for firewall configuration
Bring Your Own Auth for MCP | Descope Documentation
Agentic Identity Control Plane | Descope Documentation
Configuring Public Static IPs | Descope DocumentationDhaval Dalvadi
03/28/2026, 9:15 AMDevRev
03/28/2026, 9:15 AM// Standard OAuth 2.1 authorization code flow
const authUrl = `<https://api.descope.com/oauth2/v1/authorize>?
client_id=your_client_id&
response_type=code&
scope=mcp:tools&
redirect_uri=your_callback`
Why the SDK Helps
The Python MCP SDK simplifies integration by handling token exchange, validation, and MCP-specific authorization patterns . It reduces implementation to "five lines of code" with enterprise-grade access policy support .
Serverless Option
You can configure MCP servers in Descope without hosting additional infrastructure. Descope manages the authorization server functionality, client registration (DCR/CIMD), and token issuance . Your MCP server only needs to validate the tokens Descope issues.
Bring Your Own Auth for MCP | Descope Documentation
Descope Joins the Agentic AI Foundation (AAIF)Dhaval Dalvadi
03/28/2026, 9:20 AMDevRev
03/28/2026, 9:20 AM<claude://oauth-callback/*>
4. Your JAR server must host OAuth metadata at: <server-url>/.well-known/oauth-protected-metadata
Required Metadata JSON
Your JAR server needs to serve this at `/.well-known/oauth-protected-metadata`:
{
"authorization_servers": [
"<https://api.descope.com/v1/apps/agentic/YOUR_PROJECT_ID/YOUR_MCP_SERVER_ID>"
],
"bearer_methods_supported": [
"header"
],
"resource": "<http://localhost:8080/mcp>",
"scopes_supported": [
"your_scopes_here"
]
}
The authorization server URL comes from your Descope MCP server's Usage Samples section .
MCP Server Settings | Descope Documentation
Calendar MCP Server (w/ SSO) Example | Descope Documentation
Python MCP SDK | Descope Documentation
Managing MCP Servers | Descope DocumentationMeir Wahnon
03/29/2026, 12:14 PMRahul Rijhwani
03/29/2026, 1:08 PMDhaval Dalvadi
04/01/2026, 9:45 AMRahul Rijhwani
04/01/2026, 8:38 PM@descope/mcp-express. This SDK has proven SSE support.
Your Express app would:
1. Use descopeMcpAuthRouter() to handle OAuth metadata/discovery
2. Use descopeMcpBearerAuth() on the /sse and /message endpoints
3. Proxy authorized requests through to your JAR server running on localhost
So the flow becomes: Client (Claude) → Express auth layer (validates Descope tokens) → Your JAR MCP server (localhost)
The Fly.io deployment guide has a working end-to-end example of this exact pattern with SSE + Descope auth: https://www.descope.com/blog/post/mcp-flyio
This way your JAR stays untouched, and only authenticated requests get through.Dhaval Dalvadi
04/10/2026, 8:48 AM<https://api.descope.com/login/${process.env>
.DESCOPE_PROJECT_ID}?flow=inbound-apps-user-consent,
}
});
// Create a proxy server
const proxy = httpProxy.createProxyServer({
target: "http://localhost:8000", // your backend MCP/ThingsBoard
changeOrigin: true,
ws: true, // support WebSocket and SSE
pathRewrite: (path, req) => {
return path
}
});
// Handle proxy errors
proxy.on("error", (err, req, res) => {
console.error("Proxy error:", err.message);
try {
res.writeHead?.(500, { "Content-Type": "text/plain" });
res.end?.("Proxy error");
} catch (e) { }
});
app.use(descopeMcpAuthRouter(undefined, descopeProvider));
const descopeAuthBearer = descopeMcpBearerAuth(descopeProvider);
app.use(["/", "/mcp/message"], (req, res, next) => {
descopeAuthBearer(req, res, (err) => {
if (err) return next(err);
proxy.web(req, res);
});
});
// Proxy WebSocket / SSE upgrade requests
const server = app.listen(8002, () => {
console.log("Proxy running on http://localhost:8002");
});Dhaval Dalvadi
04/13/2026, 12:07 AMMeir Wahnon
04/13/2026, 5:56 AMAtharva Joshi
04/13/2026, 6:27 AMAtharva Joshi
04/13/2026, 11:30 AMDhaval Dalvadi
04/14/2026, 1:14 AM