Vericto account

Your Vericto workspace over OAuth: setup status, rules, CI reports, docs search and SQL checks.

Hosted MCP Server

npx add-mcp 'https://mcp.vericto.com/mcp/account'

Installs into Claude Code, Codex, Cursor and more

Documentation

Overview

Vericto runs a remote MCP server at https://mcp.vericto.com/mcp. A connected agent (Claude Code or another compatible MCP client) calls check_sql while it generates SQL and gets the same verdict as the CLI or the API: BLOCKED, FLAGGED, MONITORED or ALLOWED, with the rule that fired and a suggested fix.

It is the earliest point in the cycle: the CLI checks before merge and the TCP proxy blocks in production; MCP checks while the code is still being written. All three use the same deterministic AST engine and your workspace rules.

Nothing to install. The server is remote (Streamable HTTP) and authenticates with an API key from your workspace in the Authorization header.

Install in one click

Pick the server and your client: the buttons open Cursor or VS Code with the configuration filled in, and for Claude you copy one command or one URL. Sign in (OAuth) is the one-click option: the API key and local servers also need a key or your database URL.

The quickest way for a person: one click, sign in in the browser and approve, with no key to copy.

The vericto-account server at https://mcp.vericto.com/mcp/account, with no API key. The first time, the client opens Vericto in the browser: you sign in, pick the workspace and approve the permissions. To use check_sql, tick sql:check on the consent screen (it spends the month's checks). It acts as you, with your role.

VS Code Insiders

Claude Code

claude mcp add --scope user --transport http vericto-account https://mcp.vericto.com/mcp/account

Then, in a session, run /mcp and choose Authenticate.

Claude Desktop · claude.ai

In Customize → Connectors → Add custom connector, paste this URL and, under Authentication, choose Sign in now. On Team and Enterprise, an owner adds it under Organization settings → Connectors and each person connects with their own account.

https://mcp.vericto.com/mcp/account

The vericto server at https://mcp.vericto.com/mcp, meant for agents and CI. Create an API key with only the ci_dryrun:execute scope. Cursor opens an Install MCP server? window with the configuration filled in. The Authorization header reads Bearer ${env:VERICTO_API_KEY}: keep it if VERICTO_API_KEY is set in your environment (restart Cursor after setting it), or replace it with Bearer followed by your key. In that case Cursor stores the key in ~/.cursor/mcp.json in plain text, which is why it should carry only the ci_dryrun:execute scope. VS Code asks for the key once and stores it encrypted.

VS Code Insiders

Claude Code

claude mcp add --scope user --transport http vericto https://mcp.vericto.com/mcp \
  --header 'Authorization: Bearer ${VERICTO_API_KEY}'

Claude Desktop · claude.ai

In Customize → Connectors → Add custom connector, use the URL https://mcp.vericto.com/mcp and, under Authentication, No sign-in. Under Request headers, add Authorization with the value Bearer followed by your key: Claude keeps it in the connector, not in a file. If you do not see Request headers, use the OAuth tab or the mcp-remote bridge in the per-client setup.

The vericto-db server: vericto-proxy mcp runs in Docker on your machine, with the built-in rules and no account. It connects to your PostgreSQL and gives the agent execute_sql, describe_schema, check_sql and whoami, never the database credential. The links use the vericto/vericto-proxy:5.0.0 image.

First, once: create a read-only role (the SQL is in the docs) and save the connection URL in ~/.config/vericto/db.url, with mode 600:

mkdir -p ~/.config/vericto && chmod 700 ~/.config/vericto
printf '%s' 'postgres://vericto_agent_ro:…@db.example.com:5432/shop?sslmode=verify-full' > ~/.config/vericto/db.url
chmod 600 ~/.config/vericto/db.url

macOS and Windows (Docker Desktop)

VS Code Insiders

Linux

On Linux, Docker needs --user with your uid:gid to read the file. VS Code asks for it; the Cursor link uses 1000:1000: if id -u or id -g print something else, change it in ~/.cursor/mcp.json.

VS Code Insiders

Claude Code

On macOS and Linux; the shell fills in your uid:gid:

