Skip to main content

MCP Tools

The MCP server exposes tools and resources over JSON-RPC. The tools are grouped by category below. Every tool is scope-gated: a request must come with a token whose scope and connection allowlist permit the call.

Transports

The same tool catalog is available over two transports:
  • HTTP: MCP Streamable HTTP at http://127.0.0.1:<port>/mcp (port from the handshake file). POST for JSON-RPC requests, GET for the SSE stream that carries server-initiated notifications. Bearer token in Authorization header.
  • stdio: bundled tablepro-mcp CLI bridges stdio JSON-RPC to localhost HTTP. No token needed because the bridge reuses the in-app handshake.
The server accepts 2025-03-26, 2025-06-18, and 2025-11-25. On initialize it echoes whichever version the client requested. If the client asks for something else, the server returns 2025-11-25. See Versioning.

Scopes and access

Each tool entry below lists its minimum token scope. The effective permission is MIN(token.scope, connection.externalAccess); see Tokens for the full scope table. Two per-connection settings gate every call on top of the token:
  • External access. blocked hides the connection entirely: list_connections omits it, list_recent_tabs filters its tabs, and any tool that targets it returns 403 forbidden. readOnly makes write tools return 403 even with a readWrite token.
  • AI policy askEachTime. The first tool call per session that targets the connection shows an in-app approval dialog. TablePro waits up to 30 seconds. Deny returns 403 forbidden with message “User denied MCP access to this connection”; no answer fails the call with a timeout error. An approval covers that connection for the rest of the session.

Connection tools

list_connections

List saved connections. Connections with externalAccess: blocked are silently omitted. Input: none. Output:
Scope: readOnly.

connect

Open a database connection. Input:
Output:
current_schema and server_version are present when known. Scope: readOnly.

disconnect

Close a connection. Input: { "connection_id": "..." } Output: { "status": "disconnected" } on success. Scope: readWrite.

get_connection_status

Return version, uptime, and active database for a connection. Input: { "connection_id": "..." } Output:
status is one of connected, connecting, disconnected, error. When error, an error object with a message field is included. Scope: readOnly.

Schema tools

list_databases

Input: { "connection_id": "..." } Output: { "databases": ["app", "analytics"] } (array of database names) Scope: readOnly.

list_schemas

Input: { "connection_id": "...", "database": "app" } (database optional) Output: { "schemas": ["public", "reporting"] } (array of schema names) Scope: readOnly.

list_tables

Input:
Output:
When include_row_counts is true and the driver supports it, each entry also includes row_count. Scope: readOnly.

describe_table

Columns, indexes, foreign keys, primary key, DDL. Input:
schema is optional. The connection’s current schema is used when omitted. To target a different database, call switch_database first. Output:
default_value, extra, and comment are present on a column when set. ddl and approximate_row_count are present when the driver supports them. Scope: readOnly.

get_table_ddl

Just the CREATE TABLE statement. Input: same as describe_table (connection_id, table, schema). Output: { "ddl": "CREATE TABLE ..." } Scope: readOnly.

Query tools

execute_query

Execute a SQL query. All queries are subject to the connection’s safe mode policy. DROP, TRUNCATE, and ALTER…DROP must use confirm_destructive_operation. Input:
Defaults for max_rows and timeout_seconds come from Settings > Integrations > Server Configuration (default row limit, query timeout). max_rows is clamped to the configured maximum (default 10,000). timeout_seconds is clamped to 1-300. Single-statement queries only. Query size cap is 100 KB. database and schema are optional; when present, the tool calls switch_database and/or switch_schema before executing. Output:
columns is an array of column-name strings. rows is an array of rows, where each row is an array of strings (or null) aligned to the columns order. status_message is added when the driver returns one. Scope:
  • readOnly for SELECT, SHOW, EXPLAIN.
  • readWrite for INSERT, UPDATE, DELETE.
  • DROP, TRUNCATE, ALTER…DROP are rejected. Use confirm_destructive_operation.
