MCP快车SDK
Drop-in Express 中间器件和帮助器, 以 Descope 为您的模式上下文协议服务器添加安全认证 。 在几分钟内运送经认证的/mcp终点并登记工具.
目录
- 先决条件
- 安装
- 快速启动
- 创建认证工具
- 我应该用哪个API?
- 特征
- OAuth 执行
- 高级使用
- 遗留授权服务器模式( 未推荐)
- 校验鼠标选项
- 从现有的 MCP 服务器中迁移
- 从 v. 0.x 迁移
- 归属
- 许可证
先决条件
- 望远镜项目
- 快速应用程序
- 节点.js 18+
安装
npm install @descope/mcp-express
快速启动
在开始之前,你必须创建一个 MCP 服务器 并获取您新服务器的发现 URL.
- 创建
.env
SERVER_URL=http://localhost:3000
# Recommended: MCP Server Discovery URL
DESCOPE_MCP_SERVER_WELL_KNOWN_URL=https://api.descope.com/v1/apps/agentic/<project>/<mcp-server-id>/.well-known/openid-configuration
# Optional (advanced): issuer URL — path must be `/v1/apps/agentic/<project>/<mcp-server-id>` or `/v1/apps/<project>`
# DESCOPE_MCP_SERVER_ISSUER=https://api.descope.com/v1/apps/agentic/<project>/<mcp-server-id>
# Optional: override derived values (existing setups)
# DESCOPE_PROJECT_ID=your_project_id
# DESCOPE_BASE_URL=https://api.descope.com
- 最小服务器
import "dotenv/config";
import express from "express";
import { descopeMcpAuthRouter, defineTool, DescopeMcpProvider } from "@descope/mcp-express";
import { z } from "zod";
const app = express();
// Required: so /mcp can read JSON bodies
app.use(express.json());
// Optional: explicit provider config (env work out of the box)
const provider = new DescopeMcpProvider({
serverUrl: process.env.SERVER_URL,
descopeMcpServerWellKnownUrl: process.env.DESCOPE_MCP_SERVER_WELL_KNOWN_URL,
// Backward-compatible fallback:
projectId: process.env.DESCOPE_PROJECT_ID,
baseUrl: process.env.DESCOPE_BASE_URL,
});
// Define an authenticated tool (requires 'openid')
const hello = defineTool({
name: "hello",
description: "Say hello to the authenticated user",
input: {
name: z.string().describe("Name to greet").optional(),
},
scopes: ["openid"],
handler: async (args, extra) => {
const result = {
message: `Hello ${args.name || "there"}!`,
authenticatedUser: extra.authInfo.clientId,
};
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
},
});
// Wire the MCP router and register your tools
app.use(
descopeMcpAuthRouter((server) => {
hello(server);
}, provider),
);
app.listen(3000, () => {
console.log("MCP endpoint: POST http://localhost:3000/mcp");
});
推荐提示
- 发送
Content-Type: application/json改为/mcp。 。 。 . /mcp需要一个有效的熊鼠标志.- 元数据端点总是在。 这个
/mcp操作器只有在您通过一个toolRegistration函数. - 建议配置为
DESCOPE_MCP_SERVER_WELL_KNOWN_URL; SDK 生成发行器、 项目 ID 和 APIbaseUrl(从 URL 源) 自动 . - 自提供发行商/发现 URL 只能使用两个路径形状中的一个 :
/v1/apps/agentic/<projectId>/<mcpServerId>/...(MCP服务器)或/v1/apps/<projectId>(输入App). DESCOPE_PROJECT_ID当这些 URL 允许生成项目 ID 时是可选的。 否则就定了DESCOPE_PROJECT_ID当然.- 后向相容性: 如果没有设置发现器或发行器, 请提供
DESCOPE_PROJECT_ID(和可选)DESCOPE_BASE_URL)如前所见. - 广告OAuth发行商
/.well-known/oauth-authorization-server财务报告和审定财务报表authorization_servers: 仅用于项目配置, 保留历史形状https://api.descope.com/<projectId>(通过)new URL(projectId, baseUrl)) (中文(简体) ). 当MCP发现或DESCOPE_MCP_SERVER_ISSUER设置, 广告发行者是已解析的 MCP / Descope 发行者 URL .
创建认证工具
选取你的口味: 基因组 defineTool 或灵活 registerAuthenticatedTool。 。 。 .
defineTool(附有投入)
import { defineTool } from "@descope/mcp-express";
import { z } from "zod";
const getUser = defineTool({
name: "get_user",
description: "Get user information",
input: { userId: z.string().describe("The user ID to fetch") },
scopes: ["profile", "email"],
handler: async (args, extra) => {
return {
content: [{ type: "text", text: JSON.stringify({ userId: args.userId, scopes: extra.authInfo.scopes }, null, 2) }],
};
},
});
registerAuthenticatedTool- 有输入
import { registerAuthenticatedTool } from "@descope/mcp-express";
import { z } from "zod";
const getUser = registerAuthenticatedTool(
"get_user",
{
description: "Get user information",
inputSchema: { userId: z.string().describe("The user ID to fetch") },
},
async (args, extra) => {
return { content: [{ type: "text", text: JSON.stringify({ userId: args.userId }, null, 2) }] };
},
["profile", "email"],
);
- 无投入
const whoami = registerAuthenticatedTool(
"whoami",
{ description: "Return authenticated identity info" },
async (extra) => {
const result = {
clientId: extra.authInfo.clientId,
scopes: extra.authInfo.scopes || [],
};
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
},
["openid"],
);
我应该用哪个API?
短答: 选择 defineTool 简洁和大类型推论 registerAuthenticatedTool 如果你喜欢明显的超载 和接近金属的API.
- 同样的能力
defineTool是薄薄的包装registerAuthenticatedTool。 。 。 .- 两者都支持输入(Zod形状),可选输出方案,说明,和范围.
- 为什么
defineTool- 简明,单对象配置.
- 清除类型脚本推论
(args, extra)当您提供input。 。 。 .
- 为什么
registerAuthenticatedTool- 下层, 镜像基本的 MCP
registerTool形状. - 如果您喜欢明确的控制, 有两个超载( 有/ 没有输入) .
- 下层, 镜像基本的 MCP
也没有任何事情可以做, 选择你喜欢的风格.
特征
MCP 2025‐06‐18 兼容资源服务器.
- 保护资源元数据(RFC 8705)
- 授权服务器元数据( RFC 8414)
/mcp带有无记名证书认证的结束点- 资源指标支助(RFC 8707)
可选( 认证服务器)
/authorize结束点( 默认损坏)- 动态客户注册( 默认失效)
- 调试和撤销由Descope提供
OAuth 执行
资源服务器( 总是启用)
- RFC 8705: OAuth 2.0 保护资源元数据
- RFC 8414: OAuth 2. 0 授权服务器元数据
- RFC 8707: OAuth 2.0的资源指标
授权服务器( 可选)
- RFC 7591: OAuth 2.0 动态客户端注册
- RFC 7009: OAuth 2.0 Token 撤销(由Descope服务)
所有OAuth计划使用Zod进行运行时间验证.
高级使用
遗留授权服务器模式( 未推荐)
默认情况下,这个SDK只作为资源服务器运行. 这是建议的道路, 以下特征用于遗产相容性和测试. 使它们能够暴露出额外的终点(/授权,/注册). 打开前考虑增加的地表面积.
所需资源
- DESCOPE PROJECT ID和SERVER URL(英语:
- 设计 管理 Key (仅在启用授权服务器功能时才需要)
示例 .env
DESCOPE_MCP_SERVER_WELL_KNOWN_URL=https://api.descope.com/v1/apps/agentic/<project>/<server>/.well-known/openid-configuration
SERVER_URL=http://localhost:3000
配置示例
import { DescopeMcpProvider } from "@descope/mcp-express";
const provider = new DescopeMcpProvider({
projectId: process.env.DESCOPE_PROJECT_ID,
serverUrl: process.env.SERVER_URL,
authorizationServerOptions: {
isDisabled: false, // enable Authorization Server mode
enableAuthorizeEndpoint: true, // expose /authorize
enableDynamicClientRegistration: true, // optionally expose /register
},
// Only needed if you enable dynamic client registration
dynamicClientRegistrationOptions: {
authPageUrl: `https://api.descope.com/login/${process.env.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 },
],
nonConfidentialClient: true,
},
});
页:1
- 动态客户端注册(Dynamic Client Registration)是遗留授权服务器模式的一个子特性,默认被禁用. 仅设定
enableDynamicClientRegistration: true和提供dynamicClientRegistrationOptions如果你想揭露/register。 。 。 .
校验鼠标选项
import { DescopeMcpProvider } from "@descope/mcp-express";
const provider = new DescopeMcpProvider({
verifyTokenOptions: {
requiredScopes: ["get-schema", "run-query"],
// resourceIndicator: "your-resource", // optional
// audience: "your-audience", // optional (single value supported currently)
},
});
从现有的 MCP 服务器中迁移
已使用纯 MCP 服务器 server.registerTool以下是最简单的路径:
- 把你的MCP放到快递后面
- 添加 JSON 解析 :
app.use(express.json())。 。 。 . - 使用
descopeMcpAuthRouter((server) => { /* register tools */ }, provider)。 。 。 . - 路由器显示所需的元数据端点和线条
POST /mcp当您提供注册功能时, 持有无记名认证 .
- 环绕每个现有工具
- 在(Plain MCP)之前:
server.registerTool("whoami", { description: "Return identity" }, async (_args, _extra) => {
const data = { ok: true };
return { content: [{ type: "text", text: JSON.stringify(data) }] };
});
- 后 (定义工具):
const whoami = defineTool({
name: "whoami",
description: "Return identity",
scopes: ["openid"],
handler: async (extra) => {
const data = { ok: true };
return { content: [{ type: "text", text: JSON.stringify(data) }] };
},
});
app.use(
descopeMcpAuthRouter((server) => {
whoami(server);
}, provider),
);
- 之后(经核证的登记) 工具, 不输入 :
const whoami = registerAuthenticatedTool(
"whoami",
{ description: "Return identity" },
async (extra) => {
const data = { ok: true };
return { content: [{ type: "text", text: JSON.stringify(data) }] };
},
["openid"],
);
- 删除自定义线条
- 你不再需要管理了
StreamableHTTPServerTransport或属于自己的/.well-known/*结束点。 路由器处理它们.
- 视需要更新处理器签名并返回类型
- 输入 :
(args, extra) => CallToolResult。 。 。 . - 没有输入 :
(extra) => CallToolResult。 。 。 . - 返回时
CallToolResult作为{ content: [{ type: "text", text: "..." }] }。 。 。 .
- 可选: 代表用户调用外部 API
- 使用
extra.getOutboundToken(appId, scopes?)以获取运出的迹象.
如果您不能使用路由器, 下层的棋子存在(descopeMcpBearerAuth 财务报告和审定财务报表 createMcpServerHandler 打开 POST /mcp),但路由器是最简单最安全的路径.
从 v. 0.x 迁移
/mcp现在使用StreamableHTTPServerTransport来自官方MCP SDK.- 工具通过
descopeMcpAuthRouter。 。 。 . - 服务器端点默认为安全而禁用 .
归属
此SDK从"模型上下文协议"TypeScript SDK(MIT)中修改出代码.
许可证
麻省理工学院