メインコンテンツまでスキップ

Cursor における MCP サーバー認証とセキュリティ

MCP 認証

Model Context Protocol(MCP)サーバーは、広告プラットフォームのクエリから支払いワークフローの管理まで、Cursor に強力な外部機能を拡張します。しかし、外部接続ごとに認証とセキュリティの考慮事項が生じます。このガイドでは、Cursor における MCP サーバー認証の全範囲を説明します。OAuth フロー、API キー管理、AI 駆動の支払いに対する人間の承認レイヤー、および Live Meta Ads MCP などのサービスでユーザーが直面する具体的な課題を取り上げます。

なぜ MCP 認証が重要なのか​

Cursor が MCP サーバーに接続する際、そのサーバーはあなたに代わって行動する必要があるかもしれません:プライベートデータの読み取り、コンテンツの投稿、さらには支払いの実行まで。認証は、エージェントができることとできないことを決定するゲートキーパーです。

セキュリティモデルの概要​

レイヤー責任例
CursorMCP クライアントをホストし、接続を管理mcp.json を読み込み、サーバープロセスを起動
MCP サーバー外部 API 呼び出しを処理Meta Graph API、Stripe API を呼び出し
認証プロバイダーID を検証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 サーバーに対して 2 つの主要な認証パターンをサポートしており、選択は接続先のサーバーがサポートするものに完全に依存します。

方法 1: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 に環境から値を読み取るよう指示します。シェルプロファイルで設定してください:

# ~/.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 を再起動して新しい変数を読み込ませます。

方法 2: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 の認証失敗を頻繁に報告しています。正しくセットアップする方法は以下の通りです。

ステップ 1:Meta アプリを作成​

  1. Meta for Developers ポータルに移動
  2. アプリを作成 をクリック
  3. アプリタイプとして ビジネス を選択
  4. Marketing API プロダクトを追加
  5. App ID と App Secret をメモ

ステップ 2:長期間有効なアクセストークンを生成​

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 日間有効なトークンが含まれます。

ステップ 3: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"
}
}
}
}

ステップ 4:接続を確認​

Cursor を再起動し、Cursor 設定を開いて MCP セクションに移動します。meta-ads が緑色のステータスインジケーターとともにリストされているはずです。エラーが表示される場合は、以下のトラブルシューティングセクションを参照してください。

警告

Meta の長期間トークンは 60 日後に期限切れになります。トークンが期限切れになる前にリフレッシュするためのカレンダーリマインダーを設定してください。トークンが期限切れになると、エージェントはサイレントに広告データの取得に失敗し、唯一の症状は空の結果や MCP ログに埋もれた認証エラーである可能性があります。

一般的な MCP 認証の失敗​

フォーラムユーザーは Cursor での MCP 認証に関していくつかの繰り返される問題を報告しています。最も一般的な失敗とその解決策を以下に示します。

失敗 1:環境にトークンが見つからない​

症状: MCP サーバーは起動するが、すべてのリクエストで 401 Unauthorized を返す。

原因: Cursor が環境変数を取得できなかった。これは変数が別のシェルプロファイルに設定されたか、Cursor がすでに実行中に設定された場合によく発生します。

解決策:

# 変数が存在することを確認
echo $META_ACCESS_TOKEN

# 空の場合、シェルプロファイルに追加して Cursor を再起動
echo 'export META_ACCESS_TOKEN="your-token"' >> ~/.zshrc
source ~/.zshrc

その後、Cursor を完全に終了して再度開いてください。

失敗 2:OAuth リダイレクト URI の不一致​

症状: OAuth フローがブラウザを開くが、承認後にエラーページが表示される。

原因: Meta アプリ設定のリダイレクト URI が MCP サーバーが使用するものと一致しない。

解決策: Meta for Developers ダッシュボードで、アプリ設定 > 詳細 > OAuth 設定 に移動し、http://localhost:3000/callback(または MCP サーバーが使用する URI)を許可されたリダイレクト URI に追加してください。

失敗 3:期限切れまたは無効なトークン​

症状: MCP サーバーは以前は機能していたが、突然認証エラーを返す。

原因: 長期間有効な Meta トークンが期限切れ(60 日制限)または取り消された。

解決策: トークン交換フローを再実行し、環境変数を更新してください。

失敗 4:権限スコープの欠如​

症状: 認証は成功するが、エージェントが特定のデータにアクセスできない(例:キャンペーンは読めるがオーディンスデータにはアクセスできない)。

原因: 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"
}
}
}
}
ヒント

承認タイムアウトを設定して、人間が合理的な時間内に承認しない場合、リクエストが自動的に期限切れになるようにします。5 分が良いデフォルト値です。これにより、古い支払いリクエストが蓄積され、コンテキスト外で承認されるのを防ぎます。

警告

承認ゲートウェイパターンは、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 サーバーは中断を避けるためにリフレッシュを自動的に処理する必要があります。

パターン 1:サーバー側リフレッシュ(推奨)​

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;
}

パターン 2:Cursor 側の環境リロード​

MCP サーバーが自動リフレッシュをサポートしていない場合、Cursor で環境をリロードできます:

  1. 外部でトークンをリフレッシュ
  2. 環境変数を更新
  3. 設定から Cursor で MCP サーバーを再起動

パターン 3:ラッパースクリプト​

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 について specifically、60 日間のトークン期限切れが「突然動作しなくなった」という報告の最も一般的な原因です。cron ジョブまたはスケジュールされたタスクを使用してリフレッシュプロセスを自動化してください。macOS/Linux では cron を使用し、Windows ではタスクスケジューラを使用します。

MCP 認証のトラブルシューティング​

MCP サーバーログの確認​

Cursor は MCP サーバーのエラーを常に UI に表示するわけではありません。何が起きているかを確認するには:

  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 と表示される場合、問題はシェルプロファイルまたは 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 統合を構築できます。