Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ngquct-feat-1048-apple-intelligence-transport.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

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.

What 2025-11-25 adds

Clients on the latest spec see three things that older clients don’t:
  • Structured tool output. Every tool that returns data fills structuredContent next to content[]. Older clients keep parsing the JSON text in content[0].text. Newer clients can read the typed object directly. Applies to list_*, describe_table, get_table_ddl, get_connection_status, list_recent_tabs, search_query_history, execute_query, and confirm_destructive_operation.
  • Tool annotations. tools/list returns title, readOnlyHint, destructiveHint, idempotentHint, and openWorldHint per tool. Read tools advertise readOnlyHint=true. confirm_destructive_operation advertises destructiveHint=true. execute_query and export_data advertise openWorldHint=true.
  • Streaming progress. Long-running tool calls emit notifications/progress events when the client passes a _meta.progressToken in the request. Today this fires on execute_query at four stages: Connecting, Executing, Formatting result, Done.

Scope and access matrix

Every tool requires one of these scopes. The scope is the token’s; the connection’s externalAccess setting can downgrade it further.
ScopeRead schemaRun SELECTRun INSERT/UPDATE/DELETEConfirm DROP/TRUNCATE
readOnlyyesyesnono
readWriteyesyesyesno
fullAccessyesyesyesyes (with phrase)
If connection.externalAccess is blocked, every tool that targets that connection returns 403 forbidden. If readOnly, write tools return 403 even with a readWrite token.

Connection tools

list_connections

List all saved connections. Input: none. Output:
{
  "connections": [
    {
      "id": "9f1f0c3e-2e3d-4b14-9c3a-1d2f4ad1f6f1",
      "name": "Production",
      "type": "PostgreSQL",
      "host": "db.example.com",
      "port": 5432,
      "database": "app",
      "username": "app",
      "is_connected": false,
      "ai_policy": "askEachTime",
      "safe_mode": "silent"
    }
  ]
}
Scope: readOnly.

connect

Open a database connection. Input:
{ "connection_id": "9f1f0c3e-..." }
Output:
{
  "status": "connected",
  "current_database": "app",
  "current_schema": "public",
  "server_version": "PostgreSQL 16.2"
}
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": "connected",
  "current_database": "app",
  "current_schema": "public",
  "server_version": "PostgreSQL 16.2",
  "connected_at": "2026-04-26T10:14:22Z",
  "last_active_at": "2026-04-26T10:14:22Z"
}
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:
{
  "connection_id": "...",
  "database": "app",
  "schema": "public",
  "include_row_counts": false
}
Output:
{
  "tables": [
    { "name": "users", "type": "table" },
    { "name": "orders_view", "type": "view" }
  ]
}
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:
{
  "connection_id": "...",
  "table": "users",
  "schema": "public"
}
schema is optional. The connection’s current schema is used when omitted. To target a different database, call switch_database first. Output:
{
  "columns": [
    {
      "name": "id",
      "data_type": "uuid",
      "is_nullable": false,
      "is_primary_key": true
    },
    {
      "name": "email",
      "data_type": "text",
      "is_nullable": false
    }
  ],
  "indexes": [
    {
      "name": "users_email_idx",
      "columns": ["email"],
      "is_unique": true,
      "is_primary": false,
      "type": "btree"
    }
  ],
  "foreign_keys": [],
  "ddl": "CREATE TABLE users (...)",
  "approximate_row_count": 12345
}
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:
{
  "connection_id": "...",
  "query": "SELECT id, email FROM users WHERE active = true LIMIT 100",
  "max_rows": 500,
  "timeout_seconds": 30,
  "database": "app",
  "schema": "public"
}
Defaults for max_rows and timeout_seconds come from Settings > Integrations > MCP 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": ["id", "email"],
  "rows": [["9f1f...", "alice@example.com"]],
  "row_count": 1,
  "rows_affected": 0,
  "execution_time_ms": 14,
  "is_truncated": false
}
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:
{
  "connection_id": "...",
  "query": "DROP TABLE legacy_events",
  "confirmation_phrase": "I understand this is irreversible"
}
The confirmation phrase is fixed: I understand this is irreversible. Anything else returns 400 invalid confirmation. 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:
{
  "connection_id": "...",
  "format": "csv",
  "tables": ["users", "orders"],
  "max_rows": 50000
}
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:
{
  "status": "opened",
  "connection_id": "9f1f...",
  "window_id": "..."
}
Scope: readOnly.

open_table_tab

Open a table tab. Input:
{
  "connection_id": "...",
  "table_name": "users",
  "database_name": "app",
  "schema_name": "public"
}
database_name and schema_name are optional. If omitted, the connection’s current database/schema is used. Output:
{
  "status": "opened",
  "connection_id": "9f1f...",
  "table_name": "users",
  "window_id": "..."
}
Scope: readOnly.

focus_query_tab

Bring an existing tab to front. The tab_id comes from list_recent_tabs. Input: { "tab_id": "..." } Output:
{
  "status": "focused",
  "tab_id": "...",
  "window_id": "...",
  "connection_id": "9f1f..."
}
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:
{
  "tabs": [
    {
      "tab_id": "...",
      "connection_id": "9f1f...",
      "connection_name": "Production",
      "tab_type": "query",
      "display_title": "users by signup date",
      "is_active": true,
      "table_name": "users",
      "database_name": "app",
      "schema_name": "public",
      "window_id": "..."
    }
  ]
}
tab_type is one of query, table, createTable, erDiagram, serverDashboard, terminal. 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:
{
  "query": "users active",
  "connection_id": "9f1f...",
  "limit": 50,
  "since": 1745577262,
  "until": 1745663662
}
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:
{
  "entries": [
    {
      "id": "...",
      "connection_id": "9f1f...",
      "database_name": "app",
      "query": "SELECT * FROM users WHERE active = true",
      "executed_at": 1745663662.0,
      "execution_time_ms": 18,
      "row_count": 142,
      "was_successful": true
    }
  ]
}
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:
JSON-RPC codeHTTP statusMeaning
-32700400Parse error (malformed JSON body)
-32600400Invalid request (bad envelope, missing Mcp-Session-Id)
-32601200 / 404Method or resource URI not found
-32602200Invalid params (bad input, unknown tab id, unknown connection)
-32603500Internal error
-32001404 / 401Session not found, or unauthenticated
-32002200Request cancelled
-32003200Request timeout (e.g. query timeout)
-32004404Resource not found
-32005413Payload too large
-32007403Forbidden (token scope, allowlist, or externalAccess rejects)
-32008401Token expired
-32000429 / 503Server error (rate limited, service unavailable)
Error responses include a message. Example:
{
  "jsonrpc": "2.0",
  "id": 7,
  "error": {
    "code": -32007,
    "message": "Forbidden: Connection is read-only for external clients"
  }
}
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 include a WWW-Authenticate: Bearer realm="TablePro MCP" header. When the token has expired, the challenge adds error="invalid_token", error_description="token_expired".