Skip to content

fix(env): give the website browser a network of its own and no database - #488

Merged
earakely-scale merged 2 commits into
mainfrom
edgararakelyan/website-browser-network
Nov 9, 2026
Merged

earakely-scale merged 2 commits into
mainfrom
edgararakelyan/website-browser-network

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Every env with a website gets the website browser added as one of its MCP servers. It runs Playwright with --allowed-hosts '*' on env-network, the compose network it shared with every backing MCP server, every site backend, the state store (servicedb) and its SQL consoles (pgweb, db-mcp). So the agent could drive it to any of them by name and around the gateway: a site backend's own API, a server's data plane, or SQL through pgweb. It also got a schema and a DATABASE_URL like any MCP server, though it uses no database, and that URL carries the shared store's credentials.

What changes

  • MCPServerConfig gains networks, the compose networks its service joins, env-network by default. The gateway puts the browser it adds for an env with websites on website-network alone.
  • create_docker_compose renders each MCP server on its networks, and adds website-network when a server is on it. That network holds:
    • the gateway, which reaches the browser's MCP endpoint and card there;
    • each site's frontend;
    • for a site with no frontend image, its backend, which then serves the site.
  • The gateway and the site frontends stay on env-network as well. MCP servers, site backends, servicedb, pgweb and db-mcp stay on env-network only.
  • Only env-network reaches the database, so a server off it is no database client: it gets no schema, no DATABASE_URL and no wait on servicedb. That leaves the browser out of the local store's schemas, the init script and a remote store's prepare. agent-env env init-env-state leaves it out too, to keep matching the deploy.
  • A compose with no browser renders exactly as before, including the SDK's Harbor, Standalone and preloaded exports, which call create_docker_compose with their own server list and keep the default network.

Synthetic site frontends proxy /api and /assets to their backend inside nginx with relative URLs, so a page in the browser never needs the backend's name. The gateway's list_website_urls tool hands the agent the frontend's address.

Tests

  • Unit.

    • The network layout with and without a browser, including a site with no frontend and the SQL consoles.
    • The browser gets no DATABASE_URL, no servicedb dependency and no schema; without it on website-network it keeps all three.
    • The gateway adds the browser on website-network and prepares schemas without it, for the configured browser and a run's own.
    • init-env-state prepares no schema for the browser.
  • Integration. test_gateway_with_multi_env_including_website now has the browser try both MCP servers, the site backend, servicedb, pgweb and db-mcp by name, and requires ERR_NAME_NOT_RESOLVED for each.

    • It fails on main: http://slack/ resolves there.
  • On an agent-environments-admin EC2 box, at this head:

    • the unit suite (14,116 passed), whose 5 failures also fail on main on that box;
    • the Playwright MCP local tests and the gateway's website tests (9 passed), with the browser's recording through the gateway and its restarts.
  • Before the rebase, on the same kind of box: the full gateway suite (27 passed) and the env, artifact and bundle integration suites (82 passed).

  • Before the rebase, a real modal_vm deploy of a MultiEnv with an MCP server and a site:

    • the browser fails to resolve pgweb, db-mcp, the MCP server, servicedb and the site backend by name;
    • the site drives;
    • pgweb's UI (14 assets) and /api/query, db-mcp's 9 tools and execute_sql, and a data load all work.
  • PSI Bench Holiday Rush on real modal_vm envs, run through agent-env task run against prod with 3 runs on main and 3 on this branch before the database change:

    • the browser attached in all 6, with the same use on both sides (18–102 browser calls per run, at most 2 page timeouts) and the same psi_process scores (0.13–0.2);
    • from inside the branch's browser container: it is on website-network alone, resolves only the gateway and the Craftweb frontend, times out by IP on every env-network container (servicedb:5432, pgweb, db-mcp, the site backend), loads the site (HTTP 200) and reaches S3;
    • from main's: it resolves all 14 services and connects to Postgres directly.
  • Earlier, chaos, main against this branch on the same box, with:

    • a single site, a multi-env with two MCP servers, a deploy publishing on every interface as a VM does, 6 concurrent deploys;
    • restarts of the browser, the frontend and the gateway, and docker compose up -d --force-recreate.
    From the browser main this branch
    pgweb (UI and /api/query), db-mcp, servicedb, the site backend, both MCP servers, by name reached not resolved
    the gateway by name reached reached
    driving the site works works

    On both, after every restart and the recreate: the operator's pgweb /api/query and db-mcp execute_sql work, and loading data through the gateway works.

Not covered here

These are the next PR, the gateway's control token:

  • On a VM the SQL consoles are published on every interface, so the browser still reaches them through the host's addresses (on modal_vm: 172.17.0.1, and each compose network's gateway).
  • The gateway's own /svc relay and /agentenv data plane stay open.

A sidecar a task adds keeps its published port and stays on env-network.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge within its stated scope.

Summary

The PR separates the website browser from backing services and stops giving it database credentials or a schema.

  • The website browser can open sites without joining their backing network.

earakely-scale explicitly defers access through host-published SQL ports and the gateway’s open /svc and /agentenv routes to the next control-token PR. These are acknowledged limits, not new findings.

Review checks were code-only; no tests or services were run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Browser[Website browser] --> Sites[website-network]
  Sites --- Gateway[Gateway]
  Sites --- Entry[Website frontend or backend-only site]
  Gateway --- Env[env-network]
  Entry --- Env
  Env --- MCP[MCP servers]
  Env --- Backend[Separate website backends]
  Env --- DB[Database and SQL consoles]
Loading

Reviews (5) · Last reviewed commit: "refactor(env): MCPServerConfig states it..." · Reviewed by Greptile

The website browser shared env-network with every backing MCP server, website backend, the state store and its SQL consoles, so the agent could drive it to any of them by name and around the gateway. It now sits on website-network with the gateway and each site's frontend (the backend of a site that has none), and on nothing else.

Composes without a website browser, such as the SDK's exports, render as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale force-pushed the edgararakelyan/website-browser-network branch from e42997f to 1ea5a04 Compare November 9, 2026 17:30
…rowser gets no database

The website browser was marked with a website_browser flag that the compose renderer turned into network placement.
MCPServerConfig now carries the networks a server joins, env-network by default, and the gateway puts the browser it
adds on website-network alone.

Only env-network reaches the env's database, so a server off it is no database client: it gets no schema, no
DATABASE_URL and no wait on servicedb. The browser had all three and used none, and its URL carried the shared store's
credentials. init-env-state leaves its schema out to match the deploy's prepare, and the local store takes its schema
list from _all_environments instead of building its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale earakely-scale changed the title fix(env): give the website browser a network of its own fix(env): give the website browser a network of its own and no database Nov 9, 2026
@earakely-scale
earakely-scale merged commit c68281d into main Nov 9, 2026
35 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/website-browser-network branch November 9, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant