Skip to content

Proposal: WebSocket auth, batch form-filling tool, and connection reliability #195

Description

@saiyaangoku64

Follow-up to #194. These are larger/behavior-changing items I did not want to send as unreviewed code, since this repo can't be built or tested outside the internal monorepo (confirmed: `npm install` fails on the `workspace:*` deps). Filing as a proposal first so a maintainer can weigh in on direction before any implementation.

1. WebSocket server has no authentication

`src/ws.ts` binds a plain `WebSocketServer` with no handshake/token check, and `server.ts`'s connection handler silently drops any existing client when a new one connects, no auth, no log line. Since the extension reuses the user's real logged-in browser session, any local process that can reach that port can issue `browser_click` / `browser_navigate` / `browser_type` against the user's active tab. This matters most on shared/multi-user machines.

Proposed fix: a shared token generated at server startup, printed for the extension to pair with (or exchanged via the existing extension-icon "Connect" flow), checked on the WebSocket `upgrade`/first message before accepting commands.

2. Batch form-filling tool

Booking/checkout-style flows (tickets, forms, multi-field signups) currently require one `click`/`type`/`selectOption` round-trip per field, each re-capturing a full ARIA snapshot. Proposing a `fill_form` tool that accepts an array of `{ element, value }` pairs, applies them in one socket round-trip, and returns a single snapshot at the end. Reduces round-trips and token usage for any multi-field flow, and is a natural place to add "wait for element" retry logic instead of failing immediately on a not-yet-rendered field.

3. Connection reliability

Smaller items that came up reviewing `context.ts` / `server.ts` while working on #194:

  • No `readyState` check in `Context` — a closing/closed socket can still pass `hasWs()`/the `ws` getter and fail later inside the send call instead of failing fast.
  • No `ws.on('error')`/`on('close')` listeners anywhere, so a dropped connection isn't detected until the next `sendSocketMessage` throws.
  • `ReadResource`'s handler has no try/catch around `resource.read(...)` (unlike `CallTool`), so a thrown error there propagates uncaught instead of becoming a graceful MCP error response. Not-found resources also return `{ contents: [] }` silently instead of an `isError` result, inconsistent with how `CallTool` signals "tool not found."

Happy to implement any of these once there's agreement on direction/API shape, particularly for #1 (auth handshake design) and #2 (tool schema), since those change externally-visible behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions