# Roundhouse (remote · api.roundhouseai.io)

Read-only analytics on x402 agent payments and ERC-8004 agent identity, with SQL.

- Trust score: 66/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- remote · `api.roundhouseai.io`: 66/100 (this document), [markdown](https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp.md), [page](https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp)

## Channel facts

- Endpoint: `https://api.roundhouseai.io/v0/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one.
  - HTTPS enforcement could not be verified: the plaintext port answered with HTTP 405, which proves neither a plaintext path nor enforcement.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 57/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 8739 tokens (~514/item across 17 items; 17 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 30/100
  - Stability observed for 9 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 17 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 18 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 60/100
  - Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28.

## Install

### How do I install the Roundhouse MCP server?

Roundhouse is a hosted endpoint at https://api.roundhouseai.io/v0/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http io-roundhouseai-roundhouse 'https://api.roundhouseai.io/v0/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "io-roundhouseai-roundhouse": {
      "url": "https://api.roundhouseai.io/v0/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "io-roundhouseai-roundhouse": {
      "type": "http",
      "url": "https://api.roundhouseai.io/v0/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.io-roundhouseai-roundhouse]
url = "https://api.roundhouseai.io/v0/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io-roundhouseai-roundhouse": {
      "type": "remote",
      "url": "https://api.roundhouseai.io/v0/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add io-roundhouseai-roundhouse --url 'https://api.roundhouseai.io/v0/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  io-roundhouseai-roundhouse:
    url: "https://api.roundhouseai.io/v0/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "io-roundhouseai-roundhouse": {
      "Transport": "http",
      "Url": "https://api.roundhouseai.io/v0/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add io-roundhouseai-roundhouse -t streamable-http -u 'https://api.roundhouseai.io/v0/mcp'
```

### Other

