跳到主要内容

Cursor 中的 MCP 服务器认证与安全

MCP 认证

模型上下文协议(MCP)服务器为 Cursor 扩展了强大的外部能力,从查询广告平台到管理支付工作流。然而,每个外部连接都会引入认证和安全方面的考量。本指南将带您全面了解 Cursor 中 MCP 服务器认证的各个方面,涵盖 OAuth 流程、API 密钥管理、AI 驱动支付的人工审批层,以及用户在使用 Live Meta Ads MCP 等服务时面临的具体挑战。

为什么 MCP 认证很重要​

当 Cursor 连接到 MCP 服务器时,该服务器可能需要代表您执行操作:读取私密数据、发布内容,甚至进行支付。认证就是决定代理能做什么和不能做什么的守门人。

安全模型概览​

层级职责示例
Cursor托管 MCP 客户端,管理连接读取 mcp.json,启动服务器进程
MCP 服务器处理外部 API 调用调用 Meta Graph API、Stripe API
认证提供方验证身份来自 Meta 的 OAuth 令牌,来自提供方的 API 密钥
人工审批为敏感操作把关在支付提交前进行审批
注意

切勿将生产环境的 API 密钥或 OAuth 令牌以明文形式存储在代码仓库中。始终使用环境变量或密钥管理器。将凭据提交到 git 是开发者面临的最常见安全事件之一。

前置条件​

在 Cursor 中配置 MCP 认证之前,请确保您具备:

  1. 已安装并更新到最新版本的 Cursor
  2. 用于运行基于 npx 的 MCP 服务器的 Node.js 18+
  3. 在要连接的外部服务(例如 Meta for Developers、Stripe)上拥有账号
  4. 来自提供方的应用凭据(客户端 ID、客户端密钥或 API 密钥)

了解 MCP 认证方法​

Cursor 支持两种主要的 MCP 服务器认证模式,选择取决于您连接的服务器支持哪种方式。

方法一:API 密钥认证​

最简单的模式。MCP 服务器期望通过环境变量或请求头传递静态 API 密钥。

{
"mcpServers": {
"my-api-server": {
"command": "npx",
"args": ["-y", "@my-org/api-mcp-server"],
"env": {
"API_KEY": "${MY_API_KEY}"
}
}
}
}

${MY_API_KEY} 语法告诉 Cursor 从环境中读取该值。在您的 shell 配置文件中设置它:

# ~/.zshrc 或 ~/.bashrc
export MY_API_KEY="sk-your-actual-key-here"
提示

在 Windows 上,通过 PowerShell 或系统属性设置环境变量。在 PowerShell 中:

[System.Environment]::SetEnvironmentVariable("MY_API_KEY", "sk-your-key", "User")

然后重启 Cursor 使其加载新的变量。

方法二:OAuth 2.0 认证​

OAuth 更安全,因为它避免了静态密钥并支持范围限定、可撤销的访问。然而,它的设置更为复杂。MCP 服务器会发起一个 OAuth 流程,打开浏览器,要求您登录到提供方页面,然后向 Cursor 返回令牌。

{
"mcpServers": {
"oauth-server": {
"command": "npx",
"args": ["-y", "@my-org/oauth-mcp-server"],
"env": {
"OAUTH_CLIENT_ID": "${CLIENT_ID}",
"OAUTH_CLIENT_SECRET": "${CLIENT_SECRET}",
"OAUTH_REDIRECT_URI": "http://localhost:3000/callback"
}
}
}
}

OAuth 流程的执行步骤如下:

  1. Cursor 启动 MCP 服务器进程
  2. 服务器检测到没有有效令牌并发起 OAuth
  3. 您的浏览器打开提供方的登录页面
  4. 您授权该应用
  5. 提供方重定向到 localhost:3000/callback 并附带授权码
  6. 服务器用该代码交换访问令牌和刷新令牌
  7. 令牌存储在本地以供后续使用

设置 Live Meta Ads MCP​

Live Meta Ads MCP 是 Cursor 中最常被请求的 MCP 集成之一。它连接到 Meta Graph API,让您的代理可以查询广告效果、广告系列数据和受众洞察。论坛用户经常报告该 MCP 认证失败。以下是正确设置的方法。

步骤一:创建 Meta 应用​

  1. 前往 Meta for Developers 门户
  2. 点击 创建应用
  3. 选择 业务 作为应用类型
  4. 添加 Marketing API 产品
  5. 记录您的 应用 ID 和 应用密钥

