Skip to Content
dbmcp

YAML format

Structure of the dbmcp YAML config file, with an annotated example

The config file is a YAML mapping. Top-level keys are transport and log_level, plus the sections database, http, pii, and ssh. Every key is the YAML key listed in Configuration.

  • Keys are snake_case and strict: an unknown key is an error that names the file, line, and column, plus the keys accepted at that level.
  • Enum values are kebab-case and case-sensitive (backend: postgres, strict_host_key_checking: accept-new).
  • Durations are whole seconds as integers (query_timeout: 30).
  • Booleans are unquoted true / false. YAML 1.1 words stay strings, so an unquoted no is the string no (which is why strict_host_key_checking: no works). A quoted boolean string accepts the same set as env vars: true/false, 1/0, t/f, TRUE/FALSE, True/False.
  • Strings that YAML would read as a number or boolean need quotes (password: "12345"); a value of the wrong type is an error.
  • Null (key:, key: null, key: ~) means unset, as does an empty section (ssh:). An empty string at an integer, boolean, or list key (port: "", or an unset ${PORT}) also means unset, just like an empty DBMCP_* variable.
  • Lists are YAML sequences, or a comma-separated string (useful with ${}: allowed_hosts: ${HOSTS}), and replace the default wholesale. http.allowed_origins: [] disables server-side Origin validation; this is only expressible in YAML. http.allowed_hosts: [] and pii.categories: [] are rejected.
  • Tags other than the YAML core tags (!!str, !!int, …) are an error wherever they appear. Docker Compose's !reset and !override are not supported.
  • The http section is ignored unless transport is http; the other pii keys are ignored unless pii.enabled is true. Ignored values must still be valid: every value in the file is checked, as is every DBMCP_* value in the environment and env files.

A full annotated example:

# Top-level settings
transport: http          # stdio | http (default: stdio)
log_level: info          # error | warn | info | debug | trace

database:
  backend: postgres      # mysql | mariadb | postgres | sqlite
  host: db.internal      # resolved by the SSH server when tunnelling
  port: 5432             # default depends on backend
  user: app
  password: ${DB_PASSWORD:?DB_PASSWORD must be set}
  name: myapp            # for sqlite: a file path, relative to this file
  # charset: utf8mb4     # MySQL/MariaDB only
  ssl: true
  ssl_ca: certs/ca.pem   # relative to this file's directory
  ssl_verify_cert: true
  read_only: true        # default; write tools stay hidden
  max_pool_size: 5
  connection_timeout: 10 # seconds
  query_timeout: 30      # seconds; 0 disables
  max_query_timeout: 30  # largest readQuery `timeout`; defaults to query_timeout
  page_size: 100         # 1–500
  max_cell_chars: 4096   # per string value; 0 disables
  max_response_chars: 32000 # per response; 0 disables

http:                    # used only with transport: http
  host: 127.0.0.1
  port: 9001
  allowed_origins:
    - http://localhost:5173
  allowed_hosts: [localhost, 127.0.0.1, "::1"]
  auth_token: ${HTTP_TOKEN:?set HTTP_TOKEN}
  allow_unauthenticated: false

pii:
  enabled: true          # the other pii keys apply only when true
  operator: mask         # replace | mask | redact | hash
  categories: [financial, government]
  ner_enabled: false
  # ner_model: ~/models/bert-ner

ssh:
  host: bastion.example.com   # setting ssh.host enables the tunnel
  port: 22
  user: deploy
  key: ~/.ssh/id_ed25519
  # key_passphrase: ${SSH_KEY_PASSPHRASE}
  known_hosts: ~/.ssh/known_hosts
  strict_host_key_checking: yes  # yes | accept-new | no
  keepalive_interval: 30         # seconds; 0 disables
  # local_port: 15432