---
title: "Command line"
description: "Install the intosql command line, inspect and convert files to SQL, load them into a database, and use it in scripts and CI."
canonical: https://intosql.com/docs/cli
last_updated: 2026-10-15
---

# Command line

`intosql` runs the same engine as the converter on your own machine. It reads Excel, CSV, TSV, JSON and NDJSON files and MySQL or MariaDB dumps, writes SQL for PostgreSQL, MySQL, MariaDB, SQLite, SQL Server and Oracle, and can load a file straight into a database. Files are read from your disk and never uploaded.

## Install

### Homebrew

On macOS and Linux:

```shell
brew install alfonsobries/intosql/intosql
```

### npm

Run it once without installing, or install it globally. Both need Node 18 or newer.

```shell
npx intosql inspect ventas.xlsx
npm i -g intosql
```

The `intosql` package picks a prebuilt binary for your platform: macOS (Apple silicon and Intel), Linux (arm64 and x64) and Windows (x64).

### Direct download

Each version is published as a release named `IntoSQL CLI x.y.z` (tag `cli-vx.y.z`) at [github.com/alfonsobries/intosql-releases](https://github.com/alfonsobries/intosql-releases/releases). The release marked latest there is the desktop app, so look for the CLI release by name.

| Platform             | Archive                                           |
| -------------------- | ------------------------------------------------- |
| macOS, Apple silicon | `intosql-x.y.z-aarch64-apple-darwin.tar.gz`       |
| macOS, Intel         | `intosql-x.y.z-x86_64-apple-darwin.tar.gz`        |
| Linux, x64           | `intosql-x.y.z-x86_64-unknown-linux-musl.tar.gz`  |
| Linux, arm64         | `intosql-x.y.z-aarch64-unknown-linux-musl.tar.gz` |
| Windows, x64         | `intosql-x.y.z-x86_64-pc-windows-msvc.zip`        |

Each archive holds one file, `intosql` (or `intosql.exe`). Put it in a folder on your `PATH`. The Linux builds are static and run on any distribution. `SHA256SUMS` in the same release lists the checksum of every archive; compare it with yours:

```shell
shasum -a 256 intosql-x.y.z-aarch64-apple-darwin.tar.gz
```

Check the install:

```shell
intosql version
```

```text
intosql 0.1.0 (contract 1)
```

## A first conversion

Look at the file first, then convert it:

```shell
intosql inspect ventas.csv
intosql convert ventas.csv --to postgresql -o ventas.sql
```

`inspect` shows how the file will be read and every correction the conversion makes. `convert` writes the script. To run the script against your database, see [Loading the script](/docs/loading).

## Commands

### inspect

Shows what a file holds: its format and encoding, where the table starts, each column's name and SQL type, every fix, any problems and a preview of the first rows. Nothing is written.

```shell
intosql inspect ventas.csv
```

```text
ventas.csv: CSV (windows-1252, ";"), 5 rows, 6 columns

Columns
  1  folio    text               from "Folio"
  2  cliente  text               from "Cliente"
  3  ciudad   text               from "Ciudad"
  4  fecha    date               from "Fecha"
  5  importe  numeric(6,2) null  from "Importe"
  6  pagado   boolean            from "Pagado"

Fixes
  1. The file was written in windows-1252; it was converted to UTF-8.
  2. The header is on row 4; the rows above it were left out.
  3. Row 10 ("TOTAL") is a total, so it was left out.
  4. Leading zeros kept in "Folio": 00412 stays 00412, stored as text.
  5. 15/02/2024 proves the dates in "Fecha" are day-first, so 03/02/2024 is read as 2024-02-03.
  6. Numbers in "Importe" use a decimal comma: 1.234,50 is read as 1234.50.
  7. N/A in "Importe" read as empty (1 of 5 values).
  8. "Pagado" holds yes and no words (sí, no), stored as boolean.

Preview
  5: 00412 | Peña Muñoz | Mérida | 15/02/2024 | 1.234,50 | sí
  6: 00413 | José Ángel Ruiz | León | 03/02/2024 | 99,90 | no
  ...
```

The numbers on the left are column positions. `--rename`, `--text` and `--exclude` use them. The types are shown for PostgreSQL unless you pass `--dialect`. [Fixes](/docs/fixes) explains each correction.

| Flag             | Default      | What it does                                                                                                          |
| ---------------- | ------------ | --------------------------------------------------------------------------------------------------------------------- |
| `--dialect <db>` | `postgresql` | The database names and types are checked against: `postgresql`, `mysql`, `mariadb`, `sqlite`, `sql-server`, `oracle`. |
| `--preview <n>`  | `5`          | Rows to preview.                                                                                                      |
| `--json`         | off          | Print the report as JSON instead of text.                                                                             |

`inspect` also takes every [reading and column flag](#reading-and-column-flags).

### convert

Converts a file into a SQL script, or into clean CSV or JSON. The output goes to standard output unless `-o` names a file. The summary goes to standard error, so it never mixes with the SQL.

```shell
intosql convert clientes_2024.xlsx --to mysql -o clientes_2024.sql
```

```text
Converted 4 of 4 rows from clientes_2024.xlsx into clientes_2024 for MySQL.
10 fixes made; `intosql inspect clientes_2024.xlsx` lists them.
```

When rows can't be converted, the summary lists each one with its row number and reason, and the rest of the file is still written. [Errors](/docs/errors) lists every message.

| Flag                    | Default         | What it does                                                                                                                                                |
| ----------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--to <db>`             | `postgresql`    | The database to write SQL for: `postgresql`, `mysql`, `mariadb`, `sqlite`, `sql-server`, `oracle`. It also decides names and types for CSV and JSON output. |
| `--format <format>`     | `sql`           | What to write: `sql`, `csv` or `json`.                                                                                                                      |
| `-o`, `--output <file>` | standard output | The file to write.                                                                                                                                          |
| `--table <name>`        | the file's name | The table's name.                                                                                                                                           |
| `--schema <name>`       | none            | The schema the table goes in. The schema must already exist.                                                                                                |
| `--no-create-table`     | off             | Leave out `CREATE TABLE`, for a table that already exists.                                                                                                  |
| `--copy`                | off             | Write PostgreSQL's `COPY ... FROM stdin` instead of `INSERT`. The script then runs only in `psql`.                                                          |
| `--batch-rows <n>`      | `500`           | Rows per `INSERT`, from 1 to 100000. SQL Server scripts use at most 1000 and Oracle at most 200.                                                            |
| `--report <file>`       | none            | Also write the report (rows, column types, every fix and problem) as JSON to this file.                                                                     |
| `--spec <file>`         | none            | The whole request as a JobSpec JSON file, the same body the [API](/docs/api/conversions) takes. It replaces every other option except `-o` and `--report`.  |

`convert` also takes every [reading and column flag](#reading-and-column-flags).

### load

Loads a file straight into PostgreSQL, MySQL, MariaDB or SQLite, without a script. It creates the table with the same types the script would use, loads every row, and drops the table it created if the load fails.

```shell
intosql load clientes_2024.xlsx --into postgres://ana@localhost:5432/tienda --index alta
```

```text
Loaded 4 of 4 rows from clientes_2024.xlsx into clientes_2024 for PostgreSQL.
10 fixes made; `intosql inspect clientes_2024.xlsx` lists them.
```

> **Pro:** Loading into PostgreSQL, MySQL and MariaDB is part of IntoSQL Pro. Loading into a SQLite file is free. See [Free and Pro](#free-and-pro).

| Flag                | Default         | What it does                                                                                                |
| ------------------- | --------------- | ----------------------------------------------------------------------------------------------------------- |
| `--into <target>`   | required        | A `postgres://`, `mysql://` or `mariadb://` URL, or a SQLite file ending in `.db`, `.sqlite` or `.sqlite3`. |
| `--table <name>`    | the file's name | The table's name.                                                                                           |
| `--schema <name>`   | none            | The schema the table goes in.                                                                               |
| `--no-create-table` | off             | Load into a table that already exists.                                                                      |
| `--connections <n>` | `4`             | PostgreSQL connections loading at once.                                                                     |
| `--unlogged`        | off             | Create the PostgreSQL table `UNLOGGED`: faster, but emptied after a crash.                                  |
| `--index <column>`  | none            | Index a column after the rows are in. Repeat for more columns.                                              |
| `--batch-rows <n>`  | `500`           | Rows per `INSERT` in MySQL and MariaDB.                                                                     |
| `--json`            | off             | Print the report as JSON instead of text.                                                                   |

`load` also takes every [reading and column flag](#reading-and-column-flags). [Loading the script](/docs/loading#loading-without-a-script) covers each database's URL and what happens on failure.

### validate

Checks a conversion request (a JobSpec JSON file, as `convert --spec` and the API take it) without running it.

```shell
intosql validate pedido.json
```

```text
pedido.json is a valid request.
```

A request with problems lists each one with its fix:

```text
- Rows per batch must be between 1 and 100000; it is 0. Pick a number in that range. 500 suits most databases.
- The table name is empty. Type a name, or leave the field out to use the file's name.
```

| Flag     | Default | What it does                                                                                        |
| -------- | ------- | --------------------------------------------------------------------------------------------------- |
| `--json` | off     | Print the problems as a JSON array instead of sentences. An empty array means the request is valid. |

### license

Shows the IntoSQL Pro license on this machine, or activates one.

```shell
intosql license
intosql license activate <license>
```

```text
No license. Loading into a database server starts a 14-day trial.
```

After activation:

```text
IntoSQL pro is active on this machine.
```

`intosql license` then shows the plan, the account and the date the license is valid until. `license` has no flags; `activate` takes the license text as its only argument.

### mcp

Serves the engine to AI agents over MCP on standard input and output. An MCP client starts this command itself; you don't run it by hand. Agents get three tools: `inspect_file`, `convert_file` (writes the output to a file) and `load_file` (the same rules as `intosql load`). Files stay on your machine.

```json
{
    "mcpServers": {
        "intosql": {
            "command": "intosql",
            "args": ["mcp"]
        }
    }
}
```

`mcp` has no flags. [MCP](/docs/mcp) covers setup in each client.

### version

Prints the engine version and the version of the request and report format (the contract).

```shell
intosql version
```

```text
intosql 0.1.0 (contract 1)
```

`intosql --version` prints the version alone.

## Reading and column flags

`inspect`, `convert` and `load` read files the same way and take these flags. Everything is detected when a flag is absent.

| Flag                | What it does                                                                            |
| ------------------- | --------------------------------------------------------------------------------------- |
| `--sheet <name>`    | The sheet to read. Default: the first visible sheet.                                    |
| `--locale <locale>` | Your locale, such as `es-MX`. Decides ambiguous dates and decimal separators.           |
| `--header-row <n>`  | The row holding the column names.                                                       |
| `--delimiter <d>`   | The delimiter of a text file: `,`, `;`, `\|` or `tab`.                                  |
| `--encoding <name>` | The encoding of a text file, such as `windows-1252`.                                    |
| `--keep-headers`    | Keep column names as the headers write them, quoted, instead of `snake_case`.           |
| `--rename <N=NAME>` | Name the column at position N: `--rename 3=codigo_postal`. Repeat for more columns.     |
| `--text <N>`        | Keep the column at position N as text, every value as written. Repeat for more columns. |
| `--exclude <N>`     | Leave the column at position N out. Repeat for more columns.                            |

Positions start at 1 and match the numbers `inspect` prints.

```shell
intosql convert clientes_2024.xlsx --sheet Q3 --rename 3=codigo_postal --exclude 6 -o clientes.sql
```

## Free and Pro

Everything except loading into a database server is free: `inspect`, `convert` to every dialect, `validate`, `mcp`, and `load` into SQLite.

Loading into PostgreSQL, MySQL or MariaDB (with `intosql load`, the MCP `load_file` tool or the desktop app) needs IntoSQL Pro. Without a license, the first such load starts a 14-day trial on this machine:

```text
Your 14-day IntoSQL Pro trial starts now. After it, loading into database servers needs a license (https://intosql.com/pricing); SQLite and `intosql convert` stay free.
```

When the trial has ended, the load stops with exit code 1 and says where to get a license.

To activate Pro:

1. Open your [account dashboard](https://intosql.com/dashboard). With Pro, it shows your license under "Desktop app and command line".
2. Copy the license.
3. Run `intosql license activate <license>`.

The license is checked on your machine, without a network call. It is saved as `license` in the settings folder: `$INTOSQL_CONFIG_DIR` when set, otherwise `$XDG_CONFIG_HOME/intosql`, `%APPDATA%\intosql` on Windows, or `~/.config/intosql`. The desktop app reads the same folder, so one activation covers both. If `intosql license` says the saved license can't be used, copy the current one from the dashboard and activate it again.

## Scripts and CI

- **Input** is always a file path. Reading from standard input isn't supported.
- **Output.** `convert` writes the SQL, CSV or JSON to standard output unless `-o` is given, and its summary to standard error. You can pipe it into a database client:

```shell
intosql convert ventas.csv --to postgresql | psql -v ON_ERROR_STOP=1 -d tienda
```

- **JSON.** `inspect --json`, `load --json` and `validate --json` print machine-readable output on standard output. `convert --report report.json` writes the same report to a file.
- **Settings folder.** Set `INTOSQL_CONFIG_DIR` to keep the license and trial in a folder your CI controls.

### Exit codes

| Code | Meaning                                                                                                                                                                                                    |
| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0`  | The command finished.                                                                                                                                                                                      |
| `1`  | It failed: the file can't be read, the request isn't valid, the output can't be written, the database refused the load, or the Pro trial has ended. `validate` also exits 1 when the request has problems. |
| `2`  | The command line itself is wrong, such as an unknown flag or a value `--to` doesn't accept.                                                                                                                |

Rows left out don't change the exit code. To fail a build when any row is left out, check `rows.rejected` in the report:

```shell
intosql convert ventas.csv --to mysql -o ventas.sql --report report.json
jq -e '.rows.rejected == 0' report.json
```

### JSON output

`load --json` and `convert --report` write a conversion report. Shortened:

```json
{
    "version": 1,
    "input": {
        "format": "csv",
        "encoding": "windows-1252",
        "delimiter": ";",
        "sheet": null,
        "bytes": 357
    },
    "dialect": "postgresql",
    "table": "ventas",
    "columns": [
        {
            "source_name": "Importe",
            "name": "importe",
            "sql_type": "numeric(6,2)",
            "kind": "decimal",
            "precision": 6,
            "scale": 2,
            "max_chars": null,
            "nullable": true,
            "fixes": [6, 7],
            "excluded": false,
            "as_text": false
        }
    ],
    "rows": { "read": 5, "converted": 5, "rejected": 0 },
    "fixes": [
        {
            "number": 6,
            "code": "decimal_comma_read",
            "column": "Importe",
            "row": null,
            "args": {
                "column": "Importe",
                "example": "1.234,50",
                "reading": "1234.50"
            }
        }
    ],
    "problems": [],
    "timings": { "read_ms": 0, "convert_ms": 0, "total_ms": 0 }
}
```

`inspect --json` has the same `input`, `columns`, `fixes` and `problems`, plus `sheets` (each sheet's name and whether it is hidden), `rows` as a count, and `preview` (row numbers and values). `validate --json` prints an array of problems, each with `code`, `severity`, `column`, `row` and `args`. The `code` values are the ones listed in [Errors](/docs/errors).

## Crash reports

Official builds send a report when `intosql` crashes on an internal error. Ordinary failures, such as a file that can't be read or a database that refuses a load, are never reported.

A report holds the error message and stack trace, the `intosql` version, and the operating system and processor architecture. Before it leaves your machine:

- Paths become `<path>`, file names become `<file>` and quoted values become `<value>`.
- Local variables and source lines are removed from every stack frame.
- The computer's name, user details and breadcrumbs are never included.

To turn reports off, set `INTOSQL_NO_TELEMETRY` to any value other than `0`:

```shell
export INTOSQL_NO_TELEMETRY=1
```

The desktop app reads the same variable.