步骤二:生成长期访问令牌​

Meta 的默认访问令牌很快就会过期。对于 MCP 使用,您需要一个长期令牌:

# 用短期令牌交换长期令牌
curl -X GET "https://graph.facebook.com/v19.0/oauth/access_token" \
-d "grant_type=fb_exchange_token" \
-d "client_id=$META_APP_ID" \
-d "client_secret=$META_APP_SECRET" \
-d "fb_exchange_token=$SHORT_LIVED_TOKEN"

响应中包含一个有效期约为 60 天的令牌。

步骤三:在 Cursor 中配置 MCP 服务器​

{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "@mcp/meta-ads-server"],
"env": {
"META_ACCESS_TOKEN": "${META_ACCESS_TOKEN}",
"META_APP_ID": "${META_APP_ID}",
"META_APP_SECRET": "${META_APP_SECRET}",
"META_API_VERSION": "v19.0"
}
}
}
}

步骤四:验证连接​

重启 Cursor,然后打开 Cursor 设置并导航到 MCP 部分。您应该看到 meta-ads 列在列表中并显示绿色状态指示器。如果显示错误,请参阅下方的故障排除部分。

注意

Meta 长期令牌在 60 天后过期。请设置日历提醒,在令牌过期前刷新它。如果令牌过期,您的代理将静默无法获取广告数据,唯一的症状可能是空结果或埋在 MCP 日志中的认证错误。

常见 MCP 认证故障​

论坛用户报告了几个反复出现的 Cursor MCP 认证问题。以下是最常见的故障及其解决方案。

故障一:环境中找不到令牌​

症状: MCP 服务器启动,但每个请求都返回 401 未授权。

原因: Cursor 没有加载到环境变量。这通常发生在变量设置在不同的 shell 配置文件中,或者在 Cursor 已经运行之后才设置。

解决方案:

# 验证变量是否存在
echo $META_ACCESS_TOKEN

# 如果为空,添加到您的 shell 配置文件并重启 Cursor
echo 'export META_ACCESS_TOKEN="your-token"' >> ~/.zshrc
source ~/.zshrc

然后完全退出并重新打开 Cursor。

故障二:OAuth 重定向 URI 不匹配​

症状: OAuth 流程打开了浏览器,但在授权后,您看到一个错误页面。

原因: Meta 应用配置中的重定向 URI 与 MCP 服务器使用的不匹配。

解决方案: 在您的 Meta for Developers 控制台中,前往 应用设置 > 高级 > OAuth 设置,将 http://localhost:3000/callback(或您的 MCP 服务器使用的任何 URI)添加到允许的重定向 URI 列表中。

故障三:令牌过期或无效​

症状: MCP 服务器之前正常工作,但突然返回认证错误。

原因: Meta 长期令牌已过期(60 天限制)或被撤销。

解决方案: 重新执行令牌交换流程并更新环境变量。

故障四:缺少权限范围​

症状: 认证成功,但代理无法访问某些数据(例如,可以读取广告系列但无法访问受众数据)。

原因: Meta 应用缺少所需的 API 权限。

解决方案: 在 Meta 应用控制台中,前往 角色 > 应用审核 > 权限和功能,请求额外的权限范围:

权限范围启用的功能
ads_read读取广告系列效果数据
ads_management创建和管理广告系列
read_insights访问详细分析数据
business_management管理业务设置

为 AI 代理支付构建人工审批层​

在 Cursor 中使用 MCP 最强大但也最危险的用例之一是将 AI 代理连接到支付系统。一个能够进行购买或转账的代理需要人工审批关卡。论坛用户已经构建了自定义审批层来解决这个问题。

为什么审批层是必不可少的​

如果没有审批层,具有支付 MCP 访问权限的 AI 代理可能会:

  • 向您的卡收取意外金额
  • 向错误的收款人发送付款
  • 触发不可逆的金融交易
  • 通过重复的微小交易累积成本

支付审批层架构​

推荐的模式是在 Cursor 和支付 MCP 服务器之间插入一个审批网关:

Cursor Agent --> Approval Gateway --> Payment MCP Server --> Stripe/PayPal API
^
|
Human Review

实现审批网关​

创建一个轻量级 MCP 服务器,包装实际的支付服务器并要求审批:

// approval-gateway.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({
name: "payment-approval-gateway",
version: "1.0.0",
}, {
capabilities: { tools: {} },
});

