ドキュメント

MCPEmailsで開発する

MCPクライアントにできることは、すべて通常のHTTPSを使ってスクリプトからも実行できます。エンドポイントは1つ、APIキーも1つ、入力も出力もJSONです。このガイドでは、認証、必要な3つの呼び出し、エラー、再試行、制限、新着メール向けのWebhookを説明します。

エンドポイント

すべてのリクエストは、https://mcpemails.com/api/mcpへのJSON-RPC 2.0のPOSTです。claude.ai、ChatGPT、その他のMCPクライアントが使うのと同じエンドポイントで、ツールも権限も同じです。スクリプトとチャットアシスタントは同じ1つの製品を扱うことになります。

  • Content-Type: application/jsonとAccept: application/jsonを送信してください。応答は1つのJSONオブジェクトです。
  • サーバーはセッションを保持しません。開いたり閉じたりするものはなく、各リクエストがそれぞれAuthorizationヘッダーを持ちます。
  • ツールの実行に成功すると、型付きのstructuredContentオブジェクトが返されるため、文章を解析する必要はありません。同じデータがJSON文字列としてcontent[0].textにも入っています。

認証

APIキー

  • ダッシュボードのAPIキー → 新しいキーでキーを作成します。使用するスクリプトやワークフローにちなんだ名前を付けてください。
  • キーはmcpe_に続く64文字の16進数です。表示されるのは作成時の1回だけで、保存されるのはハッシュのみです。その場でコピーしてください。紛失したキーは復元できず、新しいキーに置き換えるしかありません。
  • すべてのリクエストでAuthorization: Bearer mcpe_...として送信します。キーをURLやクエリ文字列に含めないでください。
  • どのプランでも必要な数だけキーを作成できます。スクリプトやワークフローごとに1つのキーを使えば、他に影響を与えずに1つだけ取り消せます。
  • APIキーページでキーを取り消すと、アクセスは即座に終了します。

スコープ

各キーが持つのは、作成時にチェックを入れた権限だけです。後からアクセスを編集で変更でき、変更は再接続なしで次の呼び出しから適用されます。

スコープ許可される操作
read:emailメッセージの一覧表示、読み取り、検索、添付ファイルのダウンロード、受信トレイとフォルダーの一覧表示。
search:email古いキーのために残しています。検索はread:emailに含まれます。
send:email送信、返信、転送。
manage:drafts下書きの作成、更新、削除。下書きを送信するにはsend:emailも必要です。
manage:foldersメッセージの移動、コピー、フラグ設定、アーカイブ。フォルダーの作成、名前の変更、削除。
delete:emailメッセージの削除と一括削除。
manage:contacts最近のメールから連絡先を検索。
schedule:email予約送信の設定と、予約済みメールの管理。
manage:automations誰も見ていなくてもスケジュールどおりに実行されるルールの作成。

まずはread:emailから始め、ワークフローに必要になった時点で書き込み系のスコープを追加してください。キーのスコープ外の呼び出しは、メールサーバーに接続する前に拒否されます。ワークスペースの閲覧者が持てるのは読み取り系のスコープだけです。

受信トレイへのアクセス

既定では、キーはワークスペース内のすべての受信トレイにアクセスできます。一部に限定するには、キーのアクセスを編集を開き、受信トレイへのアクセスで受信トレイを選びます。この制限は呼び出しのたびに確認されるため、サポート用の受信トレイに限定したキーは、リクエストの内容にかかわらず経理用の受信トレイを読めません。

コネクタアプリのOAuth

claude.ai、ChatGPT、その他のMCPクライアントなど、ユーザーが自分で接続するアプリは、キーではなくOAuthでログインします。動的クライアント登録、PKCE付きの認可コード、そしてユーザーがスコープと受信トレイを選ぶ同意画面を使います。詳しくはOAuth接続をご覧ください。自分のスクリプト、サーバー、ワークフローには、APIキーのほうが簡単です。

