MCPサーバー
MCP Server
任意のModel Context Protocolクライアント(Claude Desktop、Claude Code、Cursor、Windsurf、VS Code)から、4つのネイティブツールおよび6つのワークフロープロンプトとしてFourAを使用できます。統合コードやカスタムHTTPクライアントは不要です。
GitHubでオープンソースとして公開中。npmでは@fouradata/mcpとして提供されています。現在のリリース: 0.7.3
クイックスタート: ローカル stdio(Claude Desktopで推奨)
foura.ai/dashboard#api-keysでキーを取得します(ワンクリック、作成時に1度のみ表示、フォーマット: pk_live_...)。MCPクライアントの設定に以下を追加してください:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
Claude Desktopの注意点: 設定ファイルを編集する前に、Claude Desktopを完全に終了(macOSでは
Cmd+Q)してください。アプリが実行中の場合、終了時にインメモリの設定で編集内容が上書きされます。
npxコマンドは初回起動時に@fouradata/mcpをダウンロードし、MCPクライアントのサブプロセスとして実行します。グローバルインストールは不要です。
| クライアント | 設定ファイルの場所 |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Claude Code | claude mcp add foura -- npx -y @fouradata/mcp(事前に環境変数でFOURA_API_KEYを設定) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (MCP拡張機能) | .vscode/mcp.json |
クライアントを再起動します。ツール(foura_auto、foura_single、foura_proxy、foura_browser)と6つのプロンプトがツールリストに表示されます。
クイックスタート: ホスト型 (Streamable HTTP)
Streamable HTTPトランスポートをサポートするクライアント(Cursor、Windsurf、VS Code、--transport httpを使用するClaude Code)では、ローカルのサブプロセスを実行する代わりにホスト型endpointを指定します:
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
Claude Desktop の場合は、上記の stdio 設定を使用するか、mcp-remote を介してホストされた endpoint をブリッジします:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
ホスト型エンドポイント リファレンス
| プロパティ | 値 |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| トランスポート | ストリーマブルHTTP (POST /mcp、SSEレスポンス) |
| 認証 | リクエストごとの Authorization: Bearer pk_live_... |
| MCP-Protocol-Version | @modelcontextprotocol/sdk に準拠 (現在は 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) |
| 401 チャレンジ | WWW-Authenticate: Bearer realm="foura-mcp" |
401 チャレンジには意図的に RFC 9728 resource_metadata パラメータを含めていません。これを通知すると、OAuth 対応クライアントがこのサーバーで実装されていないフローを開始してしまいます。pk_live_ キーを Bearer トークンとして送信すれば 401 は解消されます。
ホスト型サーバーはステートレスです。各リクエストが独自のキーを保持し、サーバーはそれを X-API-Key として FourA API に転送します。1 つのキーで 4 つのツールすべてを利用できます。
DNS リバインディング (CVE-2025-66414) を防止するため、サーバーは Host ヘッダー (mcp.foura.ai または localhost である必要があります) および存在する場合は Origin ヘッダー (許可リスト: mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com) を検証します。サーバー間呼び出し元 (curl、stdio ブリッジモードの MCP クライアント) は Origin を送信せず、そのまま通過します。
ツール
MCP 2025-06-18 仕様に基づき、4 つのツールすべてに readOnlyHint: true および openWorldHint: true のアノテーションが付与されています。信頼できる読み取り専用ツールを自動承認するクライアントは、リクエストごとの確認モーダルなしでこれらを呼び出します。
foura_auto はスマートなデフォルトです。URL を渡すと最適な取得方法を自動選択してコンテンツを返します。他の 3 つはこれがオーケストレーションする下位レベルのプリミティブであり、明示的な制御が必要な場合に使用します。
foura_auto
FourA にリクエスト方法を選択させたい場合に URL を渡します。利用可能な HTTP、proxy、ブラウザのパス全体で制限付きの試行を実行します。保護されたターゲットには validate を渡して、レスポンスに実際のページを識別するコンテンツが含まれるようにします。検証を満たす試行がない場合、ツールはチャレンジページを成功として返すのではなくエラーを返します。
レスポンスの meta に完了詳細が含まれ、デフォルトで proxy、cookies、userAgent を含む再利用可能な session も含まれます。単純な後続リクエストの場合は、session.proxy を proxy として foura_single を呼び出し、Cookie を Cookie ヘッダーとしてシリアライズして、session.userAgent を User-Agent ヘッダーとして送信します。JavaScript レンダリングの場合は、対応する foura_browser フィールドにセッション値を渡します。
foura_single
1 回の HTTP リクエストでレスポンスを返します。POST /api/single/ と 1 対 1 で対応します。
静的ページ、JSON API、サーバーレンダリングされた HTML に使用します。
提示するブラウザの選択
リクエストはデフォルトで最新の Google Chrome を提示します。ターゲットが特定のブラウザを受け入れ他を拒否する場合は、browser (Chrome, Edge, Safari, Firefox, Tor)、os (Windows, macOS, Android, iOS)、version を設定するか、正確な profile ID を渡します。
{
"method": "GET",
"url": "https://example.com",
"browser": "Firefox",
"os": "Windows"
}
複数のプロファイルが一致する場合、最新のバージョンが優先されます。存在しない組み合わせの場合は利用可能な一覧を含むエラーを返すため、選択していないブラウザとしてリクエストが送信されることはありません。選択には unblocker が必要で、これはデフォルトで有効になっています。カタログは GET /api/profiles で公開されており、API キーは不要です。
同じ4つのフィールドは foura_proxy の request オブジェクト内に配置されます。
foura_proxy
自動リトライ機能を備えたローテーションプロキシ経由で単一の HTTP リクエストをルーティングします。foura_single がブロックされている場合や、ターゲットが特定の送信元国を要求する場合に使用します。
exitCountries には、ユーザーまたはターゲットの要件で指定された2文字の国コードの厳格な許可リストを設定します。
{
"maxTries": 5,
"exitCountries": ["CZ", "GB"],
"request": {
"method": "GET",
"url": "https://example.com/pricing",
"browser": "Chrome",
"os": "Windows"
}
}
値はトリムされ、大文字に変換され、重複が排除されます。不明なイグジットを持つプロキシは除外され、リクエストが要求されていない国にフォールバックすることはありません。選択には、通常10分以内に更新される、ターゲットから可視の利用可能な最新の国メタデータが使用されます。リクエスト中のライブな地理位置情報ルックアップではありません。プロキシホストのアドレスから提供元の国を推測しないでください。
スコープ指定が成功すると、exitCountryと再利用可能なproxy IDが返されます。exitCountryが要求された許可リストに属していることを確認してください。現在のプールに一致するものがない場合、ツールはdetails.exitCountriesに正規化されたスコープを含めてcode: "no_eligible_proxy"を返します。そのスコープを保持し、後で再試行してください。スコープの変更や拡張は、ユーザーが要件を明示的に変更した場合にのみ行ってください。国スコープの指定はStartupプラン以上で利用可能です。対象外のプランでexitCountriesを送信した呼び出しは、403およびX-FourA-Limit: plan_limit_featureによって拒否されます。
選択されたページで後からJavaScriptが必要になった場合は、返されたproxy IDをfoura_browser.proxyに渡すことで、ブラウザが同じイグジットを再利用できるようにします。
何度イグジットを試行しても標準プールでは到達できないターゲットに対しては、exitClass: "premium"を設定します。これは許可であり、強制的な指示ではありません。標準プールも応答を競合して試行し、通常は標準プールが優先されます。プレミアムイグジットが試行される前に標準プールが応答した場合、プレミアムトラフィックは消費されません。プレミアム試行では、失敗した場合でも転送されたトラフィックがカウントされます。レスポンスにはexitClassとしてpremiumまたはstandardが返されるため、リクエストごとにどのクラスが処理したかを確認できます。プランに含まれるプレミアムトラフィックを使い切った場合もstandardが返されますが、これはエラーではなく正常な結果です。exitClass: "standard"はエスカレーションを完全に禁止します。プレミアムイグジットのないプランでのexitClass: "premium"はcode: "plan_limit_premium"で拒否されます。exitClassを参照してください。
応答を得るためにローテーションで別のブラウザファミリーへの移行が必要だった場合、成功したレスポンスには最終的に選択されたファミリーを示すprofileが含まれます。この値を使用してリプレイしてください。そうしない場合、次の呼び出しで失敗したバージョンが再度試行されます。
失敗したローテーションでは、エラーの横にattemptReportが含まれます。これには1行のsummaryの文に加え、応答しなかったイグジット(noResponse)、Botチェックによって拒否されたイグジット(defense、ベンダーはvendorsに記載)、受信されたものの独自に設定したvalidate.dataによってのみ拒否されたページ(contentRejected)、statusRejected、およびotherを区別したカウントが含まれます。profilesTriedには、タスクが送信したブラウザが初回使用順にリストされ、defaultはリクエストが記述どおりに送信されたことを意味します。contentRejectedの値が高い場合は、FourAが実際のページを配信したものの、独自のルールによって破棄されたことを意味します。Why a Proxy Request Ran Out of Triesを参照してください。
foura_browser
完全なブラウザセッションです。JavaScriptが実行され、DOMがレンダリングされ、Cookieが返されます。POST /api/browser/に対応します。
シングルページアプリケーション、遅延ロードされるコンテンツ、または完了に実際のブラウザを必要とするチェックが含まれるページに使用します。
各ツールの入力形式、デフォルト値、および検証ルールについては、REST endpoint referenceを参照してください。ツールのスキーマは、REST APIのフィールドと1対1で対応しており、MCP限定のoffload_largeオプトイン(下記参照)も含まれます。
ターゲットがbotチェックを実行する場合
foura_singleおよびfoura_proxyは、ターゲットがbodyへの到達途中でbotチェックを実行した場合、defenseを返します。defense.solved: trueはチェックを通過しdataが実際のページであることを意味します。falseはbodyがチャレンジページの可能性があることを意味します。チャレンジページをコンテンツとして扱うのではなく、別のbrowser、os、またはversionで再試行するか、foura_proxyまたはfoura_browserへ移行してください。
型定義されたレスポンス
すべてのツールレスポンスには、content(人間が読めるテキストサマリー)とstructuredContent(ツールのoutputSchemaに対して検証された型付きJSON)の両方が含まれます。各ツールには固有の形式があります。
foura_auto: 単一形式の{ status, headers, data }に加えて、meta({ rung, solved, attempts, credits }、常に存在。rungはcache、probe、proxy、browser、warmup、failのいずれか)と、下位ツールでのリプレイ用にデフォルトでsession({ proxy, cookies, userAgent })が含まれます。total_timeはありません。foura_single:{ status, headers, data, total_time, ... }(headersは配列で、リダイレクトホップごとに1エントリ)foura_proxy: singleと同じ内容に加えて{ proxy, total }が含まれます。スコープ付きの成功にはexitCountryも含まれ、classを指定したリクエストにはexitClass、ブラウザファミリーを変更したローテーションにはprofile、失敗時にはattemptReportが含まれます。foura_browser: 固有形式の{ status, headers: object, body, cookies, userAgent }(注意:bodyはcontent-typeに応じて文字列またはオブジェクトになります)
また、すべてのツールはAPIのレスポンスヘッダーから読み取った呼び出しコストとトレース方法を報告します。
credits: この呼び出しで消費されたクレジット。処理はいずれにしても実行されるため、失敗時にも表示されます。課金されるのは成功した呼び出しのみであるため、失敗時にクレジットが表示されても費用は発生しません。request_id: この呼び出しに対するFourAのID。サポートリクエスト時に提示してください。exitClass: プレミアムイグジットが呼び出しを処理した場合にpremiumとなります。foura_singleおよびfoura_browserでは、proxyがfoura_proxyで見つかったイグジットをリプレイするときに発生します。
APIから何も報告されなかった場合は各項目が省略されるため、旧バージョン向けに記述されたクライアントもそのまま動作し続けます。同じ値がResponse Headersに記載されています。
structuredContentをサポートするクライアントは、散文からJSONをパースさせる代わりに、型付きオブジェクトをLLMに直接渡すことができます。
複数値のレスポンスヘッダー
複数回出現するヘッダー(Set-Cookie、Link、WWW-Authenticate)は配列として返されます。
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
これは、1つのresponseでセッション、トラッキング、同意cookieを設定するサイト(ほとんどのEコマース)で重要になります。
大容量response: offload_large (デフォルト: inline)
デフォルト(v0.2.0以降)では、サイズに関係なく完全なresponse bodyがstructuredContent内にインラインで返されます。これはすべてのMCPクライアントですぐに動作します。
クライアントがMCP resources/readをサポートしており、かつ大容量ページでのtoken消費を抑えたい場合は、ツール呼び出しごとにoffload_large: trueを渡してください。50 KB以上のresponseはディスクに書き込まれ、resource_linkとして返されるため、クライアントは実際に必要な場合にのみbodyを取得します。ホスト型サーバーでは、キャッシュされたpayloadは1時間後に期限切れになります。独自のインスタンスでは保存されたpayloadは自動削除されません。payloadディレクトリから1時間以上経過したファイルを手動で削除してください。
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| クライアント | offload_large: true |
|---|---|
| Claude Desktop | 未対応(デフォルトの false を維持) |
| Claude Code、Cursor、Windsurf | サポート済み |
| VS Code MCP 拡張機能 | サポート済み |
テナント分離: 各 API キーには専用の名前空間(sha256(apiKey)[:16])が割り当てられます。ペイロードを保存したキーのみがそのデータを読み取ることができます。テナント間の読み取りは、存在の漏洩を防ぐため Payload not found を返します。
組み込みプロンプト
任意の MCP クライアントにおいて、/prompts 配下に6つのワークフローテンプレートが表示されます。それぞれが名前付き引数を受け取り、1つ以上のツールをオーケストレーションするテンプレート化されたユーザーメッセージを返します。
| プロンプト | 引数 | 処理内容 |
|---|---|---|
smart_fetch |
url、オプション must_contain、extract |
自動フェッチ(手法を選択し、Bot 保護を処理)後、コンテンツを返却または抽出 |
scrape_product_page |
url |
ブラウザフェッチ後、商品名、価格、画像、在庫、SKU を JSON として抽出 |
extract_article |
url |
プロキシフォールバック付き Single リクエスト後、ナビゲーションや広告を除去してクリーンな記事 JSON を返却 |
monitor_pricing |
url、オプション target_price |
プロキシフェッチ後、現在の価格を抽出して目標価格と比較 |
check_endpoint_health |
url、オプション expected_text |
厳格な検証付き Single リクエスト後、到達可能性とタイミングを返却 |
bulk_fetch_urls |
urls(カンマ区切り) |
並列 Single リクエスト、URL ごとにプロキシへ自動フォールバック、メタデータのみを返却 |
プロンプトはアイドル時にはトークンを消費しません。呼び出されたプロンプトのみが LLM コンテキストに含まれます。
全文および手動フォールバックプロンプト: MCP レシピ。
エラーエンベロープ
すべてのエラー(isError: true)には structuredContent エンベロープが含まれます。各エラーの最小限のフィールドは以下のとおりです。
{
"service": "auto | single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
HTTPステータスを伴うアップストリームエラーの場合、statusも返されます。レート制限およびキャパシティエラーの場合、アップストリームエンベロープにretryAfter、current.{concurrency, rpm}、limits.{maxConcurrency, maxRpm}が追加されます。基本的なRESTの構造についてはAPI Errorsを参照してください。
安定したcode値:
| Code | HTTP | Meaning | Retry safe? |
|---|---|---|---|
ssrf_blocked |
n/a | ターゲットがプライベートまたは予約済みアドレス(RFC 5735、6598、IPv6予約済み)、URLがhttp(s)ではない、またはホスト名を解決できませんでした | いいえ。URLを確認してください。一時的に失敗したルックアップは再試行可能です |
upstream_non_json |
varies | アップストリームが無効な形式のbodyを返しました | 要調査 |
output_validation_failed |
n/a | MCPサーバーのoutputSchemaがアップストリームのレスポンスを拒否したか、ツールが呼び出しを完了できませんでした(APIキー未設定、API到達不能など) |
要調査: 設定を確認後、報告してください |
bad_request |
400 | 入力形式が拒否されました | いいえ。引数を修正してください |
auth_failed |
401 | キーが見つからないか、無効または無効化されています | いいえ。キーを修正してください |
forbidden |
403 | ターゲットが403を返し、validateがそれを拒否しました(サイトチェック、国制限など) |
いいえ、またはfoura_proxyに切り替えてください |
not_found |
404 | ターゲットまたはendpointが存在しません | いいえ |
rate_limited |
429 | RPM制限に達しました | はい。retryAfter待機してください |
at_capacity |
503 | 同時実行数制限に達しました | はい。retryAfter待機してください |
service_disabled |
503 | メンテナンスのためサービスが停止しています。プランに含まれていないツールはplan_limit_featureとして返されます |
サポートにお問い合わせください |
service_unavailable |
503 | 一般的な503エラー | はい。短時間のバックオフ後に再試行してください |
upstream_error |
500+ or 0 | ターゲットがサーバーエラーを返したか、foura_proxyでfoura_browserおよびfoura_autoからの応答がありませんでした |
はい。指数バックオフで再試行してください |
upstream_client_error |
4xx | その他の4xx | 通常はいいえ |
upstream_unknown |
other | リクエストは実行されましたが承認された応答が得られませんでした。foura_singleでターゲットが応答しなかった(タイムアウト、接続拒否)、または任意のツールでvalidateが2xxや3xxのレスポンスを拒否しました。statusおよびerrorを確認してください |
調査してください |
no_eligible_proxy |
n/a | 厳密なexitCountriesスコープに一致するproxyがありません |
後で再試行してください。スコープの変更は明示的な場合のみ行ってください |
plan_limit_* |
403 or 429 | プラン制限のいずれかにより呼び出しが拒否されました: plan_limit_に続きfeature、premium、concurrency、rate、browser_daily、credits、またはbandwidth。詳細はMCP Server Errorsを参照してください |
retryAfterがある場合は待機してください。それ以外は制限がリセットされるかプランが変更されるまで再試行不可です |
LLMエージェントは文章を解析することなく、codeを直接読み取って再試行ロジックを処理できます。認証のウォークスルー: Authentication。
Limits
- デフォルトでインライン body。
offload_large: trueを指定した場合、50 KB 以上の response はディスク +resource_link(テナントごと、1時間の TTL)に保存されます。 - プライベートターゲットは MCP レイヤーで拒絶されます(RFC 5735、RFC 6598、IPv6 予約ブロック)。パブリックホストのみが転送されます。
- 受信する
/mcprequest に対する 256 KB の request body 上限(実際の MCP ペイロードは 4 KB 未満)。 - rate limit は FourA API によりサービスごとに適用されます。Rate Limits を参照してください。
セルフホスティング
完全なサーバーソースは @fouradata/mcp の下で GitHub 上で公開されています。リポジトリをクローンし、npm install、npm run build を実行し、node dist/http.js を実行して独自のインスタンスを立ち上げます。任意のロードバランサーの背後で単一コンテナとしてステートレスに動作します。
設定可能な環境変数:
| Variable | Default | Purpose |
|---|---|---|
PORT |
3076 |
HTTP リッスンポート |
FOURA_API_BASE |
https://api.foura.ai/api |
アップストリーム FourA REST ベース URL |
FOURA_MCP_PAYLOADS_DIR |
システム一時ディレクトリ内の foura-mcp-payloads フォルダ(同梱の Docker Compose ファイルは /data/payloads を設定) |
50 KB 以上の response がディスク上にキャッシュされる場所(offload_large: true を使用) |
FOURA_MCP_ALLOWED_HOSTS |
mcp.foura.ai,localhost,127.0.0.1,[::1] |
Host header のホスト名許可リスト(DNS リバインディング対策) |
FOURA_MCP_ALLOWED_ORIGINS |
https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com |
ブラウザ呼び出し元の Origin 許可リスト |
公式コンテナは uid 1001(非 root)として実行されます。/data/payloads ホストバインドマウントは、その uid から書き込み可能である必要があります。
任意のロードバランサーの背後で水平スケールします。クライアントは request ごとにキーを提供するため、スティッキーセッションは不要です。