codex-computer-use-mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/ARCHITECTURE.md +134 -0
  2. package/CONTRIBUTING.md +16 -10
  3. package/MIGRATION.md +77 -0
  4. package/PROOF.md +114 -67
  5. package/README.md +94 -116
  6. package/SECURITY.md +43 -22
  7. package/dist/audit.d.ts +15 -14
  8. package/dist/audit.js +1 -1
  9. package/dist/audit.js.map +1 -1
  10. package/dist/config.d.ts +8 -8
  11. package/dist/config.js +8 -103
  12. package/dist/config.js.map +1 -1
  13. package/dist/direct-broker.d.ts +57 -0
  14. package/dist/direct-broker.js +638 -0
  15. package/dist/direct-broker.js.map +1 -0
  16. package/dist/direct-service.d.ts +31 -0
  17. package/dist/direct-service.js +345 -0
  18. package/dist/direct-service.js.map +1 -0
  19. package/dist/lock.d.ts +1 -0
  20. package/dist/lock.js +32 -3
  21. package/dist/lock.js.map +1 -1
  22. package/dist/mcp-server.js +46 -105
  23. package/dist/mcp-server.js.map +1 -1
  24. package/dist/system.d.ts +0 -1
  25. package/dist/system.js +12 -37
  26. package/dist/system.js.map +1 -1
  27. package/dist/tools.d.ts +78 -0
  28. package/dist/tools.js +192 -0
  29. package/dist/tools.js.map +1 -0
  30. package/integrations/pi/README.md +41 -27
  31. package/integrations/pi/index.ts +110 -123
  32. package/integrations/pi/mcp.json.example +3 -3
  33. package/npm-shrinkwrap.json +3278 -48
  34. package/package.json +40 -13
  35. package/dist/policy.d.ts +0 -42
  36. package/dist/policy.js +0 -428
  37. package/dist/policy.js.map +0 -1
  38. package/dist/prompt.d.ts +0 -62
  39. package/dist/prompt.js +0 -119
  40. package/dist/prompt.js.map +0 -1
  41. package/dist/runner.d.ts +0 -55
  42. package/dist/runner.js +0 -494
  43. package/dist/runner.js.map +0 -1
  44. package/dist/service.d.ts +0 -17
  45. package/dist/service.js +0 -382
  46. package/dist/service.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -1,50 +1,64 @@
1
- # Pi adapters
1
+ # Pi integration
2
2
 
3
- Choose **one** integration path. Do not load both under the same tool name.
3
+ The native Pi adapter is the primary 0.2 path. It registers ten namespaced typed tools so Pi itself chooses each official Computer Use method and argument.
4
4
 
5
- ## Native Pi package adapter
5
+ ## Source checkout acceptance
6
6
 
7
7
  ```bash
8
- pi install npm:codex-computer-use-mcp@0.1.0
8
+ npm ci
9
+ npm run build
10
+ CODEX_COMPUTER_USE_HOME="$(mktemp -d)" \
11
+ pi -ne -e /absolute/path/to/codex-computer-use-mcp/integrations/pi/index.ts
9
12
  ```
10
13
 
11
- The package manifest loads `integrations/pi/index.ts` and registers:
14
+ `-ne` prevents an installed 0.1 adapter from loading at the same time. This source workflow does not install or switch live Pi configuration.
12
15
 
13
- - `background_computer_use`
14
- - `/background-computer-use-status`
15
- - `/background-computer-use-mode`
16
-
17
- The adapter imports the same compiled service used by the MCP server; it does not fork the security-critical runner or policy. Pi signals tool failures by thrown error, so cancellation text carries observed methods and non-retry guidance while the complete structured method list remains in the private audit.
18
-
19
- For a local checkout:
16
+ For normal installation, use the exact version 0.2.0 npm package:
20
17
 
21
18
  ```bash
22
- npm ci && npm run build
23
- pi -ne -e /absolute/path/to/codex-computer-use-mcp/integrations/pi/index.ts
19
+ pi install npm:codex-computer-use-mcp@0.2.0
24
20
  ```
25
21
 
