Tokens
Every external request needs a bearer token. Tokens carry a scope, an optional connection allowlist, and an optional expiry. Tokens are stored hashed (SHA-256 + salt) at~/Library/Application Support/TablePro/mcp-tokens.json with 0600 permissions. The plaintext is shown once at creation and never again.
Token shape
prefix is shown in the token list so the user can identify a token without revealing the secret.
Scopes
A token’spermissions value maps to the MCP scopes the server enforces:
What each token can do:
Navigation tools (
open_connection_window, open_table_tab, focus_query_tab, list_recent_tabs) need only tools:read. They surface UI but never bypass the connection allowlist or externalAccess: blocked.
DROP and TRUNCATE always require an explicit confirmation phrase via confirm_destructive_operation, plus a token with tools:write (i.e. readWrite or fullAccess). There is no token permission that bypasses the phrase.
Connection allowlist
Each token can be limited to a subset of connections.allowedConnectionIds = nilmeans all connections.allowedConnectionIds = { uuid1, uuid2 }means only those.
403 forbidden before any per-connection check runs.
External access combination
The effective permission isMIN(token.scope, connection.externalAccess).
A
fullAccess or readWrite token cannot mutate data on a readOnly connection. A token’s reach is bounded by both itself and the connection’s externalAccess.
Creation
Tokens are created in three ways:- Pairing flow (most common). See Pairing.
- Settings UI. Settings > Integrations > Authentication, then Generate Token. Pick name, scope, allowlist, expiry. The plaintext is shown once in a reveal sheet.
- AppleScript-style URL is not supported. Tokens are not exposed as a URL scheme action.
tp_<base64url(32 bytes)>. The first 8 chars are the prefix.
Expiry
Optional. If set, the token stops authenticating at the expiry time. Expired requests return401 unauthorized with message: "Token expired".
Recommended values:
readWriteandfullAccessfor human-driven extensions: 90 days.readOnlyfor personal use: never.- CI or automation: 30 days, rotated.
Revocation
Settings > Integrations > Authentication lists all tokens with prefix, name, scope, allowlist, last-used time, and expiry. Each row has:- Revoke: marks the token inactive. Stays in the list with status
Revoked. Cannot be reactivated. - Delete: removes the row entirely.
401 unauthorized immediately. The MCP server invalidates any cached session for the token within one second.
After revoking a token used by an extension, the extension shows an “unauthorized” state on the next call. The user runs the pairing command again to mint a new token.
Audit log
Every authentication, every tool call, every resource read is recorded in~/Library/Application Support/TablePro/mcp-audit.db with the token id (not the plaintext). The activity log view in Settings > Integrations > Activity Log shows:
Entries are kept for 90 days, auto-pruned on app launch.
Rate limits
The MCP authenticator throttles failed token attempts. The bucket key is(client_address, principal_fingerprint), so a misbehaving bridge cannot lock out other principals on the same loopback address.
A successful auth clears the bucket. During lockout the server returns HTTP
429 Too Many Requests with JSON-RPC code: -32000, message: "Rate limited".
What tokens cannot do
The token surface is the MCP tool catalog and the URL scheme. Anything not on those lists is not reachable.
