Docs

Install mcpbus, connect SQL Server or PostgreSQL and choose what your AI assistant can reach, per server, database and time window.

Overview

mcpbus is a local MCP server that connects your AI assistant to SQL Server and PostgreSQL. Each connection gives its databases a level — schema, read or readwrite — and the assistant works within that level.

In each database mcpbus creates three database users without login, the mcpbus users, one per level. It runs the assistant's SQL as the matching user, so the database enforces the rights (on PostgreSQL, roles and wrapper functions that an administrator's setup script creates — see PostgreSQL). By default mcpbus also asks for approval before writes and hashes string values. Exceptions change access for one database, all databases or the whole server, permanently or for a limited time.

Requirements: Windows; SQL Server 2016 or later, Azure SQL Database, Azure SQL Managed Instance or PostgreSQL 16 or later; and Claude Code, Claude Desktop or VS Code.

Install

Run this in PowerShell:

irm https://mcpbus.sh/install.ps1 | iex

The script downloads the latest release to %LOCALAPPDATA%\mcpbus\bin\mcpbus.exe, checks its SHA-256 checksum and that Offe Consulting AB signed it, and runs setup. Setup needs Claude Code, Claude Desktop or VS Code on the computer. At the end the script offers to open the config UI.

To install by hand, download mcpbus.exe, place it in a permanent folder and run .\mcpbus.exe setup from there.

What setup does

  • Registers mcpbus with Claude Code, Claude Desktop and VS Code — the ones you have installed.
  • Pre-approves the mcpbus tools in Claude Code. Writes still follow your approval setting.
  • Adds mcpbus to your PATH and creates the config folder and the hashing key.
  • Keeps your connections, so you can run it again safely.

Next, add a connection and reconnect your client (/mcp in Claude Code).

Add a connection

Open the config UI:

mcpbus config

You can also ask your assistant to open it. Add a connection, pick the databases mcpbus may use, choose a level and save. The config UI runs locally on 127.0.0.1 and closes with its tab.

Each connection is stored as a file in %LOCALAPPDATA%\mcpbus\ named mcpbus.<name>.json, which you can also edit by hand or with mcpbus connection. Changes apply right away.

{
  "configVersion": 3,
  "name": "sales",
  "server": "sql01\\SQLEXPRESS",
  "auth": {
    "authType": "sqlAuth",
    "username": "reporting_user",
    "encryptedPassword": "<set with mcpbus encrypt-password sales>"
  },
  "databases": ["Sales", "Reporting"],
  "permissions": "read",
  "hashMode": true,
  "confirmMode": "prompt",
  "serverAccess": { "agentRead": false, "executeAsLogin": false }
}
databaseTypesqlserver (default) or postgresql — see PostgreSQL.
auth.authTypewindowsAuth (default), sqlAuth, azureAdInteractive, azureAdIntegrated or azureAdServicePrincipal (with clientId and the secret in encryptedPassword).
databasesThe user databases mcpbus may use, by exact name.
permissionsThe level for these databases: schema (default), read or readwrite.
hashModeHashes string and binary values in results. On by default.
confirmModeprompt (default), strict or off — see Writes & approval.
groupA label. list_connections and mcpbus connection list --group filter on it. When you name a group, the assistant runs your request on each connection in it, one call per connection.
disabledPauses the connection.
port, trustServerCertificateThe server port, and whether to trust a self-signed certificate (common on a default SQL Server install).
defaultRowLimitMaximum rows per result. Default 1,000, up to 100,000.
queryTimeoutSecondsTime limit for each tool call: the time its SQL and reads take on the server, together. Default 30; 0 means no limit.
connectTimeoutSecondsConnection timeout. Default 15, from 1 to 600.
additionalConnectionParametersExtra connection-string parameters. mcpbus rejects parameters that weaken security.
exceptionsAccess per database or time window — see Exceptions.

mcpbus reads each file strictly: an unknown or duplicated key turns that connection off until it is fixed. mcpbus treats keys starting with _ or $ as comments. configVersion is 3.

Store passwords and client secrets with mcpbus encrypt-password <name>. mcpbus encrypts them with Windows DPAPI.

Prepare databases

mcpbus creates the mcpbus users when you save in the config UI or run mcpbus database prepare <connection>. Your login needs db_owner, CONTROL on the database, or both db_securityadmin and db_accessadmin.

If it has none of these, prepare prints a setup script for a DBA to run; --script <file> saves it to a file instead. The script is safe to rerun and runs in one transaction.

For everyday use your login needs access to the database, VIEW DEFINITION and the right to impersonate the mcpbus users.

mcpbus checks the database's state on every call. mcpbus database list <connection> shows it:

