Skip to content

MCP

PerSQL is an MCP server. An agent that supports the Model Context Protocol, such as Claude Code, Claude Desktop, Cursor or your own, gets your databases as tools: list them, read a schema, look at a few rows, run SQL, and take a backup. The tools act as you, and the agent can write, so read the tool list and give a key only to an agent you trust with your databases.

The server is https://api.persql.com/mcp: JSON-RPC over POST, with one request or a batch per call, answered as JSON; a notification returns 202 with no body. It opens no stream. Send a developer key as a bearer token.

{
"mcpServers": {
  "persql": {
    "type": "http",
    "url": "https://api.persql.com/mcp",
    "headers": { "Authorization": "Bearer persql_..." }
  }
}
}

A client that can only run a local command reaches the same server through the CLI, which relays each line to the HTTP server with its key:

{
"mcpServers": {
  "persql": {
    "command": "npx",
    "args": ["-y", "@persql/cli", "mcp"],
    "env": { "PERSQL_KEY": "persql_..." }
  }
}
}

persql mcp --config prints both configurations and the hosted one below. After persql login, PERSQL_KEY can be left out, and the saved sign-in is used.

A client that cannot store a key, such as a connector added on claude.ai or in another hosted agent, signs in through your browser instead. Give it https://api.persql.com/mcp and nothing else:

  1. The server answers the client’s first call with 401 and WWW-Authenticate: Bearer resource_metadata=….
  2. The client reads https://api.persql.com/.well-known/oauth-protected-resource/mcp and https://api.persql.com/.well-known/oauth-authorization-server and registers itself (RFC 7591, no secret, PKCE required).
  3. The client sends you to https://console.persql.com/consent, where the web app names the client and asks you once to allow it.
  4. If you allow it, the client receives a token that acts as you, with the scopes databases offline_access. With offline_access, it refreshes the token itself and keeps access after the browser session in which you allowed it ends.

The client is listed under Connected agents, in Account in the web app’s Settings; removing it there revokes every token it holds at once. GET /agents and DELETE /agents/:clientId do the same through the API.

ToolTakesDoes
list_databasesList the user's databases: id, name, how many tables, size in bytes, when last changed.
create_database, nameMake a new, empty database with the given name. Returns its id.
describe_database, databaseThe schema of a database: every table with its columns, types and keys, the indexes, the foreign keys and the views. Read it before writing SQL.
read_table, database, table, limitA table's row count, its columns, and a few rows to see what the data looks like.
run_query, database, sql, params, offsetRun one SELECT, or a PRAGMA that reads, and change nothing. It returns the columns, how many rows the query returns in all, and the first 128; pass the next offset for the next page, which answers its rows without the count again. A write goes to run_change. Use ? placeholders and pass values in params.
run_change, database, sql, paramsRun one INSERT, UPDATE, DELETE, CREATE, ALTER or DROP as written, and return the rows written. It cannot be undone except from a backup, so call create_backup first when a change is hard to undo. Use ? placeholders and pass values in params.
list_backups, databaseThe backups of a database, newest first, with their kind and standing.
create_backup, database, labelTake a backup of a database before a change that is hard to undo. The backup is written in the background; the user can restore or download it.

A database argument is the database’s id, or its name when no other database has that name. Every tool returns JSON as text; a failure is an isError result with the error sentence, never a dropped connection.

The protocol version is 2025-06-18. The server supports initialize, ping, tools/list and tools/call; it does not offer resources or prompts.