26
- `-ne` avoids a duplicate-tool conflict if another copy is already installed.
22
+ Use the source workflow only when you need to test an exact reviewed commit. Follow the rollback procedure in `MIGRATION.md` when replacing version 0.1.
23
+
24
+ ## Registered surface
25
+
26
+ - `computer_use_list_apps`
27
+ - `computer_use_get_app_state`
28
+ - `computer_use_click`
29
+ - `computer_use_perform_secondary_action`
30
+ - `computer_use_set_value`
31
+ - `computer_use_select_text`
32
+ - `computer_use_scroll`
33
+ - `computer_use_drag`
34
+ - `computer_use_press_key`
35
+ - `computer_use_type_text`
36
+ - `/computer-use-status`
27
37
 
28
- ## Pi MCP gateway
38
+ No-permissions is the only policy: all ten tools are available with no wrapper approval prompts, mode selector, or app/intent/action gate. Pi does not advertise or render elicitation UI. Unexpected downstream elicitations are silently declined and never accepted.
29
39
 
30
- Merge [`mcp.json.example`](mcp.json.example) into `~/.pi/agent/mcp.json`, then reload Pi.
40
+ ## Generic MCP gateway
31
41
 
32
- `directTools: false` is intentional. It keeps this powerful capability behind Pi's MCP gateway instead of injecting it into every agent turn as an always-on direct tool.
42
+ Merge `mcp.json.example` only for the exact 0.2.0 package or after building an exact reviewed source commit. `directTools: false` is intentional; it keeps this powerful generic MCP surface behind Pi's gateway.
33
43
 
34
- For a local checkout, replace the command and arguments with:
44
+ For a source checkout:
35
45
 
36
46
  ```json
37
47
  {
38
- "command": "node",
39
- "args": ["/absolute/path/to/codex-computer-use-mcp/dist/mcp-server.js"],
40
- "lifecycle": "lazy",
41
- "requestTimeoutMs": 360000,
42
- "directTools": false
48
+ "mcpServers": {
49
+ "computer-use-direct-source": {
50
+ "command": "node",
51
+ "args": ["/absolute/path/to/codex-computer-use-mcp/dist/mcp-server.js"],
52
+ "lifecycle": "lazy",
53
+ "requestTimeoutMs": 180000,
54
+ "directTools": false
55
+ }
56
+ }
43
57
  }
44
58
  ```
45
59
 
46
- ## Permission warning
60
+ Do not load the native adapter and generic MCP adapter into the same acceptance process unless tool names are intentionally isolated.
47
61
 
48
- Standalone safe mode is list-only. `inspect`, `act`, and `dictionary_lookup` require explicitly acknowledged full-permissions mode. Full mode broadly authorizes wrapper use of official Computer Use because target checks cannot be placed before signed-client dispatch without breaking official sender authentication. Read the root README before enabling it.
62
+ The generic MCP path uses the same durable no-permissions policy: all ten methods, no wrapper approval UI, and silent decline of unexpected downstream elicitations. Configure persistent app access only through official ChatGPT Computer Use settings.
49
63
 
50
- Do not register the app-bundled Codex broker itself as a direct tool. This wrapper provides signing checks, post-dispatch validation, focus monitoring, locking, cleanup criteria, and private audits.
64
+ See the root `MIGRATION.md` before replacing an installed 0.1 adapter.
@@ -1,135 +1,122 @@
1
- import crypto from "node:crypto";
2
1
  import path from "node:path";
3
2
  import { StringEnum } from "@earendil-works/pi-ai";