```json
{
  "mcpServers": {
    "io-roundhouseai-roundhouse": {
      "type": "http",
      "url": "https://api.roundhouseai.io/v0/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 66, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 65, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-31 (score 64, +1)

No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-29 (score 63, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-28 (score 62, 0)

- [functional improvement] Stability: unverified → 0.03

### 2026-10-27 (score 62, +31)

- [security regression] Authorization: pass → partial
- [security improvement] Transport: unverified → pass
- [security improvement] Injection markers: unverified → pass
- [security] First check of Judged manipulation: pass
- [functional regression] MCP protocol: unverified → fail
- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: fail
- [functional] First check of Schema quality: excellent
- [functional] First check of Destructive annotations: pass
- [functional] First check of Schema quality: fail
- [functional] First check of Tool coverage: 100

### 2026-10-16 (score 31)

First indexed and scored.

## MCP tools (17)

### `get_account` (~857 tokens)

What this caller is entitled to, and what it would be charged

Who the credential in front of this request resolves to, which of the two paid lanes it would take, what it has left to spend, and the price of every route on both lanes. Unmetered and answerable WITHOUT a key: checking your balance must never cost a unit and must never be the thing that fails. A caller with no key gets a real answer (`tier: anonymous`, `lane: x402`, the full price list), not a 401, so both prices can be compared before committing to either. An unrecognised key also answers 200, with `key_recognised: false` — this is the endpoint you reach for when your key is the thing that is broken, so it must work then.

Wraps GET /v0/account.
Access: no API key required.

Returns:
\- authenticated: Whether a credential was accepted.
\- key_present: Whether a credential was sent at all.
\- key_recognised: Whether it resolved, or NULL when none was sent — three-valued, because "no key" and "a key that did not resolve" need different fixes and one `false` for both would conflate them.
\- tier: `anonymous`, `trial`, `oauth`, or the organization key tier.
\- plan: The organization's plan key, or null when there is no organization.
\- lane: Which lane this caller would take on a metered route, so it can be PREDICTED rather than discovered by being refused: `credit` draws down Query Units, `x402` pays per call, `invalid_key` resolves to nothing, `no_account` is a caller with no organisation behind it on the MCP surface, where there is no x402 door, and `upgrade_required` is that same surface reached by a caller that HAS an organisation whose plan excludes the route. The last two were one value until a signed-in connection with an organisation and a balance was told it had no account behind it.
\- organisation: Id and display name, or null. Named so an operator with several accounts knows which one to top up.
\- balance: Units available and the low-balance threshold, or NULL with a `balance_note` saying why there is no balance to report — an organizationless caller has none,…

### `list_flows` (~423 tokens)

Live flow of funds

The newest settlements across every indexed chain, payer to payee. This is the same feed the `/flows` page renders.

Wraps GET /v0/flows.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- flows: Settlement rows, newest first, decorated with resolved display names. Each row also carries `is_self_payment` (payer = payee, annotated rather than only excluded — a third of the feed can be self-payment) and `evidence`: `{ verified, method, probability, tier }`. `verified` is THREE-VALUED — `true` a named facilitator relayed it, `false` examined with no EIP-3009 marker, and `null` gasless and authorized but NOT ESTABLISHED as x402, which is not the same as disproven. `tier` is `proven` | `probable` | `unproven` | `not_x402` | `ungraded`.
\- next_before: Cursor for the next page, or `null` at the end of the list.
\- meta: The chain served and `as_of`. On a non-empty page `meta` also carries `page_self_payments`, `page_self_payment_usd`, `page_gross_usd` and `page_organic_usd`. All four are THIS PAGE only, as the names say: they are not site-wide figures and summing them across pages is not a total. On an EMPTY list it instead carries `dataset_last_written_at`, `dataset_row_count` and any `warnings`.

Input parameters:

- `before` (string): Opaque cursor from a previous response's `next_before`. It encodes the whole sort key, tiebreaker included, so a page boundary inside a group of rows sharing a timestamp does not skip the rest. Do no…
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.

### `list_transactions` (~603 tokens)

Global settlement feed

Every indexed settlement, newest first, filterable by how confidently it is known to be an x402 payment.

Wraps GET /v0/transactions.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- transactions: Settlement rows, newest first. Each row also carries `is_self_payment` (payer = payee, annotated rather than only excluded — a third of the feed can be self-payment) and `evidence`: `{ verified, method, probability, tier }`. `verified` is THREE-VALUED — `true` a named facilitator relayed it, `false` examined with no EIP-3009 marker, and `null` gasless and authorized but NOT ESTABLISHED as x402, which is not the same as disproven. `tier` is `proven` | `probable` | `unproven` | `not_x402` | `ungraded`.
\- next_before: Cursor for the next page, or `null`. Minted from the rows READ, not the rows shown, so `exclude_self_payments` cannot end the walk early.
\- meta: The chain served and `as_of`. On a non-empty page `meta` also carries `page_self_payments`, `page_self_payment_usd`, `page_gross_usd` and `page_organic_usd`. All four are THIS PAGE only, as the names say: they are not site-wide figures and summing them across pages is not a total. `self_payments_excluded` is set when the page was filtered.

Input parameters:

- `before` (string): Opaque cursor from a previous response's `next_before`. It encodes the whole sort key, tiebreaker included, so a page boundary inside a group of rows sharing a timestamp does not skip the rest. Do no…
- `exclude_self_payments` (string): Set to `true` to drop rows where payer = payee. Off by default: a feed is a record of what happened and a wallet paying itself did happen, so the rows are ANNOTATED (`is_self_payment`) rather than hi…
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.
- `min_probability` (number): Keep only rows at or above this x402 confidence. `1.0` is proven by a named facilitator having relayed it; `0.05` is a bare transfer to a catalogued address. Read `evidence` on the row rather than th…

### `list_entity_settlements` (~517 tokens)

Settlements for one wallet

Settlements where this wallet is either the payer or the payee, newest first. Walkable deeply in time order: `(payer, block_time desc)` and `(payee, block_time desc)` cover it, so page N costs what page 1 does and a wallet's whole history can be paged for velocity or trend.

Wraps GET /v0/entities/{wallet}/settlements.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- wallet: The wallet queried, lowercased.
\- settlements: Settlement rows, newest first, decorated with resolved display names. Each row also carries `is_self_payment` (payer = payee, annotated rather than only excluded — a third of the feed can be self-payment) and `evidence`: `{ verified, method, probability, tier }`. `verified` is THREE-VALUED — `true` a named facilitator relayed it, `false` examined with no EIP-3009 marker, and `null` gasless and authorized but NOT ESTABLISHED as x402, which is not the same as disproven. `tier` is `proven` | `probable` | `unproven` | `not_x402` | `ungraded`.
\- next_before: Cursor for the next page, or `null`.
\- meta: The chain served and `as_of`. On a non-empty page `meta` also carries `page_self_payments`, `page_self_payment_usd`, `page_gross_usd` and `page_organic_usd`. All four are THIS PAGE only, as the names say: they are not site-wide figures and summing them across pages is not a total.

Input parameters:

- `before` (string): Opaque cursor from a previous response's `next_before`. It encodes the whole sort key, tiebreaker included, so a page boundary inside a group of rows sharing a timestamp does not skip the rest. Do no…
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.
- `wallet` (string, required): An EVM address (`0x` + 40 hex digits; case-insensitive, lowercased before lookup) or a Solana address (base58; case-sensitive, used exactly as given). An address the index has not observed answers `c…