3つの呼び出し

1. initialize (省略可)

MCPクライアントはinitializeから始めます。サーバーはセッションを保持しないため、スクリプトでは省略できますが、キーが有効か確認し、サーバーの説明を読む手軽な方法として使えます。

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "clientInfo": { "name": "my-agent", "version": "1.0" },
      "capabilities": {}
    }
  }'

2. tools/list

tools/listは、このキーで呼び出せるすべてのツールを、説明、入力スキーマ、出力スキーマとともに返します。ツール名や引数をハードコードせず、起動時にこの一覧を読み込んでください。一覧はキーのスコープで絞り込まれ、ツールの引数は今後も追加されていきます。

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'

3. tools/call

ツールを名前と引数で呼び出します。多くのツールは、動作を指定するactionを受け取ります。たとえばemail_readのlist、read、searchです。メールボックスはinbox (アドレス) またはinbox_idで指定します。inbox_listは両方を返します。

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "email_read",
      "arguments": { "action": "list", "inbox": "you@example.com", "unread": true, "limit": 20 }
    }
  }'

成功した場合の結果:

JSON
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [{ "type": "text", "text": "{\"messages\":[...],\"total\":42, ...}" }],
    "structuredContent": {
      "messages": [{ "id": "...", "subject": "...", "from": { "name": "...", "email": "..." } }],
      "total": 42,
      "total_is_estimate": false,
      "has_more": true,
      "next_offset": 20
    }
  }
}

各ツールの説明はツールリファレンスに、その他の例はcurlガイドにあります。

エラー

エラーには2種類あります。まったく実行できなかったリクエストは、HTTPステータス付きのJSON-RPC errorとして返ります。ツールまで届いたものの、ツールに拒否されたリクエストは、AIモデルが理由を読めるように、isError: true付きの通常のresultとして返ります。分岐はメッセージの文面ではなく、data.error_codeまたは_metaのコードで行ってください。

レスポンス発生する状況対処
HTTP 401、-32001キーがない、形式が不正、取り消し済み、または期限切れ。Authorizationヘッダーを修正するか、新しいキーを作成します。再試行しても解決しません。
HTTP 403、-32004、insufficient_scopeこのツール操作に必要なスコープがキーにない。許可に必要なスコープはdata.required_scopesに一覧されます。アクセスを編集でスコープを追加するか、別のキーを使います。
HTTP 429、-32003、rate_limit_exceededリクエストが多すぎる。どの時間枠が上限に達したかはdata.windowに示されます。Retry-Afterの秒数 (data.retry_afterにも記載) だけ待ってから、同じリクエストを再試行します。
-32602不明なツール名。このキーで呼び出せる名前はdata.available_toolsに一覧されます。tools/listにある名前を使います。
isError: true、invalid_arguments引数がツールのスキーマに合わない。何も実行されていません。テキストに問題のある引数がそれぞれ示され、引数名が推測で付けられていた場合は、実在する引数名も示されます。引数を修正します。同じ引数は同じように拒否されます。
isError: true、usage_limit_reachedFreeのワークスペースが月間のメール操作回数を使い切った。_metaにあるリセット日まで待つか、アップグレードします。有料プランではメール操作は無制限です。
isError: true、その他ツールは実行されたが失敗した。メッセージが見つからない、プロバイダーに拒否された、宛先が無効、など。content[0].textを読んでください。何が起きたか、何かが送信されたかどうかが書かれています。
HTTP
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope", ...

{
  "jsonrpc": "2.0",
  "id": 4,
  "error": {
    "code": -32004,
    "message": "Insufficient scope: the 'send:email' scope is required to call email_compose.",
    "data": { "error_code": "insufficient_scope", "required_scopes": ["send:email"], ... }
  }
}
HTTP
HTTP/1.1 429 Too Many Requests
Retry-After: 12

