Configuration
Configure dbmcp with CLI flags, environment variables, and backend-specific defaults
Database MCP is configured through CLI flags and environment variables. This page documents every available option.
Precedence
Configuration values are resolved in this order (highest priority first):
- CLI flags — explicitly passed on the command line
- Environment variables — set by the MCP client (via
envorenvFilein server config) - Built-in defaults — backend-aware defaults described below
When the same option is set in multiple places, the higher-priority source wins.
Database Connection
| CLI Flag | Environment Variable | Default | Description |
|---|---|---|---|
--db-backend | DB_BACKEND | mysql | Database backend: mysql, mariadb, postgres, sqlite |
--db-host | DB_HOST | localhost | Database host |
--db-port | DB_PORT | Backend-dependent | Database port (see Backend Defaults) |
--db-user | DB_USER | Backend-dependent | Database user (see Backend Defaults) |
--db-password | DB_PASSWORD | — | Database password |
--db-name | DB_NAME | — | Database name, or file path for SQLite |
Character Set
| CLI Flag | Environment Variable | Default | Description |
|---|---|---|---|
--db-charset | DB_CHARSET | — | Character set (MySQL/MariaDB only) |
Backend Defaults
Default values for --db-port and --db-user depend on the selected backend:
| Backend | Default Port | Default User |
|---|---|---|
| MySQL | 3306 | root |
| MariaDB | 3306 | root |
| PostgreSQL | 5432 | postgres |
| SQLite | N/A | N/A |
SQLite does not use host, port, or user — only --db-name (the file path) is required.
SSL / TLS
| CLI Flag | Environment Variable | Default | Description |
|---|---|---|---|
--db-ssl | DB_SSL | false | Enable SSL for the database connection |
--db-ssl-ca | DB_SSL_CA | — | Path to CA certificate |
--db-ssl-cert | DB_SSL_CERT | — | Path to client certificate |
--db-ssl-key | DB_SSL_KEY | — | Path to client key |
--db-ssl-verify-cert | DB_SSL_VERIFY_CERT | true | Verify the server certificate |
When --db-ssl is enabled, the server validates that any provided certificate paths exist before connecting.
Server Behavior
| CLI Flag | Environment Variable | Default | Description |
|---|---|---|---|
--db-read-only | DB_READ_ONLY | true | Enable read-only mode |
--db-max-pool-size | DB_MAX_POOL_SIZE | 5 | Maximum database connection pool size |
--db-connection-timeout | DB_CONNECTION_TIMEOUT | — | Connection timeout in seconds |
--db-query-timeout | DB_QUERY_TIMEOUT | 30 | Query execution timeout in seconds |
--db-page-size | DB_PAGE_SIZE | 100 | Max items per paginated tool response (range 1–500) |
--log-level | LOG_LEVEL | info | Log level: error, warn, info, debug, trace |
Security note: Read-only mode is enabled by default. In this mode, write tools (
writeQuery,createDatabase) are hidden from the AI assistant. Only read tools are available, andreadQueryenforces SQL validation (SELECT,SHOW,DESCRIBE,USE,EXPLAINonly). Set--db-read-only=falseorDB_READ_ONLY=falseto enable write tools.
The page size applies uniformly to every paginated tool; see the Cursor Pagination section on the Features page for the full protocol.
HTTP Transport
These options are available only when running in HTTP mode (dbmcp http):
| CLI Flag | Default | Description |
|---|---|---|
--host | 127.0.0.1 | Bind host for the HTTP server |
--port | 9001 | Bind port for the HTTP server |
--allowed-origins | http://localhost,http://127.0.0.1,https://localhost,https://127.0.0.1 | Allowed browser origins (comma-separated). Drives both CORS preflight and server-side Origin header rejection. |
--allowed-hosts | localhost,127.0.0.1,::1 | Allowed host names (comma-separated). Enforced server-side; HTTP/2 :authority is honored. |
A transport subcommand is required — running dbmcp with no subcommand prints usage help and exits with a non-zero status. The stdio transport requires no additional configuration beyond the database options above.
PII
Database MCP can rewrite detected PII spans inside query tool output. The feature is opt-in and off by default — applies to query tool response payloads (readQuery and any future query tools that route through the redactor) and is not applied to logs, errors, schema-discovery responses, or tool arguments. See Features for the supported entity list.
| CLI Flag | Environment Variable | Default | Description |
|---|---|---|---|
--pii | PII_ENABLE | false | Enable PII redaction of query tool output |
--pii-operator | PII_OPERATOR | replace | Operator applied to detected PII spans |
--pii-categories | PII_CATEGORIES | unset (all built-ins) | Comma-separated category subset for the analyzer registry |
--pii-ner | PII_NER_ENABLE | false | Enable the optional ML/NER pass (person, location, organization, NRP & facility detection) |
--pii-ner-model | PII_NER_MODEL | unset | Path to the NER model directory (required with --pii-ner) |
Operator Values
--pii-operator accepts one of the following values:
replace— replace each detected span with an entity-aware placeholder (for example, anEMAIL_ADDRESSmatch becomes<EMAIL_ADDRESS>)mask— mask each detected span with*(length-preserving)redact— remove each detected span (replace with empty string)hash— replace each detected span with a stable hex digest (SHA-256)
Category Values
--pii-categories accepts a comma-separated list of kebab-case category names. Leaving the flag unset enables every built-in recogniser; passing a subset narrows the analyzer registry to recognisers tagged with at least one of the selected categories.
personal—EMAIL_ADDRESSfinancial—BANK_ACCOUNT_UK,CREDIT_CARD,CVV,IBAN_CODE,ROUTING_NUMBER_US,SORT_CODE_UKgovernment—ITIN,NHS_NUMBER,NINO_UK,PASSPORT_UK,PASSPORT_US,SIN_CA,TAX_ID_EIN,US_SSN,VAT_NUMBERcontact—PHONE_NUMBERnetwork—IP_ADDRESS,MAC_ADDRESS,URLdigital-identity—API_KEY,JWT_TOKEN,PRIVATE_KEYcrypto—CRYPTO
An empty list is rejected at startup. If the selected categories produce an empty registry, the analyzer falls back to the default registry and logs a warning so redaction is never silently disabled.
ML/NER pass (person, location, organization, NRP & facility)
The regex/checksum recognisers cannot catch free-form person names, place names, organizations, nationality/religious/political groups, or facilities — those have no fixed pattern. An optional machine-learning Named Entity Recognition (NER) pass adds PERSON, LOCATION, ORGANIZATION, NATIONALITY_RELIGION_POLITICS, and FACILITY detection on top of the regex layer. Which entities a given model can produce depends on its label set: a CoNLL model (e.g. dslim/bert-base-NER) yields person/location/organization, while an OntoNotes-class model additionally yields NRP and facility.
It is opt-in at runtime: the ML/NER code is always built into the binary, but stays inactive until both --pii and --pii-ner are enabled and a model directory is supplied.
Inference uses ONNX Runtime — there is no external runtime library to install: you need only the dbmcp binary and a model directory. The directory must contain:
config.json(with anid2labelmap exposing at least one supported NER label:PER/PERSON,LOC/GPE,ORG/ORGANIZATION,NORP/NRP, orFAC)tokenizer.jsonmodel.onnx
Any other files in the directory are ignored — dbmcp reads only these three.
Set up a model locally
The quickest path is to download a model that has already been exported to ONNX. The steps below use the recommended English model, optimum/bert-base-NER — an ONNX export of dslim/bert-base-NER (MIT licensed). It uses CoNLL labels, so it detects PERSON, LOCATION, and ORGANIZATION; protectai/bert-base-NER-onnx is an equivalent alternative. NRP and facility detection require an OntoNotes-class model. v1 is English-only, but the pipeline is model-agnostic — any directory with the three files above works.
Note: These pre-exported models are full-precision (fp32, ~430 MB). They need no Python toolchain to obtain, but an int8-quantized export is smaller and faster at inference if you can produce one.
1. Download the model into a local directory — either with the Hugging Face CLI (pip install huggingface_hub):
hf download optimum/bert-base-NER \
--include config.json tokenizer.json model.onnx \
--local-dir ./models/bert-ner--include fetches only the three required files and skips the rest.
or with git + Git LFS (the model.onnx weights are LFS-tracked):
git lfs install
git clone https://huggingface.co/optimum/bert-base-NER ./models/bert-neror manually from the browser — open the model's Files and versions tab on Hugging Face and download config.json, tokenizer.json, and model.onnx with the download icon next to each, saving all three into one directory (e.g. ./models/bert-ner).
2. Confirm the required files are present:
ls ./models/bert-ner
# config.json model.onnx tokenizer.json (plus vocab.txt, tokenizer_config.json, … — ignored)3. Start dbmcp with the NER pass enabled, pointing at the directory:
dbmcp stdio --db-backend sqlite --db-name app.db \
--pii true --pii-ner true --pii-ner-model ./models/bert-ner4. Verify it loaded. Loading is fail-closed: a missing file or an unusable model makes the server refuse to start, so a clean startup means the model loaded. To confirm the pass is rewriting output, run a readQuery over a column holding a person or place name and check the value comes back as <PERSON> / <LOCATION> (with the default replace operator).
Behaviour notes:
- Fail-closed. If
--pii-neris set but the model cannot be loaded, the server refuses to start. If inference fails mid-request, that request errors — it never silently falls back to regex-only. - Category-aware. The NER pass respects
--pii-categories:PERSON,ORGANIZATION, andNATIONALITY_RELIGION_POLITICSare emitted only whenpersonalis selected;LOCATIONandFACILITYonly whencontactis. With no subset (the default), all apply. When the subset selects neither category, the model is not loaded at all.
Default: redaction is off. Setting
PII_ENABLE=true(or--pii true) is the only way to activate the redactor —PII_OPERATOR,PII_CATEGORIES, and thePII_NER_*flags alone have no effect.
Client Configuration Examples
MCP clients configure servers through JSON files. Each tool uses a slightly different file path, but the format is nearly identical. The examples below connect to a local MySQL database.
Claude Code
Create a .mcp.json file in your project root:
{
"mcpServers": {
"dbmcp": {
"command": "dbmcp",
"args": ["stdio"],
"env": {
"DB_BACKEND": "mysql",
"DB_HOST": "localhost",
"DB_USER": "root",
"DB_PASSWORD": "secret",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Claude Code also supports HTTP transport for remote servers:
{
"mcpServers": {
"dbmcp": {
"type": "http",
"url": "http://127.0.0.1:9001/mcp"
}
}
}File locations: .mcp.json (project, shareable) · ~/.claude.json (user, global)
Using Docker:
{
"mcpServers": {
"dbmcp": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "DB_BACKEND", "-e", "DB_HOST", "-e", "DB_USER",
"-e", "DB_PASSWORD", "-e", "DB_NAME",
"ghcr.io/haymon-ai/dbmcp"
],
"env": {
"DB_BACKEND": "postgres",
"DB_HOST": "host.docker.internal",
"DB_USER": "postgres",
"DB_PASSWORD": "secret",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Claude Desktop
Edit the config file at:
- Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"dbmcp": {
"command": "dbmcp",
"args": ["stdio"],
"env": {
"DB_BACKEND": "postgres",
"DB_HOST": "localhost",
"DB_USER": "postgres",
"DB_PASSWORD": "secret",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Using Docker:
{
"mcpServers": {
"dbmcp": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "DB_BACKEND", "-e", "DB_HOST", "-e", "DB_USER",
"-e", "DB_PASSWORD", "-e", "DB_NAME",
"ghcr.io/haymon-ai/dbmcp"
],
"env": {
"DB_BACKEND": "postgres",
"DB_HOST": "host.docker.internal",
"DB_USER": "postgres",
"DB_PASSWORD": "secret",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Claude Desktop only supports stdio transport. For HTTP mode, use the Connectors UI under Settings > Connectors > Add custom connector.
Cursor
Create .cursor/mcp.json in your project root, or use ~/.cursor/mcp.json for global configuration:
{
"mcpServers": {
"dbmcp": {
"type": "stdio",
"command": "dbmcp",
"args": ["stdio"],
"env": {
"DB_BACKEND": "mysql",
"DB_HOST": "localhost",
"DB_USER": "root",
"DB_NAME": "myapp"
},
"envFile": ".env"
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Using Docker:
{
"mcpServers": {
"dbmcp": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "DB_BACKEND", "-e", "DB_HOST", "-e", "DB_USER",
"-e", "DB_PASSWORD", "-e", "DB_NAME",
"ghcr.io/haymon-ai/dbmcp"
],
"env": {
"DB_BACKEND": "mysql",
"DB_HOST": "host.docker.internal",
"DB_USER": "root",
"DB_NAME": "myapp"
},
"envFile": ".env"
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Cursor supports envFile to load variables from a .env file. Sensitive values like DB_PASSWORD can be kept there instead of in the JSON config.
Windsurf
Edit the config file at:
- Linux:
~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"dbmcp": {
"command": "dbmcp",
"args": ["stdio"],
"env": {
"DB_BACKEND": "mysql",
"DB_HOST": "localhost",
"DB_USER": "root",
"DB_PASSWORD": "${env:DB_PASSWORD}",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Using Docker:
{
"mcpServers": {
"dbmcp": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "DB_BACKEND", "-e", "DB_HOST", "-e", "DB_USER",
"-e", "DB_PASSWORD", "-e", "DB_NAME",
"ghcr.io/haymon-ai/dbmcp"
],
"env": {
"DB_BACKEND": "mysql",
"DB_HOST": "host.docker.internal",
"DB_USER": "root",
"DB_PASSWORD": "${env:DB_PASSWORD}",
"DB_NAME": "myapp"
}
}
}
}To enable PII redaction, add "PII_ENABLE": "true" and optionally "PII_OPERATOR": "<replace|mask|redact|hash>" (and "PII_CATEGORIES": "<personal,financial,...>" to scope detection) to the env map.
Windsurf supports ${env:VARIABLE_NAME} interpolation to reference values from your shell environment instead of hardcoding them.
Environment Variables vs. envFile
| Feature | Claude Code | Claude Desktop | Cursor | Windsurf |
|---|---|---|---|---|
env object | Yes | Yes | Yes | Yes |
envFile | No | No | Yes | No |
| Variable interpolation | ${VAR} | No | ${env:VAR} | ${env:VAR} |
| HTTP transport in config | Yes | No | Yes | Yes |
| Project-scoped config | Yes | No | Yes | No |