Skip to content

fix: validate the MCP server port instead of throwing on a bad one - #2437

Merged
willeastcott merged 4 commits into
mainfrom
fix/mcp-port-validation
Oct 24, 2026
Merged

willeastcott merged 4 commits into
mainfrom
fix/mcp-port-validation

Conversation

@willeastcott

@willeastcott willeastcott commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What's Changed

  • The MCP server popover now accepts only a port from 1 to 65535, and checks it as you type. While the port is invalid, the field shows its error outline, a red "Enter a port from 1 to 65535" hint appears, and Connect is disabled, so a bad port is never stored or tried. An empty field counts as invalid too; previously it silently connected to 52000. The field still starts filled with 52000. Validation listens to the DOM input event rather than PCUI's keyChange (keyup), so paste, autofill and mobile keyboards are covered too. Cancel and Disconnect stay enabled whatever the field holds.
  • The error outline stays visible while the field is focused, in both placements: the toolbar's red ring over PCUI's orange focus ring, and the projects page's red border over its orange focus border.
  • A bad port stored by an earlier version falls back to the default when the popover auto-reconnects, so editors already caught by this recover on their next load.
  • MCPConnection.connect() refuses an invalid port with a logged [MCP] error instead of throwing, whoever calls mcp:connect.
  • New parsePort() helper in src/editor/mcp/port.ts, with tests.

Why: new WebSocket() throws a SyntaxError for a port outside 1–65535. The popover read its field with parseInt(value) || 52000, which accepts any integer, so a typo such as 520000 threw out of the Connect click handler. The error landed in error reporting, and the status was left on "Connecting" with no socket behind it. The popover had already stored editor:mcp:connected = true and the bad port before connecting, so the auto-reconnect retried it, and threw again, on every reload until the user noticed.

Testing:

  • npm test: the new parsePort tests pass, including 520000, 400000, 65536, 0, -1, empty, 52000abc, 5e4 and 52000.5.
  • eslint and stylelint report no errors in the changed files.
  • In Chrome, on a standalone page running the real popover.ts, connection.ts and port.ts against the compiled editor.scss, with a stub editor global:
    • Typing 520000 into the toolbar popover turns on the error ring (red even while focused), shows the red hint and disables CONNECT. Clicking CONNECT then stores nothing and doesn't connect.
    • Correcting it to 52001 removes the error and re-enables CONNECT. (Clearing the field now disables CONNECT; that change is covered by the parsePort('') test, not re-run in the browser.)
    • Escape revalidates after PCUI restores the pre-edit value, in both directions. From 52000, appending 0 makes it invalid, and Escape brings back 52000 with the error cleared and CONNECT enabled; before the fix the error and the disabled CONNECT stuck. From a committed 65536, deleting a digit makes it valid (6553), and Escape brings back 65536 with the error back on.
    • In the projects-page popover, 400000 gives the red border, the hint and a disabled Connect.
    • Reloading with editor:mcp:connected = true and editor:mcp:port = 520000 already stored shows 52000 in the field and auto-connects to ws://127.0.0.1:52000.
  • Not exercised inside a full editor session.

Checks

🤖 Generated with Claude Code

new WebSocket() throws a SyntaxError for a port outside 1-65535. The MCP
popover took any integer from its port field (parseInt), so a typo such as
520000 for 52000 threw out of the Connect click handler, left the status
stuck on "connecting" with no socket, and reported the error to Sentry.
It also stored the bad port and connected=true before connecting, so the
auto-reconnect retried it, and threw again, on every reload.

parsePort() accepts only whole numbers from 1 to 65535. The popover shows
"Enter a port from 1 to 65535" and neither stores nor connects; a bad
stored port falls back to the default; and MCPConnection.connect() refuses
an invalid port with a logged error rather than throwing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@willeastcott willeastcott added bug Something isn't working area: editor interface labels Oct 24, 2026
@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
editor Ready Ready Preview Oct 24, 2026 1:43pm UTC

Request Review

Instead of waiting for Connect, the popover checks the port on every edit:
the field shows its error state, the "Enter a port from 1 to 65535" hint
turns red, and Connect stays disabled until the port is valid. It listens
to the DOM input event rather than PCUI's keyChange (keyup), so paste,
autofill and mobile keyboards are caught too. Cancel and Disconnect stay
enabled whatever the field holds.

Both placements keep the error outline while the field is focused: the
toolbar's red ring over PCUI's orange focus ring, and the projects page's
red border over its orange focus border.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An empty field used to mean the default port, so CONNECT stayed enabled
on a blank field and silently connected to 52000. It now counts as invalid
like any other bad value: CONNECT is disabled and the hint asks for a
port. The field still starts filled with 52000.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PCUI's Escape handler puts the pre-edit value back without firing input or
change (change only with keyChange), so after appending a digit to 52000
and pressing Escape the field showed 52000 with the error hint still up and
CONNECT disabled. Revalidate on PCUI's keydown event for Escape, which it
emits after restoring the value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@willeastcott
willeastcott merged commit c135df3 into main Oct 24, 2026
9 checks passed
@willeastcott
willeastcott deleted the fix/mcp-port-validation branch October 24, 2026 13:48
playcanvas-bot Bot pushed a commit that referenced this pull request Oct 26, 2026
…2437)

* fix: validate the MCP server port instead of throwing on a bad one

new WebSocket() throws a SyntaxError for a port outside 1-65535. The MCP
popover took any integer from its port field (parseInt), so a typo such as
520000 for 52000 threw out of the Connect click handler, left the status
stuck on "connecting" with no socket, and reported the error to Sentry.
It also stored the bad port and connected=true before connecting, so the
auto-reconnect retried it, and threw again, on every reload.

parsePort() accepts only whole numbers from 1 to 65535. The popover shows
"Enter a port from 1 to 65535" and neither stores nor connects; a bad
stored port falls back to the default; and MCPConnection.connect() refuses
an invalid port with a logged error rather than throwing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: validate the MCP port as it is typed

Instead of waiting for Connect, the popover checks the port on every edit:
the field shows its error state, the "Enter a port from 1 to 65535" hint
turns red, and Connect stays disabled until the port is valid. It listens
to the DOM input event rather than PCUI's keyChange (keyup), so paste,
autofill and mobile keyboards are caught too. Cancel and Disconnect stay
enabled whatever the field holds.

Both placements keep the error outline while the field is focused: the
toolbar's red ring over PCUI's orange focus ring, and the projects page's
red border over its orange focus border.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: treat an empty MCP port field as invalid

An empty field used to mean the default port, so CONNECT stayed enabled
on a blank field and silently connected to 52000. It now counts as invalid
like any other bad value: CONNECT is disabled and the hint asks for a
port. The field still starts filled with 52000.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: revalidate the MCP port after Escape restores it

PCUI's Escape handler puts the pre-edit value back without firing input or
change (change only with keyChange), so after appending a digit to 52000
and pressing Escape the field showed 52000 with the error hint still up and
CONNECT disabled. Revalidate on PCUI's keydown event for Escape, which it
emits after restoring the value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Will Eastcott <weastcott@snapchat.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c135df3)

This branch was successfully deployed

1 active deployment
Preview — 80de5344 Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: editor interface bug Something isn't working release: next patch Ticket marked for next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants