Skip to content

feat(cli): run queries from the shell with tablepro query - #3762

Merged
datlechin merged 3 commits into
mainfrom
feat/3617-cli-query-command
Oct 21, 2026
Merged

datlechin merged 3 commits into
mainfrom
feat/3617-cli-query-command

Conversation

@datlechin

@datlechin datlechin commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

  • tablepro query --connection <name or id> runs one statement through TablePro and prints the rows as csv, tsv, json, jsonl or table. SQL from the argument, -f <file> or stdin. Options: --database, --schema, --limit, --timeout, --read-only.
  • Exit status: 0 success, 1 query error, 2 usage, 3 refused, 4 timed out.
  • tablepro connections --format json lists name, id and type only.
  • New tablepro-cli helper in Contents/MacOS. The tablepro script hands query and connections to it; everything else still goes to open -b.
  • The helper reaches the app over the MCP server: it launches TablePro in the background like the bridge, checks the handshake and the server's instance id, then pairs once through the loopback pairing flow. The sheet starts at Read Only. The token goes to the login Keychain, or to a file inside TABLEPRO_UI_TEST_SANDBOX. A revoked token is dropped and the run exits 3. Pairing starts only when stderr is a terminal.
  • execute_query takes read_only. A statement that is not a read is refused with -33007 before the approval prompt and before Safe Mode, whatever the connection level and token scope allow.
  • New history source Command Line, picked when the request's clientInfo.name is tablepro-cli. Recorded even with "Log MCP queries in history" off, as AppleScript is. A stored all-sources filter widens to include it.
  • Table output escapes control characters, so a stored escape sequence is shown, not run by the terminal.

What a client can do now that it could not:

  • Nothing wider. read_only only adds a refusal. The command is an ordinary paired token with the scope the user picks, and it clears the same gates as any MCP client.
  • A client can file its queries under Command Line instead of AI and MCP by naming itself tablepro-cli, the same way its clientInfo already names it in Connected Clients. The audit log still names the token.

Docs: TableProApp/docs#111

Test plan

  • CLIArgumentsTests, CLIRowWriterTests, CLIFailureTests, CLIPairingTests, CLIRunnerTests, CLITokenStoreTests (TableProMCPTests): parsing, every format, exit status mapping, PKCE and the callback listener, the runner against a mock server, sandbox token storage.
  • ExecuteQueryReadOnlyTests: on a Read & Write connection a read_only write is refused with no prompt and no driver call; a read still runs.
  • CLIPairingContractTests: the app parses the command's pair link as a read-only loopback pairing, and its approve and deny redirects reach the command's callback parser.
  • MCPCommandLineHistoryTests, QueryHistorySourceTests, ExecuteQueryToolTests, the MCP write policy matrix.
  • Live, the built tablepro script against a sandboxed Debug build launched in the background, token in the sandbox file: --format csv "SELECT 1 AS n" printed n and 1 and exited 0; --read-only with an INSERT exited 3 and the table kept its rows; --timeout 1 on a long recursive query exited 4. Also checked: json from stdin, table with an escape shown, connections, an unknown name (2), two statements (2), a missing table (1), the --limit note, -f, and a bogus token (3, token file removed). History recorded every run under command_line with MCP history off.
  • Not run live: the pairing sheet click and the browser hop. The contract test covers both ends of that exchange.

Not in this PR

  • Rows do not stream from the server. execute_query answers with the whole result, capped by the MCP row limit.
  • A connection whose AI policy is Never is refused, since the command is an MCP client. Exempting it needs an identity a client cannot claim for itself.
  • DROP and TRUNCATE are refused with a message that names confirm_destructive_operation, an MCP tool the command does not offer.
  • The footer of Settings > General > Command Line still describes only opening URLs.

Fixes #3617

…ommand

# Conflicts:
#	apple/TablePro/Models/Query/QueryHistorySource.swift
@datlechin
datlechin merged commit 45bb7f8 into main Oct 21, 2026
8 checks passed
@datlechin
datlechin deleted the feat/3617-cli-query-command branch October 22, 2026 07:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A tablepro query command that prints results for shell scripts

1 participant