LogoFoca Upscaler Docs

MCP

Connect an AI client to Foca, create image upscaling tasks, and download the results.

Foca MCP lets an AI client check your credit balance, upscale an image from an HTTPS URL, and retrieve the result. It uses the Advanced engine (physics) and shares your website account’s credits and plan permissions. Each call creates a task for one image. The default output tier is 2K, at 15 credits per image.

Connect your client

MCP task creation and new API keys require an active paid subscription or a successful credit pack purchase. A previous successful credit pack purchase keeps this eligibility even when its balance reaches zero. Signup gift credits do not qualify. An account with only a credit pack can create 2K tasks; higher tiers require the matching active subscription.

  1. Sign in and open API key settings to create a key.
  2. Save the key when it appears. It is shown only once.
  3. Choose your client below. The endpoint uses Streamable HTTP with Authorization: Bearer YOUR_API_KEY.

Merge this into your Cursor mcp.json. After using the install link, replace YOUR_API_KEY in the Authorization header.

{
  "mcpServers": {
    "foca": {
      "url": "https://focaupscaler.com/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
Connect Cursor

Save this in .vscode/mcp.json or your user MCP configuration. VS Code prompts for the key using a password input.

{
  "inputs": [
    {
      "type": "promptString",
      "id": "foca-api-key",
      "description": "Foca API key",
      "password": true
    }
  ],
  "servers": {
    "foca": {
      "type": "http",
      "url": "https://focaupscaler.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ${input:foca-api-key}"
      }
    }
  }
}
Connect VS Code

Run this HTTP transport command in your terminal. Claude Code saves the Authorization header in its local MCP configuration.

claude mcp add --transport http foca https://focaupscaler.com/api/mcp   --header 'Authorization: Bearer YOUR_API_KEY'

Add this to ~/.codex/config.toml or a trusted project’s .codex/config.toml. The token stays in FOCA_API_KEY rather than the TOML file.

[mcp_servers.foca]
url = "https://focaupscaler.com/api/mcp"
bearer_token_env_var = "FOCA_API_KEY"

Set this environment variable in the shell that starts Codex, then restart the client.

export FOCA_API_KEY='YOUR_API_KEY'

Merge this into Windsurf’s mcp_config.json. This client uses serverUrl and headers for its remote HTTP connection.

{
  "mcpServers": {
    "foca": {
      "serverUrl": "https://focaupscaler.com/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Merge this into claude_desktop_config.json and restart Claude Desktop. Node.js with npx is required; the fixed mcp-remote version bridges local stdio to Streamable HTTP.

{
  "mcpServers": {
    "foca": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@0.15.1",
        "https://focaupscaler.com/api/mcp",
        "--transport",
        "http-only",
        "--header",
        "Authorization:${FOCA_AUTH_HEADER}"
      ],
      "env": {
        "FOCA_AUTH_HEADER": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Replace YOUR_API_KEY with your key. VS Code asks for it through a hidden password input; Codex reads FOCA_API_KEY from its environment.

Install links contain placeholders only. Review the configuration in your client and enter your key there.

API keys act on your account and can spend its credits. Keep them in your client’s secret settings, and revoke unused keys in API key settings. Do not put keys in URLs, prompts, or a source repository. Tasks and credits belong to the account that created the key.

The “Read in ChatGPT” and “Read in Claude” actions open a prompt to read this public guide. They do not connect MCP or authorize account access.

Credits and plan access

resolution_tierOutput tierTarget long edgeCredits per imageRequired plan
22K1920 px15Paid MCP access
44K3840 px30Starter, Pro, or Elite
88K7680 px60Pro or Elite
1616K15360 px120Elite

Use get_upscale_info before submitting. Each tier’s available value reflects your plan access; your balance must also cover the task’s cost. MCP and the website use the same balance. See plans and credits to change your plan or add credits.

Image requirements

  • A publicly accessible HTTPS URL on port 443, with no username, password, or additional authentication headers. Private network and local addresses are rejected.
  • A valid JPEG, PNG, or WebP file, up to 20 MB (20 MiB, or 20,971,520 bytes).
  • Up to 64 million input pixels (64 MP).
  • A temporary signed URL is allowed if it remains valid while the image is downloaded. Downloads have a 20-second limit and allow up to three redirects.

A failed input download or validation does not create a task or charge task credits.

JSON-RPC request examples

MCP clients normally handle initialization and tool discovery. To inspect the requests directly, run the following examples in the same shell. Replace the API key and sample image URL with your own values.

All requests use POST and the headers below. This endpoint returns JSON and is stateless: it does not issue a session ID or provide a separate GET SSE connection. The examples use protocol version 2025-11-25; a client should use the version negotiated by initialize for subsequent requests.

export FOCA_API_KEY='YOUR_API_KEY'

foca_mcp() {
  curl --silent --show-error 'https://focaupscaler.com/api/mcp' \
    --header "Authorization: Bearer $FOCA_API_KEY" \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json, text/event-stream' \
    --header 'MCP-Protocol-Version: 2025-11-25' \
    --data-binary @-
}

Initialize and discover tools

Send initialize, then the notifications/initialized notification after initialization succeeds. The initialization result identifies the server as foca-upscaler and advertises its tools capability.

foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": {
      "name": "foca-example-client",
      "version": "1.0.0"
    }
  }
}
JSON

foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}
JSON

Request the tool schemas with tools/list:

foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}
JSON

The returned result.tools contains get_upscale_info, upscale_image, and get_upscale_task. Follow each tool’s inputSchema; extra arguments are rejected.

1. Check your account with get_upscale_info

Arguments: an empty object, {}. This query does not charge task credits.

foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_upscale_info",
    "arguments": {}
  }
}
JSON

