Download src/agents/cli-runner/bundle-mcp.codex.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 8.64 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/cli-runner/bundle-mcp.codex.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/agents/cli-runner/bundle-mcp.codex.test.ts
-
curl -L -o bundle-mcp.codex.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/cli-runner/bundle-mcp.codex.test.ts
8.64 kB
| /** Tests Codex CLI bundle-MCP config override generation. */ | |
| import { describe, expect, it } from "vitest"; | |
| import type { OpenClawConfig } from "../../config/types.openclaw.js"; | |
| import { withEnvAsync } from "../../test-utils/env.js"; | |
| import { retireSessionMcpRuntime } from "../agent-bundle-mcp-manager-api.js"; | |
| import { AuthStorage } from "../sessions/auth-storage.js"; | |
| import { ModelRegistry } from "../sessions/model-registry.js"; | |
| import { buildCodexUserMcpServersThreadConfigPatchForRun } from "./bundle-mcp-codex.js"; | |
| import { prepareCliBundleMcpConfig } from "./bundle-mcp.js"; | |
| import { | |
| cliBundleMcpHarness, | |
| cliNativeMcpPolicyContext, | |
| setupCliBundleMcpTestHarness, | |
| writeCliMcpPolicyProbeServer, | |
| } from "./bundle-mcp.test-support.js"; | |
| setupCliBundleMcpTestHarness(); | |
| describe("prepareCliBundleMcpConfig codex", () => { | |
| it.each([ | |
| ["agent:worker:policy", undefined], | |
| ["global", "worker"], | |
| ] as const)( | |
| "keeps Codex server ownership separate from the runtime policy owner (%s)", | |
| async (sandboxSessionKey, sandboxAgentId) => { | |
| const serverPath = await writeCliMcpPolicyProbeServer(); | |
| const workspaceDir = cliBundleMcpHarness.bundleProbeWorkspaceDir; | |
| const sessionId = "codex-independent-policy-owner"; | |
| const config: OpenClawConfig = { | |
| plugins: { enabled: false }, | |
| agents: { | |
| entries: { main: {}, worker: { tools: { deny: ["docs__delete_docs"] } } }, | |
| }, | |
| mcp: { | |
| servers: { | |
| docs: { command: process.execPath, args: [serverPath], codex: { agents: ["main"] } }, | |
| }, | |
| }, | |
| }; | |
| const authStorage = AuthStorage.inMemory(); | |
| await withEnvAsync( | |
| { OPENCLAW_STATE_DIR: cliBundleMcpHarness.bundleProbeHomeDir }, | |
| async () => { | |
| try { | |
| const patch = await buildCodexUserMcpServersThreadConfigPatchForRun({ | |
| cwd: workspaceDir, | |
| run: { | |
| agentId: "main", | |
| sessionId, | |
| sessionKey: "agent:main:conversation", | |
| sandboxSessionKey, | |
| sandboxAgentId, | |
| sessionFile: "agent:main:conversation", | |
| workspaceDir, | |
| config, | |
| prompt: "hello", | |
| timeoutMs: 1_000, | |
| runId: sessionId, | |
| provider: "openai", | |
| modelId: "gpt-5.6-luna", | |
| model: { | |
| id: "gpt-5.6-luna", | |
| name: "Test model", | |
| api: "openai-responses", | |
| provider: "openai", | |
| baseUrl: "https://api.openai.com/v1", | |
| reasoning: false, | |
| input: ["text"], | |
| cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, | |
| contextWindow: 100_000, | |
| maxTokens: 1_000, | |
| }, | |
| authStorage, | |
| authProfileStore: { version: 1, profiles: {} }, | |
| modelRegistry: ModelRegistry.inMemory(authStorage), | |
| thinkLevel: "off", | |
| }, | |
| }); | |
| expect(patch?.mcp_servers.docs).toMatchObject({ | |
| enabled_tools: ["read_docs"], | |
| disabled_tools: ["app_docs", "delete_docs", "task_docs"], | |
| }); | |
| } finally { | |
| await retireSessionMcpRuntime({ sessionId, reason: "test-complete" }); | |
| } | |
| }, | |
| ); | |
| }, | |
| ); | |
| it("disables Codex native web search without bundle MCP", async () => { | |
| const prepared = await prepareCliBundleMcpConfig({ | |
| enabled: false, | |
| mode: "codex-config-overrides", | |
| backend: { command: "codex", args: ["exec"] }, | |
| workspaceDir: "/tmp/openclaw-cli-codex-web-search-disabled", | |
| toolOverrides: { webSearch: false }, | |
| }); | |
| expect(prepared.backend.args).toEqual(["exec", "-c", 'web_search="disabled"']); | |
| expect(prepared.mcpConfigHash).toMatch(/^[0-9a-f]{64}$/); | |
| }); | |
| it("projects session MCP tool denials into Codex disabled_tools", async () => { | |
| const prepared = await prepareCliBundleMcpConfig({ | |
| enabled: true, | |
| mode: "codex-config-overrides", | |
| backend: { command: "codex", args: ["exec"] }, | |
| workspaceDir: "/tmp/openclaw-bundle-mcp-codex-deny", | |
| config: { | |
| plugins: { enabled: false }, | |
| mcp: { | |
| servers: { | |
| docs: { transport: "streamable-http", url: "https://docs.example.com/mcp" }, | |
| }, | |
| }, | |
| }, | |
| toolOverrides: { mcpToolsDeny: { docs: ["delete_docs"] }, webSearch: false }, | |
| }); | |
| expect(prepared.backend.args?.find((arg) => arg.startsWith("mcp_servers="))).toContain( | |
| 'disabled_tools = ["delete_docs"]', | |
| ); | |
| expect(prepared.backend.args).toContain('web_search="disabled"'); | |
| }); | |
| it("projects configured wildcard filters as exact Codex CLI overrides", async () => { | |
| const serverPath = await writeCliMcpPolicyProbeServer(); | |
| const config: OpenClawConfig = { | |
| plugins: { enabled: false }, | |
| tools: { allow: ["docs__*"] }, | |
| mcp: { | |
| servers: { | |
| docs: { | |
| command: process.execPath, | |
| args: [serverPath], | |
| toolFilter: { exclude: ["delete_*"] }, | |
| }, | |
| }, | |
| }, | |
| }; | |
| const prepared = await prepareCliBundleMcpConfig({ | |
| enabled: true, | |
| mode: "codex-config-overrides", | |
| backend: { command: "codex", args: ["exec"] }, | |
| workspaceDir: cliBundleMcpHarness.bundleProbeWorkspaceDir, | |
| config, | |
| nativeMcpPolicy: cliNativeMcpPolicyContext(config, "codex-cli-policy"), | |
| }); | |
| const override = prepared.backend.args?.find((arg) => arg.startsWith("mcp_servers=")); | |
| expect(override).toContain('enabled_tools = ["read_docs"]'); | |
| expect(override).toContain('disabled_tools = ["app_docs", "delete_docs", "task_docs"]'); | |
| expect(override).not.toContain("delete_*"); | |
| }); | |
| it("hides non-model MCP tools from Codex without an explicit policy", async () => { | |
| const serverPath = await writeCliMcpPolicyProbeServer(); | |
| const config: OpenClawConfig = { | |
| plugins: { enabled: false }, | |
| mcp: { servers: { docs: { command: process.execPath, args: [serverPath] } } }, | |
| }; | |
| const prepared = await prepareCliBundleMcpConfig({ | |
| enabled: true, | |
| mode: "codex-config-overrides", | |
| backend: { command: "codex", args: ["exec"] }, | |
| workspaceDir: cliBundleMcpHarness.bundleProbeWorkspaceDir, | |
| config, | |
| nativeMcpPolicy: cliNativeMcpPolicyContext(config, "codex-default-hidden"), | |
| }); | |
| const override = prepared.backend.args?.find((arg) => arg.startsWith("mcp_servers=")); | |
| expect(override).toContain('enabled_tools = ["delete_docs", "read_docs"]'); | |
| expect(override).toContain('disabled_tools = ["app_docs", "task_docs"]'); | |
| }); | |
| it("injects codex MCP config overrides with env-backed loopback headers", async () => { | |
| const prepared = await prepareCliBundleMcpConfig({ | |
| enabled: true, | |
| mode: "codex-config-overrides", | |
| backend: { | |
| command: "codex", | |
| args: ["exec", "--json"], | |
| resumeArgs: ["exec", "resume", "{sessionId}"], | |
| }, | |
| workspaceDir: "/tmp/openclaw-bundle-mcp-codex", | |
| config: { plugins: { enabled: false } }, | |
| additionalConfig: { | |
| mcpServers: { | |
| openclaw: { | |
| type: "http", | |
| url: "http://127.0.0.1:23119/mcp", | |
| headers: { | |
| Authorization: "Bearer ${OPENCLAW_MCP_TOKEN}", | |
| "x-session-key": "${OPENCLAW_MCP_SESSION_KEY}", | |
| "x-openclaw-cli-capture-key": "${OPENCLAW_MCP_CLI_CAPTURE_KEY}", | |
| }, | |
| }, | |
| }, | |
| }, | |
| }); | |
| // Codex consumes MCP config through TOML-like -c overrides instead of a | |
| // generated config file. | |
| expect(prepared.backend.args).toEqual([ | |
| "exec", | |
| "--json", | |
| "-c", | |
| 'mcp_servers={ openclaw = { url = "http://127.0.0.1:23119/mcp", default_tools_approval_mode = "approve", bearer_token_env_var = "OPENCLAW_MCP_TOKEN", env_http_headers = { x-session-key = "OPENCLAW_MCP_SESSION_KEY", x-openclaw-cli-capture-key = "OPENCLAW_MCP_CLI_CAPTURE_KEY" } } }', | |
| ]); | |
| expect(prepared.backend.resumeArgs).toEqual([ | |
| "exec", | |
| "resume", | |
| "{sessionId}", | |
| "-c", | |
| 'mcp_servers={ openclaw = { url = "http://127.0.0.1:23119/mcp", default_tools_approval_mode = "approve", bearer_token_env_var = "OPENCLAW_MCP_TOKEN", env_http_headers = { x-session-key = "OPENCLAW_MCP_SESSION_KEY", x-openclaw-cli-capture-key = "OPENCLAW_MCP_CLI_CAPTURE_KEY" } } }', | |
| ]); | |
| expect(prepared.cleanup).toBeUndefined(); | |
| }); | |
| }); | |