Remote MCP is a URL you authenticated to. Local MCP is a program.
Cursor's stdio transport starts that program with command and args from mcp.json. Messages go over stdin and stdout. There is no extra sandbox in the default path. Playwright's own README says the server is not a security boundary. Believe them.
In this directory, only Playwright and Firecrawl are that shape. Everything else is a URL. I like that ratio.
What the dialog is saying
Cursor asks for approval before MCP tools run, by default. The docs say you can expand the tool name and see the arguments. Run modes match the terminal: in Auto-review, allowlisted tools go through and the rest hit a classifier.
For stdio there is a second, earlier decision: will you let Cursor spawn this command at all. npx -y @playwright/mcp@latest means npm may download whatever "latest" is, then execute it as you. The -y flag is how you skip npm's "ok to install?" prompt. Convenient. Also how you skip thinking.
If the dialog says Playwright and the args are npx -y some-other-package, stop. That mismatch is the whole game.
The trust dialog is not a terms of service. It is Cursor asking, "this binary is you now, yes?"
Why this got a CVE
Check Point Research published MCPoison, CVE-2025-54136. Once an MCP entry was approved, Cursor trusted later edits to that entry by key name. Change echo to nc -e /bin/bash ... under the same name, and the process could start without a fresh "are you sure?" Tenable's writeup puts that next to CurXecute (CVE-2025-54135), where prompt injection could land a new mcp.json entry that auto-started.
A separate bug, CVE-2025-64106, was an install dialog that could show a trusted name such as Playwright while running different commands. Reports put the fix in Cursor 2.0.
If your Cursor is current, you should get re-prompted when the command changes. I would still glance at the args. I would still pin versions on stdio packages instead of @latest if I cared about a machine.
Do not take a project .cursor/mcp.json from an unknown repo and approve it like a README badge. That file is closer to a shell script than a list of plugins. See Global vs project mcp.json.
When I click through
Playwright, when I typed the Microsoft package myself, Node is on PATH, and I want a browser pointed at localhost.
Firecrawl, when the package name matches their current docs and the key is in env, not in the repo.
I do not click through on:
- a command I cannot find on the vendor's site
curl | shstuffed into args- a "Playwright" server whose package is not
@playwright/mcp - anything that wants a cloud secret and also wants to run locally for no reason
If the vendor has a hosted URL, use the URL. When remote HTTP is enough is the rest of that sermon.
After it is running
A red row usually means the process died. npx could not reach the registry. Node is missing. The first Playwright browser download is still going. Cursor on a remote SSH host often cannot spawn what your laptop could.
Run the same command in a terminal. If it fails there, Cursor cannot save you.
Microsoft: Node 18+. Firecrawl: a real API key. Neither problem looks like "the model is dumb." Both look like a silent stdio child.
Approve the program you meant. Then keep the set small.
