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, xql_run, and xql_nl_reference tools as the REST API, exposed over MCP through xcreener-mcp, an open-source local bridge for Claude Desktop, Claude Code, Cursor, Windsurf, and any other stdio MCP client.

Claude Desktop — download & double-click to install
Download xcreener.mcpb
Claude Code
claude mcp add xcreener -e XCREENER_API_KEY=<your-api-key> -- npx -y @xcreener/mcp
Cursor, Windsurf & other stdio clients — via npx
{
  "mcpServers": {
    "xcreener": {
      "command": "npx",
      "args": ["-y", "@xcreener/mcp"],
      "env": {
        "XCREENER_API_KEY": "your-actual-key-here"
      }
    }
  }
}

Claude Code

One CLI command wires up the bridge as a local stdio server, with your API key passed as an environment variable.

Claude Desktop

Download the xcreener.mcpb bundle, then double-click it to install — Desktop asks for your API key in a masked field as part of that same dialog. No JSON to hand-edit, no separate Node install.

Cursor & Windsurf

Run npx @xcreener/mcp locally via the config below (Cursor: ~/.cursor/mcp.json, Windsurf: ~/.codeium/windsurf/mcp_config.json).

Other MCP clients

Any stdio-capable MCP client can run npx @xcreener/mcp the same way, with XCREENER_API_KEY set in its environment.

Human query → XQL

Ask in plain English — the assistant calls the xql_nl_reference tool to look up the phrase-to-XQL mapping, then validates and runs the query for you.

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