4
- import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+ import { getAgentDir, truncateHead, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
4
  import { Text } from "@earendil-works/pi-tui";
6
- import { Type } from "typebox";
7
- import { appendAudit, type AuditRecord } from "../../dist/audit.js";
8
- import { ConfigError, loadConfig, saveConfig } from "../../dist/config.js";
9
- import { COMPUTER_USE_TOOLS, MODEL } from "../../dist/policy.js";
10
- import { executeOperation, getStatus } from "../../dist/service.js";
5
+ import { Type, type TSchema } from "typebox";
6
+ import { executeDirectTool, getDirectStatus } from "../../dist/direct-service.js";
7
+ import type { DirectMethod } from "../../dist/tools.js";
11
8
 
12
- const Params = Type.Object({
13
- mode: StringEnum(["list", "inspect", "act", "dictionary_lookup"] as const, {
14
- description: "safe mode permits only list; targeted modes require explicitly acknowledged broad full-permissions",
15
- }),
16
- app: Type.Optional(Type.String({ maxLength: 500, description: "App name, bundle identifier, or app-bundle path" })),
17
- task: Type.Optional(Type.String({ maxLength: 4000, description: "Concrete target-app task for act mode" })),
18
- query: Type.Optional(Type.String({ maxLength: 200, description: "Local word or phrase for dictionary_lookup" })),
19
- cleanup: Type.Optional(Type.Boolean({ description: "Restore transient state and verify cleanup" })),
20
- cleanup_instructions: Type.Optional(Type.String({ maxLength: 2000, description: "Optional cleanup postcondition" })),
21
- required_capabilities: Type.Optional(
22
- Type.Array(StringEnum(COMPUTER_USE_TOOLS), {
23
- maxItems: 8,
24
- description: "Official Computer Use methods that must genuinely be exercised",
25
- }),
26
- ),
27
- });
9
+ const App = Type.String({ minLength: 1, maxLength: 500, description: "App name, full app path, or unambiguous bundle identifier" });
10
+ const Element = Type.String({ minLength: 1, maxLength: 200, description: "Element identifier from computer_use_get_app_state" });
11
+ const Coordinate = Type.Number({ minimum: 0, maximum: 1_000_000 });
28
12
 
29
- export default function codexComputerUse(pi: ExtensionAPI) {
30
- const stateRoot = process.env.CODEX_COMPUTER_USE_HOME || path.join(getAgentDir(), "background-computer-use");
13
+ const ToolParameters: Record<DirectMethod, TSchema> = {
14
+ list_apps: Type.Object({}, { additionalProperties: false }),
15
+ get_app_state: Type.Object({ app: App }, { additionalProperties: false }),
16
+ click: Type.Object({
17
+ app: App,
18
+ click_count: Type.Optional(Type.Integer({ minimum: 1, maximum: 10 })),
19
+ element_index: Type.Optional(Element),
20
+ mouse_button: Type.Optional(StringEnum(["left", "right", "middle"] as const)),
21
+ x: Type.Optional(Coordinate),
22
+ y: Type.Optional(Coordinate),
23
+ }, { additionalProperties: false }),
24
+ perform_secondary_action: Type.Object({ app: App, element_index: Element, action: Type.String({ minLength: 1, maxLength: 200 }) }, { additionalProperties: false }),
25
+ set_value: Type.Object({ app: App, element_index: Element, value: Type.String({ maxLength: 20_000 }) }, { additionalProperties: false }),
26
+ select_text: Type.Object({
27
+ app: App,
28
+ element_index: Element,
29
+ text: Type.String({ minLength: 1, maxLength: 20_000 }),
30
+ prefix: Type.Optional(Type.String({ maxLength: 2_000 })),
31
+ selection: Type.Optional(StringEnum(["text", "cursor_before", "cursor_after"] as const)),
32
+ suffix: Type.Optional(Type.String({ maxLength: 2_000 })),
33
+ }, { additionalProperties: false }),
34
+ scroll: Type.Object({
35
+ app: App,
36
+ element_index: Element,
37
+ direction: StringEnum(["up", "down", "left", "right"] as const),
38
+ pages: Type.Optional(Type.Number({ exclusiveMinimum: 0, maximum: 100 })),
39
+ }, { additionalProperties: false }),
40
+ drag: Type.Object({ app: App, from_x: Coordinate, from_y: Coordinate, to_x: Coordinate, to_y: Coordinate }, { additionalProperties: false }),
41
+ press_key: Type.Object({ app: App, key: Type.String({ minLength: 1, maxLength: 100, description: "Key or combination; common aliases such as CMD+A are normalized to the official xdotool-style Meta_L+a form" }) }, { additionalProperties: false }),
42
+ type_text: Type.Object({ app: App, text: Type.String({ maxLength: 20_000 }) }, { additionalProperties: false }),
43
+ };
31
44
 
32
- pi.registerCommand("background-computer-use-status", {
33
- description: "Show permission mode, signed Computer Use surface, audit path, and approval boundary",
45
+ function toolDescription(method: DirectMethod): string {
46
+ return `Call the official signed Computer Use ${method} capability directly through the unrestricted no-permissions interface. Pi supplies the typed arguments itself; there is no wrapper approval prompt, mode gate, nested model, planner, prompt, or separate model-token usage.`;
47
+ }
48
+
49
+ function titleFor(method: DirectMethod): string {
50
+ return method.split("_").map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
51
+ }
52
+
53
+ function toPiContent(content: Array<Record<string, unknown>>): Array<{ type: "text"; text: string } | { type: "image"; data: string; mimeType: string }> {
54
+ const result: Array<{ type: "text"; text: string } | { type: "image"; data: string; mimeType: string }> = [];
55
+ for (const block of content) {
56
+ if (block.type === "image") {
57
+ result.push({ type: "image", data: String(block.data), mimeType: String(block.mimeType) });
58
+ continue;
59
+ }
60
+ const original = String(block.text ?? "");
61
+ const truncated = truncateHead(original, { maxLines: 2_000, maxBytes: 50 * 1024 });
62
+ const suffix = truncated.truncated
63
+ ? `\n\n[Official Computer Use text truncated in-memory: ${truncated.outputLines}/${truncated.totalLines} lines, ${truncated.outputBytes}/${truncated.totalBytes} bytes. No full-output file was written.]`
64
+ : "";
65
+ result.push({ type: "text", text: `${truncated.content}${suffix}` });
66
+ }
67
+ return result;
68
+ }
69
+
70
+ function errorText(content: Array<Record<string, unknown>>): string {
71
+ return content
72
+ .filter((block) => block.type === "text")
73
+ .map((block) => String(block.text ?? ""))
74
+ .join("\n")
75
+ .slice(0, 2_000) || "Official Computer Use returned an error";
76
+ }
77
+
78
+ export default function directComputerUse(pi: ExtensionAPI) {
79
+ const stateRoot = process.env.CODEX_COMPUTER_USE_HOME || path.join(getAgentDir(), "direct-computer-use");
80
+
81
+ pi.registerCommand("computer-use-status", {
82
+ description: "Show the direct-call architecture, durable no-permissions policy, signed broker, and private audit path",
34
83
  handler: async (_args, ctx) => {
35
- const status = await getStatus(stateRoot);
36
- ctx.ui.notify(JSON.stringify(status, null, 2), status.permissionMode === "full-permissions" ? "warning" : "info");
84
+ const status = await getDirectStatus(stateRoot);
85
+ ctx.ui.notify(JSON.stringify(status, null, 2), "info");
37
86
  },
38
87
  });
39
88
 
40
- pi.registerCommand("background-computer-use-mode", {
41
- description: "Show or explicitly change safe/default vs full-permissions mode",
42
- handler: async (args, ctx) => {
43
- const requested = args.trim();
44
- const current = await loadConfig(stateRoot);
45
- if (!requested) {
46
- ctx.ui.notify(`Current Computer Use permission mode: ${current.permissionMode}`, "info");
47
- return;
48
- }
49
- if (requested !== "safe" && requested !== "full-permissions") {
50
- throw new ConfigError("Usage: /background-computer-use-mode safe|full-permissions");
51
- }
52
- if (requested === current.permissionMode) {
53
- ctx.ui.notify(`Computer Use permission mode is already ${requested}.`, "info");
54
- return;
55
- }
56
- if (requested === "full-permissions") {
57
- if (!ctx.hasUI) throw new ConfigError("Enabling full-permissions requires an interactive Pi UI");
58
- const confirmed = await ctx.ui.confirm(
59
- "Enable FULL Computer Use permissions?",
60
- "This broadly enables targeted operations that safe mode refuses. Official OpenAI/macOS approvals and signing, post-dispatch validation, lock, focus, timeout, cleanup, and audit controls remain.",
61
- { timeout: 60_000 },
89
+ const methods = Object.keys(ToolParameters) as DirectMethod[];
90
+ for (const method of methods) {
91
+ const piName = `computer_use_${method}`;
92
+ pi.registerTool({
93
+ name: piName,
94
+ label: titleFor(method),
95
+ description: toolDescription(method),
96
+ promptSnippet: `${titleFor(method)} through the official signed macOS Computer Use service`,
97
+ promptGuidelines: [
98
+ `${piName} is a direct typed tool: choose its arguments yourself; it does not invoke a nested planner or model.`,
99
+ `${piName} must use current element identifiers from computer_use_get_app_state; inspect again after UI state changes.`,
100
+ `${piName} must not be used for credentials, authentication, payments, external messages, or destructive actions without the user's explicit request; this wrapper will not open a permission prompt.`,
101
+ ],
102
+ parameters: ToolParameters[method] as any,
103
+ async execute(_toolCallId, params, signal, onUpdate) {
104
+ const response = await executeDirectTool(
105
+ { method, arguments: params as Record<string, unknown> },
106
+ {
107
+ stateRoot,
108
+ signal,
109
+ onProgress: (message) => onUpdate?.({ content: [{ type: "text", text: message }], details: { status: "running" } }),
110
+ },
62
111
  );
63
- if (!confirmed) {
64
- ctx.ui.notify("Full-permissions mode was not enabled.", "info");
65
- return;
66
- }
67
- }
68
- await saveConfig(stateRoot, { version: 1, permissionMode: requested });
69
- const record: AuditRecord = {
70
- timestamp: new Date().toISOString(),
71
- runId: crypto.randomUUID(),
72
- operation: "configure",
73
- permissionMode: requested,
74
- app: null,
75
- mutating: true,
76
- cleanupRequested: false,
77
- userConfirmed: requested === "full-permissions",
78
- authorization: requested === "full-permissions" ? "full_permissions_config" : "none",
79
- inputBytes: 0,
80
- outcome: "ok",
81
- durationMs: 0,
82
- model: MODEL,
83
- usage: { input: 0, cachedInput: 0, output: 0 },
84
- computerUseCalls: 0,
85
- computerUseMethods: [],
86
- backgroundPreserved: null,
87
- cleanupVerified: null,
88
- };
89
- try {
90
- await appendAudit(stateRoot, record);
91
- } catch {
92
- await saveConfig(stateRoot, current);
93
- throw new ConfigError("Permission mode change was rolled back because secure audit logging failed");
94
- }
95
- ctx.ui.notify(`Computer Use permission mode set to ${requested}.`, requested === "full-permissions" ? "warning" : "info");
96
- },
97
- });
98
-
99
- pi.registerTool({
100
- name: "background_computer_use",
101
- label: "Background Computer Use",
102
- description:
103
- "Use the official signed Codex Computer Use broker for native macOS apps. Safe mode is list-only; explicit full-permissions broadly authorizes targeted operations but never bypasses first-party approvals or technical controls. Calls consume separate Codex usage.",
104
- promptSnippet: "Inspect or operate a native macOS app in the background through signed Codex Computer Use",
105
- promptGuidelines: [
106
- "Use background_computer_use when the user asks to inspect or operate a native macOS app in the background.",
107
- "Set background_computer_use required_capabilities when the user explicitly needs click, secondary action, set value, select text, scroll, drag, keypress, or typing exercised.",
108
- "If background_computer_use reports a first-party approval or active app lease, do not retry automatically.",
109
- "Disclose that background_computer_use starts a nested Codex model call and consumes separate Codex usage.",
110
- ],
111
- parameters: Params,
112
- async execute(_toolCallId, params, signal, onUpdate, _ctx) {
113
- const response = await executeOperation(params, {
114
- stateRoot,
115
- signal,
116
- onProgress: (message) =>
117
- onUpdate?.({ content: [{ type: "text", text: message }], details: { status: "running" } }),
118
- });
119
- if (response.isError) throw new Error(response.text);
120
- return {
121
- content: [{ type: "text", text: response.text }],
122
- details: response.details,
123
- };
124
- },
125
- renderCall(args, theme) {
126
- return new Text(
127
- theme.fg("toolTitle", theme.bold("background_computer_use ")) +
128
- theme.fg("accent", String(args.app ?? "apps")) +
129
- theme.fg("muted", ` ${String(args.mode ?? "")}`),
130
- 0,
131
- 0,
132
- );
133
- },
134
- });
112
+ if (response.isError) throw new Error(errorText(response.content));
113
+ return { content: toPiContent(response.content), details: response.details };
114
+ },
115
+ renderCall(args, theme) {
116
+ const renderedArgs = args as Record<string, unknown>;
117
+ const app = typeof renderedArgs.app === "string" ? ` ${renderedArgs.app}` : "";
118
+ return new Text(theme.fg("toolTitle", theme.bold(`${piName} `)) + theme.fg("accent", app.trim()), 0, 0);
119
+ },
120
+ });
121
+ }
135
122
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "mcpServers": {
3
- "codex-computer-use": {
3
+ "computer-use-direct": {
4
4
  "command": "npx",
5
5
  "args": [
6
6
  "-y",
7
- "codex-computer-use-mcp@0.1.0"
7
+ "codex-computer-use-mcp@0.2.0"
8
8
  ],
9
9
  "lifecycle": "lazy",
10
- "requestTimeoutMs": 360000,
10
+ "requestTimeoutMs": 180000,
11
11
  "directTools": false,
12
12
  "debug": false
13
13
  }