xcode-cli 1.0.5

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Peter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # xcode-cli-skill
2
+
3
+ [中文文档](./README_CN.md)
4
+
5
+ CLI + Skill wrapper for the [official Xcode 26.3+ MCP tools](https://developer.apple.com/xcode/mcp/): a persistent local bridge service so the "Allow access to Xcode?" popup stops showing up on every call, plus a Claude Code / Codex Skill that keeps the full Xcode MCP tool surface out of every conversation by default.
6
+
7
+ | Problem | What this repo gives you |
8
+ |---------|--------------------------|
9
+ | AI agents get a "Allow access to Xcode?" popup over and over when talking to Xcode MCP | A long-lived local bridge service managed by `xcode-cli-ctl`, so the agent talks to one stable endpoint instead of spawning a fresh bridge every time |
10
+ | Xcode MCP tools are powerful, but you usually do not want all of them loaded into every conversation | A packaged `xcode-cli` Skill, so agents can load the workflow on demand instead of treating raw MCP as the default path |
11
+
12
+ ## Details
13
+
14
+ ### Problem 1: Permission Popup Spam
15
+
16
+ <img src="alert.jpg" width="360" alt="macOS permission dialog: Allow Codex to access Xcode?">
17
+
18
+ When AI agents (Claude Code, Codex, Cursor) call Xcode 26.3 MCP tools, macOS can keep popping up "Allow access to Xcode?" every few seconds. If the bridge process keeps changing, macOS does not treat it as the same long-lived integration.
19
+
20
+ ### Root Cause
21
+
22
+ The Xcode MCP bridge is process-bound. If every call goes through a fresh short-lived process, you get repeated permission prompts and a worse day-to-day workflow.
23
+
24
+ ### The Fix
25
+
26
+ This repo runs a persistent local bridge service in front of `xcrun mcpbridge`. The agent or terminal CLI talks to that stable HTTP endpoint, while `xcode-cli-ctl` manages the background service for you.
27
+
28
+ ```text
29
+ Agent / CLI ──HTTP──▶ local bridge service ──▶ xcrun mcpbridge ──▶ Xcode
30
+
31
+ managed by xcode-cli-ctl
32
+ ```
33
+
34
+ ### Problem 2: Keep MCP Out of Every Conversation by Default
35
+
36
+ Raw MCP server integration is available, but it is not the recommended default. For Claude Code and Codex, this repo is primarily about the packaged `xcode-cli` Skill: let the agent load the workflow when it actually needs Xcode, instead of wiring raw MCP tools into every session.
37
+
38
+ ## Prerequisites
39
+
40
+ - **macOS** with **Xcode 26.3+**
41
+ - **Node.js** 18+
42
+ - Xcode open with the target project/workspace when you want to build, test, preview, or inspect issues
43
+
44
+ ## Quick Start
45
+
46
+ ```bash
47
+ # 1. Install from npm
48
+ npm install -g xcode-cli
49
+
50
+ # 2. Install and start the local bridge service
51
+ xcode-cli-ctl install
52
+
53
+ # 3. Check service health
54
+ xcode-cli-ctl status
55
+
56
+ # 4. Install the packaged skill
57
+ xcode-cli-ctl skill install
58
+ ```
59
+
60
+ Click "Allow" when macOS asks for Xcode permission.
61
+
62
+ ### Verify
63
+
64
+ ```bash
65
+ # Make sure Xcode is open with a project
66
+ xcode-cli windows
67
+ xcode-cli build
68
+ ```
69
+
70
+ ## AI Agent Integration
71
+
72
+ ### Claude Code (Skill)
73
+
74
+ Install the packaged skill so Claude Code can use `xcode-cli` as an on-demand workflow:
75
+
76
+ ```bash
77
+ xcode-cli-ctl skill install --claude
78
+ ```
79
+
80
+ If you omit `--claude` / `--codex`, the skill installs to both by default.
81
+
82
+ ### Codex (Skill)
83
+
84
+ Install the packaged skill for Codex:
85
+
86
+ ```bash
87
+ xcode-cli-ctl skill install --codex
88
+ ```
89
+
90
+ Or install to both agents at once:
91
+
92
+ ```bash
93
+ xcode-cli-ctl skill install
94
+ ```
95
+
96
+ ### MCP Server (not recommended)
97
+
98
+ If you really want raw MCP wiring instead of the skill-first workflow, add the local bridge manually:
99
+
100
+ ```bash
101
+ # Claude Code
102
+ claude mcp add --transport http xcode http://localhost:48321/mcp
103
+
104
+ # Codex
105
+ codex mcp add xcode --url http://localhost:48321/mcp
106
+ ```
107
+
108
+ > **Note:** This is available as a manual fallback, but the main point of this repo is the skill-based workflow, not raw MCP as the default integration path.
109
+
110
+ ### Common `xcode-cli` Commands
111
+
112
+ ```bash
113
+ xcode-cli windows
114
+ xcode-cli status
115
+ xcode-cli build
116
+ xcode-cli build-log --severity error
117
+ xcode-cli test list
118
+ xcode-cli test all
119
+ xcode-cli test some --target MyTests "FeatureTests#testExample"
120
+ xcode-cli file-issues "Sources/App.swift"
121
+ xcode-cli preview "Sources/MyView.swift" --out ./preview-out
122
+ xcode-cli doc "SwiftUI NavigationStack" --frameworks SwiftUI
123
+ ```
124
+
125
+ ### Available Tools (20) provided by Xcode 26.3+
126
+
127
+ | Category | Tools |
128
+ |----------|-------|
129
+ | **Build & Diagnostics** | `BuildProject`, `GetBuildLog`, `XcodeRefreshCodeIssuesInFile`, `XcodeListNavigatorIssues` |
130
+ | **File Operations** | `XcodeRead`, `XcodeWrite`, `XcodeUpdate`, `XcodeRM`, `XcodeMV`, `XcodeMakeDir`, `XcodeLS` |
131
+ | **Search** | `XcodeGrep`, `XcodeGlob`, `DocumentationSearch` |
132
+ | **Testing** | `GetTestList`, `RunAllTests`, `RunSomeTests` |
133
+ | **Preview & Execution** | `RenderPreview`, `ExecuteSnippet` |
134
+ | **Workspace** | `XcodeListWindows` |
135
+
136
+ ## How It Works
137
+
138
+ ```text
139
+ AI Agent ──skill / bash──▶ xcode-cli ──HTTP──▶ local bridge service ──▶ xcrun mcpbridge ──▶ Xcode IDE
140
+ ```
141
+
142
+ | Component | Role |
143
+ |-----------|------|
144
+ | `xcrun mcpbridge` | Xcode's built-in MCP bridge |
145
+ | local bridge service | Persistent HTTP bridge managed via `xcode-cli-ctl` on port `48321` |
146
+ | `xcode-cli` | Friendly CLI surface for Xcode MCP workflows |
147
+ | `xcode-cli` Skill | The recommended integration path for Claude Code / Codex |
148
+
149
+ ## License
150
+
151
+ MIT
package/bin/xcode-cli ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ SOURCE="${BASH_SOURCE[0]}"
3
+ while [ -h "$SOURCE" ]; do
4
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
5
+ SOURCE="$(readlink "$SOURCE")"
6
+ if [[ "$SOURCE" != /* ]]; then
7
+ SOURCE="$DIR/$SOURCE"
8
+ fi
9
+ done
10
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
11
+ ROOT_DIR="$(cd -P "$DIR/.." && pwd)"
12
+ TSX_LOADER="$(node -e 'try { console.log(require.resolve("tsx", { paths: [process.argv[1]] })); } catch { process.exit(1); }' "$ROOT_DIR")"
13
+ if [[ -z "$TSX_LOADER" || ! -f "$TSX_LOADER" ]]; then
14
+ echo "xcode-cli: missing runtime dependency 'tsx'" >&2
15
+ echo "Reinstall package dependencies (npm install) or reinstall xcode-cli." >&2
16
+ exit 1
17
+ fi
18
+
19
+ exec node --import "$TSX_LOADER" "$ROOT_DIR/src/xcode.ts" "$@"
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ SOURCE="${BASH_SOURCE[0]}"
3
+ while [ -h "$SOURCE" ]; do
4
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
5
+ SOURCE="$(readlink "$SOURCE")"
6
+ if [[ "$SOURCE" != /* ]]; then
7
+ SOURCE="$DIR/$SOURCE"
8
+ fi
9
+ done
10
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
11
+ ROOT_DIR="$(cd -P "$DIR/.." && pwd)"
12
+ TSX_LOADER="$(node -e 'try { console.log(require.resolve("tsx", { paths: [process.argv[1]] })); } catch { process.exit(1); }' "$ROOT_DIR")"
13
+ if [[ -z "$TSX_LOADER" || ! -f "$TSX_LOADER" ]]; then
14
+ echo "xcode-cli-ctl: missing runtime dependency 'tsx'" >&2
15
+ echo "Reinstall package dependencies (npm install) or reinstall xcode-cli." >&2
16
+ exit 1
17
+ fi
18
+
19
+ exec node --import "$TSX_LOADER" "$ROOT_DIR/src/xcode-ctl.ts" "$@"
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "xcode-cli",
3
+ "version": "1.0.5",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "node --import tsx --test \"tests/**/*.test.ts\"",
7
+ "generate": "mcporter generate-cli --command \"xcrun mcpbridge\" --name mcpbridge --description \"xcode-tools\" --output ./src/mcpbridge.ts"
8
+ },
9
+ "keywords": [
10
+ "xcode",
11
+ "mcp",
12
+ "model-context-protocol",
13
+ "cli",
14
+ "ios",
15
+ "swift"
16
+ ],
17
+ "author": "Peter Gammelgaard",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/dazuiba/xcode-cli-skill.git"
21
+ },
22
+ "license": "MIT",
23
+ "description": "CLI for interacting with Xcode MCP tools from the terminal.",
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.27.0",
26
+ "commander": "^14.0.3",
27
+ "mcporter": "^0.7.3",
28
+ "tsx": "^4.21.0"
29
+ },
30
+ "devDependencies": {},
31
+ "type": "module",
32
+ "files": [
33
+ "bin/",
34
+ "src/",
35
+ "skills/"
36
+ ],
37
+ "bin": {
38
+ "xcode-cli": "./bin/xcode-cli",
39
+ "xcode-cli-ctl": "./bin/xcode-cli-ctl"
40
+ }
41
+ }
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: xcode-cli
3
+ version: 1.0.0
4
+ description: >-
5
+ Xcode IDE interaction skill. Uses the xcode-cli CLI to build, diagnose,
6
+ test, preview, and edit Xcode projects via MCP. Use when the user asks to
7
+ build an Xcode project, view build errors, run diagnostics, run tests,
8
+ render SwiftUI previews, search Apple documentation, or manage project files.
9
+ ---
10
+
11
+ # xcode-cli Skill
12
+
13
+ Interact with Xcode through the `xcode-cli` CLI backed by the Xcode MCP bridge.
14
+
15
+ ## Prerequisites
16
+
17
+ - Xcode 26.3 or later is installed and open with the target project
18
+ - `xcode-cli` is installed: `npm install -g xcode-cli`
19
+ - The bridge is running via one of:
20
+ - Background service: `xcode-cli-ctl install`
21
+ - Foreground (in a separate terminal): `xcode-cli-ctl run`
22
+ - The bridge listens on `http://127.0.0.1:48321/mcp`
23
+
24
+ ## Workflow
25
+
26
+ ### 1. Discover tab identifier
27
+ ```bash
28
+ xcode-cli windows
29
+ ```
30
+ Returns the `tabIdentifier` (e.g. `windowtab1`) and corresponding workspace path.
31
+ If exactly one Xcode tab is open, `--tab` is auto-detected for all commands.
32
+
33
+ ### 2. Build
34
+ ```bash
35
+ xcode-cli build
36
+ ```
37
+
38
+ ### 3. View build errors
39
+ ```bash
40
+ xcode-cli build-log --severity error
41
+ ```
42
+
43
+ ### 4. Single-file diagnostics (no full build required)
44
+ ```bash
45
+ xcode-cli file-issues "MyApp/Sources/Controllers/MyFile.swift"
46
+ ```
47
+
48
+ ### 5. View all Navigator issues
49
+ ```bash
50
+ xcode-cli issues --severity error
51
+ ```
52
+
53
+ ### 6. Quick project status (windows + issues)
54
+ ```bash
55
+ xcode-cli status
56
+ ```
57
+
58
+ ### 7. SwiftUI preview (requires #Preview macro)
59
+ ```bash
60
+ xcode-cli preview "MyApp/Sources/Views/MyView.swift" --out ./preview-out
61
+ ```
62
+
63
+ ### 8. Execute code snippet
64
+ ```bash
65
+ xcode-cli snippet "MyApp/Sources/SomeFile.swift" "print(someExpression)"
66
+ ```
67
+
68
+ ### 9. Testing
69
+ ```bash
70
+ xcode-cli test all
71
+ xcode-cli test list --json
72
+ xcode-cli test some "TargetName::ClassName/testMethod()"
73
+ xcode-cli test some --target TargetName "ClassName#testMethod"
74
+ xcode-cli test list
75
+ ```
76
+ For exact MCP parity, use `targetName` + `identifier` from `test list --json`:
77
+ - `targetName` maps to `RunSomeTests.tests[].targetName`
78
+ - `identifier` maps to `RunSomeTests.tests[].testIdentifier`
79
+
80
+ `RunSomeTests` only runs tests from the active scheme's active test plan in Xcode.
81
+ If a target is missing (for example you need `DashProxyMac` while `DashProxy` is active), switch scheme in Xcode first, then run `xcode-cli test list --json` again.
82
+
83
+ ### 10. Search Apple documentation
84
+ ```bash
85
+ xcode-cli doc "SwiftUI NavigationStack" --frameworks SwiftUI
86
+ ```
87
+
88
+ ### 11. File operations (within Xcode project structure)
89
+ ```bash
90
+ xcode-cli read "path/to/file"
91
+ xcode-cli ls /
92
+ xcode-cli ls -r /
93
+ xcode-cli grep "TODO|FIXME"
94
+ xcode-cli glob "**/*.swift"
95
+ xcode-cli write "path/to/file" "content"
96
+ xcode-cli update "path/to/file" "oldText" "newText" --replace-all
97
+ xcode-cli mv "Old.swift" "New.swift"
98
+ xcode-cli mkdir "MyApp/Sources/Feature"
99
+ xcode-cli rm "MyApp/Sources/Unused.swift"
100
+ ```
101
+
102
+ ### 12. Service management
103
+ ```bash
104
+ xcode-cli-ctl install # Install and start as background service (launchd)
105
+ xcode-cli-ctl status # Check if bridge is running
106
+ xcode-cli-ctl logs -f # Follow bridge logs
107
+ xcode-cli-ctl uninstall # Stop and remove service
108
+ ```
109
+
110
+ ## Notes
111
+ - File paths are relative to the Xcode project structure, not absolute filesystem paths.
112
+ - Use `--tab <tabIdentifier>` if multiple Xcode tabs are open.
113
+ - If the bridge is not responding: `xcode-cli-ctl status` then `xcode-cli-ctl uninstall && xcode-cli-ctl install`.
114
+ - For JSON output, add `--json` to any command.
115
+ - Use `xcode-cli run <toolName> --args '{"key":"value"}'` to invoke any MCP tool directly.
116
+
117
+ ## CLI to MCP Mapping
118
+ - `status` -> `XcodeListWindows` + `XcodeListNavigatorIssues`
119
+ - `build` -> `BuildProject`
120
+ - `build-log` -> `GetBuildLog`
121
+ - `test all` -> `RunAllTests`
122
+ - `test list` -> `GetTestList`
123
+ - `test some` -> `RunSomeTests`
124
+ - `issues` -> `XcodeListNavigatorIssues`
125
+ - `file-issues` -> `XcodeRefreshCodeIssuesInFile`
126
+ - `windows` -> `XcodeListWindows`
127
+ - `read` -> `XcodeRead`
128
+ - `grep` -> `XcodeGrep`
129
+ - `ls` -> `XcodeLS`
130
+ - `glob` -> `XcodeGlob`
131
+ - `write` -> `XcodeWrite`
132
+ - `update` -> `XcodeUpdate`
133
+ - `mv` -> `XcodeMV`
134
+ - `mkdir` -> `XcodeMakeDir`
135
+ - `rm` -> `XcodeRM`
136
+ - `preview` -> `RenderPreview`
137
+ - `snippet` -> `ExecuteSnippet`
138
+ - `doc` -> `DocumentationSearch`