With --adapter claude the planner browses the app and the plan is full of real page names. With --adapter openai against our internal endpoint, the same command produces a plan invented out of the route file. No error, no warning, and the dry run tool list has no browser_* entries at all.
It is being read and then not used. This is a listed limitation, not a config mistake on your side:
The OpenAI-compatible adapter runs a plain tool loop and ignores mcp.servers; only the Claude adapter can drive the bundled Playwright MCP server.
Workaround is the one on the limitations page: use the Claude adapter for the roles whose job is looking at the application — plan, generate, heal. The roles that read the repository rather than the app (review, upgrade) are unaffected and can stay on your endpoint.
agents.provider is a single value, not a per-role one, so this is a flag on the command rather than a yaml change:
yaml
agents:
provider: openai-compatible
bash
sdods agent plan -p demo-shop --goal "checkout" --adapter claude
sdods agent review -p demo-shop
agents.models does take a model per role, but that picks the model, not the adapter — the provider is still whatever --adapter or agents.provider says.
Known limitations is worth a read before you design around any of this.
Flagging the thing that cost me an afternoon on the same problem: the MCP guide reads as though every adapter bridges those servers in and presents them as mcp__<server>__<tool> functions. The limitations page says the opposite. The limitations page is the one that matches what the binary does.
The tell is exactly what you found — the dry-run tool list. If browser_navigate is not in it, no amount of yaml is going to make the model browse anything.
bash
sdods agent plan -p demo-shop --goal x --adapter openai --dry-run