Example result.structuredContent for an account with access to every tier:

{
  "engine": "physics",
  "balance": 200,
  "can_create_tasks": true,
  "tiers": [
    { "resolution_tier": 2, "credits": 15, "available": true },
    { "resolution_tier": 4, "credits": 30, "available": true },
    { "resolution_tier": 8, "credits": 60, "available": true },
    { "resolution_tier": 16, "credits": 120, "available": true }
  ],
  "max_file_size_bytes": 20971520,
  "formats": ["image/jpeg", "image/png", "image/webp"]
}

balance is the current credit balance. tiers lists each tier’s cost and plan availability. max_file_size_bytes and formats describe accepted files. Tool results also include a content text item containing the same JSON data; the examples show the decoded structuredContent only.

can_create_tasks indicates whether this account currently has paid MCP eligibility. A valid, unrevoked API key can still call get_upscale_info and get_upscale_task after a subscription expires; when there is no successful credit pack purchase, can_create_tasks becomes false and new tasks are denied. This field does not promise sufficient credits or access to every tier.

2. Create a task with upscale_image

ArgumentRequiredDescription
image_urlYesPublic HTTPS image URL meeting the requirements above.
resolution_tierNoNumber 2, 4, 8, or 16; defaults to 2 (2K, 15 credits).
idempotency_keyYesString of 1–128 characters. Reuse it for retries of the same image URL and tier.
foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "upscale_image",
    "arguments": {
      "image_url": "https://images.example.com/source.png",
      "resolution_tier": 2,
      "idempotency_key": "source-001-2k"
    }
  }
}
JSON

A newly created task may return the following result.structuredContent before processing finishes:

{
  "task_id": "00000000-0000-4000-8000-000000000001",
  "status": "pending",
  "credits_charged": 15,
  "credits_remaining": 185,
  "resolution_tier": 2
}

task_id is the UUID to use in subsequent queries. Creation is asynchronous, so the initial status may already have advanced by the time you receive it. credits_charged records the task’s credit cost; query get_upscale_info again for your current balance.

credits_remaining is the current account balance returned with task creation and retrieval. For an idempotent replay it reflects the current balance, which may differ from the balance immediately after the original charge.

3. Retrieve a task with get_upscale_task

The only argument is the required task_id, a UUID returned by task creation. Only tasks belonging to the API key’s account can be retrieved. Replace the sample UUID below with your task ID.

foca_mcp <<'JSON'
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "get_upscale_task",
    "arguments": {
      "task_id": "00000000-0000-4000-8000-000000000001"
    }
  }
}
JSON

A completed task returns this form of result.structuredContent. The URL and timestamp are illustrative:

{
  "task_id": "00000000-0000-4000-8000-000000000001",
  "status": "succeeded",
  "credits_charged": 15,
  "credits_remaining": 185,
  "resolution_tier": 2,
  "download_url": "https://downloads.example.com/result.png?signature=EXAMPLE",
  "expires_at": "2026-10-17T13:00:00.000Z"
}

Task status and result expiry

statusMeaningClient action
pendingWaiting for processing capacity.Query again after a delay.
processingBeing dispatched or processed.Query again after a delay.
succeededProcessing finished.Download from download_url before expires_at.
failedProcessing failed; error_code is PROCESSING_FAILED / RESULT_EXPIRED.Stop querying and inspect your account before creating a new task.

