Skip to content

MCP Blacklist

Introduction

The FraudScore channel blacklist service exposes a single interface that can be used in two ways:

  • as an MCP server — connected to any LLM client with Model Context Protocol support (Claude Desktop, Cursor, etc.);
  • as a plain JSON-RPC 2.0 API — by sending requests directly from your code, with no LLM involved.

Both modes use the same protocol and the same set of tools: the MCP transport is built on top of JSON-RPC 2.0, so any request an MCP client sends can be reproduced with a plain HTTP POST /mcp call.

Note: tool names, tool descriptions and all API-returned texts (success messages and errors) are always in English, regardless of the language of this documentation. This ensures unambiguous interpretation by both LLMs and integrations.

General overview

Parameter Value
Base URL https://mcp.fraudscore.ai
API endpoint POST /mcp
Health check GET /healthz — returns {"status":"ok"}
Protocol JSON-RPC 2.0 (Streamable HTTP, sessionless)
Response format application/json (single JSON response, no streaming)
Maximum request size 256 KB

The service is sessionless: every HTTP request is processed independently. There is no session ID to keep, no handshake to perform, and no re-initialization — you simply send standalone JSON-RPC requests.

Authentication

Every request to POST /mcp requires an API token in the Authorization header:

Authorization: Bearer mcp_XXXXXXXXXXXXXXXX

Token requirements:

  • the mcp_ prefix;
  • followed by 8 to 128 characters: Latin letters, digits, _, - and ..

The token determines your account and the list of channels you are allowed to manage. Any attempt to access a channel not linked to your account will be rejected. Use the list_channels tool to see the channels available to you.

The token is a secret. Only send it over HTTPS and never publish it.

Tools

The service provides three tools. Tool names and the descriptions shown to the LLM in tools/list are in English. Standard MCP annotations (readOnlyHint, destructiveHint, idempotentHint) are declared for read and write tools — MCP clients may use them to confirm dangerous actions.

list_channels

Returns the list of channel identifiers available to your account. Takes no parameters.

Result: {"channels": ["my_channel_1", "my_channel_2"]} — identifiers only, with no additional channel information.

Typical workflow: call list_channels to discover valid IDs first, then use get_install_filter / update_install_filter to read and modify.

get_install_filter

Retrieves the current blacklist settings of a channel.

Parameters:

Field Type Required Description
channelId string | number yes Channel identifier

channelId format: a string of 1 to 200 characters, allowing Latin letters, digits, _ and -. Numeric identifiers are accepted as well.

Result: the install_filter object with the channel's current filter configuration (see the format below).

update_install_filter

Updates the blacklist settings of a channel.

Parameters:

Field Type Required Description
channelId string | number yes Channel identifier
install_filter object yes New filter configuration

Important: the operation replaces the filter configuration as a whole — the submitted lists are not merged with the existing ones. To preserve current values, first fetch them via get_install_filter, apply your changes, and submit the full object.

Result: a confirmation that the update succeeded, along with the applied filter configuration.

install_filter format

{
  "type": "block",
  "affiliate": ["affiliate_1", "affiliate_2"],
  "offer": ["offer_1"]
}
Field Type Required Description
type string yes Always "block" — no other value is accepted
affiliate string[] no List of affiliate identifiers the filter applies to
offer string[] no List of offer identifiers the filter applies to

Constraints on the affiliate and offer lists:

  • up to 100 items per list;
  • each item is a string of 1 to 648 characters (surrounding whitespace is trimmed);
  • passing an empty array [] or omitting the field entirely clears the list;
  • no fields other than the ones listed above are allowed — the object is validated strictly, and unknown fields cause an error.

The type field is required in every update request, including updates that only modify the lists.

Direct API

Every tool is invoked via the JSON-RPC method tools/call. To retrieve the list of available tools, use tools/list.

Request headers

POST https://mcp.fraudscore.ai/mcp
Authorization: Bearer mcp_XXXXXXXXXXXXXXXX
Content-Type: application/json
Accept: application/json, text/event-stream

Listing tools

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

Calling list_channels

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "list_channels",
    "arguments": {}
  }
}