Safe Mode rules apply on top. A connection in Safe Mode readOnly returns 403 for any write SQL. Streaming progress: pass _meta.progressToken in the request and the server sends notifications/progress events on the SSE channel as the query moves through “Connecting”, “Executing”, “Formatting result”, and “Done”. Clients that don’t include a token get the final response only.

confirm_destructive_operation

Run a DROP, TRUNCATE, or ALTER…DROP after a typed confirmation. Input:
The confirmation phrase is fixed: I understand this is irreversible. Anything else returns JSON-RPC -32602 over HTTP 200 with message Invalid params: confirmation_phrase must be exactly: I understand this is irreversible. Output: same shape as execute_query. Scope: readWrite or fullAccess (both grant the tools:write MCP scope). The connection’s external access must also permit writes; a readOnly connection rejects destructive operations even with a matching token.

export_data

Export query or table data as CSV, JSON, or SQL. Input:
format is one of csv, json, sql. max_rows defaults to 50,000, max 100,000. Provide either tables or query. Table names accept letters, digits, underscore, and . for schema-qualified names. Pass output_path to write to disk instead of returning data inline; the path must resolve inside the user’s ~/Downloads directory or the request is rejected with 400. Output: when output_path is set, returns { "path": "...", "rows_exported": N }. Otherwise returns the export inline. A single export returns { "label": "...", "format": "csv", "row_count": N, "data": "..." }. Multiple exports (multi-table requests) return { "exports": [ { "label": "...", "format": "csv", "row_count": N, "data": "..." }, ... ] }. Scope: readOnly.

switch_database / switch_schema

Input: { "connection_id": "...", "database": "analytics" } or { "connection_id": "...", "schema": "reporting" } Output: { "status": "switched", "current_database": "analytics" } or { "status": "switched", "current_schema": "reporting" } Scope: readWrite (mutates session state). These open or focus tabs and windows in the running TablePro app. They require readOnly scope and respect the connection allowlist; tabs from externalAccess: blocked connections are filtered out.

open_connection_window

Open a connection in TablePro and bring its window to front. If the connection is already open, the existing window is focused. Input: { "connection_id": "..." } Output:
Scope: readOnly.

open_table_tab

Open a table tab. Input:
database_name and schema_name are optional. If omitted, the connection’s current database/schema is used. Output:
Scope: readOnly.

focus_query_tab

Bring an existing tab to front. The tab_id comes from list_recent_tabs. Input: { "tab_id": "..." } Output:
If the tab is no longer open, the call returns -32602 invalid params with detail tab not found. Scope: readOnly.

list_recent_tabs

Read the cross-window tab registry. Tabs from connections with externalAccess: blocked are filtered out. Input: { "limit": 20 } (optional, 1-500, default 20). Output:
tab_type is one of query, table, createTable, erDiagram, serverDashboard, usersRoles. table_name, database_name, schema_name, and window_id are present when known. Scope: readOnly.

History tools

search_query_history

Full-text search over the query history database. Input:
connection_id is optional. limit is 1-500, default 50. since and until are optional Unix epoch seconds; both bounds are inclusive. Either may be set on its own. Pass an empty query ("") to skip the full-text filter and only narrow by date or connection. Output:
executed_at is a Unix timestamp in seconds. error_message is included when was_successful is false. Scope: readOnly.

Errors

Tool failures come back as JSON-RPC error envelopes. Codes follow the JSON-RPC spec plus TablePro’s reserved range: Error responses include a message. Example:
A 404 from GET/POST/DELETE /mcp with a stale Mcp-Session-Id returns the JSON-RPC envelope with code: -32001, message: "Session not found". Per the MCP spec, clients MUST treat that response as a signal to start a new initialize handshake before retrying. 401 responses carry a WWW-Authenticate challenge. A missing token returns Bearer realm="TablePro". An unknown or revoked token returns Bearer error="invalid_token". An expired token returns Bearer error="invalid_token", error_description="token expired".