Qwen, Zed, and the Browser Tools That Wouldn't Show Up

Qwen was running locally. The context allocation reached 65,536 tokens. The browser still opened the wrong session. A Mac mini, an MCP server, and the configuration work between a model that answers and an agent that can reach the lab.

Claude Code hit the weekly limit. I was mid-job.

GPT Codex was still available, right up until the cybersecurity lab got to exfiltration. Then it rejected the work. The lab had not changed. The task had not changed. I had reached a part of the job the hosted assistant would not help with.

So I put Qwen 3.5 9B on the Mac mini. Ollama underneath, Zed in front, Playwright MCP for the browser. No model-provider sign-in for that local inference path. I wanted to keep working on the authorized lab without waiting for a weekly reset or finding another way to explain what exfiltration means in a security exercise.

The machine is a 2024 Mac mini, M4, 16 GB of unified memory. It was already on the desk. This was about getting a usable local cybersecurity workbench onto it, then getting that workbench into the Chrome session where the lab was actually open.

The model answered. Images worked. Playwright took more work.

The context I could actually see

The target allocation was 65,536 tokens. Zed's model entry used max_tokens: 65536, and Ollama's running-state output confirmed the allocation. This is the relevant part of the observed ollama ps output, with the changing expiry column omitted:

NAME          ID              SIZE      PROCESSOR    CONTEXT
qwen3.5:9b    56671c2ab938    6.9 GB    100% GPU     65536

That establishes a loaded model with that context allocation. It does not establish that I filled the entire window, measured retrieval accuracy across it, or ran a long-session stability benchmark. Sixteen gigabytes is still sixteen gigabytes. The editor, browser, operating system, and model all live there.

Zed's Ollama integration sends a num_ctx value with its requests and supports a per-model context setting through available_models. That matters because a model's advertised capacity, an editor's configured limit, and a runtime's allocation are separate things to inspect.

The first draft of this writeup credited a custom Modelfile as a required fix. The active model remained qwen3.5:9b, and its stored parameters did not show a custom num_ctx override. The running allocation was visible. A required custom-model build was not established, so that claim came out.

Valid JSON can still contain settings nobody uses

During the configuration work, a misplaced brace separated settings that belonged under one root object. Fixing that made the file structurally readable again. It did not prove that every key inside it meant something to Zed.

There was a second trap in the draft configuration: a flat mcp:playwright:* permission entry. Zed's documented permission structure places individual tool rules under agent.tool_permissions.tools. A plausible-looking wildcard pasted somewhere else is a poor basis for claiming automatic approval works. The visible browser tool call still asked for confirmation.

We also changed the profile and thinking settings together. The request then stalled while the editor remained responsive. That was enough to stop changing things and roll back. It was not enough to diagnose a thinking-mode bug. No isolated test established which change caused the stall.

A configuration session can generate a surprisingly confident incident report about an experiment nobody actually controlled.

The tools appeared before the right browser did

In the profile configuration, Playwright's tool list appeared with enabled checkmarks. Then Zed issued a real browser_snapshot call and waited for approval. That was progress I could point to, rather than another paragraph from the model about its intentions.

Profiles control tool availability. Permissions govern approval after a tool is available. Neither tells the browser which session I meant.

The first browser window opened at about:blank. Playwright had launched a separate session. My lab was already open in Chrome, with the state I needed to continue working. Asking the agent to inspect that existing tab while connecting it to a new browser gave it the wrong place to look.

The connection changed when the MCP launch arguments included --extension and I installed Microsoft's Playwright Extension in the Chrome profile holding the lab. The extension connection lets the user select an existing tab. Microsoft documents that route here.

The server declaration was:

{
  "context_servers": {
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest", "--extension"]
    }
  }
}

The local npm cache contained Playwright MCP 0.0.83. The session's launch command used @latest, which can resolve differently later. The downloadable configuration pins that cached version for a more useful reference.

After selecting the existing Chrome session, I confirmed the connection reached my lab. This records a working connection during a live task. It does not report a completed security engagement, a benchmark of autonomous browser actions, or a new vulnerability.

No sign-in still leaves network traffic

The model request went to Ollama on localhost. That is the part I wanted to keep on the machine. Zed documents local inference as a request to the configured local server. It does not make every other feature in the editor local.

The browser still contacts the lab and anything its pages load. Those destinations can receive the request's source IP, cookies for their own site, and whatever data an action submits. The extension connects the agent to the selected browser session. No extra model login is required, but the lab's existing browser session can already be authenticated.

Zed also has metrics and diagnostic reporting independent of model inference. Its telemetry documentation gives a root-level telemetry setting with diagnostics and metrics both set to false to disable client-side reporting. Edit Prediction has its own provider and data path. Check it separately before assuming a local chat model covers every AI feature in the editor.

For my lab work, the practical controls are a dedicated Chrome profile containing only lab sessions, only the required MCP tools enabled, and confirmation for actions until I have checked what the tool will receive and send. Keep Ollama bound to loopback. Install the dependencies first and pin the MCP package rather than treating @latest as a reproducible version. For local-only exercises, enforce outbound restrictions outside the model. For a hosted lab, permit the destinations it actually needs.

Those are controls to apply and verify. I have not captured this session's traffic, so I cannot claim that no information left the machine. A VPN would change the source address a destination sees. It would not stop an allowed tool from submitting data to that destination.

The browser can bring untrusted page text back into the agent, and the agent can request another action. That is familiar territory for agentic AI security work, even when the model runs a few inches from the keyboard. Local inference gives me control over the inference path. The tool connections still need their own boundaries.

Download the session settings or save the settings image. Those preserve the file used during the session with only the private lab hostname removed, including the unresolved thinking flags and flat permission entry discussed above. Their presence in a working session does not establish that Zed used those particular keys.

Download the reduced reference settings. This is a reduced reference, not a byte-for-byte copy of my live file. It removes lab hosts and workspace details, leaves approvals at confirm, omits the unresolved thinking overrides, and pins the cached MCP package version. Enable Playwright in the profile you intend to use. Merge the settings into an existing configuration rather than discarding unrelated editor preferences. The reference parses as JSON and follows the documented structure. It has not been substituted into the live session for a separate end-to-end run.

Recorded October 24, 2026: Zed 1.25.3, Ollama client 0.33.2, Qwen model ID 56671c2ab938. The hardware stayed the same throughout. The useful changes happened between the model and the tab it was supposed to reach.


GhostInThePrompt.com // The model kept explaining. The browser finally reached the lab.