preparedReady to use at its level.
not preparedThe mcpbus users are missing or out of date. Run prepare.
awaiting scriptWaiting for a DBA to run the setup script.
excessAn mcpbus user has rights beyond its level. Revoke the extra grant or role.
blockedTRUSTWORTHY is on for the database, or mcpbus can't read the setting. A DBA turns it off or makes it readable.
unreachablemcpbus can't reach or check the database, and shows why.

On PostgreSQL mcpbus creates nothing itself — see PostgreSQL.

When cross-database ownership chaining is on for the database or the server, mcpbus refuses read and readwrite calls there and the catalog tools keep working; database list shows it as a warning. mcpbus database remove deselects a database; add --script to get a script that removes its mcpbus users.

PostgreSQL

mcpbus supports PostgreSQL 16 or later, with standard_conforming_strings on and UTF8 encoding. It signs in as mcpbus_login with a user name and password, and runs the assistant's SQL through two wrapper functions: at read, query runs one SELECT as mcpbus_r in a read-only transaction; at readwrite, execute runs as mcpbus_rw. At schema only the catalog tools work. Before every call mcpbus checks the wrappers and roles and refuses the call if anything differs from the setup.

  1. Add the connection: mcpbus connection add shop --type postgresql --server pg01 --user mcpbus_login (port 5432 unless you give --port), or choose PostgreSQL in the config UI. Select the databases and the level there. Database names are case-sensitive.
  2. Write the setup script and give it to an administrator: mcpbus database prepare shop --script mcpbus-setup.sql, then psql -h pg01 -U <administrator> -d postgres -f mcpbus-setup.sql. It creates the roles once per server, and in each database the schema mcpbus, the wrappers and the grants. It is safe to rerun and ends with SETUP COMPLETE or SETUP INCOMPLETE.
  3. Set a password: ALTER ROLE mcpbus_login PASSWORD '…', and store it with mcpbus encrypt-password shop.
  4. Check with mcpbus database list shop or mcpbus status --test.

The administrator needs CREATEROLE, ownership of the database and of the application's tables (or membership in the role that owns them); a superuser also works. The SQL Agent tools, get_index_usage and get_query_plan are not available for PostgreSQL. Each call opens a new connection, and several statements in one execute run as one transaction.

Access levels

LevelThe assistant can
schemaRead the structure: objects, columns, keys and definitions. query reads the catalog views. This is the default.
readEverything in schema, plus reading data with query, query plans and index usage.
readwriteEverything in read, plus changing data and objects with execute.

Catalog tools run as mcpbus_schema, query reads data as mcpbus_r (at read and readwrite) and execute writes as mcpbus_rw. readwrite covers data and objects; schemas, users, roles and grants go through execute_as_login.

Each call runs in one database (the database parameter) on its own connection.

Exceptions & time windows

The connection sets the default. An exception changes it for one database, all databases or the whole server — for a set time or until you remove it. For example: read on one database until Friday, or readwrite for two hours.

"exceptions": {
  "databases": [
    { "database": "Reporting", "permissions": "readwrite",
      "from": "2026-11-10", "until": "2026-11-14T17:00" }
  ],
  "server": [
    { "agentRead": true, "until": "2026-11-10",
      "note": "Checking last night's failed jobs" }
  ]
}
  • A database exception sets permissions and hashMode for selected databases. "database": null covers all of them, and its hashMode also applies to execute_as_login, as does hashing turned on for a single database.
  • A server exception sets agentRead, executeAsLogin and hashMode, which then covers every selected database and execute_as_login.
  • A server exception can carry a note: your guidance to the assistant, up to 500 characters. While the exception is in force, mcpbus sends the note with every tool result on the connection; it restricts nothing. The config UI and the command line require a note when a server exception turns a switch on (see requireServerExceptionNote under Global ceiling). Database exceptions have no note.
  • from and until take a local date (yyyy-MM-dd, the whole day) or a date and time (yyyy-MM-ddTHH:mm). The exception ends on its own at until; leave until out to keep it until you remove it. Set active: false to pause it.

Exceptions in force replace the connection's settings. For the level, an exception that lowers it always wins; otherwise a database exception wins over an all-databases one. For hashing and switches, when several exceptions apply, hashing on wins and a switch that is off wins. The global ceiling applies last.

From the command line you can lower access: mcpbus exception add database sales --database Reporting --permissions schema --for 2h. Raising access is done in the config UI or the file, so an assistant that can run commands can't raise its own access.

Writes & approval

confirmMode sets how execute, execute_strict and execute_as_login ask for approval:

  • prompt (default) — the assistant shows you the SQL and runs it after you approve. It shows the whole statement, never a summary; a statement longer than 7 lines may be shown on one line. The assistant asks for the approval, so it relies on the assistant following the rule.
  • strict — writes go through their own tool, execute_strict, and your client asks you before each one runs, so the assistant can't answer it. In Claude Code — in a terminal and in the Code tab of the Claude desktop app — that is Claude Code's own approval prompt with the whole statement, in every permission mode and whatever the tool permissions setup grants. Other clients are asked to show an approval dialog; clients without one refuse writes in strict, so use prompt there. A statement too long to show whole, or with invisible characters, is refused.
  • off — execute runs statements without approval.

