Skip to content

Commit 7adcec8

Browse files
{  "message": "Bad credentials",  "documentation_url": "https://docs.github.com/rest",  "status": "401"}{  "message": "Bad credentials",  "documentation_url": "https://docs.github.com/rest",  "status": "401"}
authored andcommitted
fix(mcp): isolate agents from shared browser
1 parent 93d945c commit 7adcec8

16 files changed

Lines changed: 57 additions & 19 deletions

File tree

packages/api/src/services/agents.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,18 @@ const sourceLabel = (request: CreateAgentRequest): string =>
5555

5656
const pickDefaultCommand = (provider: CreateAgentRequest["provider"]): string => {
5757
if (provider === "codex") {
58-
return "codex"
58+
return "MCP_PLAYWRIGHT_ISOLATED=1 codex"
5959
}
6060
if (provider === "opencode") {
6161
return "opencode"
6262
}
6363
if (provider === "claude") {
64-
return "claude"
64+
return "MCP_PLAYWRIGHT_ISOLATED=1 claude"
6565
}
6666
return ""
6767
}
6868

69-
const buildCommand = (request: CreateAgentRequest): string => {
69+
export const buildCommand = (request: CreateAgentRequest): string => {
7070
const direct = request.command?.trim() ?? ""
7171
if (direct.length > 0) {
7272
return direct

packages/api/tests/agents.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { describe, expect, it } from "vitest"
2+
3+
import { buildCommand } from "../src/services/agents.js"
4+
5+
describe("agent service", () => {
6+
it("starts default Codex agents with isolated Playwright MCP", () => {
7+
expect(buildCommand({ provider: "codex" })).toBe("MCP_PLAYWRIGHT_ISOLATED=1 codex")
8+
expect(buildCommand({ provider: "codex", args: ["exec", "hello world"] })).toBe(
9+
"MCP_PLAYWRIGHT_ISOLATED=1 codex 'exec' 'hello world'"
10+
)
11+
})
12+
13+
it("starts default Claude agents with isolated Playwright MCP", () => {
14+
expect(buildCommand({ provider: "claude" })).toBe("MCP_PLAYWRIGHT_ISOLATED=1 claude")
15+
expect(buildCommand({ provider: "claude", args: ["-p", "hello world"] })).toBe(
16+
"MCP_PLAYWRIGHT_ISOLATED=1 claude '-p' 'hello world'"
17+
)
18+
})
19+
20+
it("does not rewrite custom agent commands", () => {
21+
expect(buildCommand({ provider: "codex", command: "codex --help" })).toBe("codex --help")
22+
})
23+
})

packages/app/src/docker-git/cli/usage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Container runtime env (set via .orch/env/project.env):
9393
DOCKER_GIT_ZSH_AUTOSUGGEST=1|0 Enable zsh-autosuggestions (default: 1)
9494
DOCKER_GIT_ZSH_AUTOSUGGEST_STYLE=... zsh-autosuggestions highlight style (default: fg=8,italic)
9595
DOCKER_GIT_ZSH_AUTOSUGGEST_STRATEGY=... Suggestion sources (default: history completion)
96-
MCP_PLAYWRIGHT_ISOLATED=1|0 Isolated browser contexts (recommended for many Codex; default: 1)
96+
MCP_PLAYWRIGHT_ISOLATED=1|0 Isolated browser contexts; default 0 shares the VNC session
9797
MCP_PLAYWRIGHT_CDP_GUARD=1|0 Guard CDP so MCP cannot close/crash shared Chromium (default: 1)
9898
MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE=1|0 Block destructive Browser.close/crash CDP methods (default: 1)
9999
MCP_PLAYWRIGHT_CDP_ENDPOINT=http://... Override CDP endpoint (default: http://dg-<repo>-browser:9223)

packages/app/src/lib/core/templates-entrypoint/agent.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,13 @@ fi`
5252

5353
const renderAgentPromptCommand = (mode: AgentMode): string =>
5454
Match.value(mode).pipe(
55-
Match.when("claude", () => String.raw`claude --dangerously-skip-permissions -p \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
56-
Match.when("codex", () => String.raw`codex exec \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
55+
Match.when(
56+
"claude",
57+
() =>
58+
String
59+
.raw`MCP_PLAYWRIGHT_ISOLATED=1 claude --dangerously-skip-permissions -p \"\$(cat \"$AGENT_PROMPT_FILE\")\"`
60+
),
61+
Match.when("codex", () => String.raw`MCP_PLAYWRIGHT_ISOLATED=1 codex exec \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
5762
Match.when("gemini", () => String.raw`gemini --approval-mode=yolo \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
5863
Match.exhaustive
5964
)

packages/app/src/lib/core/templates-entrypoint/base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ AGENT_MODE="\${AGENT_MODE:-}"
2929
AGENT_AUTO="\${AGENT_AUTO:-}"
3030
MCP_PLAYWRIGHT_ENABLE="\${MCP_PLAYWRIGHT_ENABLE:-${config.enableMcpPlaywright ? "1" : "0"}}"
3131
MCP_PLAYWRIGHT_CDP_ENDPOINT="\${MCP_PLAYWRIGHT_CDP_ENDPOINT:-}"
32-
MCP_PLAYWRIGHT_ISOLATED="\${MCP_PLAYWRIGHT_ISOLATED:-1}"
32+
MCP_PLAYWRIGHT_ISOLATED="\${MCP_PLAYWRIGHT_ISOLATED:-0}"
3333
MCP_PLAYWRIGHT_CDP_GUARD="\${MCP_PLAYWRIGHT_CDP_GUARD:-1}"
3434
MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE="\${MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE:-1}"
3535

packages/app/src/lib/core/templates-entrypoint/nested-docker-git.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ CODEX_AUTO_UPDATE=1
116116
DOCKER_GIT_ZSH_AUTOSUGGEST=1
117117
DOCKER_GIT_ZSH_AUTOSUGGEST_STYLE=fg=8,italic
118118
DOCKER_GIT_ZSH_AUTOSUGGEST_STRATEGY=history completion
119-
MCP_PLAYWRIGHT_ISOLATED=1
119+
MCP_PLAYWRIGHT_ISOLATED=0
120120
EOF
121121
fi
122122

packages/app/src/lib/core/templates/dockerfile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ if [[ -z "$JSON" ]]; then
172172
fi
173173
174174
EXTRA_ARGS=()
175-
if [[ "\${MCP_PLAYWRIGHT_ISOLATED:-1}" == "1" ]]; then
175+
if [[ "\${MCP_PLAYWRIGHT_ISOLATED:-0}" == "1" ]]; then
176176
EXTRA_ARGS+=(--isolated)
177177
fi
178178

packages/app/src/lib/usecases/actions/prepare-files.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ const defaultProjectEnvContents = [
230230
"DOCKER_GIT_ZSH_AUTOSUGGEST=1",
231231
"DOCKER_GIT_ZSH_AUTOSUGGEST_STYLE=fg=8,italic",
232232
"DOCKER_GIT_ZSH_AUTOSUGGEST_STRATEGY=history completion",
233-
"MCP_PLAYWRIGHT_ISOLATED=1",
233+
"MCP_PLAYWRIGHT_ISOLATED=0",
234234
"MCP_PLAYWRIGHT_CDP_GUARD=1",
235235
"MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE=1",
236236
""

packages/lib/src/core/templates-entrypoint/agent.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,13 @@ fi`
5151

5252
const renderAgentPromptCommand = (mode: AgentMode): string =>
5353
Match.value(mode).pipe(
54-
Match.when("claude", () => String.raw`claude --dangerously-skip-permissions -p \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
55-
Match.when("codex", () => String.raw`codex exec \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
54+
Match.when(
55+
"claude",
56+
() =>
57+
String
58+
.raw`MCP_PLAYWRIGHT_ISOLATED=1 claude --dangerously-skip-permissions -p \"\$(cat \"$AGENT_PROMPT_FILE\")\"`
59+
),
60+
Match.when("codex", () => String.raw`MCP_PLAYWRIGHT_ISOLATED=1 codex exec \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
5661
Match.when("gemini", () => String.raw`gemini --approval-mode=yolo \"\$(cat \"$AGENT_PROMPT_FILE\")\"`),
5762
Match.exhaustive
5863
)

packages/lib/src/core/templates-entrypoint/base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ AGENT_MODE="\${AGENT_MODE:-}"
2828
AGENT_AUTO="\${AGENT_AUTO:-}"
2929
MCP_PLAYWRIGHT_ENABLE="\${MCP_PLAYWRIGHT_ENABLE:-${config.enableMcpPlaywright ? "1" : "0"}}"
3030
MCP_PLAYWRIGHT_CDP_ENDPOINT="\${MCP_PLAYWRIGHT_CDP_ENDPOINT:-}"
31-
MCP_PLAYWRIGHT_ISOLATED="\${MCP_PLAYWRIGHT_ISOLATED:-1}"
31+
MCP_PLAYWRIGHT_ISOLATED="\${MCP_PLAYWRIGHT_ISOLATED:-0}"
3232
MCP_PLAYWRIGHT_CDP_GUARD="\${MCP_PLAYWRIGHT_CDP_GUARD:-1}"
3333
MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE="\${MCP_PLAYWRIGHT_BLOCK_BROWSER_CLOSE:-1}"
3434

0 commit comments

Comments
 (0)