---
name: tidbcloud-http
description: |
  Call TiDB Serverless HTTP endpoint directly, without SDK/driver.
  Supports stateless, stateful, and transaction query flows.
  Use when users ask for raw SQL over HTTP or want to bypass @tidbcloud/serverless.
---

# TiDBCloud HTTP

Use this skill to send SQL to TiDB Serverless with direct HTTP `POST /v1beta/sql`.

Use it when the user asks to:

- query TiDB Cloud with raw HTTP
- bypass the JS SDK/driver
- run stateless/stateful/transaction flows over HTTP

Supported query styles:

- Stateless
- Stateful session
- Transaction

## What this skill includes

- `scripts/tidb_serverless_http.sh`: direct HTTP client script
- `references/01-quickstart.md`: shortest path examples
- `references/02-http-protocol.md`: request/response and headers
- `references/03-query-modes.md`: stateless/stateful/transaction workflows

## Request protocol (from this repo)

The script follows the same protocol as `src/serverless.ts`:

- URL: `https://http-<host>/v1beta/sql`
- Method: `POST`
- Auth: `Authorization: Basic base64(username:password)`
- Body: `{"query":"<sql>"}`
- Core headers:
  - `Content-Type: application/json`
  - `TiDB-Database: <database>`
  - `TiDB-Session: <session>`
  - `X-Debug-Trace-Id: <request-id>`
  - `TiDB-Isolation-Level: READ COMMITTED|REPEATABLE READ` (when BEGIN)
  - `TiDB-Stateful-Action: open|close` (stateful lifecycle)

## Authentication and credentials

This skill requires `DATABASE_URL` in environment or `.env`.

Expected format:

```text
mysql://<username>:<password>@<host>/<database>
```

Example:

```text
mysql://4FriSs61wM5o1zu.root:ZwuR6cdSNdjpxEY8@gateway01.us-east-1.dev.shared.aws.tidbcloud.com/test
```

You can provide it in either way:

1. Environment variable:

```bash
export DATABASE_URL="mysql://<username>:<password>@<host>/<database>"
```

2. `.env` file (auto-loaded by script):

```bash
DATABASE_URL="mysql://<username>:<password>@<host>/<database>"
```

If `DATABASE_URL` is missing, the script returns a setup message. Prefer `.env` for persistent credentials.

## Use the script

After `DATABASE_URL` is set:

```bash
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateless --sql "show tables"
```

## Three query modes

### 1) Stateless

```bash
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateless --sql "select * from t"
```

### 2) Stateful session

```bash
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateful open
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateful query --sql "use test"
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateful query --sql "select 1"
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh stateful close
```

### 3) Interactive transaction

```bash
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh tx begin --isolation "READ COMMITTED"
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh tx query --sql "insert into t values (1)"
bash skills/tidbcloud-http/scripts/tidb_serverless_http.sh tx commit
```

## Output convention

Script outputs JSON so agents can parse reliably:

- `ok`: boolean
- `status`: HTTP status
- `session`: current/latest session token (from `TiDB-Session`, case-insensitive)
- `data`: response JSON when parse succeeds
- `text`: response body when non-JSON

Binary decode behavior:

- Script executes SQL once, then inspects response `types`.
- If a column type is `BLOB`/`TINYBLOB`/`MEDIUMBLOB`/`LONGBLOB`/`BINARY`/`VARBINARY`/`BIT`, matching row values are decoded in-memory from hex to byte arrays.
- No extra SQL request is sent for decode.
- Implementation is pure shell + `jq` (no Node.js dependency).

Query row limit:

- The script enforces a hard cap of 10,000 rows per query response.
- If a query returns more than 10,000 rows, the script returns `ok:false` with an error asking to add `LIMIT`.

Session behavior (all modes):

- If response includes `TiDB-Session`, script stores and returns it.
- This replacement happens even on non-2xx responses (for example, `invalid session`), so retries use the latest server-issued session from the same session file.
- If response is `invalid session`, script clears that same session file and retries once automatically (no alternate session filename).
- All follow-up requests send the latest stored session when available.
- `stateful close` clears stored session after request.
- Session files are always stored under `.session/` (path portions from `--session-file` are ignored).
- In stateless mode, server may still return a token-like session; script reuses it on later requests.

## Troubleshooting

- missing `DATABASE_URL`: set env var or add it to `.env`
- 401/403: check username/password and cluster access
- host not found / DNS failure: this endpoint mode only supports TiDB Cloud Starter and Essential plans; Dedicated/Premium hosts are not supported by this skill
- 400 with SQL error: validate SQL text and database
- query returned too many rows: add `LIMIT` so result rows are <= 10000
- session seems empty unexpectedly: use `--debug` and inspect raw headers (`curl -i`) to verify `TiDB-Session`
- TLS/network failure: verify `host` and egress policy
