C1 Identity & least privilege
Minimal 0.25 / 1.00
The server connects to Postgres with whatever database user and password the operator puts in environment variables and uses that one static credential for every tool call, reads and writes alike. Nothing in the server narrows it, and in the default stdio mode there is no per-caller authorization at all. An opt-in feature (auth services with authRequired tools and parameters filled from verified ID-token claims) can tie individual custom tools to an authenticated caller over HTTP, but it never narrows the database credential and tools without authRequired stay open. For the Cloud SQL, AlloyDB and BigQuery prebuilts the server instead uses the operator's Application Default Credentials.
C2 Approval gates
Minimal 0.33 / 1.00
As a tool server, Toolbox leaves approval to the MCP host and its contribution is risk signalling. Every postgres tool carries MCP annotations: execute_sql is marked destructive and the catalog/listing tools read-only, and other config-defined SQL tools default to destructive. But the main SQL tool mixes reads and writes, there is no read-only SQL tool or dry-run, and the plain postgres source has no server-enforced read-only mode (Cloud SQL, AlloyDB and BigQuery sources do, opt-in). A wrongly approved execute_sql call can DROP or DELETE production data irreversibly.
C3 Tool & action scoping
Minimal 0.33 / 1.00
Toolbox has a real argument-validation mechanism: typed parameters and fixed SQL statements that receive arguments as bind parameters ($1), which is how most of the 29 prebuilt postgres tools work. However, the default tool set also includes execute_sql, which runs any SQL the model writes, and get_query_plan, which pastes a model string into the statement with a Go text template (its own description warns about SQL injection). Toolsets can be selected with --prebuilt=postgres/<toolset>, but the default loads every tool, so the agent can touch any table the credential reaches.
C4 Code-execution isolation
Minimal 0.05 / 1.00
The code-execution surface here is SQL: execute_sql (and the template-built get_query_plan) send model-written statements straight to the database through the connection pool. There is no isolation boundary: no read-only transaction, statement-type filter, or sandboxed role is applied for the postgres source, and nothing is opt-in either. What that SQL can reach is the whole database under the configured login; with a superuser login Postgres features such as COPY ... PROGRAM extend that to the database host.
C5 Untrusted input blast radius
Minimal 0.07 / 1.00
Database rows can contain attacker-written text (customer records, comments, tickets), and Toolbox returns them to the model as plain JSON text with nothing marking them as untrusted. The same default session can read sensitive data and run destructive SQL, so a successful injection could make the host read data and delete or alter it with no server-side barrier. The server offers no read-only or no-write mode for postgres that would drop one of those legs.
C6 Memory, context & configuration integrity
N/A · full credit 1.00 / 1.00
In the scored configuration (--prebuilt=postgres) the tool definitions come from YAML embedded in the binary and the connection settings come from the process environment; the server keeps no memory, writes nothing back, and loads no workspace files. Note that a different mode behaves differently: when started with neither --prebuilt nor --config, the server loads tools.yaml from the current directory and watches it for changes, so a launch from inside an untrusted repository would take that repository's tool definitions.
C7 Third-party extensions
N/A · full credit 1.00 / 1.00
The server loads no third-party code at runtime in the scored configuration: tool types and database drivers are compiled into the Go binary, and the prebuilt configs are embedded. It does not launch other MCP servers, install packages, or load plugins. The only process spawn in the codebase is the optional Dataform compile-local tool, which is not part of the postgres prebuilt.
C8 Secrets & sensitive-data protection
Minimal 0.25 / 1.00
The database password arrives through an environment variable and is kept as a plain string in the source config and the connection URL; there is no secret type or redaction layer in the server. It is not sent to the model, telemetry export is opt-in, and the default info log level does not record SQL or parameters. Debug logging, which is a single flag away, logs full SQL text and parameters unredacted, and query results (which may contain sensitive data) go to the model unfiltered.
C9 Audit & traceability
Minimal 0.28 / 1.00
In the default configuration, tool calls leave no record: the tool name and parameters are only logged at debug level, the default level is info, and in stdio mode there is no request log. OpenTelemetry tracing is built in and creates a span per tool call with the tool name, but exporters are off unless the operator passes --telemetry-otlp or --telemetry-gcp, and the spans do not include arguments or caller identity. There is no tamper-evident audit trail.
C10 Limits & kill switch
Minimal 0.25 / 1.00
For the postgres source the server puts no time, row or size bound on queries: execute_sql runs until the database finishes, results are fully buffered, and the server has no MCP cancellation handling. Some listing tools take an optional limit with a default of 50, but the caller can raise it. An operator can add a statement_timeout through POSTGRES_QUERY_PARAMS, but it is empty by default. Other sources do better (BigQuery caps rows at 50 by default and supports a billing limit).