{
  "jsonrpc": "2.0",
  "id": 5,
  "error": {
    "code": -32003,
    "message": "Rate limit exceeded",
    "data": { "error_code": "rate_limit_exceeded", "window": "per_minute", "retry_after": 12, ... }
  }
}
JSON
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "isError": true,
    "content": [{ "type": "text", "text": "Invalid arguments for email_read. The call was rejected before it ran, ..." }],
    "_meta": {
      "com.mcpemails/invalid_arguments": {
        "error_code": "invalid_arguments",
        "retryable": false,
        "errors": [{ "path": "arguments.since", "message": "..." }]
      }
    }
  }
}

ページネーション

一覧と検索の結果は、すべて同じ4つのフィールドで終わります。

  • has_more: 次のページがあるときはtrue。すべて確認したことを意味するのはhas_more: falseだけです。
  • next_offset: 他の引数はすべてそのままで、この値をoffsetとして渡すと次のページを取得できます。has_moreがfalseのときはnullです。
  • total: 一致した件数。プロバイダーが件数を数えられない場合はnullです。手元のページと矛盾することはありません。
  • total_is_estimate: totalが正確な件数ではなく、推定値または下限値のときにtrue。

長いメッセージ本文も同じように分割されます。body_truncatedがtrueの場合は、body_next_offsetをbody_offsetとして渡して再度読み取ってください。

再試行と冪等性キー

送信後に接続が切れると、メールが送られたかどうかわからなくなります。idempotency_keyを渡し、同じキーで再試行すれば、処理は1回だけ実行されます。

bash
curl -s https://mcpemails.com/api/mcp \
  -H "Authorization: Bearer $MCPEMAILS_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 7,
    "method": "tools/call",
    "params": {
      "name": "email_compose",
      "arguments": {
        "action": "send",
        "inbox": "you@example.com",
        "to": ["customer@example.com"],
        "subject": "Your order has shipped",
        "body": "Hi, your order is on its way.",
        "idempotency_key": "order-1042-shipped"
      }
    }
  }'
  • 送信、返信、転送、予約送信、下書きの書き込み、そして移動、フラグ設定、削除などのメールボックスの変更で使えます。tools/listでは、対応するすべてのツールの入力スキーマにidempotency_keyが表示されます。
  • 最大200文字です。注文番号とイベント名など、自分のシステムにある値を使ってください。
  • キーは送信元のAPIキーごとに区別され、24時間保持されます。
  • 同じキーと同じ引数で再試行しても、処理は再実行されません。idempotent_replay: true、元のstatus、そしてresultに元の結果が返されます。失われたかもしれないmessage_idもここに含まれます。
  • 同じキーで引数が異なる場合は、idempotency_key_conflictで拒否されます。新しい操作には新しいキーを使ってください。
  • 最初の呼び出しがまだ実行中のときに再試行すると、status: "processing"が返ります。少し待ってから再試行してください。
  • メールプロバイダーが受け付ける前に送信を拒否した場合は、何も送信されずキーが解放されるため、同じ内容で再試行すると実際に送信されます。
  • 結果が不確かな場合、再実行の応答はstatus: "unknown"になります。新しいキーで送り直す前に、送信済みフォルダーを確認してください。
JSON
{
  "idempotency_key": "order-1042-shipped",
  "idempotent_replay": true,
  "status": "succeeded",
  "result": { "message_id": "...", "inbox_id": "...", "status": "sent" },
  "message": "This logical request was already processed. ..."
}

送信の承認

どの受信トレイでも、すべての送信を保留して担当者の承認を待つように設定できます。その場合、スクリプトからの送信はすぐには送られず、status: "pending_approval"とともにapproval_idが返ります。誰かがダッシュボードで承認すると送信されます。この機能はすべてのプランで使え、新しい自動化の動作を確かめている間の既定の設定として適しています。同じidempotency_keyで再試行すると、2つ目の承認を作らずに既存の承認が返されます。

レート制限

各プランには、ワークスペース全体での1分あたりの上限があります。1つのキーでプランの1分あたりの上限をすべて使うことができ、複数のキーがある場合はその上限を共有します。

プラン1分あたりのリクエスト数Webhook
Free60なし
Personal120なし
Pro300あり
Business1,000あり
  • tools/callのレスポンスには、上限に近いほうの時間枠についてRateLimit-Limit、RateLimit-Remaining、RateLimit-Reset (秒単位) が含まれるため、クライアントは上限に達する前にペースを調整できます。
  • 各キーには1時間ごとと1日ごとの時間枠もあります。429では、上限に達した時間枠がdata.windowに示されます。
  • 429には秒単位のRetry-Afterが含まれます。その時間だけ待ってから、同じリクエストを再試行してください。
  • Freeには月間のメール操作回数の枠があります。有料プランではメール操作は無制限で、呼び出しごとの課金はありません。

新着メール向けのWebhook

ProとBusinessでは、受信トレイにメールが届いたときにMCPEmailsから指定のURLへPOSTできます。ワークフローはポーリングせずに新着メールで起動します。ダッシュボードでエンドポイントを作成し、対象の受信トレイを選んで、署名シークレットをコピーしてください。シークレットが表示されるのは1回だけです。URLはHTTPSで、ポートは443または8443である必要があります。テストボタンを使うと、署名付きのpingイベントを送信できます。

イベント

HTTP
POST /your/webhook HTTP/1.1
Content-Type: application/json
MCPEmails-Event-Id: evt_...
MCPEmails-Event-Type: message.received
MCPEmails-Signature: t=1792843200,v1=5f2b...

{
  "id": "evt_...",
  "type": "message.received",
  "created_at": "2026-10-24T09:20:00.000Z",
  "workspace_id": "...",
  "inbox_id": "...",
  "folder": "INBOX",
  "count": 1,
  "message_ids": ["..."]
}
  • typeはmessage.receivedです。message_idsには、その受信トレイのINBOXフォルダーに届いた新しいメッセージが、1イベントあたり最大10件まで含まれます。countは届いた件数で、それより多いこともあります。
  • 既定では、ペイロードに含まれるのはIDだけで、内容は含まれません。ヘッダーを含めるよう設定したエンドポイントには、各メッセージのid、from、subjectを含むmessagesリストも届きます。
  • メッセージはAPIキーを使い、email_read (action: "read"、inbox_id、message_id) で取得します。そのキーのスコープと受信トレイへのアクセスは通常どおり適用されます。
  • 配信は通常、メッセージの到着から約2分以内です。受信トレイは一定の間隔で確認されるため、即時ではありません。

署名を検証する

すべての配信にはMCPEmails-Signature: t=<unix seconds>,v1=<hex>が含まれます。v1は、タイムスタンプ、ドット、生のリクエスト本文をつなげたものに対する、エンドポイントのシークレットをキーとしたHMAC-SHA256です。キーには表示されたとおりのシークレット全体を、whsec_の接頭辞も含めて使います。生の本文から署名を再計算し、定数時間で比較して、5分より古いタイムスタンプは拒否してください。

JavaScript
import crypto from 'node:crypto';

