> ## Documentation Index
> Fetch the complete documentation index at: https://ngquct-feat-ai-sql-walkthroughs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokens

> Token model, scopes, connection allowlists, expiry, revocation, and the audit log

# Tokens

Bearer tokens authenticate external requests to the MCP server. Each token carries a scope, an optional connection allowlist, and an optional expiry. TablePro stores only the SHA-256 hash plus a per-token salt at `~/Library/Application Support/TablePro/mcp-tokens.json` with `0600` permissions. The plaintext is shown once at creation and never again.

## Require authentication

**Settings > Integrations > Authentication > Require authentication** is on by default. With the toggle off, requests from your own machine (loopback) are accepted without any token and run with full scopes and access to all connections. Remote clients need a bearer token regardless of the toggle. Turning it on for the first time with no tokens yet mints a full-access "Default token" and reveals the plaintext once.

<Warning>
  With Require authentication off, any local process can call the MCP server with full scopes. Leave it on.
</Warning>

## Stored fields

| Field                     | Purpose                                                                                             |
| ------------------------- | --------------------------------------------------------------------------------------------------- |
| `name`                    | Label in the token list. Pairing uses the client name.                                              |
| `prefix`                  | First 8 characters of the plaintext, e.g. `tp_a1b2c`, for identifying a token without revealing it. |
| `tokenHash`, `salt`       | SHA-256 of salt + plaintext. The plaintext is never persisted.                                      |
| `permissions`             | `readOnly`, `readWrite`, or `fullAccess`.                                                           |
| `connectionAccess`        | All connections, or a limited set of connection UUIDs.                                              |
| `expiresAt`               | Optional. Absent means never.                                                                       |
| `isActive`                | `false` after revocation.                                                                           |
| `createdAt`, `lastUsedAt` | Shown in the token list.                                                                            |

The plaintext format is `tp_` followed by 32 base64url-encoded random bytes.

## Scopes

A token's `permissions` value maps to the MCP scopes the server enforces:

| Token permission | MCP scopes granted                                     |
| ---------------- | ------------------------------------------------------ |
| `readOnly`       | `tools:read`, `resources:read`                         |
| `readWrite`      | `tools:read`, `tools:write`, `resources:read`          |
| `fullAccess`     | `tools:read`, `tools:write`, `resources:read`, `admin` |

What each token can do:

| Permission   | Read schema | SELECT | INSERT/UPDATE/DELETE |   DROP/TRUNCATE   | switch\_database/switch\_schema | open / focus tabs |
| ------------ | :---------: | :----: | :------------------: | :---------------: | :-----------------------------: | :---------------: |
| `readOnly`   |     yes     |   yes  |          no          |         no        |                no               |        yes        |
| `readWrite`  |     yes     |   yes  |          yes         | yes (with phrase) |               yes               |        yes        |
| `fullAccess` |     yes     |   yes  |          yes         | yes (with phrase) |               yes               |        yes        |

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`. No token permission bypasses the phrase.

## Connection allowlist

Each token grants access to all connections or a limited set. A request that targets a connection outside the allowlist returns `403 Forbidden` before any per-connection check runs.

## External access combination

The effective permission is `MIN(token.scope, connection.externalAccess)`.

| Token scope  | Connection access | Effective   |
| ------------ | ----------------- | ----------- |
| `readOnly`   | `readWrite`       | `readOnly`  |
| `readWrite`  | `readOnly`        | `readOnly`  |
| `fullAccess` | `readOnly`        | `readOnly`  |
| `fullAccess` | `readWrite`       | `readWrite` |
| any          | `blocked`         | denied      |

A token's reach is bounded by both itself and the connection's `externalAccess`.

## The stdio bridge token

Every MCP server start mints a `fullAccess` token named `__stdio_bridge__` and writes its plaintext to the handshake file for the bundled stdio bridge. It is hidden from the Settings token list, deleted when the server stops, and stale copies are removed the next time the store loads. Its name can appear in the activity log. To give an AI agent less than full access, skip the bridge and connect over [HTTP with a scoped token](/external-api/mcp-clients#http-transport).

## Creation

1. **Pairing flow** (most common). See [Pairing](/external-api/pairing). Approving a pairing request first revokes any active token with the same client name.
2. **Settings UI**: **Settings > Integrations > Authentication > Generate Token**. Pick name, scope, allowlist, and expiry. The plaintext is shown once in a reveal sheet.

## Expiry

Optional. An expired token stops authenticating and requests return `401 Unauthorized`. Prefer short expiries for anything with write access.

## 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. It stays in the list and cannot be reactivated.
* **Delete**: removes the row entirely.

A revoked token returns `401 Unauthorized` and the server terminates its active sessions immediately. The extension shows an unauthorized state on its next call; run the pairing command again to mint a new token.

## Audit log

Every authentication, tool call, and resource read is recorded in `~/Library/Application Support/TablePro/mcp-audit.db` with the token id, never the plaintext. View it via **Settings > Integrations > View Activity**:

| Field      | Values                                                                                                |
| ---------- | ----------------------------------------------------------------------------------------------------- |
| Timestamp  | 2026-04-26 10:14:22                                                                                   |
| Token      | Raycast on macbook-pro (`tp_a1b2c`)                                                                   |
| Category   | `auth`, `access`, `admin`, `query`, `tool`, `resource`                                                |
| Action     | `auth.success`, `pairing.exchange`, `token.revoked`, `query.executed`, `tool.<name>`, `resource.read` |
| Connection | Production (or `-`)                                                                                   |
| Outcome    | `success`, `denied`, `error`, `rateLimited`                                                           |

Entries older than 90 days are pruned when the audit store opens.

## Rate limits

The 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.

| Setting                 | Value      |
| ----------------------- | ---------- |
| Failure window          | 60 seconds |
| Max failures in window  | 5          |
| Lockout after threshold | 5 minutes  |

A successful auth clears the bucket. During lockout the server returns HTTP `429 Too Many Requests`.

## What tokens cannot do

| Capability                                                         | State |
| ------------------------------------------------------------------ | ----- |
| Read connection passwords                                          | no    |
| Read SSH keys                                                      | no    |
| Read license data                                                  | no    |
| Read app settings                                                  | no    |
| Read local files outside `~/Library/Application Support/TablePro/` | no    |
| Mutate Safe Mode rules                                             | no    |
| Mutate other tokens                                                | no    |
| Mutate connection records                                          | no    |

The token surface is the [MCP tool catalog](/external-api/mcp-tools), [resources](/external-api/mcp-resources), and the [URL scheme](/external-api/url-scheme). Anything not on those lists is not reachable.
