"The editor MCP port is one global setting: bump it by hand, let your agent discover it"
▸ SYMPTOM
An MCP tool call that worked yesterday now hits the wrong editor, or nothing at all. A port you hardcoded (or remembered from a previous session) either answers with a different project's editor or times out. A second editor you just opened serves no MCP at all, and its Preferences page reads "Not running" with no reason given. Mutating calls, anything that changes a scene or asset, are the dangerous case: they land against whichever project happens to hold that port right now.
▸ CAUSE
The editor MCP port cannot be pinned per project. It is a single engine-global preference (Editor.EditorPreferences.McpServerPort, persisted in the engine's config/tools.json; stored via the engine-global editor cookie, so there is no per-project override by design). The engine default is 7269. Whichever project's editor launches first binds the configured port.
There is no auto-increment. When the configured port is already bound by another open editor, the second editor does not fall back to a neighbouring port. It fails the bind and starts no MCP server at all. The engine source wraps the listener start in a single try/catch: on failure it logs one warning and gives up, with no retry and no port search.
Confirmed with three editors live on build 26.07.15a: one project's editor held the configured port 7279; two more editors opened afterward, and a full identity-probe scan of ports 7200-7330 found only that first editor. The later editors exposed no MCP server on any port.
The console warning is the only diagnostic. On a bind conflict the editor logs (grep your console for this, tag MCP):
Couldn't start MCP server on port <port> (<reason>)A clean start logs MCP server listening on <url> instead. The Preferences page (Edit > Preferences > MCP Server) shows only "Not running" on a failed bind, the same text it shows when the server is disabled, so the page alone will not tell you a conflict happened. Check the console.
Consequences:
- Any hardcoded or remembered port goes stale on every restart or launch-order change.
- A port that answered yesterday can be a different project today, the silent and dangerous failure, because a mutating call succeeds against the wrong editor.
- A second editor opened on the same configured port serves nothing until you give it a free port by hand.
▸ FIX
Two parts: set the port by hand, and let agents discover it.
Set a free port by hand
The port is read at editor startup, so before launching an additional editor that needs MCP, open Edit > Preferences > MCP Server and set the "Mcp Server Port" field to a free number (increment it yourself), then launch the new editor.
Changing the port (or the enabled checkbox) restarts the server immediately, so you can also fix an editor that already failed its bind: open its Preferences and set a free port there, and its MCP server starts on the spot, no restart needed.
Discover, never pin
Because ports are launch-order and hand-set, don't hand a fixed port to your tooling each session. Discover the live port at run time:
- Scan the plausible range (e.g.
7200to7330) with a parallel, read-onlyeditor_statusprobe per port.editor_statusis safe to call against any project. - Match the returned
Projectfield to the project you mean to drive. - Feed the found URL to all tooling via an env var, so every call targets the confirmed editor.
A ~130-port threaded scan completes in about a second.
Implementation caveats
Write the probe as a self-contained raw JSON-RPC POST (e.g. urllib). Do not reuse an interactive MCP client helper that prints guidance and calls sys.exit() on an unreachable port:
SystemExitis not anException, so it slips past a normaltry/except Exceptionand kills your scan.contextlib.redirect_stdoutis process-global and not thread-safe, so it corrupts output under a parallel scan.
A minimal per-port probe that opens a socket, POSTs an editor_status request, reads the Project, and returns the URL is all you need.
▸ WHY IT WORKS
Because the port is assigned by launch order and set by hand, never auto-negotiated, the only reliable identifier is the Project field the editor reports about itself. Scanning and matching that field targets the editor by identity instead of by a number that drifts, so tooling always talks to the intended project, and a mutating call can never silently land on the wrong one.
- Corrected: the editor does not auto-increment; the port must be bumped manually before launching another editor
- Published