open-computer-use 0.1.5 → 0.1.9
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.
- package/README.md +17 -2
- package/bin/open-codex-computer-use-mcp +83 -0
- package/bin/open-computer-use +83 -0
- package/bin/open-computer-use-mcp +83 -0
- package/dist/Open Computer Use.app/Contents/Info.plist +1 -1
- package/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse +0 -0
- package/package.json +4 -2
- package/plugins/open-computer-use/.codex-plugin/plugin.json +1 -1
- package/scripts/install-claude-mcp.sh +100 -0
- package/scripts/install-codex-mcp.sh +119 -0
- package/scripts/postinstall.mjs +20 -4
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ This package bundles a ready-to-run `Open Computer Use.app`, the Codex plugin me
|
|
|
14
14
|
npm install -g open-computer-use
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
After install, run `open-computer-use doctor` first. If macOS `Accessibility` or `Screen Recording` permission is missing, it will open the permission onboarding window and tell you what still needs to be granted.
|
|
18
|
+
|
|
17
19
|
## MCP config
|
|
18
20
|
|
|
19
21
|
If your MCP client accepts a stdio-style `mcpServers` JSON config, this is the default setup:
|
|
@@ -31,10 +33,23 @@ If your MCP client accepts a stdio-style `mcpServers` JSON config, this is the d
|
|
|
31
33
|
|
|
32
34
|
In practice, using this package as MCP is: global install, add the JSON config, then grant macOS `Accessibility` and `Screen Recording` permission to the host terminal or app on first use.
|
|
33
35
|
|
|
36
|
+
Package page: https://www.npmjs.com/package/open-computer-use
|
|
37
|
+
|
|
34
38
|
## Use
|
|
35
39
|
|
|
36
40
|
```bash
|
|
37
|
-
#
|
|
41
|
+
# Show global help, command help, and version
|
|
42
|
+
open-computer-use --help
|
|
43
|
+
open-computer-use help snapshot
|
|
44
|
+
open-computer-use --version
|
|
45
|
+
|
|
46
|
+
# Install into Claude Code for the current project
|
|
47
|
+
open-computer-use install-claude-mcp
|
|
48
|
+
|
|
49
|
+
# Install into Codex as a plain MCP entry in ~/.codex/config.toml
|
|
50
|
+
open-computer-use install-codex-mcp
|
|
51
|
+
|
|
52
|
+
# Check permissions first; if Accessibility / Screen Recording is missing, open the permission onboarding window
|
|
38
53
|
open-computer-use doctor
|
|
39
54
|
|
|
40
55
|
# Start the stdio MCP server for Claude Desktop, Cursor, Cline, or another MCP client
|
|
@@ -46,7 +61,7 @@ open-computer-use install-codex-plugin
|
|
|
46
61
|
|
|
47
62
|
## Notes
|
|
48
63
|
|
|
49
|
-
- Version: `0.1.
|
|
64
|
+
- Version: `0.1.9`
|
|
50
65
|
- Platform: macOS 14+
|
|
51
66
|
- Architectures: `arm64` and `x64` via a universal app bundle
|
|
52
67
|
- The host terminal or app still needs macOS `Accessibility` and `Screen Recording` permissions
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
+
print_launcher_help() {
|
|
5
|
+
cat <<'EOF'
|
|
6
|
+
Open Computer Use
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
open-computer-use [command] [options]
|
|
10
|
+
open-computer-use
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
mcp Start the stdio MCP server.
|
|
14
|
+
doctor Print permission status and launch onboarding if needed.
|
|
15
|
+
list-apps Print running or recently used apps.
|
|
16
|
+
snapshot <app> Print the current accessibility snapshot for an app.
|
|
17
|
+
turn-ended Acknowledge the host turn boundary.
|
|
18
|
+
install-claude-mcp Install the MCP server into ~/.claude.json for this project.
|
|
19
|
+
install-codex-mcp Install the MCP server into ~/.codex/config.toml.
|
|
20
|
+
install-codex-plugin Install this npm package into the local Codex plugin cache.
|
|
21
|
+
help [command] Show general or command-specific help.
|
|
22
|
+
version Print the CLI version.
|
|
23
|
+
|
|
24
|
+
Global options:
|
|
25
|
+
-h, --help Show help.
|
|
26
|
+
-v, --version Show version.
|
|
27
|
+
|
|
28
|
+
Notes:
|
|
29
|
+
Running without a command launches the permission onboarding app.
|
|
30
|
+
Use `open-computer-use help <command>` for command-specific help.
|
|
31
|
+
EOF
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
script_path="${BASH_SOURCE[0]}"
|
|
5
35
|
while [[ -L "${script_path}" ]]; do
|
|
6
36
|
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
|
|
@@ -11,13 +41,66 @@ while [[ -L "${script_path}" ]]; do
|
|
|
11
41
|
done
|
|
12
42
|
package_root="$(cd "$(dirname "${script_path}")/.." && pwd)"
|
|
13
43
|
app_binary="${package_root}/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
|
|
44
|
+
install_claude_mcp_script="${package_root}/scripts/install-claude-mcp.sh"
|
|
45
|
+
install_mcp_script="${package_root}/scripts/install-codex-mcp.sh"
|
|
14
46
|
install_script="${package_root}/scripts/install-codex-plugin.sh"
|
|
15
47
|
|
|
48
|
+
if [[ "${1:-}" == "install-claude-mcp" || "${1:-}" == "install-clauce-mcp" ]]; then
|
|
49
|
+
shift
|
|
50
|
+
exec "${install_claude_mcp_script}" "$@"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [[ "${1:-}" == "install-codex-mcp" ]]; then
|
|
54
|
+
shift
|
|
55
|
+
exec "${install_mcp_script}" "$@"
|
|
56
|
+
fi
|
|
57
|
+
|
|
16
58
|
if [[ "${1:-}" == "install-codex-plugin" ]]; then
|
|
17
59
|
shift
|
|
18
60
|
exec "${install_script}" "$@"
|
|
19
61
|
fi
|
|
20
62
|
|
|
63
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
64
|
+
print_launcher_help
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ "${1:-}" == "help" && $# -le 1 ]]; then
|
|
69
|
+
print_launcher_help
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-plugin" ]]; then
|
|
74
|
+
cat <<'EOF'
|
|
75
|
+
Usage:
|
|
76
|
+
open-computer-use install-codex-plugin
|
|
77
|
+
|
|
78
|
+
Install this npm package into the local Codex plugin cache.
|
|
79
|
+
EOF
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-mcp" ]]; then
|
|
84
|
+
cat <<'EOF'
|
|
85
|
+
Usage:
|
|
86
|
+
open-computer-use install-codex-mcp
|
|
87
|
+
|
|
88
|
+
Install the open-computer-use MCP server into ~/.codex/config.toml.
|
|
89
|
+
EOF
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [[ "${1:-}" == "help" && ( "${2:-}" == "install-claude-mcp" || "${2:-}" == "install-clauce-mcp" ) ]]; then
|
|
94
|
+
cat <<'EOF'
|
|
95
|
+
Usage:
|
|
96
|
+
open-computer-use install-claude-mcp
|
|
97
|
+
open-computer-use install-clauce-mcp
|
|
98
|
+
|
|
99
|
+
Install the open-computer-use MCP server into ~/.claude.json for the current project.
|
|
100
|
+
EOF
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
21
104
|
if [[ ! -x "${app_binary}" ]]; then
|
|
22
105
|
echo "open-computer-use could not find a runnable app bundle at ${app_binary}." >&2
|
|
23
106
|
exit 1
|
package/bin/open-computer-use
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
+
print_launcher_help() {
|
|
5
|
+
cat <<'EOF'
|
|
6
|
+
Open Computer Use
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
open-computer-use [command] [options]
|
|
10
|
+
open-computer-use
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
mcp Start the stdio MCP server.
|
|
14
|
+
doctor Print permission status and launch onboarding if needed.
|
|
15
|
+
list-apps Print running or recently used apps.
|
|
16
|
+
snapshot <app> Print the current accessibility snapshot for an app.
|
|
17
|
+
turn-ended Acknowledge the host turn boundary.
|
|
18
|
+
install-claude-mcp Install the MCP server into ~/.claude.json for this project.
|
|
19
|
+
install-codex-mcp Install the MCP server into ~/.codex/config.toml.
|
|
20
|
+
install-codex-plugin Install this npm package into the local Codex plugin cache.
|
|
21
|
+
help [command] Show general or command-specific help.
|
|
22
|
+
version Print the CLI version.
|
|
23
|
+
|
|
24
|
+
Global options:
|
|
25
|
+
-h, --help Show help.
|
|
26
|
+
-v, --version Show version.
|
|
27
|
+
|
|
28
|
+
Notes:
|
|
29
|
+
Running without a command launches the permission onboarding app.
|
|
30
|
+
Use `open-computer-use help <command>` for command-specific help.
|
|
31
|
+
EOF
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
script_path="${BASH_SOURCE[0]}"
|
|
5
35
|
while [[ -L "${script_path}" ]]; do
|
|
6
36
|
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
|
|
@@ -11,13 +41,66 @@ while [[ -L "${script_path}" ]]; do
|
|
|
11
41
|
done
|
|
12
42
|
package_root="$(cd "$(dirname "${script_path}")/.." && pwd)"
|
|
13
43
|
app_binary="${package_root}/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
|
|
44
|
+
install_claude_mcp_script="${package_root}/scripts/install-claude-mcp.sh"
|
|
45
|
+
install_mcp_script="${package_root}/scripts/install-codex-mcp.sh"
|
|
14
46
|
install_script="${package_root}/scripts/install-codex-plugin.sh"
|
|
15
47
|
|
|
48
|
+
if [[ "${1:-}" == "install-claude-mcp" || "${1:-}" == "install-clauce-mcp" ]]; then
|
|
49
|
+
shift
|
|
50
|
+
exec "${install_claude_mcp_script}" "$@"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [[ "${1:-}" == "install-codex-mcp" ]]; then
|
|
54
|
+
shift
|
|
55
|
+
exec "${install_mcp_script}" "$@"
|
|
56
|
+
fi
|
|
57
|
+
|
|
16
58
|
if [[ "${1:-}" == "install-codex-plugin" ]]; then
|
|
17
59
|
shift
|
|
18
60
|
exec "${install_script}" "$@"
|
|
19
61
|
fi
|
|
20
62
|
|
|
63
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
64
|
+
print_launcher_help
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ "${1:-}" == "help" && $# -le 1 ]]; then
|
|
69
|
+
print_launcher_help
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-plugin" ]]; then
|
|
74
|
+
cat <<'EOF'
|
|
75
|
+
Usage:
|
|
76
|
+
open-computer-use install-codex-plugin
|
|
77
|
+
|
|
78
|
+
Install this npm package into the local Codex plugin cache.
|
|
79
|
+
EOF
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-mcp" ]]; then
|
|
84
|
+
cat <<'EOF'
|
|
85
|
+
Usage:
|
|
86
|
+
open-computer-use install-codex-mcp
|
|
87
|
+
|
|
88
|
+
Install the open-computer-use MCP server into ~/.codex/config.toml.
|
|
89
|
+
EOF
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [[ "${1:-}" == "help" && ( "${2:-}" == "install-claude-mcp" || "${2:-}" == "install-clauce-mcp" ) ]]; then
|
|
94
|
+
cat <<'EOF'
|
|
95
|
+
Usage:
|
|
96
|
+
open-computer-use install-claude-mcp
|
|
97
|
+
open-computer-use install-clauce-mcp
|
|
98
|
+
|
|
99
|
+
Install the open-computer-use MCP server into ~/.claude.json for the current project.
|
|
100
|
+
EOF
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
21
104
|
if [[ ! -x "${app_binary}" ]]; then
|
|
22
105
|
echo "open-computer-use could not find a runnable app bundle at ${app_binary}." >&2
|
|
23
106
|
exit 1
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
+
print_launcher_help() {
|
|
5
|
+
cat <<'EOF'
|
|
6
|
+
Open Computer Use
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
open-computer-use [command] [options]
|
|
10
|
+
open-computer-use
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
mcp Start the stdio MCP server.
|
|
14
|
+
doctor Print permission status and launch onboarding if needed.
|
|
15
|
+
list-apps Print running or recently used apps.
|
|
16
|
+
snapshot <app> Print the current accessibility snapshot for an app.
|
|
17
|
+
turn-ended Acknowledge the host turn boundary.
|
|
18
|
+
install-claude-mcp Install the MCP server into ~/.claude.json for this project.
|
|
19
|
+
install-codex-mcp Install the MCP server into ~/.codex/config.toml.
|
|
20
|
+
install-codex-plugin Install this npm package into the local Codex plugin cache.
|
|
21
|
+
help [command] Show general or command-specific help.
|
|
22
|
+
version Print the CLI version.
|
|
23
|
+
|
|
24
|
+
Global options:
|
|
25
|
+
-h, --help Show help.
|
|
26
|
+
-v, --version Show version.
|
|
27
|
+
|
|
28
|
+
Notes:
|
|
29
|
+
Running without a command launches the permission onboarding app.
|
|
30
|
+
Use `open-computer-use help <command>` for command-specific help.
|
|
31
|
+
EOF
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
script_path="${BASH_SOURCE[0]}"
|
|
5
35
|
while [[ -L "${script_path}" ]]; do
|
|
6
36
|
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
|
|
@@ -11,13 +41,66 @@ while [[ -L "${script_path}" ]]; do
|
|
|
11
41
|
done
|
|
12
42
|
package_root="$(cd "$(dirname "${script_path}")/.." && pwd)"
|
|
13
43
|
app_binary="${package_root}/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
|
|
44
|
+
install_claude_mcp_script="${package_root}/scripts/install-claude-mcp.sh"
|
|
45
|
+
install_mcp_script="${package_root}/scripts/install-codex-mcp.sh"
|
|
14
46
|
install_script="${package_root}/scripts/install-codex-plugin.sh"
|
|
15
47
|
|
|
48
|
+
if [[ "${1:-}" == "install-claude-mcp" || "${1:-}" == "install-clauce-mcp" ]]; then
|
|
49
|
+
shift
|
|
50
|
+
exec "${install_claude_mcp_script}" "$@"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [[ "${1:-}" == "install-codex-mcp" ]]; then
|
|
54
|
+
shift
|
|
55
|
+
exec "${install_mcp_script}" "$@"
|
|
56
|
+
fi
|
|
57
|
+
|
|
16
58
|
if [[ "${1:-}" == "install-codex-plugin" ]]; then
|
|
17
59
|
shift
|
|
18
60
|
exec "${install_script}" "$@"
|
|
19
61
|
fi
|
|
20
62
|
|
|
63
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
64
|
+
print_launcher_help
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ "${1:-}" == "help" && $# -le 1 ]]; then
|
|
69
|
+
print_launcher_help
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-plugin" ]]; then
|
|
74
|
+
cat <<'EOF'
|
|
75
|
+
Usage:
|
|
76
|
+
open-computer-use install-codex-plugin
|
|
77
|
+
|
|
78
|
+
Install this npm package into the local Codex plugin cache.
|
|
79
|
+
EOF
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-mcp" ]]; then
|
|
84
|
+
cat <<'EOF'
|
|
85
|
+
Usage:
|
|
86
|
+
open-computer-use install-codex-mcp
|
|
87
|
+
|
|
88
|
+
Install the open-computer-use MCP server into ~/.codex/config.toml.
|
|
89
|
+
EOF
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [[ "${1:-}" == "help" && ( "${2:-}" == "install-claude-mcp" || "${2:-}" == "install-clauce-mcp" ) ]]; then
|
|
94
|
+
cat <<'EOF'
|
|
95
|
+
Usage:
|
|
96
|
+
open-computer-use install-claude-mcp
|
|
97
|
+
open-computer-use install-clauce-mcp
|
|
98
|
+
|
|
99
|
+
Install the open-computer-use MCP server into ~/.claude.json for the current project.
|
|
100
|
+
EOF
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
21
104
|
if [[ ! -x "${app_binary}" ]]; then
|
|
22
105
|
echo "open-computer-use could not find a runnable app bundle at ${app_binary}." >&2
|
|
23
106
|
exit 1
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-computer-use",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Prebuilt macOS Computer Use MCP server
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "Prebuilt macOS Computer Use MCP server. After install, run open-computer-use doctor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/iFurySt/open-codex-computer-use",
|
|
7
7
|
"repository": {
|
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
"plugins/open-computer-use/.mcp.json",
|
|
46
46
|
"plugins/open-computer-use/assets/",
|
|
47
47
|
"plugins/open-computer-use/scripts/",
|
|
48
|
+
"scripts/install-claude-mcp.sh",
|
|
49
|
+
"scripts/install-codex-mcp.sh",
|
|
48
50
|
"scripts/install-codex-plugin.sh",
|
|
49
51
|
"scripts/postinstall.mjs",
|
|
50
52
|
"README.md",
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
claude_config_path="${CLAUDE_CONFIG_PATH:-${HOME}/.claude.json}"
|
|
6
|
+
project_root="$(pwd -P)"
|
|
7
|
+
server_name="open-computer-use"
|
|
8
|
+
command_name="open-computer-use"
|
|
9
|
+
|
|
10
|
+
usage() {
|
|
11
|
+
cat <<'EOF'
|
|
12
|
+
Usage: ./scripts/install-claude-mcp.sh
|
|
13
|
+
|
|
14
|
+
Install the open-computer-use stdio MCP entry into ~/.claude.json for the current project.
|
|
15
|
+
The script is idempotent: if the same MCP server entry already exists, it leaves the file unchanged.
|
|
16
|
+
EOF
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
while [[ $# -gt 0 ]]; do
|
|
20
|
+
case "$1" in
|
|
21
|
+
-h|--help)
|
|
22
|
+
usage
|
|
23
|
+
exit 0
|
|
24
|
+
;;
|
|
25
|
+
*)
|
|
26
|
+
echo "Unknown argument: $1" >&2
|
|
27
|
+
usage >&2
|
|
28
|
+
exit 1
|
|
29
|
+
;;
|
|
30
|
+
esac
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
python3 - "${claude_config_path}" "${project_root}" "${server_name}" "${command_name}" <<'PY'
|
|
34
|
+
import json
|
|
35
|
+
import sys
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
|
|
38
|
+
config_path = Path(sys.argv[1])
|
|
39
|
+
project_root = sys.argv[2]
|
|
40
|
+
server_name = sys.argv[3]
|
|
41
|
+
command_name = sys.argv[4]
|
|
42
|
+
desired_entry = {
|
|
43
|
+
"type": "stdio",
|
|
44
|
+
"command": command_name,
|
|
45
|
+
"args": ["mcp"],
|
|
46
|
+
}
|
|
47
|
+
legacy_server_name = "open-codex-computer-use"
|
|
48
|
+
|
|
49
|
+
if config_path.exists():
|
|
50
|
+
try:
|
|
51
|
+
raw = config_path.read_text()
|
|
52
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
53
|
+
except json.JSONDecodeError as exc:
|
|
54
|
+
print(f"Existing Claude config is not valid JSON: {exc}", file=sys.stderr)
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
else:
|
|
57
|
+
data = {}
|
|
58
|
+
|
|
59
|
+
if not isinstance(data, dict):
|
|
60
|
+
print("Existing Claude config root is not a JSON object; refusing to modify it.", file=sys.stderr)
|
|
61
|
+
sys.exit(1)
|
|
62
|
+
|
|
63
|
+
projects = data.setdefault("projects", {})
|
|
64
|
+
if not isinstance(projects, dict):
|
|
65
|
+
print('Existing Claude config has non-object "projects"; refusing to modify it.', file=sys.stderr)
|
|
66
|
+
sys.exit(1)
|
|
67
|
+
|
|
68
|
+
project_entry = projects.setdefault(project_root, {})
|
|
69
|
+
if not isinstance(project_entry, dict):
|
|
70
|
+
print(f'Existing Claude project entry for {project_root} is not an object; refusing to modify it.', file=sys.stderr)
|
|
71
|
+
sys.exit(1)
|
|
72
|
+
|
|
73
|
+
mcp_servers = project_entry.setdefault("mcpServers", {})
|
|
74
|
+
if not isinstance(mcp_servers, dict):
|
|
75
|
+
print(f'Existing Claude project MCP config for {project_root} is not an object; refusing to modify it.', file=sys.stderr)
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
|
|
78
|
+
target = mcp_servers.get(server_name)
|
|
79
|
+
legacy = mcp_servers.get(legacy_server_name)
|
|
80
|
+
|
|
81
|
+
target_matches = target == desired_entry
|
|
82
|
+
legacy_matches = legacy == desired_entry
|
|
83
|
+
|
|
84
|
+
if target_matches and not legacy_matches:
|
|
85
|
+
print(f'Claude MCP server "{server_name}" is already installed for {project_root} in {config_path}.')
|
|
86
|
+
sys.exit(0)
|
|
87
|
+
|
|
88
|
+
mcp_servers[server_name] = desired_entry
|
|
89
|
+
|
|
90
|
+
if legacy_matches:
|
|
91
|
+
del mcp_servers[legacy_server_name]
|
|
92
|
+
|
|
93
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
94
|
+
config_path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n")
|
|
95
|
+
|
|
96
|
+
if target_matches and legacy_matches:
|
|
97
|
+
print(f'Claude MCP server "{server_name}" was already installed for {project_root}; removed legacy alias "{legacy_server_name}" from {config_path}.')
|
|
98
|
+
else:
|
|
99
|
+
print(f'Installed Claude MCP server "{server_name}" for {project_root} into {config_path}.')
|
|
100
|
+
PY
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
codex_home="${CODEX_HOME:-${HOME}/.codex}"
|
|
6
|
+
config_path="${codex_home}/config.toml"
|
|
7
|
+
server_name="open-computer-use"
|
|
8
|
+
command_name="open-computer-use"
|
|
9
|
+
|
|
10
|
+
usage() {
|
|
11
|
+
cat <<'EOF'
|
|
12
|
+
Usage: ./scripts/install-codex-mcp.sh
|
|
13
|
+
|
|
14
|
+
Install the open-computer-use stdio MCP entry into ~/.codex/config.toml.
|
|
15
|
+
The script is idempotent: if the same MCP server entry already exists, it leaves the file unchanged.
|
|
16
|
+
EOF
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
while [[ $# -gt 0 ]]; do
|
|
20
|
+
case "$1" in
|
|
21
|
+
-h|--help)
|
|
22
|
+
usage
|
|
23
|
+
exit 0
|
|
24
|
+
;;
|
|
25
|
+
*)
|
|
26
|
+
echo "Unknown argument: $1" >&2
|
|
27
|
+
usage >&2
|
|
28
|
+
exit 1
|
|
29
|
+
;;
|
|
30
|
+
esac
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
mkdir -p "${codex_home}"
|
|
34
|
+
|
|
35
|
+
python3 - "${config_path}" "${server_name}" "${command_name}" <<'PY'
|
|
36
|
+
import json
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
import tomllib
|
|
43
|
+
except ModuleNotFoundError as exc:
|
|
44
|
+
print(f"python3 with tomllib is required: {exc}", file=sys.stderr)
|
|
45
|
+
sys.exit(1)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def section_pattern(header: str) -> re.Pattern[str]:
|
|
49
|
+
return re.compile(rf'(?ms)^\[{re.escape(header)}\]\n.*?(?=^\[|\Z)')
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def remove_section(text: str, header: str) -> str:
|
|
53
|
+
return section_pattern(header).sub("", text)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def upsert_section(text: str, header: str, body: str) -> str:
|
|
57
|
+
section = f'[{header}]\n{body.rstrip()}\n'
|
|
58
|
+
pattern = section_pattern(header)
|
|
59
|
+
if pattern.search(text):
|
|
60
|
+
return pattern.sub(section, text, count=1)
|
|
61
|
+
|
|
62
|
+
if text and not text.endswith("\n"):
|
|
63
|
+
text += "\n"
|
|
64
|
+
if text and not text.endswith("\n\n"):
|
|
65
|
+
text += "\n"
|
|
66
|
+
return text + section
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
config_path = Path(sys.argv[1])
|
|
70
|
+
server_name = sys.argv[2]
|
|
71
|
+
command_name = sys.argv[3]
|
|
72
|
+
desired_args = ["mcp"]
|
|
73
|
+
legacy_server_name = "open-codex-computer-use"
|
|
74
|
+
|
|
75
|
+
text = config_path.read_text() if config_path.exists() else ""
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
parsed = tomllib.loads(text) if text.strip() else {}
|
|
79
|
+
except tomllib.TOMLDecodeError as exc:
|
|
80
|
+
print(f"Existing Codex config is not valid TOML: {exc}", file=sys.stderr)
|
|
81
|
+
sys.exit(1)
|
|
82
|
+
|
|
83
|
+
mcp_servers = parsed.get("mcp_servers")
|
|
84
|
+
if mcp_servers is not None and not isinstance(mcp_servers, dict):
|
|
85
|
+
print('Existing Codex config has non-table "mcp_servers"; refusing to modify it.', file=sys.stderr)
|
|
86
|
+
sys.exit(1)
|
|
87
|
+
|
|
88
|
+
target = (mcp_servers or {}).get(server_name)
|
|
89
|
+
legacy = (mcp_servers or {}).get(legacy_server_name)
|
|
90
|
+
|
|
91
|
+
target_matches = (
|
|
92
|
+
isinstance(target, dict)
|
|
93
|
+
and target.get("command") == command_name
|
|
94
|
+
and target.get("args") == desired_args
|
|
95
|
+
)
|
|
96
|
+
legacy_matches = (
|
|
97
|
+
isinstance(legacy, dict)
|
|
98
|
+
and legacy.get("command") == command_name
|
|
99
|
+
and legacy.get("args") == desired_args
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if target_matches and not legacy_matches:
|
|
103
|
+
print(f'Codex MCP server "{server_name}" is already installed in {config_path}.')
|
|
104
|
+
sys.exit(0)
|
|
105
|
+
|
|
106
|
+
body = f'command = {json.dumps(command_name)}\nargs = {json.dumps(desired_args)}'
|
|
107
|
+
text = upsert_section(text, f'mcp_servers."{server_name}"', body)
|
|
108
|
+
|
|
109
|
+
if legacy_matches:
|
|
110
|
+
text = remove_section(text, f'mcp_servers."{legacy_server_name}"')
|
|
111
|
+
|
|
112
|
+
text = re.sub(r"\n{3,}", "\n\n", text).rstrip() + "\n"
|
|
113
|
+
config_path.write_text(text)
|
|
114
|
+
|
|
115
|
+
if target_matches and legacy_matches:
|
|
116
|
+
print(f'Codex MCP server "{server_name}" was already installed; removed legacy alias "{legacy_server_name}" from {config_path}.')
|
|
117
|
+
else:
|
|
118
|
+
print(f'Installed Codex MCP server "{server_name}" into {config_path}.')
|
|
119
|
+
PY
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const mcpConfig = {
|
|
3
|
+
"mcpServers": {
|
|
4
|
+
"open-computer-use": {
|
|
5
|
+
"command": "open-computer-use",
|
|
6
|
+
"args": [
|
|
7
|
+
"mcp"
|
|
8
|
+
]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
2
12
|
const lines = [
|
|
3
13
|
"",
|
|
4
|
-
"Installed open-computer-use.",
|
|
14
|
+
"Installed open-computer-use@0.1.9.",
|
|
15
|
+
"Package: https://www.npmjs.com/package/open-computer-use",
|
|
5
16
|
"Commands: open-computer-use, open-computer-use-mcp, open-codex-computer-use-mcp",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
17
|
+
"",
|
|
18
|
+
"Next:",
|
|
19
|
+
"1. Run open-computer-use doctor",
|
|
20
|
+
"2. In macOS System Settings, grant Accessibility and Screen Recording to your host terminal or MCP client",
|
|
21
|
+
"3. Run open-computer-use install-claude-mcp for Claude Code, open-computer-use install-codex-mcp for Codex, or open-computer-use install-codex-plugin for the local plugin cache",
|
|
22
|
+
"",
|
|
23
|
+
"You can add this to any MCP-capable client:",
|
|
24
|
+
JSON.stringify(mcpConfig, null, 2),
|
|
9
25
|
"",
|
|
10
26
|
];
|
|
11
27
|
for (const line of lines) {
|