Example response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"channels\":[\"my_channel_1\",\"my_channel_2\"]}"
      }
    ],
    "isError": false
  }
}

Calling get_install_filter

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_install_filter",
    "arguments": {
      "channelId": "my_channel_1"
    }
  }
}

Example response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"install_filter\":{\"type\":\"block\",\"affiliate\":[\"affiliate_1\"]}}"
      }
    ],
    "isError": false
  }
}

A tool's payload is always returned in result.content[0].text as a compact JSON string (no whitespace) — parse it on your side (e.g., JSON.parse in JavaScript).

Calling update_install_filter

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "update_install_filter",
    "arguments": {
      "channelId": "my_channel_1",
      "install_filter": {
        "type": "block",
        "affiliate": ["affiliate_1", "affiliate_2"],
        "offer": ["offer_1"]
      }
    }
  }
}

Example success response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"success\":true,\"message\":\"Filter updated successfully\",\"install_filter\":{\"type\":\"block\",\"affiliate\":[\"affiliate_1\",\"affiliate_2\"],\"offer\":[\"offer_1\"]}}"
      }
    ],
    "isError": false
  }
}

JavaScript example (no SDK)

const response = await fetch('https://mcp.fraudscore.ai/mcp', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer mcp_XXXXXXXXXXXXXXXX',
    'Content-Type': 'application/json',
    'Accept': 'application/json, text/event-stream'
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'tools/call',
    params: {
      name: 'get_install_filter',
      arguments: { channelId: 'my_channel_1' }
    }
  })
})

const rpc = await response.json()
const payload = JSON.parse(rpc.result.content[0].text)
console.log(payload.install_filter)

MCP server

Connect the service to your MCP client. Example configuration:

{
  "mcpServers": {
    "fraudscore": {
      "type": "http",
      "url": "https://mcp.fraudscore.ai/mcp",
      "headers": {
        "Authorization": "Bearer mcp_XXXXXXXXXXXXXXXX"
      }
    }
  }
}

Once connected, you can give the model instructions in natural language, for example:

  • "Show the available channels";
  • "Show the current blacklist of channel my_channel_1";
  • "Add affiliate affiliate_3 to the blacklist of channel my_channel_1" — with such a request the model performs the chain on its own: list_channels → get_install_filter → update_install_filter with the complete object.

The client and the server exchange exactly the same JSON-RPC messages as in direct mode — the MCP client and the LLM simply take care of composing them. You can talk to the model in any language; only the API's service texts (tool descriptions, success messages and errors) are in English.

Error handling

Errors are returned on two levels. All API error texts are in English.

HTTP level

Code Response body Reason What to do
401 {"error": "Unauthorized. Valid mcp_* token required"} Missing token or invalid format Check the Authorization header and the mcp_* token format
403 {"error": "Forbidden or account not found"} Token not found or account unavailable Contact support to verify your token
502 {"error": "Authorization service unavailable"} Temporary unavailability of the authorization service Retry the request later

Tool level

If the HTTP request succeeds but the tool itself fails, the response comes back with isError: true and a textual error description in English.

Example — no access to the channel:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Access to channel my_channel_2 denied"
      }
    ],
    "isError": true
  }
}

Example — filter validation error (the specific reason is included):

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Invalid install_filter: \"type\" must be strictly \"block\""
      }
    ],
    "isError": true
  }
}

Typical causes and message formats:

  • no access to the channel — the channel is not linked to your token's account: Access to channel ... denied;
  • install_filter validation error — unknown fields, wrong type, values too long, etc.: Invalid install_filter: <specific reason>;
  • internal failure — a neutral message with no internal details: Failed to retrieve filter on reads, Failed to update filter on writes.

This message format lets integrations (and LLMs) immediately understand the cause of an error and fix the request, without exposing the service's internal details.

Constraints and notes

  • One request, one operation: the service keeps no state between requests.
  • The update operation replaces the filter configuration as a whole: to preserve the current lists, first fetch them via get_install_filter, apply your changes, and submit the full object.
  • Retrying the same update request is safe: it brings the filter to the same state.
  • All requests and responses use UTF-8 encoding.

oct 7, 2026