claude mcp add --scope user vericto-db -- \
  docker run -i --rm --user "$(id -u):$(id -g)" \
    -v ~/.config/vericto/db.url:/run/secrets/db.url:ro \
    vericto/vericto-proxy:5.0.0 /usr/local/bin/vericto-proxy mcp --database-url-file /run/secrets/db.url

Claude Desktop

In Settings → Developer → Edit Config, add the server to claude_desktop_config.json with your home's absolute path instead of /Users/me (no ~) and restart Claude Desktop.

{
  "mcpServers": {
    "vericto-db": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
               "-v", "/Users/me/.config/vericto/db.url:/run/secrets/db.url:ro",
               "vericto/vericto-proxy:5.0.0", "/usr/local/bin/vericto-proxy", "mcp",
               "--database-url-file", "/run/secrets/db.url"]
    }
  }
}

Cursor and VS Code show the configuration and ask you to confirm before they add the server. For other clients, follow the manual setup below.

Setup

1. Create an API key

In Dashboard → API Keys → New API key, create a key with only the ci_dryrun:execute scope (the one the CLI uses) and, optionally, an expiry date. Copy it: it is shown only once. Keep it in an environment variable, not in a file in your repository:

# ~/.zshrc or ~/.bashrc
export VERICTO_API_KEY="vtro_..."

2. Connect your client

claude mcp add --scope user --transport http vericto https://mcp.vericto.com/mcp \
  --header 'Authorization: Bearer ${VERICTO_API_KEY}'

The single quotes keep ${VERICTO_API_KEY} unexpanded: the config stores the reference and Claude Code resolves it at startup, so the key is never written to ~/.claude.json. Open a new session and run /mcp: vericto should show as connected with 6 tools.

Tested with Claude Code.

Do not paste the API key into files that get committed, such as a project .mcp.json. Use the environment-variable reference your client offers.

Tools

ToolWhat it doesQuota
check_sqlEvaluates SQL against the workspace rules and returns a verdict per statement.1 check per statement evaluated, with sql or queries
whoamiPlan, checks left this month, ruleset version, and the workspace's databases with their dialect.Free
list_rulesThe effective rule catalogue (standard and custom) with the resolved action.Free
show_ruleOne rule in detail by code, including the AST condition it matches.Free
list_reportsThe checks made with this same API key, newest first.Free
show_reportThe full result of an earlier check made with this API key, query by query.Free

On connect the server sends usage instructions, so the agent knows when to call each tool without you having to explain it.

How check_sql works

It takes one of two inputs:

  • sql: the whole script, such as a migration file. Vericto splits it into statements and reports each one with the line it starts on. It costs one check per statement, the same as that file through the CLI.
  • queries: statements already split, each with an optional line. It costs one check per statement.

Always pass the dialect of the database the SQL targets: postgres (the default), mysql, oracle, mssql, snowflake or sqlite. whoami lists the workspace's databases with their dialect.

The answer is compact: a summary and, for every statement that is not ALLOWED, its line, status, rule, severity and suggested fix. With verbose: true it returns the full CLI result.

Every answer ends with next steps, in the text and as next_action and next_steps in the structured result (each finding also carries its next_action): apply_fix_and_recheck, do_not_run (call show_rule or ask the user), request_access, fix_and_recheck (parse errors: fix the syntax or the dialect), run_approved_query, mention_to_user, run_as_written or stop (kill switch). They only name tools the connection can call; on /mcp/account, a missing one is named as the scope to grant. The agent should follow them instead of rephrasing a blocked statement and checking it again. whoami, show_rule, list_reports, show_report and explain_block add a short next_step too.

DDL. check_sql applies your workspace's full action to the schema and DDL rules too (VERICTO-010 to 019): a DROP TABLE or a TRUNCATE comes back BLOCKED by the rule's severity, as on the Runtime API, the SDKs and the TCP proxy, on both /mcp and /mcp/account. Only the CLI, the Validation API and the dashboard dry-run, which review migrations in CI, cap it at FLAGGED (schema_migration_cap).