// rawBody: the request body exactly as received, before JSON.parse.
export function verifyMcpemailsSignature(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    String(header ?? '').split(',').map((part) => part.trim().split('=')),
  );
  const timestamp = Number(parts.t);
  if (!Number.isFinite(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest();
  const received = Buffer.from(parts.v1 ?? '', 'hex');
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

再試行

  • 10秒以内に任意の2xxステータスで応答してください。それ以外はすべて失敗とみなされます。リダイレクトも失敗扱いで、追跡されません。
  • 失敗した配信は、1分後、5分後、30分後、2時間後、6時間後、24時間後に再試行されます。再試行のたびに新しいタイムスタンプで署名し直されます。
  • 24時間にわたって失敗し続けた、または50回連続で失敗したエンドポイントは無効になり、ワークスペースのオーナーにメールで通知されます。ダッシュボードから再び有効にできます。
  • 処理済みの配信を無視するにはMCPEmails-Event-Idを使います。再試行では同じイベントIDが送られます。

レシピ

n8n: 新着メールでワークフローを実行する

  • HTTPメソッドをPOSTにしたWebhookトリガーノードを追加し、その本番URLをMCPEmailsのダッシュボードでWebhookエンドポイントとして登録します。
  • HTTP Requestノードを追加します。メソッドはPOST、URLはhttps://mcpemails.com/api/mcp、認証はGeneric Credential Type → Header Authで、名前をAuthorization、値をBearer mcpe_...にします。
  • Send BodyをオンにしてJSONを選び、下の本文を使って新しいメッセージを読み取ります。後続のノードはresult.structuredContentでメッセージを受け取ります。
  • n8nで署名を確認するには、WebhookノードでRaw Bodyを有効にし、Codeノードで上記の検証を実行します。セルフホストのn8nでは、NODE_FUNCTION_ALLOW_BUILTIN=cryptoでcryptoモジュールを許可してください。
JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "email_read",
    "arguments": {
      "action": "read",
      "inbox_id": "{{ $json.body.inbox_id }}",
      "message_id": "{{ $json.body.message_ids[0] }}"
    }
  }
}

メールの読み取りと送信を自分で行うAI Agentノードについては、n8nガイドをご覧ください。

Claude Code

ヘッダーにキーを入れてサーバーを追加します。OAuthログイン用のブラウザーがないヘッドレス環境やCIに適しています。

bash
claude mcp add --transport http mcpemails https://mcpemails.com/api/mcp \
  --header "Authorization: Bearer $MCPEMAILS_KEY"

OAuthログインとスコープの選び方はClaude Codeガイドで説明しています。

短いNodeスクリプト

1つの受信トレイの未読メッセージをページごとにすべて一覧表示し、429が返ったら待機します。

JavaScript
// node agent.mjs  (Node 18 or later, MCPEMAILS_KEY in the environment)
const ENDPOINT = 'https://mcpemails.com/api/mcp';
let nextId = 1;

async function callTool(name, args) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.MCPEMAILS_KEY}`,
      'Content-Type': 'application/json',
      Accept: 'application/json',
    },
    body: JSON.stringify({ jsonrpc: '2.0', id: nextId++, method: 'tools/call', params: { name, arguments: args } }),
  });
  if (res.status === 429) {
    const wait = Number(res.headers.get('Retry-After') ?? 1);
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
    return callTool(name, args);
  }
  const reply = await res.json();
  if (reply.error) throw new Error(`${reply.error.code}: ${reply.error.message}`);
  if (reply.result.isError) throw new Error(reply.result.content[0].text);
  return reply.result.structuredContent;
}

const inbox = 'you@example.com';
let offset = 0;
do {
  const page = await callTool('email_read', { action: 'list', inbox, unread: true, limit: 50, offset });
  for (const m of page.messages) console.log(m.id, m.from?.email, m.subject);
  offset = page.has_more ? page.next_offset : null;
} while (offset !== null);

OpenClaw

OpenClawは既定でOAuthを使ってログインします。手順はOpenClawガイドで説明しています。代わりにスコープ付きキーを使うには、サーバーエントリのheadersマップにキーを入れ、authは設定しないでください。OpenClawは、OAuthに設定されたエントリでは静的なAuthorizationヘッダーを無視するためです。

JSON
{
  "mcp": {
    "servers": {
      "mcpemails": {
        "url": "https://mcpemails.com/api/mcp",
        "transport": "streamable-http",
        "headers": { "Authorization": "Bearer mcpe_YOUR_KEY_HERE" }
      }
    }
  }
}

受信トレイ1つから、無料で始めましょう

キーを作成してtools/listを呼び出し、自分のメールがJSONで返ってくるのを確かめてください。