> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Connecting

You query Amp by sending SQL to its query server, the part of [`ampd`](/running-amp/ampd) that reads datasets and
returns rows. The query server speaks [Arrow Flight](/querying/arrow-flight), a protocol for sending tables over gRPC.
It's the only way in: every client on this page uses it.

The query server listens on port `1602`. In [solo mode](/running-amp/solo-mode), that's `localhost:1602`. A hosted Amp
gives you its own address and a token.

## Prerequisites

* A running Amp: [solo mode](/running-amp/solo-mode) on your machine, or a hosted Amp's address and token.
* To run the examples in this section, the [example datasets](/querying/connecting#example-datasets) below.

## Example datasets

The examples in Querying run against two datasets, and show the output Amp returned for them:

* `acme/eth_mainnet`: Ethereum blocks 24,000,000 to 24,000,099, with their transactions and logs. The
  [Quickstart](/get-started/quickstart) deploys it.
* `acme/base_mainnet`: the 600 Base blocks produced over the same 20 minutes, 39,397,512 to 39,398,111.

To create the Base dataset on the Amp you ran the Quickstart with, you need a Base RPC endpoint.

::::steps
### Set your Base RPC endpoint

Any Base RPC endpoint works, as long as it still serves these blocks' receipts:

```bash
export BASE_RPC_URL=https://…
```

### Register a provider for Base

A [provider](/providers) tells Amp where to fetch a chain's data. Its `network` is the name queries use for the chain:

```bash
cat > base.toml <<EOF
kind = "evm-rpc"
network = "base"
url = "$BASE_RPC_URL"
EOF

ampctl provider register base_rpc ./base.toml
```

This writes your URL into `base.toml`, and Amp stores it as written, API key included, so you don't have to restart
`ampd`. To keep it out of storage, as the [Quickstart](/get-started/quickstart#register-a-provider) does, write
`"${BASE_RPC_URL}"` with `<<'EOF'`, and restart `ampd` with `BASE_RPC_URL` set.

### Register and deploy the dataset

The dataset starts at its first block, and its deployment stops at its last one:

```bash
ampctl manifest generate --kind evm-rpc --network base --start-block 39397512 -o base_mainnet.json
ampctl dataset register acme/base_mainnet ./base_mainnet.json --tag 1.0.0
ampctl dataset deploy acme/base_mainnet@1.0.0 --end-block 39398111
```

### Check that they're synced

After a minute or so, both datasets have all their blocks:

:::terminal
```bash
ampsql "SELECT 'ethereum' AS chain, COUNT(*) AS blocks FROM \"acme/eth_mainnet\".blocks
  UNION ALL SELECT 'base', COUNT(*) FROM \"acme/base_mainnet\".blocks ORDER BY blocks"
```

```text
+----------+--------+
| chain    | blocks |
+----------+--------+
| ethereum | 100    |
| base     | 600    |
+----------+--------+
```
:::
::::

## Clients

| Client                                                          | Use it for                                                                                                   |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| [`ampsql`](/querying/connecting#ampsql)                                             | One-off queries from a terminal or a script. Batch queries only.                                             |
| [TypeScript SDK](/sdks/typescript/querying)                     | Apps in TypeScript or JavaScript. Handles [streaming](/querying/streaming-queries), cursors, and reorgs.     |
| [Python SDK](/sdks/python/querying)                             | Scripts, notebooks, and loading query results into other databases. Handles streaming too.                   |
| [ADBC](/querying/connecting#python-with-adbc)                                       | Batch queries from any language with an ADBC Flight SQL driver: Python, Go, Java, R, C, and C++.             |
| [Arrow Flight libraries](/querying/arrow-flight#write-a-client) | Your own client, in any language with an Arrow Flight library, when you need every header and stream detail. |

### `ampsql`

[`ampsql`](/clis/ampsql) runs one query, prints its result, and exits:

:::terminal
```bash
ampsql 'SELECT block_num, gas_used FROM "acme/eth_mainnet".blocks ORDER BY block_num LIMIT 3'
```

```text
+-----------+----------+
| block_num | gas_used |
+-----------+----------+
| 24000000  | 57860235 |
| 24000001  | 27660983 |
| 24000002  | 17602635 |
+-----------+----------+
```
:::

It connects to `http://localhost:1602` unless you pass `--flight-url` or set `AMP_QUERY_URL`. Add `--format json`,
`jsonl`, or `csv` for output other programs can read. It doesn't run [streaming queries](/querying/streaming-queries):
use an SDK for those.

### Python, with ADBC

ADBC is a standard API for querying databases in Arrow format, and its Flight SQL driver works with Amp. In Python,
install it with pandas, to get results as a DataFrame:

```bash
pip install adbc-driver-flightsql pandas
```

```python [query.py]
import adbc_driver_flightsql.dbapi as flight_sql

with flight_sql.connect("grpc://localhost:1602", autocommit=True) as conn, conn.cursor() as cursor:
    cursor.execute("""
        SELECT block_num, gas_used
        FROM "acme/eth_mainnet".blocks
        ORDER BY block_num
        LIMIT 3
    """)
    print(cursor.fetch_df())
```

```text [Output]
   block_num  gas_used
0   24000000  57860235
1   24000001  27660983
2   24000002  17602635
```

* Use `grpc://` for a plain connection, like solo mode's, and `grpc+tls://` for an encrypted one. For a server with a
  self-signed certificate, pass its authority's certificate, in PEM format:
  `db_kwargs={"adbc.flight.sql.client_option.tls_root_certs": open("ca.pem").read()}`. Otherwise, queries fail with
  `tls: failed to verify certificate`.
* `autocommit=True` stops the driver from warning that it can't turn autocommit off: Amp has no transactions.
* To send a [request header](/querying/arrow-flight#headers), pass it as an option named after it:
  `flight_sql.connect(url, db_kwargs={"adbc.flight.sql.rpc.call_header.amp-alias": "…"})`.

### Other Arrow Flight SQL clients

Amp implements the part of Arrow Flight SQL that runs a SQL statement: the client sends the SQL as a
`CommandStatementQuery`, and fetches the result with the ticket it gets back. A client that only does that works. Amp
doesn't support the rest:

* **Parameters.** Put values in the SQL itself: Amp can't bind `?` placeholders.
* **Browsing catalogs.** Listing schemas and tables fails with
  `unsupported flight descriptor command: type.googleapis.com/arrow.flight.protocol.sql.CommandGetDbSchemas`. Database
  GUIs and JDBC or ODBC tools often do it when they connect, so they may not work.
* **Writing data and transactions.** Queries are read-only.

## Authentication

A hosted Amp authenticates each request from the bearer token in its `authorization` header:

* `ampsql`: pass `--auth-token`, or set `AMP_AUTH_TOKEN`.
* ADBC: set `adbc.flight.sql.authorization_header` to `Bearer` followed by the token, in `db_kwargs`.
* The SDKs: see [TypeScript](/sdks/typescript/authentication) and [Python](/sdks/python/authentication).

The token must be a JWT whose `sub` claim is the user's ID, which Amp uses for
[per-user limits](/querying/limits#per-user-limits). Any other token, even when you run Amp yourself, fails with
``malformed `authorization` header``.

:::warning
The query server doesn't check tokens itself: it expects a gateway in front of it to do that, as hosted Amp has. When
you run Amp yourself, anyone who can reach port `1602` can query every dataset. Keep it on a private network, or put an
authenticating proxy in front of it.

It doesn't encrypt connections either: it only speaks plain gRPC. For TLS, put a proxy in front of it that takes TLS
connections and forwards them as gRPC, like nginx with `grpc_pass`, and connect to the proxy with `https://` or
`grpc+tls://`.
:::

## Next steps

* Learn what [SQL](/querying/sql) Amp runs, and how to name datasets in it.
* Turn a query into a stream with [streaming queries](/querying/streaming-queries).
