diff --git a/developers/mcp-tools.mdx b/developers/mcp-tools.mdx index 6bd0cb3..7e4b7dd 100644 --- a/developers/mcp-tools.mdx +++ b/developers/mcp-tools.mdx @@ -134,7 +134,7 @@ A lost connection, or a database where no schema could be read, fails the call i |------|-----------|---------| | `browse_table` | `connection_id`, `table` (`columns`, `filters`, `logic`, `sort`, `limit`, `offset`, `timeout_seconds`, `database`, `schema`) | A result set | | `count_rows` | `connection_id`, `table` (`exact`, `filters`, `logic`, `database`, `schema`) | `table`, `row_count`, `is_approximate`, `filter_count` | -| `execute_query` | `connection_id`, `query` (`max_rows`, `timeout_seconds`, `database`, `schema`) | A result set, plus `result_sets[]` when a SQL Server script returns more than one | +| `execute_query` | `connection_id`, `query` (`max_rows`, `timeout_seconds`, `database`, `schema`, `read_only`) | A result set, plus `result_sets[]` when a SQL Server script returns more than one | | `explain_query` | `connection_id`, `query` (`analyze`, `variant`, `timeout_seconds`, `database`, `schema`) | `statement` as actually sent, `execution_time_ms`, `columns[]`, `rows[][]`, and where available `plan_text`, `plan` and `available_variants[]` (`id`, `label`, `sql_prefix`, `runs_statement`). On Oracle and SQL Server the driver builds the plan from several statements, so `statement` is the query alone and `sql_prefix` is empty | | `export_data` | `connection_id`, `format` (`query` **or** `tables`, `sql_table`, `output_path`, `max_rows`, `database`, `schema`) | `format`, `rows_exported`, `is_truncated`, `path` when a file was written, and `exports[]` (`label`, `row_count`, `is_truncated`, `data`) | | `quote_identifiers` | `connection_id` and at least one of `identifiers`, `literals` (`database`, `schema`) | `identifiers[]` as `{ input, quoted }` and `literals[]` as `{ input, escaped }`, in the order supplied | @@ -155,7 +155,7 @@ Without filters this returns the engine's fast estimate unless `exact` is set. W ### `execute_query` -One statement, 100 KB at most. `DROP` and `TRUNCATE` are refused here; use `confirm_destructive_operation`. On MongoDB, a statement is a read only when it is one call with literal arguments, as [Safe Mode](/features/safe-mode#what-counts-as-a-read) describes; any other JavaScript is a write and needs `tools:write`. When the request carries a `progressToken`, the tool emits progress at 0.0 (resolving), 0.3 (executing) and 1.0 (done). +One statement, 100 KB at most. `DROP` and `TRUNCATE` are refused here; use `confirm_destructive_operation`. With `read_only: true`, a statement that is not a read gets `-33007` before the user is asked anything, even on a connection set to **Read & Write** and with a token that carries `tools:write`. On MongoDB, a statement is a read only when it is one call with literal arguments, as [Safe Mode](/features/safe-mode#what-counts-as-a-read) describes; any other JavaScript is a write and needs `tools:write`. When the request carries a `progressToken`, the tool emits progress at 0.0 (resolving), 0.3 (executing) and 1.0 (done). On SQL Server, send the whole script instead. A variable exists only in the batch that declares it, so a `DECLARE` and the `SELECT`s that read it belong in one call. The script is cut into batches at its `GO` lines, as the query editor cuts it, and `GO 5` runs a batch five times. The gates judge the script by its worst statement: one write anywhere needs `tools:write` and Safe Mode, and one `DROP` refuses the call. `DECLARE` counts as a write. diff --git a/features/query-history.mdx b/features/query-history.mdx index 7a18953..66fa0c8 100644 --- a/features/query-history.mdx +++ b/features/query-history.mdx @@ -49,6 +49,7 @@ Search matches partial words, so `cust` finds `customers`. Several words must al | AI and MCP | Queries run by an AI assistant or an MCP client | | AppleScript | Queries run by [a script](/developers/applescript) | | Shortcuts | Queries and inserts run by a [Shortcuts action](/integrations/shortcuts) | +| Command Line | Queries run by [`tablepro query`](/integrations/terminal#run-a-query) | **My Queries**, the default, is Editor and Explain. Add **Table Browsing** to see what the app sent while you clicked around a table, **Structure Changes** to review what altered a schema and when. diff --git a/integrations/terminal.mdx b/integrations/terminal.mdx index c282ff7..d640ecd 100644 --- a/integrations/terminal.mdx +++ b/integrations/terminal.mdx @@ -1,6 +1,6 @@ --- title: Terminal -description: Open database URLs, database files and SQL files in TablePro from a shell or a script +description: Open database URLs and files in TablePro from a shell, and run queries from a script --- `open "mysql://…"` goes to whichever app claims the `mysql://` scheme, and with another database @@ -18,8 +18,9 @@ temporary and never written to disk. Running `tablepro` with no argument opens t ## Add the tablepro command to your PATH -The command ships inside the app at `TablePro.app/Contents/SharedSupport/bin/tablepro`, a script -whose whole body is `exec open -b com.TablePro "$@"`. Link it into `/usr/local/bin` once: +The command ships inside the app at `TablePro.app/Contents/SharedSupport/bin/tablepro`. It runs +`query` and `connections` itself and hands anything else to `open -b com.TablePro`. Link it into +`/usr/local/bin` once: ```bash sudo mkdir -p /usr/local/bin && sudo rm -f /usr/local/bin/tablepro && sudo ln -s /Applications/TablePro.app/Contents/SharedSupport/bin/tablepro /usr/local/bin/tablepro @@ -54,6 +55,97 @@ tablepro app.db DuckDB plugin. A window already connected to that file comes to front instead of a second one opening. +## Run a query + +```bash +tablepro query --connection Staging --format csv "SELECT id, email FROM users LIMIT 5" +tablepro query -c Staging -f report.sql > report.csv +echo "SELECT count(*) FROM orders" | tablepro query -c Staging --format json +``` + +`--connection` takes a saved connection's name or its id, and `tablepro connections` lists both. The +SQL comes from the argument, from `-f `, or from standard input. Rows go to standard output, +messages and errors to standard error. + +| Option | | +|---|---| +| `--database`, `--schema` | Where the statement runs. Without them, the connection's current database and schema | +| `--format` | `csv`, `tsv`, `json`, `jsonl` or `table`. `table` on a terminal, `csv` into a pipe or a file | +| `--limit` | Rows to return. Defaults to **Default row limit** under **Settings > MCP**, 500, and stops at **Maximum row limit** | +| `--timeout` | Seconds the statement may run, 1 to 300. Defaults to **Query timeout** under **Settings > MCP**, 30 | +| `--read-only` | Refuse any statement that is not a read, even on a connection set to **Read & Write** | + +Pass `--format` in a script rather than relying on the terminal check. A result cut short by +`--limit` says so on standard error. + +| Exit status | Meaning | +|---|---| +| 0 | The statement ran | +| 1 | The database returned an error, or TablePro could not be reached | +| 2 | A usage error: a missing option, an unknown connection name, several statements in one run | +| 3 | Refused by a setting: the connection's level, Safe Mode, `--read-only`, a declined prompt, or a revoked pairing | +| 4 | The statement ran past its timeout | + +### Output formats + +| Format | NULL | Other values | +|---|---|---| +| `csv` | An empty field. An empty string is `""` | Quoted when they hold a comma, a quote or a line break | +| `tsv` | An empty field | Tab, line break, carriage return and backslash written as `\t`, `\n`, `\r`, `\\` | +| `json` | `null` | An array of objects keyed by column name | +| `jsonl` | `null` | One object per line | +| `table` | `NULL` | Columns padded to line up. A control character shows as an escape, such as `\n` or `\x1B` | + +Every value is text, as in the grid. Binary columns come out as Base64. Two columns with the same +name become `name` and `name_2` in JSON. + +### Pair the command + +The command reaches TablePro through its MCP server, so turn on **Enable MCP Server** under +**Settings > MCP** first. With it off, every run exits 3. When TablePro is not running, the command +starts it in the background, with no window. + + + + TablePro asks **Allow tablepro command to access TablePro?** + + + The sheet starts at **Read Only**. Pick **Read & Write** if your scripts write, and limit the + connections or set an expiry if you want. + + + Your browser opens a page saying the command is paired. Close it. The query you ran continues. + + + +The token lives in your login Keychain. Revoke it under **Settings > MCP** and the next run exits 3; +the run after that asks to pair again. A run whose standard error is not a terminal, such as a cron +job, exits 3 instead of opening the sheet. + +### What a query may do + +A query clears the same gates as any [MCP client](/features/mcp#connection-access): + +- The connection's **External Clients** level: **Blocked** hides it, **Read Only** refuses writes. +- A connection whose AI policy is **Never** is refused. +- The first query on each connection asks you, as often as **Approval** under **Settings > MCP** says. +- [Safe Mode](/features/safe-mode) confirms or authenticates writes on your Mac. +- `DROP` and `TRUNCATE` are refused. Run them in TablePro. +- One statement per run. A SQL Server script runs batch by batch at its `GO` lines and prints + every result set, separated by a blank line, or in JSON as one array per result set. + +Every statement goes to the execution audit log, and to the [history drawer](/features/query-history#sources) +under **Command Line**. + +### List connections + +```bash +tablepro connections --format json +``` + +Each entry has the connection's `name`, `id` and `type`, never a host, user or password. The list +leaves out connections the command may not reach. + ## Trusting a link The first time a link connects, TablePro asks: **Open External Database Connection?**, showing the