### `get_agent` (~780 tokens)

Per-agent stats and identity

One wallet in its paying role: its resolved identity and its own settlement aggregates. Every figure is that wallet's own — there are no site-wide totals on this endpoint.

Wraps GET /v0/agents/{wallet}.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- wallet: The wallet queried, lowercased.
\- role: The role it was queried in: `agent` or `merchant`.
\- coverage: **Read this first.** `known` false means the index has never observed this address, so every figure below is a zero meaning "not observed" — not "observed to be nothing". Also `first_seen`, `last_seen`, `settlements_scanned`, `scan_truncated` and `scan_cap`.
\- entities: Resolved identity rows: display name, ENS, ERC-8004 card, role, first and last seen.
\- erc8004_agents: ERC-8004 registrations whose on-chain agentWallet is this address.
\- aggregates: That wallet's own totals: inbound/outbound USD and counts, distinct counterparties, chain split. `basis` says what they were computed over — `index_rollup` is the whole history, `scanned_settlements` is the capped scan and is a floor when `coverage.scan_truncated` is set. `distinct_counterparties` excludes the wallet itself on both bases. `chain_split` is the exception and carries its own `chain_split_basis`: the rollup is keyed by wallet and holds no chain dimension, so that split is ALWAYS the scan and is capped with it, whatever the object-level `basis` says.
\- data_quality: The risk annotation. **Route on `verdict`, not on `note`.** `verdict` is one of `unobserved` (never seen — nothing assessed), `patterns_detected`, `no_patterns_detected`, or `insufficient_evidence` — the last meaning the address WAS observed, nothing fired, and not enough of its history was examined for that to rule anything out. `checks` carries every check with its `threshold`, what was `observed`, its own `basis`, and `conclusive`: a check that FIRED is always conclusive (a pattern seen in a sample happened), a check that did not fire on a truncat…

Input parameters:

- `recent_limit` (integer): Settlement rows to embed in the profile. 0 omits them. Default 5 — this was an unbounded 25, which is most of the payload on a surface where a response is billed as context tokens.
- `wallet` (string, required): An EVM address (`0x` + 40 hex digits; case-insensitive, lowercased before lookup) or a Solana address (base58; case-sensitive, used exactly as given). An address the index has not observed answers `c…

### `get_merchant` (~765 tokens)

Per-merchant stats and identity

The same shape as `/agents/{wallet}`, for a wallet in its receiving role.

Wraps GET /v0/merchants/{wallet}.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- wallet: The wallet queried, lowercased.
\- role: The role it was queried in: `agent` or `merchant`.
\- coverage: **Read this first.** `known` false means the index has never observed this address, so every figure below is a zero meaning "not observed" — not "observed to be nothing". Also `first_seen`, `last_seen`, `settlements_scanned`, `scan_truncated` and `scan_cap`.
\- entities: Resolved identity rows: display name, ENS, ERC-8004 card, role, first and last seen.
\- erc8004_agents: ERC-8004 registrations whose on-chain agentWallet is this address.
\- aggregates: That wallet's own totals: inbound/outbound USD and counts, distinct counterparties, chain split. `basis` says what they were computed over — `index_rollup` is the whole history, `scanned_settlements` is the capped scan and is a floor when `coverage.scan_truncated` is set. `distinct_counterparties` excludes the wallet itself on both bases. `chain_split` is the exception and carries its own `chain_split_basis`: the rollup is keyed by wallet and holds no chain dimension, so that split is ALWAYS the scan and is capped with it, whatever the object-level `basis` says.
\- data_quality: The risk annotation. **Route on `verdict`, not on `note`.** `verdict` is one of `unobserved` (never seen — nothing assessed), `patterns_detected`, `no_patterns_detected`, or `insufficient_evidence` — the last meaning the address WAS observed, nothing fired, and not enough of its history was examined for that to rule anything out. `checks` carries every check with its `threshold`, what was `observed`, its own `basis`, and `conclusive`: a check that FIRED is always conclusive (a pattern seen in a sample happened), a check that did not fire on a truncated scan is not. `note` says the same thing in a sentence and is derived from the two.
\- recent:…

Input parameters:

- `recent_limit` (integer): Settlement rows to embed in the profile. 0 omits them. Default 5 — this was an unbounded 25, which is most of the payload on a surface where a response is billed as context tokens.
- `wallet` (string, required): An EVM address (`0x` + 40 hex digits; case-insensitive, lowercased before lookup) or a Solana address (base58; case-sensitive, used exactly as given). An address the index has not observed answers `c…

### `list_agents` (~631 tokens)

Indexed ERC-8004 agents

Agents read from the on-chain IdentityRegistry, with their registration card and payment wallet. `score` is the ERC-8004 reputation score derived from on-chain feedback — it is the REGISTRY's number, not a Roundhouse rating, and it is null for every agent no counterparty has left feedback for. Roundhouse publishes no trust score of its own.

Wraps GET /v0/agents.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- agents: Agent rows with identity, wallet and the ERC-8004 `score` (null where the registry holds no feedback). `x402_support` is the registration card's own declaration; `last_activity_at` and `activity_status` are the observed halves, derived from settlements and feedback.
\- next_before: Cursor for the next page, or `null`.
\- meta: The chain served and `as_of`. On an EMPTY list it also carries `dataset_last_written_at`, `dataset_row_count` and any `warnings` (e.g. `endpoints_catalog_stale`) — so a zero can be read as a quiet market or a stalled ingest rather than guessed at.

Input parameters:

