Skip to content

MCP server

Futuros ships a Model Context Protocol (MCP) server so any external agent — Claude Code, Claude Desktop, Cursor, or your own client — can query the same cited LATAM-development corpus the Futuros chat uses. Every figure a tool returns carries a citation_id; the tools only read baked data and compute deterministically — no writes, no hidden LLM call.

  • Endpoint: POST https://futuros.xyz/api/mcp
  • Transport: Streamable HTTP (JSON-RPC 2.0)
  • Protocol version: 2025-06-18
  • Server identity: futuros-corpus v1.0.0 — "Futuros — LATAM governed-data corpus"
  • Auth: none (read-only public corpus)
  • State: stateless — every request is self-contained
  • Rate limit: best-effort 60 requests/minute per client IP (HTTP 429 on exceed)

Transport semantics

The server implements the minimum of Streamable HTTP required for a stateless tool server:

Method on /api/mcpBehavior
POSTJSON-RPC 2.0 — a single message or a batch (JSON array). Returns the response object, or an array for a batch.
POST (notifications only)HTTP 202 Accepted, empty body (no id → no reply).
OPTIONSCORS preflight → 204.
GET405 — stateless server, no server-initiated SSE stream.

CORS is fully open (Access-Control-Allow-Origin: *, methods POST, OPTIONS, allowed headers Content-Type, Mcp-Session-Id, Mcp-Protocol-Version), so browser-based agents can call it cross-origin.

JSON-RPC error codes used: -32700 parse error, -32600 empty/invalid request, -32601 method not found / GET, -32602 unknown tool, -32000 rate limited.

Connecting a client

Claude Code

bash
claude mcp add --transport http futuros https://futuros.xyz/api/mcp

Claude Desktop / any config-file client

Add to your MCP client config (Claude Desktop's claude_desktop_config.json, or equivalent). A native HTTP-capable client:

jsonc
{
  "mcpServers": {
    "futuros": {
      "type": "http",
      "url": "https://futuros.xyz/api/mcp"
    }
  }
}

For a client that only speaks stdio, bridge with mcp-remote:

jsonc
{
  "mcpServers": {
    "futuros": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://futuros.xyz/api/mcp"]
    }
  }
}

On initialize the server returns its instructions string, which tells the agent how to drive the corpus: resolve a metric named in words with resolve_metric, then call get_parameter_data / compare_countries / compute; every figure carries a citation_id; if the corpus lacks a figure the tools say so rather than inventing one.

Tools

The MCP server exposes the Futuros chat toolset minus the open-web tools (web_search and fetch_url are deliberately excluded so the endpoint can't double as an SSRF proxy and stays scoped to cited Futuros data). Fourteen tools:

ToolWhat it returnsKey parameters
resolve_metricMaps a metric named in words to a governed indicator id (from the metric registry) — ranked candidates with canonical id, unit, good_direction, pillar, coverage, vintage. Call this first when you need an id.query (req), pillar, limit
get_parameter_dataFull picture for one pillar in one country: cited narrative, all indicators (value/trend/year/citation_id), governance, correlations, evidence grade.parameter (req), country (req)
compare_countriesOne pillar's indicators across 2–8 countries in one call, each figure cited.parameter (req), countries[] (req, 2–8)
get_newsCurated recent news for a pillar+country; each item's id is its citation_id.parameter (req), country (req), limit
get_regional_pulseLATAM regional aggregate for one pillar: value, trend, leaders/laggards, movers, documented source contradictions.parameter (req)
computeA reproducible calculation cited to its exact input cells. Ops: change, cagr, rank, gap_to_frontier, correlation, forecast, explain_change.op+parameter+indicator (req); then country/countries[]/from_year/to_year/year/order/frontier/method/indicator_b
get_data_healthHow fresh/reliable/complete the data is. With parameter+country: trust score, provenance %, vintage, anomalies, coverage gaps. With no args: the regional summary + refresh worklist.parameter, country (both optional)
get_discoveriesProactively surfaces the biggest anomalies and source contradictions, ranked by magnitude, each cited.parameter, country, limit (all optional)
find_pilotsSearch the bankable pilot portfolio; returns slug, pitch, country, maturity, capex, impact basis.country, parameter, query, limit (all optional)
get_pilotFull design sheet for one pilot: economics, bankability evidence, risks, financing, decision-makers.slug (req)
recommend_actionThe un-copyable action chain for a country+pillar: best-fit pilot → financing instruments → ranked decision-makers with tailored asks.country (req), pillar (req)
search_corpusSemantic search across the entire corpus (personas, pilots, cases, signals, financing, regulation…); returns hits with dataset_id + keys to fetch via get_dataset.query (req), datasets[], country, parameter, limit
get_datasetGeneric accessor for any catalogued dataset by dataset_id + that dataset's keys.dataset_id (req), country/slug/id/role/layer/status
perplexity_searchLive external web synthesis (Perplexity Sonar) for current events the corpus lacks. Results are labeled external, not corpus-verified.query (req), recency (day/week/month/year)

perplexity_search is environment-gated

perplexity_search is exposed but dormant unless PERPLEXITY_API_KEY is set on the deployment. Without it, the tool returns a note telling the agent to answer only from the corpus. On the hosted futuros.xyz server, treat its availability as best-effort; the 13 corpus/compute tools above are always live.

Citation semantics

tools/call returns MCP tool content as a single text block whose payload is a JSON string:

json
{ "result": { /* the tool's answer */ }, "citations": [ /* resolved sources */ ] }

isError is true when a tool reports a problem (e.g. an unknown indicator). Every numeric figure inside result is bound to a citation_id that appears in citations (or resolves against the public citations.json). The design contract: never surface a Futuros figure without its citation, and label perplexity_search results as outside the corpus.

Worked example

List the tools, then resolve a metric and fetch a cited comparison.

1 — initialize

bash
curl -s https://futuros.xyz/api/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-06-18","capabilities":{},
                 "clientInfo":{"name":"demo","version":"0"}}}'
jsonc
{ "jsonrpc": "2.0", "id": 1, "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": { "tools": { "listChanged": false } },
    "serverInfo": { "name": "futuros-corpus", "version": "1.0.0",
                    "title": "Futuros — LATAM governed-data corpus" },
    "instructions": "Read-only access to the Futuros corpus: …" } }

2 — tools/list

bash
curl -s https://futuros.xyz/api/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

3 — tools/call (resolve_metric)

bash
curl -s https://futuros.xyz/api/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"resolve_metric","arguments":{"query":"homicidios"}}}'

4 — tools/call (compare_countries) using the resolved id

bash
curl -s https://futuros.xyz/api/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call",
       "params":{"name":"compare_countries",
                 "arguments":{"parameter":"seguridad","countries":["MEX","BRA","COL"]}}}'
jsonc
{ "jsonrpc": "2.0", "id": 4, "result": {
    "content": [ { "type": "text",
      "text": "{\"result\":{ …per-country figures… },\"citations\":[ … ]}" } ],
    "isError": false } }

Batch — send an array to run several calls in one round-trip; the response is an array of results in order.

For flat file downloads of the same corpus (CSV/SDMX/XLSX), use the Public API v1.

Cada cifra con su fuente — la trazabilidad es el contrato.