// 待审批存储在内存中(生产环境请使用数据库)
const pendingApprovals = new Map();

server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "request_payment",
description: "Request a payment. Requires human approval before execution.",
inputSchema: {
type: "object",
properties: {
amount: { type: "number", description: "Amount in cents" },
currency: { type: "string", description: "ISO currency code" },
recipient: { type: "string", description: "Recipient identifier" },
reason: { type: "string", description: "Why this payment is needed" },
},
required: ["amount", "currency", "recipient", "reason"],
},
},
{
name: "approve_payment",
description: "Approve a pending payment by ID",
inputSchema: {
type: "object",
properties: {
approval_id: { type: "string" },
},
required: ["approval_id"],
},
},
],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "request_payment") {
const { amount, currency, recipient, reason } = request.params.arguments;
const approvalId = `appr_${Date.now()}`;

pendingApprovals.set(approvalId, {
amount,
currency,
recipient,
reason,
status: "pending",
createdAt: new Date(),
});

return {
content: [{
type: "text",
text: `Payment request created. Approval ID: ${approvalId}\n\n` +
`Amount: ${amount/100} ${currency.toUpperCase()}\n` +
`Recipient: ${recipient}\n` +
`Reason: ${reason}\n\n` +
`To execute this payment, a human must approve it using the approve_payment tool with approval_id: ${approvalId}`,
}],
};
}

if (request.params.name === "approve_payment") {
const { approval_id } = request.params.arguments;
const approval = pendingApprovals.get(approval_id);

if (!approval) {
return { content: [{ type: "text", text: "Error: Approval ID not found." }] };
}

// Forward to actual payment server here
approval.status = "approved";
return {
content: [{
type: "text",
text: `Payment approved and forwarded to payment processor.\nAmount: ${approval.amount/100} ${approval.currency.toUpperCase()}`,
}],
};
}
});

const transport = new StdioServerTransport();
await server.connect(transport);

在 Cursor 中配置审批网关​

{
"mcpServers": {
"payments": {
"command": "npx",
"args": ["tsx", "./mcp-servers/approval-gateway.ts"],
"env": {
"STRIPE_SECRET_KEY": "${STRIPE_SECRET_KEY}",
"APPROVAL_TIMEOUT_MS": "300000"
}
}
}
}
提示

设置审批超时,这样如果人工未在合理时间内审批,请求将自动过期。五分钟是一个好的默认值。这可以防止过期的支付请求累积并被在不相关的上下文中审批。

注意

审批网关模式只有在 AI 代理无法绕过它时才有效。确保直接的支付 MCP 服务器未在 Cursor 中配置。只应暴露网关。如果两者都配置了,代理理论上可以直接调用原始服务器并跳过审批。

安全的 MCP 服务器配置​

除了认证之外,在 Cursor 中配置 MCP 服务器的方式也有安全影响。请遵循这些最佳实践。

使用项目范围配置 vs 全局配置​

Cursor 同时支持全局(~/.cursor/mcp.json)和项目范围(.cursor/mcp.json)配置。

范围文件用例
全局~/.cursor/mcp.json在所有项目中使用的个人服务器
项目.cursor/mcp.json特定于某个项目的服务器
提示

对敏感服务器使用项目范围配置。这样可以将凭据从全局配置中移出,并使审计哪些项目可以访问哪些服务变得更加容易。如果 .cursor/mcp.json 包含密钥,请将其添加到 .gitignore,或者仅使用环境变量引用。

限制 MCP 工具访问​

您可以使用 disabledTools 字段限制 MCP 服务器向 Cursor 暴露的工具:

{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "@mcp/meta-ads-server"],
"env": {
"META_ACCESS_TOKEN": "${META_ACCESS_TOKEN}"
},
"disabledTools": ["delete_campaign", "pause_all_campaigns"]
}
}
}

这可以防止代理使用破坏性工具,即使 MCP 服务器暴露了它们。

传输安全​

对于远程 MCP 服务器(基于 SSE),始终使用 HTTPS:

{
"mcpServers": {
"remote-server": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ${REMOTE_MCP_TOKEN}"
}
}
}
}
注意

切勿对远程 MCP 服务器使用 HTTP(未加密)。连接传输您的认证令牌,网络上的攻击者可以拦截它们。始终使用 HTTPS,并验证服务器的 TLS 证书。

令牌刷新模式​

