0.6.0npm · @fouradata/mcp · latest release
Observed 2026-08-21T17:35:11.582Z using mcpSecurity-inventory. Protocol 2025-06-18.
| Tool | Category | Risk |
|---|---|---|
foura_autoGive it a public URL and get the content back. This is the default when you don't want to choose between HTTP, proxy rotation, and a full browser. On protected targets, or whenever HTTP 200 may still be a challenge or incomplete page, pass validate.data.accept with text unique to the real content. Auto makes bounded attempts and returns either validated content or a failure; it cannot guarantee a match. The response includes completion details and, by default, reusable session values for follow-up calls. Use a lower-level tool when you need direct control over HTTP, proxy selection, or browser navigation, or to choose which browser is presented to the target: that lives on foura_single and foura_proxy.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Public target URL. Private or reserved targets return `ssrf_blocked`. Use {ts} in the URL to insert the current Unix timestamp. Example: https://example.com/page."
},
"method": {
"description": "HTTP method for the target request (default GET).",
"type": "string",
"minLength": 1
},
"headers": {
"description": "Custom HTTP headers as [name, value] tuples. Example: [[\"Accept\", \"application/json\"], [\"Authorization\", \"Bearer ...\"]]",
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "string"
},
{
"type": "string"
}
]
}
},
"data": {
"description": "Request body for non-GET methods. Strings sent as-is; objects auto-serialized to JSON.",
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"validate": {
"description": "Post-fetch response validation. When the response fails these checks foura_auto returns an error envelope.",
"type": "object",
"properties": {
"status": {
"description": "Status-code validation: which HTTP status codes count as success (accept) or failure (fail).",
"type": "object",
"properties": {
"accept": {
"description": "HTTP status codes to treat as success",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"fail": {
"description": "HTTP status codes to treat as failure",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
}
},
"headers": {
"description": "Header validation: pass when an accepted header matches, fail when a blocklisted header matches.",
"type": "object",
"properties": {
"accept": {
"description": "Case-insensitive header substring rules. The response passes when at least one name/value pair matches.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"fail": {
"description": "Case-insensitive header substring rules that reject the response when any name/value pair matches.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
}
}
},
"data": {
"description": "Body validation: pass when the body contains an expected substring (accept), fail when it contains a blocked one (fail).",
"type": "object",
"properties": {
"accept": {
"description": "Case-sensitive substrings the final body must contain. Use this on protected targets to distinguish the real page from a challenge page.",
"type": "array",
"items": {
"type": "string"
}
},
"fail": {
"description": "Substrings the final body must not contain",
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"returnSession": {
"description": "Return reusable {proxy, cookies, userAgent} values for follow-up calls. Default true. Send false for a leaner response when you only need the content.",
"type": "boolean"
},
"forceProxy": {
"description": "Require proxy routing for every target request. Default true. Send false to allow direct HTTP when suitable.",
"type": "boolean"
},
"timeout_ms": {
"description": "Total time budget in ms for the whole operation. Every attempt must fit inside it. Default 120000, max 180000.",
"type": "integer",
"minimum": 5000,
"maximum": 180000
},
"ignoreProxies": {
"description": "Exits to avoid - base36 proxy IDs (like \"4DZ3VE\") or proxy URLs. Use this to rotate away from an exit that was just blocked.",
"type": "array",
"items": {
"type": "string"
}
},
"followRedirects": {
"description": "Follow up to N redirects for HTTP and proxy requests. Default 5; 0 means don't follow. Browser navigation handles redirects itself.",
"type": "integer",
"minimum": 0,
"maximum": 20
},
"offload_large": {
"description": "If true, response bodies of 50 KB or more are returned as a resource_link instead of inlined. Default false. Read the returned offloaded_resource_uri with resources/read.",
"type": "boolean"
}
},
"required": [
"url"
]
}Output schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"description": "HTTP status code from the request that delivered the content. `0` means no HTTP response was received; check `error`.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"headers": {
"description": "Response headers from the successful request, as an array of objects. Each entry has `result.{version, code, reason}` plus header-name keys. The last entry is the final response.",
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"result": {
"type": "object",
"properties": {
"version": {
"type": "string"
},
"code": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reason": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
},
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"data": {
"description": "Decoded response body of the delivered page. String by default; object when the body parsed as JSON. Omitted when offloaded."
},
"meta": {
"description": "Completion details: rung, solved, attempts, and credits. Always present.",
"type": "object",
"properties": {
"rung": {
"description": "Which method delivered the content (e.g. probe / proxy / browser / cache). `cache` means a reusable session was used.",
"type": "string"
},
"solved": {
"description": "True when a bot-defense was actively solved on the way to the content (vs. the target being open).",
"type": "boolean"
},
"attempts": {
"description": "Total fetch attempts made for this request.",
"type": "number"
},
"credits": {
"description": "Total credits spent across all attempts.",
"type": "number"
}
},
"additionalProperties": {}
},
"session": {
"description": "Reusable {proxy, cookies, userAgent} values for follow-up calls. For plain HTTP, call foura_single with session.proxy as proxy, session.userAgent as a User-Agent header, and session.cookies serialized as a Cookie header. For JavaScript, pass the three values to foura_browser fields. Present by default; send returnSession:false to omit.",
"type": "object",
"properties": {
"proxy": {
"description": "Opaque base36 exit id of the session (e.g. `4DZ3VE`) - pass to foura_single.proxy / foura_proxy.proxy to replay through the same exit. Never a raw IP.",
"type": "string"
},
"cookies": {
"description": "Cookie objects accumulated by the winning session. For foura_single, serialize their name/value pairs into a Cookie header; pass the array directly to foura_browser.cookies."
},
"userAgent": {
"description": "User-Agent used by the winning session. Send it as a User-Agent header to foura_single or as foura_browser.userAgent.",
"type": "string"
}
},
"additionalProperties": {}
},
"offloaded_resource_uri": {
"description": "foura-mcp://payload/<uuid>. Pass this URI to resources/read to retrieve the offloaded body.",
"type": "string"
},
"size_bytes": {
"description": "Total offloaded body size in bytes",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"error": {
"description": "Human-readable error message when the request could not deliver content within the budget.",
"type": "string"
},
"attempts": {
"description": "Total attempts when the request failed (also present inside `meta`).",
"type": "number"
},
"service": {
"type": "string",
"enum": [
"single",
"proxy",
"browser",
"api",
"auto"
]
},
"retryAfter": {
"description": "Seconds to wait before retrying a 429 or 503 response",
"type": "number"
},
"current": {
"description": "Caller's current usage at error time",
"type": "object",
"properties": {
"concurrency": {
"type": "number"
},
"rpm": {
"type": "number"
}
},
"additionalProperties": false
},
"limits": {
"description": "Per-service limits at error time",
"type": "object",
"properties": {
"maxConcurrency": {
"type": "number"
},
"maxRpm": {
"type": "number"
}
},
"additionalProperties": false
},
"code": {
"description": "Stable error code for retry classification. auth_failed means the FourA API key was rejected; verify that key, not target-site credentials. Other codes: ssrf_blocked, upstream_non_json, output_validation_failed, bad_request (400), forbidden (403), not_found (404), rate_limited (429), at_capacity (503), service_disabled (503), service_unavailable (503), upstream_error (>=500), upstream_client_error (other 4xx), upstream_unknown (defensive).",
"type": "string"
}
},
"additionalProperties": false
}Annotations{
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | — |
foura_browserLoad a public URL in a full browser session. JavaScript runs, the DOM renders, and cookies come back with the response. Use it for single-page apps, lazy-loaded content, or supported browser challenges. For a protected page, call foura_proxy first and pass its returned proxy ID here to reuse that exit. Set unblocker:false when you want the page exactly as it loads.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Public URL to load in a full browser session. Private or reserved targets return `ssrf_blocked`. Example: https://shop.example.com/product/123."
},
"headers": {
"description": "Custom HTTP headers as a key-value object rather than [name, value] tuples. Example: {\"Referer\": \"https://google.com/\"}",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"cookies": {
"description": "Cookies to set before navigation: [{ name, value, domain? }]",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Cookie name."
},
"value": {
"type": "string",
"description": "Cookie value."
},
"domain": {
"description": "Cookie domain (e.g. .example.com). Omit to scope it to the navigated URL's host.",
"type": "string"
}
},
"required": [
"name",
"value"
]
}
},
"userAgent": {
"description": "Override the browser's User-Agent string",
"type": "string"
},
"proxy": {
"description": "Optional proxy. Three forms: (1) URL `http://user:pass@host:port` or `socks5://host:port`; (2) base36 ID from foura_proxy (e.g. `4DZ3VE`) to reuse the same exit; (3) omit to use the default route.",
"type": "string"
},
"timeout_ms": {
"description": "Page load timeout in ms (default 30000, max 120000)",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"checkStatus": {
"description": "Expected HTTP status code. A different status returns an error envelope carrying the actual value. Example: 200 for a product page.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"checkText": {
"description": "Validate the rendered HTML once navigation completes. This is a substring check, not a waiter, and it doesn't poll. A missing substring returns an error envelope. Example: \"add to cart\" for a product page.",
"type": "string"
},
"unblocker": {
"description": "Handle supported anti-bot or captcha challenges during navigation. Default true. Set false to return the page exactly as it loads, including any challenge page.",
"type": "boolean"
},
"offload_large": {
"description": "If true, response bodies of 50 KB or more are returned as a resource_link instead of inlined. Default false. Read the returned offloaded_resource_uri with resources/read.",
"type": "boolean"
}
},
"required": [
"url"
]
}Output schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"description": "HTTP status code from the target page. `0` indicates the navigation failed before any HTTP response (DNS / connection refused / timeout) - check the `error` field for the underlying reason.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"headers": {
"description": "Response headers as a flat key-value object. Values are typically strings but may be arrays for repeated headers.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"body": {
"description": "Fully-rendered page content. String HTML when content-type is HTML; object when the page returned JSON and it was auto-parsed. Field is named `body`, not `data`. Omitted when offloaded.",
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"cookies": {
"description": "Full cookie objects collected after navigation, including name, value, domain, path, expiry, and same-site settings.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"domain": {
"type": "string"
},
"path": {
"type": "string"
},
"expires": {
"type": "number"
},
"size": {
"type": "number"
},
"httpOnly": {
"type": "boolean"
},
"secure": {
"type": "boolean"
},
"session": {
"type": "boolean"
},
"sameSite": {
"type": "string"
}
},
"required": [
"name",
"value"
],
"additionalProperties": {}
}
},
"userAgent": {
"description": "The User-Agent the browser session presented",
"type": "string"
},
"offloaded_resource_uri": {
"description": "foura-mcp://payload/<uuid>. Pass this URI to resources/read to retrieve the offloaded body.",
"type": "string"
},
"size_bytes": {
"description": "Total offloaded body size in bytes",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"error": {
"description": "Human-readable error message",
"type": "string"
},
"service": {
"type": "string",
"enum": [
"single",
"proxy",
"browser",
"api"
]
},
"retryAfter": {
"type": "number"
},
"current": {
"type": "object",
"properties": {
"concurrency": {
"type": "number"
},
"rpm": {
"type": "number"
}
},
"additionalProperties": false
},
"limits": {
"type": "object",
"properties": {
"maxConcurrency": {
"type": "number"
},
"maxRpm": {
"type": "number"
}
},
"additionalProperties": false
},
"code": {
"description": "Stable error code for retry classification. auth_failed means the FourA API key was rejected; verify that key, not target-site credentials. Other codes: ssrf_blocked, upstream_non_json, output_validation_failed, bad_request (400), forbidden (403), not_found (404), rate_limited (429), at_capacity (503), service_disabled (503), service_unavailable (503), upstream_error (>=500), upstream_client_error (other 4xx), upstream_unknown (defensive).",
"type": "string"
}
},
"additionalProperties": false
}Annotations{
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | — |
foura_proxyRoute an HTTP request through rotating proxies with automatic retry. Use it when foura_single is blocked or the target requires a specific exit country. The response includes the proxy ID that succeeded; reuse it with foura_single or foura_browser, or exclude it with ignoreProxies. Use foura_browser when the page needs JavaScript. Set exitCountries for a strict country allowlist, and request.browser, request.os, or request.version to present a different browser.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"request": {
"type": "object",
"properties": {
"method": {
"type": "string",
"minLength": 1,
"description": "HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, or any WebDAV verb)"
},
"url": {
"type": "string",
"format": "uri",
"description": "Public target URL. Private or reserved targets return `ssrf_blocked`. Use {ts} in the URL to insert the current Unix timestamp. Example: https://shop.example.com/pricing."
},
"headers": {
"description": "Custom HTTP headers as [name, value] tuples. Example: [[\"Accept\", \"application/json\"]]",
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "string"
},
{
"type": "string"
}
]
}
},
"unblocker": {
"description": "Send a full browser header set, including User-Agent and Sec-Ch-Ua. Default true. Set false for a plain HTTP request; profile selection needs it on and errors when it is off.",
"type": "boolean"
},
"profile": {
"description": "Exact profile id from the public catalogue at https://api.foura.ai/api/profiles. Use browser/os/version when you do not have an id.",
"type": "string"
},
"browser": {
"description": "Browser to present: Chrome, Edge, Safari, Firefox, or Tor. Omit every profile field and the request presents the latest Google Chrome.",
"type": "string"
},
"os": {
"description": "Operating system to present: Windows, macOS, Android, or iOS. A family name accepts any of its versions.",
"type": "string"
},
"version": {
"description": "Browser version to present, as listed in the catalogue. The newest match wins when several fit. An impossible combination returns an error listing what is available; no other browser is substituted.",
"type": "string"
},
"data": {
"description": "Request body.",
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"timeout_ms": {
"description": "Per-attempt timeout in ms",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"connect_timeout_ms": {
"description": "Timeout in ms for establishing the connection to the target through the proxy (0-120000). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"accept_timeout_ms": {
"description": "Timeout in ms to receive the first response byte after the request is sent (0-120000). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"server_response_timeout_ms": {
"description": "Timeout in ms for the server to send the complete response (0-120000). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"dns_cache_timeout_sec": {
"description": "How long (seconds) to cache the target's resolved DNS (0-240). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 240
},
"followRedirects": {
"description": "Max number of redirects to follow (0-20). Omit to disable redirect following.",
"type": "integer",
"minimum": 0,
"maximum": 20
},
"tryJsonData": {
"description": "If true, attempt JSON.parse on the response body; on success `data` is the parsed value, otherwise it stays the original string. Omit to keep the body as-is.",
"type": "boolean"
},
"returnBuffer": {
"description": "Return raw bytes as a serialized Buffer JSON shape ({type:\"Buffer\", data:[byte, ...]}) instead of a decoded string. Use for binary responses (images, protobuf).",
"type": "boolean"
},
"validate": {
"description": "Per-attempt response validation. A proxy attempt that fails these checks is treated as failed and the next proxy is tried.",
"type": "object",
"properties": {
"status": {
"description": "Status-code validation: which HTTP status codes count as success (accept) or failure (fail).",
"type": "object",
"properties": {
"accept": {
"description": "HTTP status codes to treat as success",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"fail": {
"description": "HTTP status codes to treat as failure",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
}
},
"headers": {
"description": "Header validation: pass when an accepted header matches, fail when a blocklisted header matches.",
"type": "object",
"properties": {
"accept": {
"description": "Case-insensitive header substring rules. The response passes when at least one name/value pair matches across the redirect chain.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"fail": {
"description": "Case-insensitive header substring rules that reject the response when any name/value pair matches.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
}
}
},
"data": {
"description": "Body validation: pass when the body contains an expected substring (accept), fail when it contains a blocked one (fail).",
"type": "object",
"properties": {
"accept": {
"description": "Substrings the response body must contain to pass.",
"type": "array",
"items": {
"type": "string"
}
},
"fail": {
"description": "Substrings that, if present in the body, mark the response as failed.",
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"required": [
"method",
"url"
],
"description": "The inner HTTP request to send through each proxy attempt. Validation rules here determine when a proxy is treated as failed and retried."
},
"maxTries": {
"description": "Maximum rotation attempts before giving up (default 5, max 90). Difficult protected targets may need 25-30. Use exitCountries for country scope.",
"type": "integer",
"minimum": 1,
"maximum": 90
},
"timeout_ms": {
"description": "Overall timeout across all rotation attempts in ms (default 45000, max 120000). Must be positive.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 120000
},
"ignoreProxies": {
"description": "Encoded proxy IDs (base36 strings like \"4DZ3VE\") or proxy URLs to exclude from rotation.",
"type": "array",
"items": {
"type": "string"
}
},
"exitCountries": {
"description": "Optional target-visible proxy countries as two-letter provider codes, for example [\"CZ\", \"GB\"]. Use codes supplied by the user or target requirements. When geography matters, do not guess codes or substitute unscoped rotation. Values are trimmed, uppercased, and deduplicated. Unknown exits are excluded and the request never falls back to another country.",
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Z]{2}$"
}
},
"offload_large": {
"description": "If true, response bodies of 50 KB or more are returned as a resource_link instead of inlined. Default false. Read the returned offloaded_resource_uri with resources/read.",
"type": "boolean"
}
},
"required": [
"request"
]
}Output schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"description": "HTTP status code from the target (from the succeeding proxy attempt). `0` indicates every attempt failed before any HTTP response (DNS / connection refused / timeout) - check the `error` field for the underlying reason.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"headers": {
"description": "Response headers per redirect hop, as an array of objects. Each entry has `result.{version, code, reason}` plus arbitrary header-name keys whose values are strings (or arrays of strings for multi-value headers like Set-Cookie / Link).",
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"result": {
"type": "object",
"properties": {
"version": {
"type": "string"
},
"code": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reason": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
},
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"data": {
"description": "Decoded response body. Omitted when offloaded."
},
"total_time": {
"description": "Per-attempt wall-clock duration of the succeeding inner request",
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
}
]
},
"defense": {
"description": "Present when the target ran a bot check. When solved is false the body may be a challenge page: retry with a different browser, os, or version, or move to foura_browser.",
"type": "object",
"properties": {
"solved": {
"description": "True when the check was met and `data` is the real page.",
"type": "boolean"
}
},
"additionalProperties": {}
},
"proxy": {
"description": "Base36 ID of the exit that succeeded (e.g. `4DZ3VE`). Pass it to foura_single.proxy or foura_browser.proxy to reuse that exit, or to foura_proxy.ignoreProxies to skip it on future rotations.",
"type": "string"
},
"exitCountry": {
"description": "Latest available two-letter target-visible exit-country code used for selection. Present on successful requests that use exitCountries.",
"type": "string",
"pattern": "^[A-Z]{2}$"
},
"total": {
"description": "Outer total time in seconds (proxy selection + retries + the successful inner attempt). Float.",
"type": "number"
},
"offloaded_resource_uri": {
"description": "foura-mcp://payload/<uuid>. Pass this URI to resources/read to retrieve the offloaded body.",
"type": "string"
},
"size_bytes": {
"description": "Total offloaded body size in bytes",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"error": {
"description": "Human-readable error message",
"type": "string"
},
"service": {
"type": "string",
"enum": [
"single",
"proxy",
"browser",
"api"
]
},
"retryAfter": {
"type": "number"
},
"current": {
"type": "object",
"properties": {
"concurrency": {
"type": "number"
},
"rpm": {
"type": "number"
}
},
"additionalProperties": false
},
"limits": {
"type": "object",
"properties": {
"maxConcurrency": {
"type": "number"
},
"maxRpm": {
"type": "number"
}
},
"additionalProperties": false
},
"request": {
"description": "Echoed PrRequest from upstream PrResponseError"
},
"details": {
"description": "Structured no_eligible_proxy context containing the normalized requested country scope. Preserve this scope and retry later. Do not propose or perform an unscoped fallback; change it only after the user explicitly changes the requirement.",
"type": "object",
"properties": {
"exitCountries": {
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Z]{2}$"
}
}
},
"required": [
"exitCountries"
],
"additionalProperties": false
},
"code": {
"description": "Stable error code for retry classification. auth_failed means the FourA API key was rejected; verify that key, not target-site credentials. no_eligible_proxy means the strict exitCountries scope had no match. Keep that scope and retry later; do not propose or perform an unscoped fallback.",
"type": "string"
}
},
"additionalProperties": false
}Annotations{
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | — |
foura_singleSend one HTTP request and return the response. Use it for static pages, JSON APIs, and server-rendered HTML. Set browser, os, or version when a target refuses the default Chrome. Switch to foura_proxy if the response is blocked, and use foura_browser when the page needs JavaScript.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"method": {
"type": "string",
"minLength": 1,
"description": "HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, or any WebDAV verb like PROPFIND/MKCOL)"
},
"url": {
"type": "string",
"format": "uri",
"description": "Public target URL. Private or reserved targets return `ssrf_blocked`. Use {ts} in the URL to insert the current Unix timestamp. Example: https://api.example.com/v1/users."
},
"headers": {
"description": "Custom HTTP headers as [name, value] tuples. Example: [[\"Accept\", \"application/json\"], [\"Referer\", \"https://google.com/\"]]",
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "string"
},
{
"type": "string"
}
]
}
},
"unblocker": {
"description": "Send a full browser header set, including User-Agent and Sec-Ch-Ua. Default true. Set false for a plain HTTP request; profile selection needs it on and errors when it is off.",
"type": "boolean"
},
"profile": {
"description": "Exact profile id from the public catalogue at https://api.foura.ai/api/profiles. Use browser/os/version when you do not have an id.",
"type": "string"
},
"browser": {
"description": "Browser to present: Chrome, Edge, Safari, Firefox, or Tor. Omit every profile field and the request presents the latest Google Chrome.",
"type": "string"
},
"os": {
"description": "Operating system to present: Windows, macOS, Android, or iOS. A family name accepts any of its versions.",
"type": "string"
},
"version": {
"description": "Browser version to present, as listed in the catalogue. The newest match wins when several fit. An impossible combination returns an error listing what is available; no other browser is substituted.",
"type": "string"
},
"data": {
"description": "Request body. Strings sent as-is; objects auto-serialized to JSON. Example: {\"query\": \"hello\"} for POST APIs.",
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"proxy": {
"description": "Optional proxy. Two forms: (1) URL `http://host:port` or `socks5://host:port`; (2) base36 ID from foura_proxy (e.g. `4DZ3VE`) to reuse the same exit. For rotation, use foura_proxy.",
"type": "string"
},
"timeout_ms": {
"description": "Overall request timeout in ms (max 120000, default 15000)",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"connect_timeout_ms": {
"description": "Timeout in ms for establishing the TCP/TLS connection (0-120000). Omit to use the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"accept_timeout_ms": {
"description": "Timeout in ms to receive the first response byte after the request is sent (0-120000). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"server_response_timeout_ms": {
"description": "Timeout in ms for the server to send the complete response (0-120000). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 120000
},
"dns_cache_timeout_sec": {
"description": "How long (seconds) to cache the target's resolved DNS (0-240). Omit for the default.",
"type": "integer",
"minimum": 0,
"maximum": 240
},
"followRedirects": {
"description": "Max number of redirects to follow (0-20). Omit to disable redirect following.",
"type": "integer",
"minimum": 0,
"maximum": 20
},
"tryJsonData": {
"description": "If true, attempt JSON.parse on the response body. On success, `data` is the parsed value (typically object or array). On parse failure, `data` silently stays as the original string - no error, no warning. Set false (or omit) when you need to detect parse failures explicitly.",
"type": "boolean"
},
"returnBuffer": {
"description": "Return raw bytes as a serialized Buffer JSON shape (`{type:\"Buffer\", data:[byte, ...]}`, bytes 0-255) instead of decoded string. Use for binary responses (images, protobuf). Reconstruct: `Buffer.from(data.data)` in Node, `new Uint8Array(data.data)` elsewhere.",
"type": "boolean"
},
"validate": {
"description": "Post-fetch response validation. When the response fails these checks the tool returns an error envelope.",
"type": "object",
"properties": {
"status": {
"description": "Status-code validation: which HTTP status codes count as success (accept) or failure (fail).",
"type": "object",
"properties": {
"accept": {
"description": "HTTP status codes to treat as success",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"fail": {
"description": "HTTP status codes to treat as failure",
"type": "array",
"items": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
}
}
},
"headers": {
"description": "Header validation: pass when an accepted header matches, fail when a blocklisted header matches.",
"type": "object",
"properties": {
"accept": {
"description": "Case-insensitive header substring rules. The response passes when at least one name/value pair matches across the redirect chain.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"fail": {
"description": "Case-insensitive header substring rules that reject the response when any name/value pair matches.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
}
}
},
"data": {
"description": "Body validation: pass when the body contains an expected substring (accept), fail when it contains a blocked one (fail).",
"type": "object",
"properties": {
"accept": {
"description": "Substrings the response body must contain",
"type": "array",
"items": {
"type": "string"
}
},
"fail": {
"description": "Substrings the response body must not contain",
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"offload_large": {
"description": "If true, response bodies of 50 KB or more are returned as a resource_link instead of inlined. Default false. Read the returned offloaded_resource_uri with resources/read.",
"type": "boolean"
}
},
"required": [
"method",
"url"
]
}Output schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"description": "HTTP status code from the target. `0` indicates the request failed before any HTTP response (DNS failure, connection refused, timeout) - check the `error` field for the underlying reason.",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"headers": {
"description": "Response headers per redirect hop, as an array of objects. Each entry has `result.{version, code, reason}` plus arbitrary header-name keys whose values are strings (or arrays of strings for multi-value headers like Set-Cookie / Link). Last array entry is the final response.",
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"result": {
"type": "object",
"properties": {
"version": {
"type": "string"
},
"code": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reason": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
},
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
]
},
"data": {
"description": "Decoded response body. String by default; object when tryJsonData=true and the body parsed as JSON; serialized Buffer JSON shape (`{type:\"Buffer\", data:[byte, ...]}`, bytes 0-255) when returnBuffer=true - reconstruct with `Buffer.from(data.data)` in Node, `new Uint8Array(data.data)` elsewhere. Omitted when offloaded."
},
"total_time": {
"description": "Wall-clock request duration in seconds. Number when present; string in some variants; null when the request never started.",
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
}
]
},
"defense": {
"description": "Present when the target ran a bot check. When solved is false the body may be a challenge page: retry with a different browser, os, or version, or move to foura_proxy or foura_browser.",
"type": "object",
"properties": {
"solved": {
"description": "True when the check was met and `data` is the real page.",
"type": "boolean"
}
},
"additionalProperties": {}
},
"offloaded_resource_uri": {
"description": "foura-mcp://payload/<uuid>. Pass this URI to resources/read to retrieve the offloaded body.",
"type": "string"
},
"size_bytes": {
"description": "Total offloaded body size in bytes",
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"error": {
"description": "Human-readable error message",
"type": "string"
},
"service": {
"type": "string",
"enum": [
"single",
"proxy",
"browser",
"api"
]
},
"retryAfter": {
"description": "Seconds to wait before retrying (429/503)",
"type": "number"
},
"current": {
"description": "Caller's current usage at error time",
"type": "object",
"properties": {
"concurrency": {
"type": "number"
},
"rpm": {
"type": "number"
}
},
"additionalProperties": false
},
"limits": {
"description": "Per-service limits at error time",
"type": "object",
"properties": {
"maxConcurrency": {
"type": "number"
},
"maxRpm": {
"type": "number"
}
},
"additionalProperties": false
},
"code": {
"description": "Stable error code for retry classification. auth_failed means the FourA API key was rejected; verify that key, not target-site credentials. Other codes: ssrf_blocked, upstream_non_json, output_validation_failed, bad_request (400), forbidden (403), not_found (404), rate_limited (429), at_capacity (503), service_disabled (503), service_unavailable (503), upstream_error (>=500), upstream_client_error (other 4xx), upstream_unknown (defensive).",
"type": "string"
}
},
"additionalProperties": false
}Annotations{
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | — |
A large response body (>=50KB) returned by an earlier foura-mcp tool call, available for follow-up reads instead of inlined into context. Only the API key that created the resource can read it.
{
"template_key": "foura-mcp://payload/{uuid}",
"uri_template": "foura-mcp://payload/{uuid}",
"name": "payload",
"description": "A large response body (>=50KB) returned by an earlier foura-mcp tool call, available for follow-up reads instead of inlined into context. Only the API key that created the resource can read it.",
"mime_type": null,
"annotations": null,
"metadata_hash": "d68f55529b2b160c19f3ee07e24290b976c8f521f7dc59aab56c4dad8c270495"
}Fetch multiple URLs concurrently and return each outcome. Retry blocked URLs through foura_proxy.
{
"prompt_key": "bulk_fetch_urls",
"name": "bulk_fetch_urls",
"description": "Fetch multiple URLs concurrently and return each outcome. Retry blocked URLs through foura_proxy.",
"arguments": [
{
"name": "urls",
"description": "Comma-separated list of URLs to fetch",
"required": true
}
],
"metadata_hash": "0387ea2e06e7f1f84dadf4e68d0e8ac803f32d515a713c6452265cb231d6e0a1"
}GET a URL through foura_single with strict validation and report whether it's reachable and responding correctly.
{
"prompt_key": "check_endpoint_health",
"name": "check_endpoint_health",
"description": "GET a URL through foura_single with strict validation and report whether it's reachable and responding correctly.",
"arguments": [
{
"name": "url",
"description": "HTTP endpoint URL to probe",
"required": true
},
{
"name": "expected_text",
"description": "Optional substring that must appear in the response body for the endpoint to count as healthy",
"required": false
}
],
"metadata_hash": "1df5311e27b41527377b0fb44748e95683f82711e07cab2a03531aaf6526154c"
}Fetch a news/blog article URL and extract the main content (headline, author, body, date) stripped of nav/ads/footer.
{
"prompt_key": "extract_article",
"name": "extract_article",
"description": "Fetch a news/blog article URL and extract the main content (headline, author, body, date) stripped of nav/ads/footer.",
"arguments": [
{
"name": "url",
"description": "Article URL",
"required": true
}
],
"metadata_hash": "fc38d85bcfbb7c2e6cd5af5005ccb2e4ad0d09f2da79d5b70e9bdac85db76c46"
}Fetch a pricing page and extract the current price; compare to a target if provided.
{
"prompt_key": "monitor_pricing",
"name": "monitor_pricing",
"description": "Fetch a pricing page and extract the current price; compare to a target if provided.",
"arguments": [
{
"name": "url",
"description": "Pricing or product page URL",
"required": true
},
{
"name": "target_price",
"description": "Optional target price to compare against (e.g. \"19.99\")",
"required": false
}
],
"metadata_hash": "ad8a6f950483b4fbb74fa963dcae0017d4062c45cd1c17d8797d02e292213052"
}Fetch an e-commerce product URL and extract structured product info as JSON (title, price, image, availability).
{
"prompt_key": "scrape_product_page",
"name": "scrape_product_page",
"description": "Fetch an e-commerce product URL and extract structured product info as JSON (title, price, image, availability).",
"arguments": [
{
"name": "url",
"description": "Product page URL (any e-commerce site)",
"required": true
}
],
"metadata_hash": "adf188200fe4c7fbd2682875271f8d99692717e94f5c869c6a4bea3974d018d9"
}Fetch any URL with foura_auto - one call that picks the method (direct / proxy / browser), gets past common bot protection, and returns the content. Use when you just want the page and don't want to choose a tool.
{
"prompt_key": "smart_fetch",
"name": "smart_fetch",
"description": "Fetch any URL with foura_auto - one call that picks the method (direct / proxy / browser), gets past common bot protection, and returns the content. Use when you just want the page and don't want to choose a tool.",
"arguments": [
{
"name": "url",
"description": "URL to fetch",
"required": true
},
{
"name": "must_contain",
"description": "Optional substring the real page must contain - lets auto tell a real page from a challenge page on protected targets.",
"required": false
},
{
"name": "extract",
"description": "Optional plain-English description of what to pull out of the page (e.g. \"title, price, image\").",
"required": false
}
],
"metadata_hash": "e0dfa39fd2c19d4dc6a75f7ba477ce3e30196abacdb2e7eec1af288dca4866c4"
}No completed comparison is available.
| Risk | Change | Subject |
|---|---|---|
| No material changes recorded. | ||
| Severity | Finding | Advisory |
|---|---|---|
| No confirmed vulnerability is published for this version. | ||
Artifact SHA-256: 874739e8d5b115200a35f9bd8a81c8c7569dac8c02e59e93a95f917adf9f0cda
Scanner: mcp-proof-engine 0.1.0.