Document that external sessions take their destination from the node
The MinIO endpoint and bucket, and the PostgreSQL host, port and database, come from the node's configuration through the catalog entry; without an allowlist only public addresses are reachable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ea6e6ac443
commit
52f8d653e7
|
|
@ -50,7 +50,7 @@ Generate a token with `openssl rand -hex 32`.
|
|||
|---|---|---|
|
||||
| `MINIO_MCP_INTERNAL_BUCKET_PREFIX` | `exec-` | Every internal-mode bucket is `<prefix><execution id>`. Cannot be empty; at most 27 lowercase letters, digits or `-`. It is the boundary that keeps the API key inside buckets this server made. |
|
||||
| `MINIO_MCP_INTERNAL_BUCKET_EXPIRE_DAYS` | `7` | Lifecycle rule set on an execution's bucket when this server creates it: objects are deleted that many days after they were written. `0` sets none. The empty bucket stays. Needs permission to set a bucket lifecycle; if refused, the session still opens and a warning is logged. |
|
||||
| `MINIO_MCP_ALLOWED_ENDPOINTS` | empty (any) | Comma-separated S3 origins, e.g. `https://s3.example.org`. **Set it on an exposed server.** It applies to both modes, so the internal MinIO's endpoint must be on it. |
|
||||
| `MINIO_MCP_ALLOWED_ENDPOINTS` | empty (public addresses) | Comma-separated S3 origins, e.g. `https://s3.example.org`. In external mode the endpoint comes from the node's configuration (`x-minio-endpoint`); empty, any **public** address is reachable and private, loopback and metadata ones are refused at every connection; set, exactly the listed origins, private ones included. It applies to both modes, so when set the internal MinIO's endpoint must be on it. |
|
||||
| `MINIO_MCP_DEFAULT_REGION` | `us-east-1` | Region when a session names none. |
|
||||
| `MINIO_MCP_MAX_OBJECT_BYTES` | `1048576` (1 MiB) | Limit for one read and one write. Ceiling 32 MiB. |
|
||||
| `MINIO_MCP_MAX_CONNECTIONS_PER_SESSION` | `8` | External mode only. Ceiling 64. |
|
||||
|
|
@ -65,7 +65,7 @@ The internal MinIO's endpoint and keys are **not** variables here: they are head
|
|||
|---|---|---|
|
||||
| `POSTGRES_MCP_API_KEYS` | none, **required** | Bearer tokens, as for the other servers; at least 32 characters each. |
|
||||
| `POSTGRES_MCP_INTERNAL_DATABASE_PREFIX` | `exec_` | Every internal-mode database, and its user, is `<prefix><execution id>` with the id's dashes as underscores. Cannot be empty; at most 26 lowercase letters, digits or `_`, starting with a letter. It is the boundary that keeps the API key inside databases this server made. |
|
||||
| `POSTGRES_MCP_ALLOWED_HOSTS` | empty | Comma-separated host names this server may connect to. **The external mode is off while it is empty**: the model could otherwise aim the server at any address it reaches. For the internal mode it is optional; when set, the platform's PostgreSQL host has to be on it. |
|
||||
| `POSTGRES_MCP_ALLOWED_HOSTS` | empty (public addresses) | Comma-separated host names this server may connect to. In external mode the host and port come from the node's configuration (`x-postgres-host`, `x-postgres-port`); empty, any **public** address is reachable and private, loopback and metadata ones are refused; set, exactly the listed hosts, private ones included. For the internal mode it is optional; when set, the platform's PostgreSQL host has to be on it. |
|
||||
| `POSTGRES_MCP_MAX_ROWS` | `1000` | Most rows one query returns, whatever the model asks. Ceiling 10000. |
|
||||
| `POSTGRES_MCP_MAX_RESULT_BYTES` | `1048576` (1 MiB) | Most bytes of rows one statement returns; the rest is cut and the answer says so. Ceiling 16 MiB. |
|
||||
| `POSTGRES_MCP_STATEMENT_TIMEOUT_MS` | `30000` | A statement running longer is stopped by the server. Ceiling 10 minutes. |
|
||||
|
|
@ -210,7 +210,7 @@ cannot be set through `.env`. Defaults shown are the ones in the code.
|
|||
| `MINIO_MCP_API_KEYS` | none, **required** | |
|
||||
| `MINIO_MCP_INTERNAL_BUCKET_PREFIX` | `exec-` | See above. |
|
||||
| `MINIO_MCP_INTERNAL_BUCKET_EXPIRE_DAYS` | `7` | See above. |
|
||||
| `MINIO_MCP_ALLOWED_ENDPOINTS` | empty (any) | |
|
||||
| `MINIO_MCP_ALLOWED_ENDPOINTS` | empty (public addresses) | |
|
||||
| `MINIO_MCP_DEFAULT_REGION` | `us-east-1` | |
|
||||
| `MINIO_MCP_MAX_OBJECT_BYTES` | `1048576` | Ceiling 32 MiB. |
|
||||
| `MINIO_MCP_MAX_CONNECTIONS_PER_SESSION` | `8` | Ceiling 64. |
|
||||
|
|
@ -226,7 +226,7 @@ cannot be set through `.env`. Defaults shown are the ones in the code.
|
|||
|---|---|---|
|
||||
| `POSTGRES_MCP_API_KEYS` | none, **required** | |
|
||||
| `POSTGRES_MCP_INTERNAL_DATABASE_PREFIX` | `exec_` | See above. |
|
||||
| `POSTGRES_MCP_ALLOWED_HOSTS` | empty | See above: empty turns the external mode off. |
|
||||
| `POSTGRES_MCP_ALLOWED_HOSTS` | empty (public addresses) | See above. |
|
||||
| `POSTGRES_MCP_MAX_ROWS` | `1000` | Ceiling 10000. |
|
||||
| `POSTGRES_MCP_MAX_RESULT_BYTES` | `1048576` | Ceiling 16 MiB. |
|
||||
| `POSTGRES_MCP_STATEMENT_TIMEOUT_MS` | `30000` | |
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ them, so a server running it needs neither the sources nor a build toolchain.
|
|||
| `luciolelii/coding-agent-mcp` | Scoped workspace editing. Task execution is disabled in this stack. |
|
||||
| `luciolelii/dev-server-mcp` | Authenticated facade for a private, allowlisted development-server worker. One instance per execution, each in a throwaway copy of that execution's tree and on its own port. The same image runs the facade and the worker. |
|
||||
| `luciolelii/browser-mcp` | Playwright automation restricted to exact allowed origins. |
|
||||
| `luciolelii/minio-mcp` | Bounded list/read/stat/write access to object storage, with no delete tool. In internal mode (catalog entry `minio-mcp-internal`, header `x-minio-scope`) it uses the platform's MinIO whose endpoint and keys the catalog entry sends as headers, and one bucket per execution, `<MINIO_MCP_INTERNAL_BUCKET_PREFIX><execution id>`, created when the session opens; in external mode the model opens session-scoped connections to MinIO deployments itself. |
|
||||
| `luciolelii/postgres-mcp` | SQL access to PostgreSQL: `postgres_query` (read-only, bounded rows), `postgres_execute`, `postgres_list_tables` and `postgres_describe_table`. In internal mode (catalog entry `postgres-mcp-internal`, header `x-postgres-scope`) each execution gets a database and a user of its own, `<POSTGRES_MCP_INTERNAL_DATABASE_PREFIX><execution id>`, created when the session opens, which nobody else can connect to; the model may do anything inside it and nothing outside. In external mode the model opens a connection to a host the server allows, and the mode is off until `POSTGRES_MCP_ALLOWED_HOSTS` names one. |
|
||||
| `luciolelii/minio-mcp` | Bounded list/read/stat/write access to object storage, with no delete tool. In internal mode (catalog entry `minio-mcp-internal`, header `x-minio-scope`) it uses the platform's MinIO whose endpoint and keys the catalog entry sends as headers, and one bucket per execution, `<MINIO_MCP_INTERNAL_BUCKET_PREFIX><execution id>`, created when the session opens; in external mode it connects to the MinIO endpoint and bucket of the node's configuration, which must exist, with the keys the model gives. |
|
||||
| `luciolelii/postgres-mcp` | SQL access to PostgreSQL: `postgres_query` (read-only, bounded rows), `postgres_execute`, `postgres_list_tables` and `postgres_describe_table`. In internal mode (catalog entry `postgres-mcp-internal`, header `x-postgres-scope`) each execution gets a database and a user of its own, `<POSTGRES_MCP_INTERNAL_DATABASE_PREFIX><execution id>`, created when the session opens, which nobody else can connect to; the model may do anything inside it and nothing outside. In external mode it connects to the host, port and database of the node's configuration, which must exist, with the user and password the model gives. |
|
||||
|
||||
`egress-proxy` is the development worker's only route to package registries: it allows their CONNECT
|
||||
requests and refuses everything else.
|
||||
|
|
@ -25,7 +25,7 @@ The MCP client orchestrates the servers; they do not share MCP sessions or crede
|
|||
(`sudo chown -R 10001:10001 <dir>`): that is the user the images run as.
|
||||
3. Copy and edit `dev-server-mcp/services.example.json`, and point `DEV_SERVER_SERVICES_CONFIG` at the copy. It ships four worked service definitions: a shared Vite tree, and per-execution ones for Node, Java (through the project's own `./mvnw`) and Python.
|
||||
Keep `BROWSER_MCP_ALLOWED_ORIGINS` aligned with `DEV_SERVER_PORT_RANGE`: the browser reaches a preview only on a port that range covers.
|
||||
4. Optionally set `MINIO_MCP_ALLOWED_ENDPOINTS` to the comma-separated MinIO S3 origins clients may use.
|
||||
4. Optionally set `MINIO_MCP_ALLOWED_ENDPOINTS` and `POSTGRES_MCP_ALLOWED_HOSTS` to the MinIO origins and PostgreSQL hosts external sessions may use. Without them, only public addresses are reachable.
|
||||
5. If the Docker Hub repositories are private, run `docker login` on this host first.
|
||||
6. Pull and run:
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ bearer_token_env_var = "POSTGRES_MCP_TOKEN"
|
|||
|
||||
Set those variables in the MCP client's environment to the token portions configured for the corresponding servers. Do not reuse a token between servers.
|
||||
|
||||
Only the minimal Caddy gateway publishes loopback ports. The coding, development and browser services stay exclusively on internal networks. `minio-mcp` has outbound connectivity because each MCP session can open connections to remote S3 endpoints. Set `MINIO_MCP_ALLOWED_ENDPOINTS` whenever those endpoints are known; leaving it empty gives authenticated MCP clients an intentional network-request capability. `postgres-mcp` is the same, and stricter by default: it has outbound connectivity because the internal mode reaches the platform's PostgreSQL and the external mode a host the model names, but the external mode is off until `POSTGRES_MCP_ALLOWED_HOSTS` lists the hosts it may use. For remote use, use the included VM overlay so Caddy terminates TLS, and add rate limiting at the network edge when appropriate.
|
||||
Only the minimal Caddy gateway publishes loopback ports. The coding, development and browser services stay exclusively on internal networks. `minio-mcp` and `postgres-mcp` have outbound connectivity, because the internal mode reaches the platform's store and the external mode the one a flow author put in the node's configuration. The model never chooses where to connect. Without `MINIO_MCP_ALLOWED_ENDPOINTS` or `POSTGRES_MCP_ALLOWED_HOSTS` an external session reaches public addresses only, so a flow cannot point either server at something inside its own network; with them set, exactly the listed destinations. For remote use, use the included VM overlay so Caddy terminates TLS, and add rate limiting at the network edge when appropriate.
|
||||
|
||||
The worker and browser networks are marked internal, no service uses host networking or the Docker socket, and the development-server workspace mount is read-only. Container isolation reduces the blast radius but is not a substitute for an ephemeral VM/microVM when executing hostile multi-tenant code.
|
||||
|
||||
|
|
|
|||
|
|
@ -195,8 +195,10 @@ services:
|
|||
MINIO_MCP_DEFAULT_REGION: ${MINIO_MCP_DEFAULT_REGION:-us-east-1}
|
||||
MINIO_MCP_MAX_OBJECT_BYTES: ${MINIO_MCP_MAX_OBJECT_BYTES:-1048576}
|
||||
MINIO_MCP_MAX_CONNECTIONS_PER_SESSION: ${MINIO_MCP_MAX_CONNECTIONS_PER_SESSION:-8}
|
||||
# Optional comma-separated origins. Empty permits any HTTP(S) MinIO origin; restrict this
|
||||
# when the set of deployments is known, because every allowed MCP client can open sessions.
|
||||
# Optional comma-separated origins. In external mode the endpoint and bucket are the node's
|
||||
# (x-minio-endpoint, x-minio-bucket).
|
||||
# Empty, any public address is reachable and private ones are refused at every connection; set,
|
||||
# exactly these origins, private ones included.
|
||||
MINIO_MCP_ALLOWED_ENDPOINTS: ${MINIO_MCP_ALLOWED_ENDPOINTS:-}
|
||||
# Internal mode: the workflow manager's catalog entry minio-mcp-internal sends the platform
|
||||
# MinIO's endpoint and keys with x-minio-scope, and the bucket <prefix><execution id> is
|
||||
|
|
@ -230,9 +232,10 @@ services:
|
|||
POSTGRES_MCP_MAX_RESULT_BYTES: ${POSTGRES_MCP_MAX_RESULT_BYTES:-1048576}
|
||||
POSTGRES_MCP_STATEMENT_TIMEOUT_MS: ${POSTGRES_MCP_STATEMENT_TIMEOUT_MS:-30000}
|
||||
POSTGRES_MCP_MAX_CONNECTIONS_PER_SESSION: ${POSTGRES_MCP_MAX_CONNECTIONS_PER_SESSION:-4}
|
||||
# Comma-separated host names the server may connect to. For the external mode it is the whole of its
|
||||
# permission: empty, and the model cannot open a connection of its own. For the internal mode it is
|
||||
# optional, and when set the platform's PostgreSQL has to be on it.
|
||||
# Comma-separated host names the server may connect to. In external mode the host and port are the
|
||||
# node's (x-postgres-host, x-postgres-port, x-postgres-database). Empty, any public address is reachable and private ones are
|
||||
# refused; set, exactly these hosts, private ones included. For the internal mode it is optional, and
|
||||
# when set the platform's PostgreSQL has to be on it.
|
||||
POSTGRES_MCP_ALLOWED_HOSTS: ${POSTGRES_MCP_ALLOWED_HOSTS:-}
|
||||
# Internal mode: the workflow manager's catalog entry postgres-mcp-internal sends the platform
|
||||
# PostgreSQL's host and the credentials of the user that makes databases (CREATEDB, CREATEROLE) with
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ MINIO_MCP_API_KEYS=agent=replace-with-a-fourth-32-char-token
|
|||
POSTGRES_MCP_API_KEYS=agent=replace-with-a-fifth-32-char-token
|
||||
DEV_SERVER_WORKER_TOKEN=replace-with-a-private-worker-token-32-chars
|
||||
|
||||
# External mode: URL, bucket and credentials are passed once to minio_open_session, not configured
|
||||
# on this long-running container. It can therefore hold sessions to different MinIO installations.
|
||||
# External mode: the endpoint is the one the flow author put in the node's configuration, sent by the catalog
|
||||
# entry as x-minio-endpoint with its bucket as x-minio-bucket; only the keys are passed to minio_open_session,
|
||||
# and the bucket has to exist.
|
||||
MINIO_MCP_DEFAULT_REGION=us-east-1
|
||||
MINIO_MCP_MAX_CONNECTIONS_PER_SESSION=8
|
||||
# Optional comma-separated S3 endpoint origins. Leave empty only when every MCP client is trusted
|
||||
# to make this server connect to arbitrary HTTP(S) destinations.
|
||||
# Optional comma-separated S3 endpoint origins. Empty, any public address is reachable and private,
|
||||
# loopback and metadata ones are refused; set, exactly these, private ones included.
|
||||
MINIO_MCP_ALLOWED_ENDPOINTS=
|
||||
# Applies independently to reads and writes. Base64 overhead is handled by the HTTP body limit.
|
||||
MINIO_MCP_MAX_OBJECT_BYTES=1048576
|
||||
|
|
@ -31,9 +32,10 @@ MINIO_MCP_INTERNAL_BUCKET_PREFIX=exec-
|
|||
# bucket is created). 0 keeps them for ever. The empty bucket itself stays.
|
||||
MINIO_MCP_INTERNAL_BUCKET_EXPIRE_DAYS=7
|
||||
|
||||
# PostgreSQL MCP. External mode: host, database and credentials are passed once to postgres_open_session.
|
||||
# It is OFF while this list is empty - the model could otherwise aim the server at any address it can reach -
|
||||
# so name the hosts it may use, comma-separated. For the internal mode the list is optional.
|
||||
# PostgreSQL MCP. External mode: the host and port are the ones the flow author put in the node's configuration,
|
||||
# with its database, sent by the catalog entry as x-postgres-host, x-postgres-port and x-postgres-database; only the
|
||||
# user and the password are passed to postgres_open_session, and the database has to exist. Empty, any public address is reachable and private ones are refused; set, exactly
|
||||
# these hosts, private ones included. For the internal mode the list is optional.
|
||||
POSTGRES_MCP_ALLOWED_HOSTS=
|
||||
POSTGRES_MCP_MAX_ROWS=1000
|
||||
POSTGRES_MCP_MAX_RESULT_BYTES=1048576
|
||||
|
|
|
|||
Loading…
Reference in New Issue