Issue Type
Browser Issue
Operating System
Windows
Description of the bug
Description
BrowserOS neo's MCP endpoint (Streamable HTTP) rejects any request that carries browser-default Fetch Metadata headers (Sec-Fetch-Site / Sec-Fetch-Mode / Sec-Fetch-Dest) with 403 {"error":"unsupported request"}. Requests carrying an Origin header are rejected as well.
This makes the neo endpoint unusable from Electron-based MCP clients such as Cherry Studio: Electron's network stack automatically attaches Sec-Fetch-* headers to outgoing requests, and apps cannot strip them. Other GUI clients built on Chromium/Electron likely hit the same wall.
The legacy BrowserOS MCP server (browseros_mcp v0.0.127) is less strict: it rejects Origin but accepts Sec-Fetch-*, so the same client connects to it natively. In short: the stricter request filter introduced in neo is what breaks Electron-based clients.
Test results (BrowserOS neo 0.0.44 vs legacy 0.0.127, Windows 11)
| Request headers |
neo (0.0.44) |
legacy (0.0.127) |
| none (plain MCP initialize) |
200 |
200 |
Sec-Fetch-Site/Mode/Dest only |
403 {"error":"unsupported request"} |
200 |
Origin only |
403 {"error":"unsupported request"} |
403 |
Impact
Cherry Studio (and likely other Electron-based MCP clients) cannot connect to neo directly. The only workaround is a local stdio bridge (npx mcp-remote http://127.0.0.1:9010/mcp --transport http-only), which adds a resident process and, in my testing, also breaks the run tool's output-schema negotiation (mcp-remote 0.8.2).
Suggested fix
Relax the request filter to match the legacy server's behavior: keep Origin/Host validation (DNS-rebinding protection — see #2424 for analysis of this filter layer), but allow requests that carry no Origin and only the browser-default Sec-Fetch-* metadata, which are added automatically by Chromium/Electron and are not attacker-controlled.
Steps to Reproduce
-
Start BrowserOS neo (MCP endpoint at http://127.0.0.1:9010/mcp).
-
POST a normal MCP initialize request — it returns 200:
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://127.0.0.1:9010/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}'
- Repeat the exact same request with only the browser-default Fetch Metadata headers added — it returns 403 with body
{"error":"unsupported request"}:
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://127.0.0.1:9010/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Sec-Fetch-Site: same-site" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}'
- Compare with the legacy MCP server (port 9000,
browseros_mcp v0.0.127): the same request with Sec-Fetch-* headers returns 200, confirming the rejection is a neo-only regression.
Screenshots / Videos
No response
BrowserOS Version
BrowserOS neo 0.0.44 (MCP server version)
Additional Context
Feature request (bonus): please consider adding Cherry Studio (open-source, supports Streamable HTTP MCP servers) to the one-click MCP setup board in the neo cockpit.
Issue Type
Browser Issue
Operating System
Windows
Description of the bug
Description
BrowserOS neo's MCP endpoint (Streamable HTTP) rejects any request that carries browser-default Fetch Metadata headers (
Sec-Fetch-Site/Sec-Fetch-Mode/Sec-Fetch-Dest) with403 {"error":"unsupported request"}. Requests carrying anOriginheader are rejected as well.This makes the neo endpoint unusable from Electron-based MCP clients such as Cherry Studio: Electron's network stack automatically attaches
Sec-Fetch-*headers to outgoing requests, and apps cannot strip them. Other GUI clients built on Chromium/Electron likely hit the same wall.The legacy BrowserOS MCP server (
browseros_mcpv0.0.127) is less strict: it rejectsOriginbut acceptsSec-Fetch-*, so the same client connects to it natively. In short: the stricter request filter introduced in neo is what breaks Electron-based clients.Test results (BrowserOS neo 0.0.44 vs legacy 0.0.127, Windows 11)
Sec-Fetch-Site/Mode/Destonly{"error":"unsupported request"}Originonly{"error":"unsupported request"}Impact
Cherry Studio (and likely other Electron-based MCP clients) cannot connect to neo directly. The only workaround is a local stdio bridge (
npx mcp-remote http://127.0.0.1:9010/mcp --transport http-only), which adds a resident process and, in my testing, also breaks theruntool's output-schema negotiation (mcp-remote 0.8.2).Suggested fix
Relax the request filter to match the legacy server's behavior: keep
Origin/Hostvalidation (DNS-rebinding protection — see #2424 for analysis of this filter layer), but allow requests that carry noOriginand only the browser-defaultSec-Fetch-*metadata, which are added automatically by Chromium/Electron and are not attacker-controlled.Steps to Reproduce
Start BrowserOS neo (MCP endpoint at
http://127.0.0.1:9010/mcp).POST a normal MCP
initializerequest — it returns 200:{"error":"unsupported request"}:browseros_mcpv0.0.127): the same request withSec-Fetch-*headers returns 200, confirming the rejection is a neo-only regression.Screenshots / Videos
No response
BrowserOS Version
BrowserOS neo 0.0.44 (MCP server version)
Additional Context
Feature request (bonus): please consider adding Cherry Studio (open-source, supports Streamable HTTP MCP servers) to the one-click MCP setup board in the neo cockpit.