- `before` (string): Opaque cursor from a previous response's `next_before`. It encodes the whole sort key, tiebreaker included, so a page boundary inside a group of rows sharing a timestamp does not skip the rest. Do no…
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.
- `q` (string): Free-text search over name and description.
- `x402` (string): The earlier name for `x402_declared`, kept because it is published and a caller sending it wants the same rows. Prefer `x402_declared`, whose name says what it reads. Sending both uses `x402_declared…
- `x402_declared` (string): Set to `true` to keep only agents whose own ERC-8004 registration card declares x402 support (`x402Support: true`). This is the agent's CLAIM ABOUT ITSELF, copied out of a document its owner wrote, a…

### `list_wallets` (~245 tokens)

Every address the index has seen

All settling wallets, filterable by the role they were seen in.

Wraps GET /v0/wallets.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- wallets: Wallet rows with role and last seen.
\- next_before: Cursor for the next page, or `null`.
\- meta: The chain served and `as_of`. On an EMPTY list it also carries `dataset_last_written_at`, `dataset_row_count` and any `warnings` (e.g. `endpoints_catalog_stale`) — so a zero can be read as a quiet market or a stalled ingest rather than guessed at.

Input parameters:

- `before` (string): Opaque cursor from a previous response's `next_before`. It encodes the whole sort key, tiebreaker included, so a page boundary inside a group of rows sharing a timestamp does not skip the rest. Do no…
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.
- `role` (string): Restrict to one observed role.

### `get_leaderboard` (~316 tokens)

ERC-8004 agents by registry feedback score

Agents ordered by the ERC-8004 reputation score, which is the on-chain registry's number and not a Roundhouse rating. Unscored agents sort last rather than dropping out, so a board where nothing has been scored still comes back looking ordered — check `meta.page_scored_agents`, which is how many rows on the page carry a score at all. Zero means the order is the `agent_id` tie-break and nothing more. It pages by `offset` rather than a cursor, because a rank is a position and `score` is nullable — a keyset has nothing stable to compare against across the scored/unscored boundary.

Wraps GET /v0/leaderboard.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- leaderboard: Agent rows in score order, unscored last.
\- next_offset: Offset for the next page, or `null`.
\- meta: The chain served, `as_of`, and `page_scored_agents` — rows on this page with a non-null score. A `no_agent_on_this_page_has_a_score` warning when that is zero.

Input parameters:

- `include_spam` (string): Set to `1` to include agents with no feedback, which are hidden by default.
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.
- `offset` (integer): Rows to skip. Use the returned `next_offset`.

### `list_agent_feedback` (~211 tokens)

ERC-8004 feedback for one agent

Raw feedback entries from the ReputationRegistry for a single agent id.

Wraps GET /v0/agents/{agentId}/feedback.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- agent_id: The id queried.
\- chain: The chain the feedback was read from.
\- feedback: Feedback entries.
\- meta: The chain served and `as_of`. On an EMPTY list it also carries `dataset_last_written_at`, `dataset_row_count` and any `warnings` (e.g. `endpoints_catalog_stale`) — so a zero can be read as a quiet market or a stalled ingest rather than guessed at.

Input parameters:

- `agentId` (string, required): ERC-8004 agent id.
- `chain` (string): CAIP-2 chain id. An agent id is not unique across chains.
- `limit` (integer): Rows to return. Clamped to 100; values outside the range are clamped, not rejected.

### `list_facilitators` (~358 tokens)

Relayers, per chain

The facilitators seen relaying settlements, with their known relayer wallets. Paged: this used to return up to 200 rows unpaged, most of their columns null. Null-valued columns are omitted from each row.

Wraps GET /v0/facilitators.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- chain: The chain served — this deployment's default when none was named.
\- facilitators: Facilitator rows, busiest first. Null-valued fields are omitted.
\- next_offset: Offset for the next page, or `null`.
\- meta: The chain served and `as_of`. On an EMPTY list it also carries `dataset_last_written_at`, `dataset_row_count` and any `warnings` (e.g. `endpoints_catalog_stale`) — so a zero can be read as a quiet market or a stalled ingest rather than guessed at.

Input parameters:

- `chain` (string): CAIP-2 chain id. Defaults to the chain this deployment indexes (`eip155:8453` in production, `eip155:84532` on staging) — the same default every endpoint on this API uses. A chain the index does not…
- `enriched_only` (string): Keep only relayers whose nonce and gas balance have been read. A row without `enriched_at` has nothing populated but its address.
- `limit` (integer): Rows to return. Clamped to 200; values outside the range are clamped, not rejected.
- `offset` (integer): Rows to skip. Use the returned `next_offset`.

### `get_graph` (~1027 tokens)

Payment graph: nodes and payer→payee edges

Entities as nodes and settlements aggregated into edges, over a bounded window. Two window forms, and exactly one may be sent: `window=N` is a row count running to the live tip (briefly cacheable); `days=N` covers **whole UTC days only**, excluding today, so an answer is stable for the day. Use `days` for anything an agent will cache. Self-payments are excluded from BOTH edges and node totals and counted in `meta.excluded`, so `sum(node.window_usd)` is exactly twice `sum(edge.usd)`.

Wraps GET /v0/graph.
Access: requires an API key (Authorization: Bearer rh_live_… or x-api-key).

Returns:
\- applied: Every parameter as APPLIED, not as requested — both windows, the edge cap, the facilitator caps, the chain, the filters. Read this rather than assuming the request was honoured verbatim. `days` and `window` can BOTH be non-null: a wallet-focused day window is read row by row, so a row cap applies inside the declared range and `complete` says whether it bit.
\- complete: Whether the declared window was read in full. False means a row cap stopped the read inside the range — the response then covers the newest `applied.window` settlements in it, not the whole of it, and `meta.warnings` says so. Only `?days=` with `?wallet=` can be false.
\- days: The whole-UTC-day window applied, or `null` on the `window=N` path.
\- since: Inclusive start of the day window, or `null` on the `window=N` path.
\- until: Exclusive end of the day window (midnight today), or `null` on the `window=N` path.
\- since_day: The `since` bound as a UTC date, or `null`.
\- until_day: The `until` bound as a UTC date, or `null`.
\- mode: `daily` when the answer came from the per-day rollup, which covers the window exactly; `raw` when it was folded from settlement rows.
\- bucket: What one source row represented: `day` under `mode: daily`, `settlement` under `raw`.
\- truncated: True when the edge cap dropped edges the window contained.
\- nodes: One entry per wallet: role, display name, ENS, and its window totals.…

Input parameters:

- `chain` (string): CAIP-2 chain id. Defaults to the chain this deployment indexes (`eip155:8453` in production, `eip155:84532` on staging) — the same default every endpoint on this API uses. A chain the index does not…
- `days` (integer): Whole UTC days, excluding today, honoured exactly: `days=1` is one day. Mutually exclusive with `window`. Out of `[1,180]` is refused rather than clamped.
- `edges` (integer): Hard cap on edges returned, highest volume first. Honoured exactly; `truncated` says whether it bit.
- `min_probability` (number): Minimum x402 confidence, in `[0,1]`. Default 0.5.
- `min_usd` (number): Drop settlements below this USD value.
- `via` (string): Restrict to settlements relayed by this facilitator key or wallet.
- `wallet` (string): Restrict to edges touching this wallet. Must be a well-formed EVM address (case-insensitive) or Solana address (base58, case-sensitive).
- `window` (integer): Row count back from the live tip. Mutually exclusive with `days` — sending both is refused with 400, not silently resolved in favour of one.

### `list_services` (~303 tokens)

Indexed x402 service directory

The x402 service catalog, ordered by observed 30-day call volume. A listing is a claim; the observed columns are evidence — prefer `is_live` with non-zero `l30_unique_payers`. Note the path stays `/v0/endpoints` although the human page moved to `/services`; renaming it would break published integrations.

Wraps GET /v0/endpoints.
Access: no API key required.

Returns:
\- endpoints: Catalog rows with price, network, payTo, liveness and observed demand.
\- next_offset: Offset for the next page, or `null` when this page was the last.
\- meta: The chain served and `as_of`. On an EMPTY list it also carries `dataset_last_written_at`, `dataset_row_count` and any `warnings` (e.g. `endpoints_catalog_stale`) — so a zero can be read as a quiet market or a stalled ingest rather than guessed at.

Input parameters:

- `fields` (string): `compact` returns name, resource, price, network, payTo and liveness only — no description, icon or tags — which is roughly a third of the payload.
- `limit` (integer): Rows to return. Clamped to 200; values outside the range are clamped, not rejected.
- `offset` (integer): Rows to skip. Use the returned `next_offset`.
- `q` (string): Free-text search over service name, description and resource URL.

### `list_capabilities` (~226 tokens)

The capability catalogue

Every job the catalog is grouped by, with the canonical request and response each provider of that job is mapped onto — which is what lets an agent swap one endpoint for another without changing its code. Static: no market figures here, because each one costs its own catalog walk. Ask `/unified/{slug}` for a capability's offers and going rate. Send `fields=compact` when you are only choosing a capability: the full response carries both IO schemas for all of them.

Wraps GET /v0/unified.
Access: no API key required.

Returns:
\- capabilities: Slug, name, group, priced unit and — on `fields=full` — summary and the canonical input/output fields.
\- count: How many capabilities the registry defines.
\- fields: Which shape was served: `full` or `compact`.
\- note: Where the market figures for one capability live.

Input parameters:

- `fields` (string): `compact` returns slug, name, group and unit only — enough to pick a capability, without 34 pairs of IO schemas in the payload.

### `get_capability` (~353 tokens)

One capability: who offers it, and what it costs

Every indexed endpoint that does this job, with the market's going rate. `price.spot` is the call-WEIGHTED price, not the median — a median counts one wallet's forty near-identical listings as forty votes for its price. Check `price.spot_basis`: `median` means no offer reported any calls and the figure is a fallback, which does not mean the same thing as a market rate. `truncated: true` means the offer list is a floor.

Wraps GET /v0/unified/{slug}.
Access: no API key required.

Returns:
\- capability: The registry entry: the job, its priced unit, and its canonical request/response.
\- price: Going rate (`spot`), its basis, and the min / p25 / median / p75 / max spread.
\- stats: How many offers, distinct providers, distinct hosts, and how many were answering when last probed.
\- models: For inference capabilities: which model families are sold here, and by how many providers.
\- offers: Each endpoint, its listed price, its index against spot (100 = the going rate), and its reported 30-day demand.
\- truncated: True when the candidate read hit its cap, so the offer list is a floor rather than the whole market.

Input parameters:

- `limit` (integer): Rows to return. Clamped to 200; values outside the range are clamped, not rejected.
- `probable` (boolean): Include endpoints the matcher was not confident about. Off by default: grouping two endpoints that do different jobs invents a cheaper competitor that does not exist.
- `slug` (string, required): Capability slug, from `/v0/unified`.

### `recommend_capability_offers` (~342 tokens)

Shortlist endpoints for a capability

A ranked shortlist of endpoints that do this job, under criteria you choose and the response echoes back. Every term is something the endpoint publishes about itself — its listed price against the going rate, and its own reported demand. Roundhouse does not endorse any provider, and there is no cross-capability ranking. Only confident matches are ever recommended.

Wraps GET /v0/unified/{slug}/recommend.
Access: no API key required.

Returns:
\- capability: The registry entry for the job being shortlisted.
\- criteria: Your criteria, echoed — a recommendation whose basis is invisible is an opinion.
\- price: The capability's going rate, so each candidate's index has context.
\- candidates: Ranked endpoints, each with `reasons` for where it placed.
\- considered: How many confident offers were ranked before filters.
\- excluded: How many were dropped, by which filter.
\- truncated: True when the candidate read hit its cap.
\- note: What the ranking is and is not — Roundhouse endorses no provider.

Input parameters:

- `limit` (integer): Rows to return. Clamped to 25; values outside the range are clamped, not rejected.
- `live` (boolean): Only endpoints answering when last probed.
- `max_price` (number): Hard ceiling in USDC per call. Endpoints with no published price are excluded when set.
- `model` (string): Require the endpoint to name this model family (inference capabilities only).
- `prefer` (string): What to weight: cheapest, most-used, or an even split.
- `slug` (string, required): Capability slug, from `/v0/unified`.

### `run_sql` (~556 tokens)

Read-only SQL over the public dataset

One `SELECT` (or `WITH`) over the public data-layer tables. Enforced in the database, not the worker: a read-only transaction as a role that can see only those tables, a statement timeout set by the TIER, and a hard 300-row cap. No semicolons, no comments, no multi-statement.

Priced by the time it takes: one Query Unit per started 5 seconds, floor of 1 — so a query that answers quickly costs 1, which is what every query cost before this was metered. `tier` buys the ceiling (`standard` 15s, `extended` 60s and a paid plan); the tier maximum is HELD when the call starts and the unused part released the moment the duration is known, so `usage.units_charged` on the response is the settled figure. Call `get_account` for the tier table, or send `explain_only` to be quoted without running or paying for anything.

Wraps POST /v0/sql.
Access: an organization API key on any plan, metered against that organization’s Query Unit balance at 1 unit per started 5 seconds of query time. A paid plan buys the longer 60-second tier, not the route. A trial key belongs to no organization and is refused with the x402 price of one query instead of being served.

Returns:
\- rows: Result rows.
\- row_count: Number of rows returned.
\- duration_ms: Server-side execution time. This is what the call is priced on.
\- authenticated: Whether a key was accepted.
\- tier: The CREDENTIAL: `anonymous`, `trial`, or an organization tier.
\- sql_tier: The QUERY: which ceiling this run was given and priced at. A separate field from `tier`, which has always meant the credential.
\- quote: What the query was quoted at before it ran: the tier's ceiling and price bounds, plus the planner's own `planner_cost` and `plan_rows`. The planner figures are ADVISORY — arbitrary units, uncalibrated against this schema — and never charge anything; settlement is from measured duration, which needs no calibration to be right.
\- usage: What this call cost and what is left. `units_charged` is SETTLED, not the hold: the tier maxi…

Input parameters:

- `limit` (integer): Rows to return. Clamped to 300.
- `sql` (string, required): A single read-only SELECT (or WITH) statement over the public dataset. No semicolons, no comments, no platform internals. Row cap 300.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp#diagnostics

## Score history

- 2026-11-05: 66
- 2026-11-04: 66
- 2026-11-03: 65
- 2026-11-02: 65
- 2026-11-01: 64
- 2026-10-31: 64
- 2026-10-30: 63
- 2026-10-29: 63
- 2026-10-28: 62
- 2026-10-27: 62
- 2026-10-26: 31
- 2026-10-25: 31
- 2026-10-24: 31
- 2026-10-23: 31
- 2026-10-22: 31
- 2026-10-21: 31
- 2026-10-20: 31
- 2026-10-19: 31
- 2026-10-18: 31
- 2026-10-17: 31
- 2026-10-16: 31

## Common questions

### What is the Roundhouse MCP server?

Roundhouse is an MCP server listed in the public MCP registry as io.roundhouseai/roundhouse. Read-only analytics on x402 agent payments and ERC-8004 agent identity, with SQL. This page covers its hosted endpoint (https://api.roundhouseai.io/v0/mcp).

### Is the Roundhouse MCP server safe to use?

Roundhouse scores 66 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Roundhouse MCP server expose?

Roundhouse exposes 17 tools: get_account, list_flows, list_transactions, list_entity_settlements, get_agent, and 12 more. Their descriptions and schemas cost roughly 8,513 tokens of context every time the server is loaded.

### Does the Roundhouse MCP server require authentication?

No. We connected to Roundhouse without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the Roundhouse MCP server still maintained?

Roundhouse is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://api.roundhouseai.io/v0/mcp
- Website: https://roundhouseai.io/docs/api/mcp?utm_source=mcp_registry&utm_medium=mcp_directory
- Changelog RSS feed: https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp.json
- HTML version of this page: https://verifymcp.io/servers/io-roundhouseai-roundhouse/v0-mcp
