Commit Graph

2 Commits

Author SHA1 Message Date
Lucio Lelii a07931251b External sessions connect where the node says, not where the model says
The internal mode already took its whole connection from headers the catalog entry pins; the external one
let the model choose the endpoint, bucket, host and database in its open_session call. Now the catalog
entry sends them from the node's own configuration - x-minio-endpoint and x-minio-bucket,
x-postgres-host, x-postgres-port and x-postgres-database - pinned for the session like the internal
ones, and the model gives only the credentials. An external session still never creates a bucket or a
database: those must exist.

Without MINIO_MCP_ALLOWED_ENDPOINTS or POSTGRES_MCP_ALLOWED_HOSTS an external session reaches public
addresses only: loopback, private, link-local and metadata addresses are refused. For MinIO the check is
in the S3 client's own DNS lookup, at every connection it makes; for PostgreSQL the name is resolved and
checked, and the connection made to the address that was checked, the certificate still verified against
the name. With a list, exactly the listed destinations, private ones included. Before, an empty list let
MinIO reach anything and kept PostgreSQL's external mode off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:54:33 +02:00
Lucio Lelii da3f14e1fe Add postgres-mcp: SQL for a model, in a database of its own for each execution
Four tools - postgres_query (read-only, bounded in rows and bytes), postgres_execute, postgres_list_tables
and postgres_describe_table - in two modes chosen by the catalog entry, as for minio-mcp.

Internal: the session arrives with x-postgres-scope set to the execution's id, and the server makes a
database and a user <prefix><execution id> if they are not there, closes the database to everyone else
and connects as that user, so the model can do anything inside it and nothing outside. Checked on a real
PostgreSQL, as a catalog user who is not a superuser: it cannot switch role, make users or databases, read
the server's files or reach another execution's database. The password is derived from the name and a
secret shared with the workflow manager, whose storage nodes use the same convention; both test suites
assert the same known name and password.

External: the model opens a session with a host and credentials it is given. It is off until
POSTGRES_MCP_ALLOWED_HOSTS names the hosts it may use.

The client's query_timeout is not used: with a cursor it arms a timer that is never cleared and that,
when it fires, throws outside any handler and takes the server down.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-02 20:04:52 +02:00