MCP server
PerSQL hosts a Model Context Protocol
server at https://mcp.persql.com. Any MCP-aware runtime (Claude Desktop,
Cursor, Cline, Continue, OpenAI Agents SDK, …) can be pointed at it with a
single config block. The agent gets typed SQL tools immediately — no SDK
install, no per-runtime adapter.
OAuth-capable runtimes negotiate access automatically — the URL alone is
enough. Older runtimes pass a psql_live_… bearer header; the same token
authenticates against the /v1 REST API.
Endpoint
Section titled “Endpoint”| Stack | URL |
|---|---|
| Production | https://mcp.persql.com |
| Staging | https://mcp-staging.persql.com |
Transport: streamable-HTTP MCP (JSON-RPC 2.0 over HTTPS POST). Stateless —
each tool call is independent, no Mcp-Session-Id required.
Authentication
Section titled “Authentication”Two paths, picked automatically by the runtime:
- OAuth 2.1 with PKCE + dynamic client registration (MCP authorization
spec). On a 401, the server returns
WWW-Authenticate: Bearer resource_metadata=…. The runtime fetches the metadata at/.well-known/oauth-protected-resource, registers a public client at/oauth/register, opens the browser toconsole.persql.com/oauth-consent, you pick a namespace, the runtime stores the issued token. No copy-paste step. - Static bearer token as fallback for runtimes without OAuth support
(
Authorization: Bearer psql_live_…). Mint one under console.persql.com → API tokens.
Configuration
Section titled “Configuration”Claude Code
Section titled “Claude Code”One command, no file editing:
claude mcp add persql --transport http https://mcp.persql.comThe server registers in the current Claude Code session immediately.
Use claude mcp list to verify and claude mcp remove persql to undo.
If your Claude Code build doesn’t speak MCP OAuth, append a bearer header:
claude mcp add persql \ --transport http https://mcp.persql.com \ --header "Authorization: Bearer psql_live_…"Claude Desktop
Section titled “Claude Desktop”Edit ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{ "mcpServers": { "persql": { "url": "https://mcp.persql.com" } }}Restart Claude Desktop. The first tool call opens the browser to the PerSQL consent screen; pick a namespace and you’re in. Tools appear under the 🔌 plug icon.
Bearer fallback:
{ "mcpServers": { "persql": { "url": "https://mcp.persql.com", "headers": { "Authorization": "Bearer psql_live_…" } } }}Cursor
Section titled “Cursor”Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):
{ "mcpServers": { "persql": { "url": "https://mcp.persql.com" } }}Same fallback shape with a headers block if needed.
Other runtimes
Section titled “Other runtimes”Any MCP runtime that speaks streamable-HTTP works. URL alone if it supports OAuth; URL + bearer header if not. Cline, Continue, Sourcegraph Cody, Codeium — the config block is the same.
All tools are scoped to the namespace your token (or OAuth grant) belongs to.
query(database, sql, params?)— single statement,?placeholders, returns{ rows, rowsRead, rowsWritten }.batch(database, statements, transaction?)— up to 100 statements; settransaction: trueto wrap in a transaction.wait_for_changes(database, since?, waitMs?, tables?)— long-poll the change feed. Returns immediately if there’s already new activity, otherwise blocks up to 25s. Use this instead of polling.validate_sql(database, sql, params?)— parse + bind-check without executing. Cheaper than running the query just to find a typo.
Schema and docs
Section titled “Schema and docs”list_databases— slug, name, status for every database in the namespace.describe_database(database)— one-call descriptor: every table’s columns, foreign keys, and stored semantic descriptions. The first call to make on a fresh database.list_tables,describe_table,sample_table— the per-table variants when you don’t want the full graph.search_schema(database, query, limit?)— natural-language ranked search across table + column names and stored descriptions.schema_doctor(database)— lints the schema; flags missing primary keys, unindexed foreign keys, ambiguous columns. Read-only.set_database_doc,set_table_doc,set_column_doc,get_docs— write and read the namespace’s stored schema descriptions.ask(database, question)— NL→SQL with a budget cap.
Agent-shape primitives
Section titled “Agent-shape primitives”claim_branch(database, ref, ttlSec?, role?)— one-shot lease that creates or resets a branch and mints a scoped token. Per-agent-run sandboxes.propose_mutation/apply_mutation— pre-flight a write, inspect the rowcount, redeem with a single-use token.pin_branch(database, branchRef, role, ttlSec?)— mint a single-use handoff token (phand_…) for a sub-agent.claim_handoff(token, name?)— sub-agent side; redeems aphand_…for a regular bearer token scoped to one (database, branch, role).query_log(database, ...)/recent_actions(database, ...)— replay what changed. Also exposed inside the DB as_persql_meta_query_logso an agent canJOINagainst its own audit.
Provisioning
Section titled “Provisioning”create_database({ name, slug, region?, ttlDays? })— spin a new SQLite database in the namespace.ttlDays(1–30) creates a self-deleting DB — useful when you want a sandbox without managing cleanup. Requires an unscoped admin-role token.
Self-poke (schedules and webhooks)
Section titled “Self-poke (schedules and webhooks)”list_schedules(database)/create_schedule({ database, name, sql, intervalSec, enabled? })/delete_schedule({ database, scheduleId })— register cron SQL inside the database’s Durable Object. Useful for periodic maintenance an agent wants to leave running unattended — TTL cleanup, derived- table refresh, agent inbox sweep.list_webhooks(database)/create_webhook({ database, name, url, tables?, events?, enabled? })/delete_webhook({ database, webhookId })— register an outbound HMAC-signed webhook. When matching rows change, the DO POSTs JSON tourl. Use this to react to writes from outside the runtime — notify a sub-agent, kick off a deploy, page a human.
Spend introspection and self-funding
Section titled “Spend introspection and self-funding”whoami— namespace, role, scopes, plus live spend counters:balanceUsdMicros,graceFloorUsdMicros, andunbilledUsdMicros(debited since the last hourly flush). Self-throttle on these before the gate returns402.topup_balance({ amountUsd, returnUrl? })— mint a Stripe Checkout URL to fund the namespace. Requires an unscoped admin-role token. Returns{ url, amountUsd, sessionId, expiresAt }. Under an MPP-capable runtime (Stripe Machine Payments Protocol, x402) the runtime can drive Checkout end-to-end; otherwise hand the URL to a human.
Endpoints, branches, snapshots, migrations, saved queries
Section titled “Endpoints, branches, snapshots, migrations, saved queries”The rest of the surface mirrors the console: list_branches,
create_branch, delete_branch, merge_branch, preview_branch_merge,
branch_diff, list_snapshots, create_snapshot, restore_snapshot,
restore_to_time, list_endpoints, create_endpoint,
publish_endpoint, discover_endpoints, endpoint_logs,
list_migrations, create_migration, apply_migration,
rollback_migration, list_saved_queries, save_query,
run_saved_query. Roughly sixty tools total — list them at runtime via
your MCP client’s tools panel.
Telemetry
Section titled “Telemetry”Every query and batch invocation through MCP records the same query
event in PerSQL’s analytics dataset as the /v1 REST path. Customer usage
dashboards aggregate both surfaces — there’s no separate “MCP usage” view.
ask additionally records an ai_call event with the model used
and the tokens consumed — the same event used to bill the AI-tokens
meter.
Spending controls
Section titled “Spending controls”MCP shares the same model as /v1: the prepaid namespace balance
is the only spend control. A token spends as fast as you call it until
the balance returns 402. The 402 response carries an
x402-compatible body
(x402Version, accepts[]) so MPP-capable runtimes can complete a
top-up programmatically; non-MPP runtimes use topup_balance to mint
a Checkout URL.
If you want a tighter blast-radius for a single key, mint a separate namespace with its own balance and scope the token to it.
AI-powered tools (ask) also drain the balance via the AI-tokens
meter — see Pricing for the rate.
Idempotency keys for safe retry are not yet exposed via MCP — use the SDK or raw HTTP if you need them.