The level sets the limits; approval is an extra check. execute_as_login asks for every statement, reads included — also under off, as under prompt, while executeAsLoginAlwaysConfirm in the global file is on (the default). Set it to false and execute_as_login follows confirmMode.

Each call runs one batch, so mcpbus refuses GO lines. Commit in the same call: mcpbus rolls back a transaction left open and reports it.

Hashing

With hashMode on (the default), string and binary values in results from query, execute and execute_as_login become 16-character one-way tokens; numbers, dates, times, booleans and GUIDs are shown as they are. The same value always gives the same token, so the assistant can still join, group and compare. Tokens are keyed with mcpbus.key in the config folder, so they stay the same when you copy the folder to a new computer. mcpbus withholds messages and PRINT output. It passes SQL Server's own error numbers through and withholds numbers that a statement sets itself (RAISERROR, THROW).

Column names, definitions, index usage and SQL Agent job details appear unhashed. Hashing keeps values out of the conversation. It does not stop a determined user from inferring values, because filters run on the real values.

Server access

Two switches under serverAccess extend mcpbus beyond the selected databases. Both are off by default.

  • executeAsLogin turns on execute_as_login: SQL as your own login, with all its rights, in any database — for linked servers, cross-database work, schemas and grants. It asks for approval as execute does, and by default also under confirmMode off — see Writes & approval.
  • agentRead turns on the SQL Agent tools, read-only and run as your login. The login needs SELECT on msdb's sysjobs, sysjobsteps, sysjobhistory and syscategories. For schedules, last run, operators and proxies, get_job also reads sysjobservers, sysjobschedules, sysschedules, sysoperators and sysproxies, and reports any it can't read. get_job shows job steps as written, including any credentials in them.

Global ceiling

An optional mcpbus.global.json in %LOCALAPPDATA%\mcpbus\ sets limits for every connection:

  • maxLevel caps the level. Below readwrite it also turns off executeAsLogin.
  • hashMode: true requires hashing.
  • defaultRowLimit and queryTimeoutSeconds apply when they are stricter than the connection's.

Two more keys are set only in this file; the config UI and the command line can't change them:

  • executeAsLoginAlwaysConfirm — true (the default): execute_as_login asks before every statement, also on a connection with confirmMode off. false: it follows the connection's confirmMode. execute always follows confirmMode.
  • requireServerExceptionNote — true (the default): the config UI and mcpbus exception save a new or changed server exception that turns agentRead or executeAsLogin on only with a note. false: no note is required. It never changes access.

configVersion 3 is required. If the file has an error, no connection starts until it is fixed.

Known limitations

mcpbus guards against an AI assistant that makes mistakes or goes too far, with SQL Server enforcing the levels. A few things remain visible or possible at every level:

  • What SQL Server shows everyone: rights granted to public, backup history in msdb, host details such as machine name and disks, and names of other databases and objects, inferred from error messages.
  • Query Store can show the text of other users' queries.
  • At schema, a few catalog views show values derived from data, such as identity values and row counts.
  • With an application role's password, the assistant can take that role's rights.
  • An existing procedure or function declared EXECUTE AS OWNER runs with its owner's rights when the assistant calls it.
  • At readwrite, the assistant can change procedures and triggers that others run with their own rights.

Tools

ToolDescriptionNeedsRuns as
list_connectionsLists connections and their databases, with level, hashing, switches and active exceptions.always—
get_server_infoShows server name, version, edition and patch level, and what the connection allows.alwaysyour login (when connecting)
list_objectsLists tables, views, procedures, triggers, databases or foreign keys, page by page.schemamcpbus_schema; databases: your login
get_schemaShows a table's columns; detail=full adds indexes, keys and constraints.schemamcpbus_schema
get_definitionReturns the CREATE text of a procedure, function, view or trigger.schemamcpbus_schema
queryRuns one read-only SELECT in one database: catalog views at schema, data from read.schemamcpbus_schema, or mcpbus_r from read
get_query_planReturns the query plan as Showplan XML. Estimated by default; actual plans need hashing off.readmcpbus_r
get_index_usageShows index usage and suggested indexes. Needs VIEW SERVER STATE.readyour login
executeChanges data or objects.readwritemcpbus_rw
execute_strictChanges data or objects on a connection with confirmMode strict.readwritemcpbus_rw
execute_as_loginRuns SQL as your own login, in any database.executeAsLoginyour login
list_jobsLists SQL Agent jobs on the server.agentReadyour login
get_jobShows one job: owner, steps with their commands, proxy and run-as user, schedules, last and next run, notifications.agentReadyour login
get_job_historyShows run history, newest first: 100 runs by default, with steps when you name a job.agentReadyour login
reload_configReloads the configuration; retryRefusedLogins retries a refused login.always—
open_configOpens the config UI.always—
check_for_updateReports whether a newer version is available.always—

