XCREENER Query Language · REST API · MCP

Query the Market Like a Database

rsi(14) < 30 and close > d::sma(200) — oversold on the hourly, still in a daily uptrend. XCREENER Query Language (XQL) reads like a query language because it is one: combine RSI, moving averages, breakouts, and multiple timeframes into the exact condition you're looking for, then run it against market data — instantly in the Playground, or over the API.

New to XCREENER? Start with the screener pages — no code, no signup required. This page is for when you want to go further.

Three endpoints, one query language

Every request reads the raw XQL query text from the request body and requires an API key. /xql/run is all you need to go live — validate and explain are there when you're debugging a query.

POST/xql/validate

Checks your query is well-formed, no data touched. Optional — skip straight to /xql/run.

curl https://api.xcreener.com/xql/validate \
  -H "Authorization: Bearer <your-api-key>" \
  --data-raw 'market = "FOREX"
timeframe = h4

close > highest(high, 20) and volume > avg(volume, 20) * 1.5'
Success — 200
{ "valid": true }
Failure — 400
{
  "valid": false,
  "error": {
    "type": "syntax",
    "message": "Unexpected end of input, expected ')'",
    "position": { "line": 3, "column": 12, "offset": 45 }
  }
}
POST/xql/explain

Returns the data your query needs and a plain description of what it matches. Optional — skip straight to /xql/run.

curl https://api.xcreener.com/xql/explain \
  -H "Authorization: Bearer <your-api-key>" \
  --data-raw 'market = "CRYPTO"
timeframe = h1

rsi(14) < 30 and h4::rsi(14) < 40'
Success — 200
{
  "plan": {
    "market": "CRYPTO",
    "sources": [
      { "timeframe": "h1", "series": ["close"], "minLookback": 15 },
      { "timeframe": "h4", "series": ["close"], "minLookback": 15 }
    ]
  },
  "explanation": "Matches when rsi(14) < 30 and h4::rsi(14) < 40."
}
Failure — 400
{
  "valid": false,
  "error": {
    "type": "syntax",
    "message": "Unknown identifier 'closee', did you mean 'close'?",
    "position": { "line": 3, "column": 1, "offset": 32 }
  }
}
POST/xql/run

Fetches data and runs your query against every instrument in the market/timeframe.

curl https://api.xcreener.com/xql/run \
  -H "Authorization: Bearer <your-api-key>" \
  --data-raw 'market = "CRYPTO"
timeframe = h1
columns = [close, volume]
sort = volume desc
limit = 5

crossover(ema(volume, 10), ema(volume, 30))'
{
  "results": [
    {
      "symbol": "ETHUSDT",
      "columns": { "close": 3421.55, "volume": 84213.4 }
    },
    {
      "symbol": "SOLUSDT",
      "columns": { "close": 142.31, "volume": 512044.2 }
    }
  ]
}

Connect via MCP

The same xql_validate, xql_explain, and xql_run tools as the REST API, exposed over MCP — plus a translate_query prompt for turning plain English into XQL, for any client that supports Bearer-token authentication.

Endpoint
https://api.xcreener.com/mcp
Claude Code
claude mcp add --transport http xcreener https://api.xcreener.com/mcp \
  --header "Authorization: Bearer <your-api-key>"
Claude Desktop, Cursor, Windsurf & others — via mcp-remote
{
  "mcpServers": {
    "xcreener": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.xcreener.com/mcp",
        "--header",
        "Authorization: Bearer <your-api-key>"
      ]
    }
  }
}

Claude Code

Fully supported natively — Claude Code sends the Authorization header exactly as configured, so one command wires it up.

Claude Desktop

Supported via the mcp-remote bridge below — Claude Desktop's native remote-connector doesn't forward the Bearer header, but adding it as a local command with mcp-remote works, since mcp-remote makes the authenticated request itself.

Cursor & Windsurf

Same mcp-remote bridge as Claude Desktop — both read their MCP config from a local file (Cursor: ~/.cursor/mcp.json, Windsurf: ~/.codeium/windsurf/mcp_config.json) in the same command/args format.

Other MCP clients

Any client that supports Bearer/custom-header auth on a remote HTTP MCP server works the same way. Clients that only speak local/stdio can bridge in with mcp-remote, same as above.

Human query → XQL

Invoke the translate_query prompt in clients that support MCP prompts, or read the xql://nl-reference resource directly in clients that don't.

It's oversold

rsi(14) < 30

Volume more than 2x its average

let avgv = avg(volume, 20)
volume > avgv * 2

New 52-week high

close >= w::highest(high, 52)

How it works

Write your query and run it — validate and explain are optional tools for when you're debugging.

Step 1

Write your query

Draft your XQL query for the market and timeframe you care about — try it in the free Playground, no API key needed.

Step 2

Debug it, if you need to

/xql/validate and /xql/explain are optional dev tools — not required once your query works.

Step 3

Run it

/xql/run is the only endpoint you need to go live.

Included with Essential and Plus

API and MCP access both come with the Essential and Plus plans — generate a key from your account once you've upgraded, and every REST endpoint and MCP tool (validate, explain, run) is ready to call. Plus includes a higher daily API request limit for heavier automated use.

Sign up for API access