许多 OAuth 提供方在签发短期访问令牌(1 小时)的同时还会签发长期刷新令牌。您的 MCP 服务器必须自动处理刷新以避免中断。

模式一:服务器端刷新(推荐)​

MCP 服务器在内部处理令牌刷新。当访问令牌过期时,服务器使用刷新令牌获取新令牌,无需用户干预。

// Inside your MCP server
let accessToken = await loadToken();
let tokenExpiry = Date.now() + 3600 * 1000; // 1 hour

async function ensureValidToken() {
if (Date.now() >= tokenExpiry - 60000) { // refresh 1 min before expiry
const response = await fetch("https://oauth.provider.com/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: process.env.REFRESH_TOKEN,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
}),
});
const data = await response.json();
accessToken = data.access_token;
tokenExpiry = Date.now() + data.expires_in * 1000;
await saveToken(accessToken, tokenExpiry);
}
return accessToken;
}

模式二:Cursor 端环境重载​

如果您的 MCP 服务器不支持自动刷新,您可以在 Cursor 中重新加载环境:

  1. 在外部刷新令牌
  2. 更新环境变量
  3. 通过设置在 Cursor 中重启 MCP 服务器

模式三:包装脚本​

创建一个包装脚本,在启动 MCP 服务器之前刷新令牌:

#!/bin/bash
# refresh-and-start.sh

# Refresh the Meta token
NEW_TOKEN=$(node /path/to/refresh-token.js)
export META_ACCESS_TOKEN=$NEW_TOKEN

# Start the MCP server
exec npx -y @mcp/meta-ads-server

配置 Cursor 使用该包装脚本:

{
"mcpServers": {
"meta-ads": {
"command": "bash",
"args": ["/path/to/refresh-and-start.sh"]
}
}
}
提示

对于 Live Meta Ads MCP,60 天令牌过期是"突然停止工作"报告的最常见原因。使用 cron 作业或计划任务自动化刷新过程。在 macOS/Linux 上使用 cron,在 Windows 上使用任务计划程序。

MCP 认证故障排除​

检查 MCP 服务器日志​

Cursor 并不总是在 UI 中显示 MCP 服务器错误。要查看发生了什么:

  1. 打开命令面板(Cmd/Ctrl + Shift + P)
  2. 搜索 Output: Show Output Channels
  3. 从下拉菜单中选择 MCP
  4. 查看日志中的认证错误

独立测试认证​

在通过 Cursor 调试之前,直接测试 MCP 服务器:

# 手动运行服务器
npx -y @mcp/meta-ads-server

# 在另一个终端发送测试请求
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | npx -y @mcp/meta-ads-server

如果服务器在 Cursor 之外认证失败,问题出在您的凭据,而不是 Cursor。

验证环境变量是否已加载​

# 创建测试脚本
cat > test-env.js << 'EOF'
console.log("META_ACCESS_TOKEN:", process.env.META_ACCESS_TOKEN ? "SET" : "NOT SET");
console.log("META_APP_ID:", process.env.META_APP_ID ? "SET" : "NOT SET");
console.log("META_APP_SECRET:", process.env.META_APP_SECRET ? "SET" : "NOT SET");
EOF

# 使用 MCP 服务器的环境运行
node test-env.js

如果变量显示为 NOT SET,问题出在您的 shell 配置文件或 Cursor 加载环境的方式。

安全检查清单​

在生产环境中部署 MCP 服务器之前,请过一遍此检查清单:

  • API 密钥存储在环境变量中,绝不在配置文件中
  • 如果包含密钥,将 .cursor/mcp.json 添加到 .gitignore
  • OAuth 重定向 URI 锁定为 localhost
  • 通过 disabledTools 禁用破坏性工具
  • 支付 MCP 服务器使用审批网关包装
  • 令牌刷新已自动化以防止静默失败
  • 远程 MCP 服务器仅使用 HTTPS
  • 监控 MCP 服务器日志中的意外认证失败
  • 访问令牌范围限定为最低所需权限
  • 从配置中移除未使用的 MCP 服务器

总结​

Cursor 中的 MCP 认证涵盖了从简单的 API 密钥环境变量到带有自动令牌刷新的复杂 OAuth 流程的各种场景。Live Meta Ads MCP 是一个常见的痛点,因为其 60 天的令牌过期和权限范围要求。通过遵循本指南中的模式,您可以构建安全、可靠的 MCP 集成,将敏感操作置于人工审批层之后,并保护您的凭据安全。