execute appears in the tool list when a database is at readwrite (execute_strict when its connection is strict), and execute_as_login when executeAsLogin is on. SQL Server errors 229, 262, 916 and 15274 mean the level refused the statement.

Limits

  • defaultRowLimit is the maximum per result, even when rowLimit or TOP asks for more. Results flag truncation (wasTruncated, hasMore).
  • query returns only the first result set.
  • list_objects returns 500 items per page by default, up to 5,000 per page.
  • Up to 3 calls run at once per server, 4 in total.
  • Temp tables, SET options and transactions last for one call.
  • If the server stops responding during execute, the rollback can take up to about 15 seconds.

Command line

mcpbus setupRegisters mcpbus with your MCP clients.
mcpbus config [<connection>]Opens the config UI.
mcpbus status [--test]Checks the config and registrations; --test also checks every connection and database.
mcpbus connection list|show|test|add|set|removeManages connections; set can only lower access.
mcpbus database list|prepare|removeShows database states, creates the mcpbus users or deselects a database.
mcpbus exception list|show|add|set|removeManages exceptions, with --from, --until or --for 2h.
mcpbus encrypt-password <name>Stores a password or client secret, encrypted for your Windows user.
mcpbus logs [--tail] [--changes] [-n <count>]Shows the log; --changes shows the history of config changes.
mcpbus telemetry show|on|offShows the usage count, or turns it on or off.
mcpbus uninstall [--remove-data]Removes mcpbus from your clients and PATH; --remove-data also removes its data.
mcpbus version · completion · help [<command>]Shows the version, sets up PowerShell tab completion, and shows help.

Short forms: conn, db, exc. Exit codes: 0 success, 1 failure, 2 usage error. mcpbus help <command> lists every option.

Updates & usage count

To update, run mcpbus update (from version 1.3.2), run the install command again, or download mcpbus.exe and run mcpbus setup. Then reconnect your client. check_for_update tells you when a new version is available.

mcpbus sends two things to the mcpbus service at api.mcpbus.sh: an update check, and once a day a usage count with the version and the database engines your connections use — no name or contact details, only a random install ID. The telemetry command controls the usage count: mcpbus telemetry show prints it, and mcpbus telemetry off, MCPBUS_NO_TELEMETRY or DO_NOT_TRACK turns it off. See Privacy.

Move to a new computer

Install mcpbus, copy the config folder, run mcpbus encrypt-password <name> for each SQL login and service principal, then run mcpbus setup.

Uninstall

mcpbus uninstall removes mcpbus from your clients, the Claude Code tool permission and PATH. It keeps mcpbus.exe and your data.

mcpbus uninstall --remove-data first saves a script to Documents that a DBA can run to remove the mcpbus users. It then shows what it will delete and removes %LOCALAPPDATA%\mcpbus\.

Troubleshooting

Start here

mcpbus status --test checks the config, the client registrations, every connection and every database. The log at %LOCALAPPDATA%\mcpbus\logs\mcpbus.log (mcpbus logs) records connections, databases, users and errors, and leaves out SQL, object names, data and credentials.

A new connection reaches nothing

New connections start at schema with no databases. Select databases and prepare them.

A database shows not prepared, excess or blocked

See the states under Prepare databases; each one lists its fix.

Login failed (18456)

Store the correct password with mcpbus encrypt-password <name>; mcpbus tries it right away. Each mcpbus process tries a refused login only once, so retries won't lock the account. If you fix the login on the server, ask the assistant to run reload_config with retryRefusedLogins, or restart the client.

"Try again shortly"

The server or database is starting, paused or busy; a paused Azure SQL database takes about a minute to wake. mcpbus retries after 5, 15 and 60 seconds, then every 5 minutes. reload_config retries right away.

Certificate error

Turn on trustServerCertificate for a self-signed certificate — in the file, in the config UI, or with --trust-cert on when you add the connection.

execute is missing

execute appears when a database is at readwrite and the global maxLevel allows it. mcpbus updates the tool list automatically; if your client doesn't pick it up, reconnect (/mcp in Claude Code).

Strict mode refuses writes

On a strict connection the assistant writes with execute_strict; execute rejects it. In a client that shows neither its own approval prompt nor approval dialogs, use prompt — see Writes & approval.

"configuration error"

An unknown or duplicated key, an invalid value, or a configVersion other than 3 — recreate such a file with mcpbus connection add. mcpbus logs shows which.

The wrong mcpbus runs

Setup prints the path of the mcpbus.exe it registered. In PowerShell, run .\mcpbus.exe from that folder.