Space out get_upscale_task calls and back off when rate limited. Stop when the status is succeeded or failed. Task updates continue on the server; the MCP connection does not need to remain open during processing.

Download links are temporary. expires_at is an ISO 8601 timestamp; use that returned value as the deadline. The default link lifetime is one hour, but it can vary. If only the link has expired, query the task again to obtain a new signed link while the result is retained.

Task results are retained for 24 hours from task creation. After that, a query returns status: "failed" with error_code: "RESULT_EXPIRED", or TASK_NOT_FOUND if the record has been removed. Download the result and save your own copy within that period.

Retries and idempotency

For a retry after a timeout or lost response, keep the same idempotency_key, image_url, and resolution_tier. A replay returns the existing task and does not charge task credits again. The key is scoped to the account, including requests made with its other API keys.

Use a new key for a different image URL or tier. Reusing a key with different parameters returns IDEMPOTENCY_CONFLICT. Do not create a new key just because a response was lost; the original task may already exist. Changing a signed URL’s query string also changes the request parameters.

Idempotency records are retained for at least 30 days and removed by daily cleanup once older than 30 days. After cleanup, reusing an old key can create and charge a new task. Do not retry an old creation request after this period; task results still have their separate 24-hour retention.

Errors and limits

Business tool failures set result.isError to true and return result.structuredContent.error.code with an error message. Check the code rather than matching the message text. Invalid JSON-RPC or schema arguments are rejected by the protocol layer.

Error messages are returned in English for every client locale. For insufficient credits, result.structuredContent includes the following error details. Use required_credits and credits_remaining to explain the shortfall, and upgrade_url to open pricing.

{
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "message": "Not enough credits to create this task.",
    "required_credits": 15,
    "credits_remaining": 5,
    "upgrade_url": "https://focaupscaler.com/pricing"
  }
}
Error codeMeaning and action
PAID_ACCESS_REQUIREDActivate a paid subscription or complete a credit pack purchase before creating new tasks.
IMPORT_BUSYImage import capacity is busy. Wait five seconds and retry with the same idempotency key, URL, and tier.
INSUFFICIENT_CREDITSAdd credits, then retry.
PLAN_REQUIREDChoose an available tier or upgrade your plan.
IDEMPOTENCY_CONFLICTThe key was used with different parameters; check the original request.
TASK_NOT_FOUNDThe task does not exist, belongs to another account, or has been removed.
INVALID_IMAGE_URL / UNSAFE_IMAGE_URLUse a public HTTPS URL on port 443 without embedded credentials.
INVALID_IMAGESupply a valid JPEG, PNG, or WebP file.
IMAGE_TOO_LARGE / IMAGE_DIMENSIONS_UNSUPPORTEDReduce the file to 20 MB and 64 MP or less.
IMAGE_DOWNLOAD_FAILED / IMAGE_DOWNLOAD_TIMEOUT / TOO_MANY_REDIRECTSCheck that the URL is reachable, sufficiently long-lived, and uses at most three redirects.
IMAGE_CONVERTER_UNAVAILABLE / INTERNAL_ERRORRetry later, preserving the original idempotency key for creation.
TASK_REJECTEDThe task failed account or queue validation; review the request and account.
RATE_LIMITEDDelay the next request.

The account limit is 60 MCP requests per minute, with at most five new task submission attempts per minute. The HTTP layer may return 401 UNAUTHORIZED for a missing, invalid, or revoked key; 403 INVALID_ORIGIN for a rejected Origin header; 429 RATE_LIMITED with Retry-After: 60; or 503 MCP_UNAVAILABLE when the service is unavailable. Use a remote MCP client that can send the required authorization headers.

In API key settings, POST /api/mcp/keys returns HTTP 403 PAID_ACCESS_REQUIRED when the account has no paid eligibility and HTTP 503 MCP_UNAVAILABLE if key creation is temporarily unavailable. Listing and revoking existing keys remain available. An invalid MCP bearer key always receives HTTP 401; it is not reported as a successful tool response.

Test your setup

After connecting, ask your client:

Use Foca get_upscale_info to show my remaining credits and available output tiers. Do not create an image task.

A successful response confirms that your client can discover tools and authenticate. This read-only check does not spend task credits. To test processing afterward, provide your own public HTTPS image URL and explicitly request an output tier; the listed task cost applies.

Privacy and terms

Review the Privacy Policy and Terms of Service before submitting images. Only submit images you are authorized to process.