Sensitive columns. Pass the database's database_id (whoami lists it) so its sensitive columns apply; without it, those of every database in the workspace apply, with the strictest policy per column. When a finding carries approved_query, the query reads a masked column: that is the only approved query, and the agent must run it instead of the original. MCP cannot enforce it; only the TCP proxy enforces masking.

BLOCKED: 1 of 3 statements must not ship as written.
- line 4 BLOCKED VERICTO-001 (critical): DELETE FROM users Fix: DELETE FROM users WHERE id = $1
Next:
- line 4 (VERICTO-001): do not run it as written; apply the suggested fix, then call check_sql again with the corrected SQL.
- lines 2, 5: safe to run as written under ruleset v1.0.0-3f2a9c1b7d4e; no need to call check_sql again while ruleset_version stays v1.0.0-3f2a9c1b7d4e.
Ruleset v1.0.0-3f2a9c1b7d4e · 999 checks left this month

If the script has procedural bodies (CREATE PROCEDURE … BEGIN … END, BEGIN ATOMIC or MySQL DELIMITER), Vericto does not split it: it evaluates it as one unit, as the CLI does with a file, reports its most severe finding and counts one check.

The ruleset_version in the answer changes only when a workspace rule or sensitive column changes. While it matches the one from whoami (which is that of a check without database_id), an earlier verdict still holds.

Every call is recorded in the workspace's check history (Dashboard → SQL checks; list_reports shows only the ones made with the same API key), with an excerpt of up to 100 characters of each statement.

Quota and limits

PlanChecks per month (CLI, Validation API and MCP)
Free1,000
Builder10,000
TeamUnlimited
EnterpriseUnlimited

The monthly quota is shared between the CLI, the Validation API and MCP, and each statement evaluated counts as one check. If a call needs more checks than are left, it is rejected whole, with nothing evaluated, and the message says how many remain: split the script or wait for next month. The read-only tools do not use the quota.

There is also a per-API-key rate limit on every plan: 30 check_sql calls per minute and 300 per hour, and 60 per minute for the read-only tools. When exceeded, the tool answers with how many seconds to wait.

Security

  • The API key determines the workspace. The agent cannot pick or see another one.
  • A key with only ci_dryrun:execute cannot read the audit trail or change rules: whoever gets it can, at most, spend your check quota.
  • Vericto only analyzes the SQL text. It does not connect to your database or run anything.
  • Revoke the key in Dashboard → API Keys and the agent loses access immediately.

Support MCP (vericto-account)

Next to the runtime server there is a server for your account: your coding agent checks the workspace's setup, diagnoses the proxy, explains why a query was blocked, searches these docs and, for you, also checks SQL and reads the rules and the CI reports. It is the same server on another path, /mcp/account, with another credential: an MCP connection of yours, bound to your user and your role, that you approve with OAuth or create as a key in Dashboard → MCP connections.

Connect with OAuth

If your client supports OAuth for remote MCP servers, add only the URL https://mcp.vericto.com/mcp/account, without an Authorization header. The first time it connects, the client opens Vericto in your browser: you sign in, pick the workspace and approve what it may do. There is no key to copy.

  • Claude (claude.ai and Claude Desktop): Customize → Connectors → Add custom connector, with that URL and Authentication set to Sign in now. In Claude Code: claude mcp add --scope user --transport http vericto-account https://mcp.vericto.com/mcp/account, then /mcp → authenticate.
  • Cursor: in ~/.cursor/mcp.json, the vericto-account entry with "url" only; Cursor opens the browser to approve it.
  • ChatGPT: in chatgpt.com/plugins, + → Add custom MCP server, with that URL and OAuth as the authentication. Other clients with OAuth: add the server by its URL and pick OAuth. Vericto supports Client ID Metadata Documents and dynamic client registration.
  • Cursor and VS Code, in one click: VS Code Insiders
  • The approval screen shows your user, the client's name marked unverified (Vericto does not review clients: approve it only if you just started the connection), where you go back to, the workspace and the permissions. Read access comes ticked; checking SQL (sql:check) only if you tick it, and only what your role allows. The write permissions (tickets:write, config:write) cannot be approved over OAuth yet: to open tickets or change the configuration from an agent, use a connection key.
  • If the agent needs a permission you did not approve, the server answers insufficient_scope and the client asks you again for that permission. The connection shows in Dashboard → MCP connections with the client's name; it expires like a key (30 days, 90 at most, renewable), and revoking it cuts its tokens at once.

If your client does not support OAuth, or it is an automation of yours, use a key: create it in Dashboard → MCP connections, keep it in the environment variable VERICTO_ACCOUNT_KEY and add the server next to the runtime one in your client:

claude mcp add --scope user --transport http vericto-account https://mcp.vericto.com/mcp/account \
  --header 'Authorization: Bearer ${VERICTO_ACCOUNT_KEY}'

As with the runtime one, the single quotes keep the reference, not the key. In /mcp, vericto-account must show as connected, with its tools.

ToolScopeWhat it does
setup_statussetup:readWhat is already in place and what is missing: databases, connection modes seen, proxy health, observe mode and next steps.
diagnose_proxyproxy:readThe state of each TCP proxy (healthy, silent, delayed, dropping telemetry), its version and what to check.
explain_blockevents:readWhy an event or a check was blocked or only flagged: the rule, its condition and the workspace mode.
search_docsdocs:readSearches this documentation. Every connection holds this scope.
get_configconfig:readThe current configuration: enforcement mode, rules, databases with their sensitive columns, and alert channels (type and name, never their URL).
open_support_tickettickets:writeOpens a support ticket as you. Only when the connection holds tickets:write.
plan_config_changeconfig:writeStep 1 of 2: plans one or more changes that add protection and returns the diff and a plan_id. It changes nothing.
apply_config_changeconfig:writeStep 2 of 2: applies that plan, all of it or nothing, only if the configuration has not changed since it was planned. With a key it does not apply: it sends you the plan to approve in the dashboard.
config_approval_statusconfig:writeReads the outcome of a change sent for approval: pending, applied, rejected, expired or not applied.
check_sqlsql:checkChecks SQL against the workspace's rules before it runs, as on the runtime server. It spends the workspace's monthly CI checks and stores the report under your connection, so it is not ticked by default.
list_rules, show_ruleruleset:readThe workspace's rules, and one rule's detail with its condition.
list_reports, show_reportreports:readThe workspace's CI reports (from the CLI, pipelines, the API and agents), as your role sees them: a viewer gets each statement's hash instead of its SQL.
whoamisetup:readThe plan, the CI checks left this month, the ruleset version and the databases with their dialect.
  • You pick the scopes one by one, grouped by area, with read and write separate; write includes its read (config:write needs config:read) and docs:read is always there. By default a new connection only reads.
  • A viewer can only hold read scopes; tickets:write needs member or above, and config:write admin or owner. It is checked against your current role on every call, and a tool missing a scope says which one.
  • Changing the configuration takes two steps: your agent shows you the diff from plan_config_change and only after your explicit OK calls apply_config_change. The plan_id expires after 10 minutes, is used once and only from the connection that made it. With a key, the change is not applied until you approve it in the dashboard (it reaches you by email, with the diff; it expires after 24 hours): a key copied into an autonomous agent cannot change the configuration without you. The write permission cannot be approved over OAuth yet, so configuration changes from an agent go through a key.
  • Only changes that add protection are possible: adding a database (within your plan) or an email alert channel, turning a paused email channel back on, turning a rule on or raising its severity, moving to enforce, blocking SQL that cannot be parsed, sanitizing telemetry and tagging sensitive columns.
  • Anything that removes or weakens protection is refused with a link to the dashboard page that does it: moving to observe or monitor, turning a rule off or lowering its severity, removing or changing sensitive columns, turning off or deleting alert channels, deleting databases, and creating, rotating or revoking keys. So are channels with a destination URL (Slack, Teams, webhook, PagerDuty), to add or turn back on: an agent could redirect alerts to a destination it controls. That way a prompt-injected agent cannot turn the guardrails off.
  • It returns what your role sees in the dashboard: a viewer gets an event’s metadata, without the SQL. The SQL it returns is always sanitized, without literals.
  • A runtime API key does not see these tools and does not work on /mcp/account: autonomous agents and services use /mcp with an API key. Your connection, on the other hand, also sees the runtime tools, with their own permissions.
  • It expires after 30 days (90 at most): we email you 7 and 2 days before, and the dashboard shows it from 7 days before. It is revoked on the same page, stops working if you leave the workspace, and every call, including each plan and each applied change, is recorded in the audit log under your name and the connection’s.
  • Renewing extends it by 30 or 90 days (never more than 90 from today) with the same key, so your client keeps working unchanged. You can renew up to 30 days after it expires; after that, you create a new connection. Renewing checks your permissions against your current role again: if it can no longer hold one, you can renew without it. Rotating is different: it issues a new key and you update your client.

Turning every support connection off

An owner or admin can block every support MCP connection of the workspace at once in Dashboard → Settings → Support MCP connections (Allow support MCP connections, on by default). While it is off, every call to /mcp/account is refused before any tool runs, with a message that says where to turn it back on, and connections cannot be created, renewed, rotated or widened, nor OAuth ones approved or refreshed. Connections are not revoked: turning it back on makes them work again, except those that expired. The change is recorded in the audit log, and the runtime MCP (/mcp) is not affected.

OAuth only

In the same place, OAuth only on /mcp/account (off by default) refuses connection keys on every call and does not let anyone create, renew or rotate them; OAuth connections keep working. Keys are kept and work again when it is turned off. It can only be turned on when OAuth is available, so nobody is locked out.

Local server (vericto-db)

vericto-proxy mcp is an MCP server that runs on your machine, in Docker, and connects to a PostgreSQL database: the agent gets execute_sql, describe_schema, check_sql and whoami, and never the database credential. It uses the proxy's built-in rules, so it needs no account. Unlike /mcp, this server does run SQL on your database: give it a read-only role.

1. Create a read-only role

CREATE ROLE vericto_agent_ro LOGIN PASSWORD '…';
GRANT CONNECT ON DATABASE shop TO vericto_agent_ro;
GRANT USAGE ON SCHEMA public TO vericto_agent_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO vericto_agent_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO vericto_agent_ro;

2. Save the connection URL in a file

mkdir -p ~/.config/vericto && chmod 700 ~/.config/vericto
printf '%s' 'postgres://vericto_agent_ro:…@db.example.com:5432/shop?sslmode=verify-full' > ~/.config/vericto/db.url
chmod 600 ~/.config/vericto/db.url

The buttons and commands mount that file read-only at /run/secrets/db.url and pass it with --database-url-file: the URL appears neither in the client's configuration nor in the Docker arguments.

3. Add the server

Use the Local, no account tab of Install in one click: buttons for Cursor and VS Code, the Claude Code command and the Claude Desktop configuration. On macOS and Windows, Docker Desktop reads the file as is. On Linux, Docker needs --user with your uid:gid to read a mode-600 file: the Claude Code command computes it with $(id -u):$(id -g), VS Code asks for it and the Cursor link uses 1000:1000 (change it in ~/.cursor/mcp.json if your uid:gid differs).

Keep the agent from reading the file on its own: in Claude Code, deny those tools in ~/.claude/settings.json.

"permissions": { "deny": ["Read(~/.config/vericto/**)", "Bash(psql:*)", "Bash(cat ~/.config/vericto/*)"] }

Troubleshooting

SymptomCauseWhat to do
401The Authorization header is missing, or the environment variable is empty.Check that VERICTO_API_KEY is exported in the shell you start the client from, and open a new session.
403The key lacks the ci_dryrun:execute scope.Create a key with that scope.
Rate limitedToo many calls in a short time.Wait the number of seconds the message gives.
Monthly CI-check allowance used upThis month's quota is used up.Wait for next month or upgrade. The read-only tools keep working.
Not enough CI checks leftThe call has more statements than checks left this month. Nothing was evaluated.Send at most the number of statements the message gives, or upgrade.
PARSE_ERRORAlmost always, the wrong dialect.Pass the right dialect; whoami shows it per database.