# Calling the REST twin

Every tool is reachable at one uniform shape — `POST /api/v1/tools/{name}`, with the tool's
arguments as the body. There is no per-tool route dialect to learn:

```bash
curl -X POST "https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp/api/v1/tools/get_performance_summary" \
  -H "Authorization: Bearer ck_your_token" \
  -H "Content-Type: application/json" \
  -d '{"start_date":"2026-07-01","end_date":"2026-07-31"}'
```

A success is `{ "ok": true, "tool": "<name>", "data": … }`, where `data` is byte-identical to
what the same tool returns over MCP.

- **REST body:** the tool's arguments, as a JSON object. Capped at 64 KiB.
- Every REST response carries an `X-Request-Id` — quote it in support requests and it maps to one
  audit row.
- Errors use the flat `{ error, message, path?, request_id }` shape — see [Errors](/errors).

## OpenAPI contract

Generate a client from the OpenAPI 3.1 document at `https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp/api/v1/openapi.json`. It is served
**unauthenticated and cacheable** (5 minutes): the tool names, descriptions and argument schemas
are public, the data behind them is not.

The same contract powers the interactive [API Reference](/api) on this site.

:::warning{title="Schema caveat"}

Published argument schemas are generated from the server's own validation
schemas, so they are exact about property names, types and unknown-key rejection. They cannot
express **cross-field** constraints — a `.refine()` rule such as "`start_date` must be on or
before `end_date`" has no JSON Schema form and is not in the published contract. Those rules are
still enforced, and answer with a normal `400 validation_error`. Treat the published schema as
necessary, not sufficient.

:::
