drews-xcode-mcp 1.3.16b1__tar.gz
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.
- drews_xcode_mcp-1.3.16b1/.gitignore +35 -0
- drews_xcode_mcp-1.3.16b1/LICENSE +21 -0
- drews_xcode_mcp-1.3.16b1/PKG-INFO +208 -0
- drews_xcode_mcp-1.3.16b1/README.md +184 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/__init__.py +12 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/__main__.py +7 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/cli.py +188 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/config_manager.py +530 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/config_ui.py +538 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/exceptions.py +20 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/security.py +298 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/server.py +165 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/__init__.py +32 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/build_project.py +424 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/clean_project.py +76 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/create_project.py +133 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/debug_list_notification_history.py +69 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_active_run_destination.py +145 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_build_errors.py +109 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_build_results.py +134 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_directory_listing.py +133 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_directory_tree.py +195 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_latest_test_results.py +120 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_project_schemes.py +88 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_runtime_output.py +83 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/get_xcode_projects.py +352 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/list_booted_simulators.py +61 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/list_mac_app_windows.py +146 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/list_project_tests.py +240 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/list_run_destinations.py +117 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/list_running_mac_apps.py +113 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/run_project_tests.py +381 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/run_project_unmonitored.py +83 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/run_project_until_terminated.py +210 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/run_project_with_user_interaction.py +305 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/set_run_destination.py +90 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/stop_project.py +69 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/take_app_screenshot.py +115 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/take_simulator_screenshot.py +110 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/take_window_screenshot.py +121 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/take_xcode_screenshot.py +115 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/tools/version.py +71 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/__init__.py +1 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/applescript.py +439 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/build_log_parser.py +787 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/decode_active_destination.swift +104 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/decode_xcode_recents.swift +47 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/paths.py +16 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/project_templates.py +666 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/run_guard.py +87 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/screenshot.py +180 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/xcodebuild_query.py +341 -0
- drews_xcode_mcp-1.3.16b1/drews_xcode_mcp/utils/xcresult.py +996 -0
- drews_xcode_mcp-1.3.16b1/pyproject.toml +46 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
build/
|
|
11
|
+
*.egg-info/
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.env
|
|
15
|
+
.venv
|
|
16
|
+
env/
|
|
17
|
+
venv/
|
|
18
|
+
ENV/
|
|
19
|
+
|
|
20
|
+
# IDE specific files
|
|
21
|
+
.idea/
|
|
22
|
+
.vscode/
|
|
23
|
+
*.swp
|
|
24
|
+
*.swo
|
|
25
|
+
|
|
26
|
+
# OS specific files
|
|
27
|
+
.DS_Store
|
|
28
|
+
Thumbs.db
|
|
29
|
+
|
|
30
|
+
# Claude
|
|
31
|
+
.claude
|
|
32
|
+
.claude/**
|
|
33
|
+
|
|
34
|
+
# Test working directory (ephemeral test artifacts)
|
|
35
|
+
test_projects/working/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andrew Benson
|
|
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.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drews-xcode-mcp
|
|
3
|
+
Version: 1.3.16b1
|
|
4
|
+
Summary: Drew's MCP server for Xcode integration
|
|
5
|
+
Project-URL: Homepage, https://github.com/drewster99/drews-xcode-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/drewster99/drews-xcode-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/drewster99/drews-xcode-mcp/issues
|
|
8
|
+
Author-email: Andrew Benson <db@nuclearcyborg.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: mcp,server,xcode
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: mcp[cli]>=1.7.0
|
|
21
|
+
Requires-Dist: questionary>=2.0.0
|
|
22
|
+
Requires-Dist: rich>=13.0.0
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Drew's Xcode MCP Server (drews-xcode-mcp)
|
|
26
|
+
|
|
27
|
+
[](https://pypi.org/project/drews-xcode-mcp/)
|
|
28
|
+
[](https://pypi.org/project/drews-xcode-mcp/)
|
|
29
|
+
[](https://pepy.tech/project/drews-xcode-mcp)
|
|
30
|
+
[](https://modelcontextprotocol.io)
|
|
31
|
+
[](https://www.apple.com/macos/)
|
|
32
|
+
[](https://developer.apple.com/xcode/)
|
|
33
|
+
[](https://opensource.org/licenses/MIT)
|
|
34
|
+
|
|
35
|
+
[](https://github.com/drewster99/drews-xcode-mcp/commits)
|
|
36
|
+
|
|
37
|
+
An MCP (Model Context Protocol) server that enables AI assistants to control and interact with Xcode for Apple platform development.
|
|
38
|
+
|
|
39
|
+
> **Renamed from `xcode-mcp-server`.** With several unrelated projects sharing that
|
|
40
|
+
> name — and Xcode itself now shipping a built-in MCP server — this project is now
|
|
41
|
+
> `drews-xcode-mcp`. **Existing setups keep working:** the old PyPI name is a
|
|
42
|
+
> compatibility package that forwards to this one, and all settings carry over.
|
|
43
|
+
> When convenient, update your MCP configuration to run `drews-xcode-mcp` (keep
|
|
44
|
+
> your existing server key/name so tool permissions are unaffected).
|
|
45
|
+
|
|
46
|
+
## What It Does
|
|
47
|
+
|
|
48
|
+
This server allows AI assistants (like Claude, Cursor, or other MCP clients) to:
|
|
49
|
+
|
|
50
|
+
- **Discover and navigate** your Xcode projects and source files
|
|
51
|
+
- **Build and run** iOS, macOS, tvOS, and watchOS applications
|
|
52
|
+
- **Execute and monitor tests** with detailed results
|
|
53
|
+
- **Debug build failures** by retrieving errors and warnings
|
|
54
|
+
- **Capture console output** from running applications
|
|
55
|
+
- **Take screenshots** of Xcode windows and iOS simulators
|
|
56
|
+
- **Manage simulators** and view their status
|
|
57
|
+
|
|
58
|
+
The AI can perform complete development workflows - from finding a project, to building it, running tests, debugging failures, and capturing results.
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
- **macOS** - This server only works on macOS
|
|
63
|
+
- **Xcode** - Xcode must be installed
|
|
64
|
+
- **Python 3.10+** - For running the server (uvx will fetch a compatible Python automatically if your system Python is older)
|
|
65
|
+
|
|
66
|
+
## Security
|
|
67
|
+
|
|
68
|
+
The server implements path-based security to control which directories are accessible:
|
|
69
|
+
|
|
70
|
+
- **With restrictions:** Set `XCODEMCP_ALLOWED_FOLDERS=/path1:/path2:/path3` to limit access to specific directories
|
|
71
|
+
- **Default:** If not specified, allows access to your home directory (`$HOME`)
|
|
72
|
+
|
|
73
|
+
Security requirements:
|
|
74
|
+
- All paths must be absolute (starting with `/`)
|
|
75
|
+
- No `..` path components allowed
|
|
76
|
+
- All paths must exist and be directories
|
|
77
|
+
|
|
78
|
+
## Setup
|
|
79
|
+
|
|
80
|
+
First, ensure `uv` is installed (required for all methods below):
|
|
81
|
+
```bash
|
|
82
|
+
which uv || brew install uv
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 1. Claude Code (Recommended)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
claude mcp add --scope user --transport stdio -- drews-xcode-mcp `which uvx` drews-xcode-mcp
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
To run a specific version, use:
|
|
92
|
+
```bash
|
|
93
|
+
# Example: How to run v1.3.0b6
|
|
94
|
+
claude mcp add --scope user --transport stdio -- drews-xcode-mcp `which uvx` drews-xcode-mcp==1.3.0b6
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
That's it! Claude Code handles the rest automatically.
|
|
98
|
+
|
|
99
|
+
### 2. Claude Desktop
|
|
100
|
+
|
|
101
|
+
Edit your Claude Desktop config file (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"drews-xcode-mcp": {
|
|
107
|
+
"command": "uvx",
|
|
108
|
+
"args": [
|
|
109
|
+
"drews-xcode-mcp"
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If you'd like to allow only certain projects or folders to be accessible by drews-xcode-mcp, add the `env` option, with a colon-separated list of absolute folder paths, like this:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"drews-xcode-mcp": {
|
|
122
|
+
"command": "uvx",
|
|
123
|
+
"args": [
|
|
124
|
+
"drews-xcode-mcp"
|
|
125
|
+
],
|
|
126
|
+
"env": {
|
|
127
|
+
"XCODEMCP_ALLOWED_FOLDERS": "/Users/andrew/my_project:/Users/andrew/Documents/source"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 3. Cursor AI
|
|
135
|
+
|
|
136
|
+
In Cursor: Settings → Tools & Integrations → + New MCP Server
|
|
137
|
+
|
|
138
|
+
Or edit `~/.cursor/mcp.json` directly:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"drews-xcode-mcp": {
|
|
144
|
+
"command": "uvx",
|
|
145
|
+
"args": ["drews-xcode-mcp"]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Optional:** Add folder restrictions with an `env` section (same format as Claude Desktop above).
|
|
152
|
+
|
|
153
|
+
## Usage
|
|
154
|
+
|
|
155
|
+
Once configured, simply ask your AI assistant to help with Xcode tasks:
|
|
156
|
+
|
|
157
|
+
- "Find all Xcode projects in my home directory"
|
|
158
|
+
- "Build the project at /path/to/MyProject.xcodeproj"
|
|
159
|
+
- "Run tests for this project and show me any failures"
|
|
160
|
+
- "What are the build errors in this project?"
|
|
161
|
+
- "Show me the directory structure of this project"
|
|
162
|
+
- "Take a screenshot of the Xcode window"
|
|
163
|
+
|
|
164
|
+
Most tools work with paths to `.xcodeproj` or `.xcworkspace` files, or with regular directory paths for browsing and navigation.
|
|
165
|
+
|
|
166
|
+
## Advanced Configuration
|
|
167
|
+
|
|
168
|
+
### Command Line Arguments
|
|
169
|
+
|
|
170
|
+
When running the server directly (for development or custom setups), these options are available:
|
|
171
|
+
|
|
172
|
+
**Build output control:**
|
|
173
|
+
- `--no-build-warnings` - Show only errors, exclude warnings
|
|
174
|
+
- `--always-include-build-warnings` - Always show warnings (default)
|
|
175
|
+
|
|
176
|
+
**Notifications:**
|
|
177
|
+
- `--show-notifications` - Enable macOS notifications for operations
|
|
178
|
+
- `--hide-notifications` - Disable notifications (default)
|
|
179
|
+
|
|
180
|
+
**Access control:**
|
|
181
|
+
- `--allowed /path` - Add allowed folder (can be repeated)
|
|
182
|
+
|
|
183
|
+
Example:
|
|
184
|
+
```bash
|
|
185
|
+
drews-xcode-mcp --no-build-warnings --show-notifications --allowed ~/Projects
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Note:** When using MCP clients (Claude, Cursor), configure these via the `env` section in your client's config file instead.
|
|
189
|
+
|
|
190
|
+
## Development
|
|
191
|
+
|
|
192
|
+
The server is built with FastMCP and uses AppleScript to communicate with Xcode.
|
|
193
|
+
|
|
194
|
+
### Local Testing
|
|
195
|
+
|
|
196
|
+
Test with MCP Inspector:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
export XCODEMCP_ALLOWED_FOLDERS=~/Projects
|
|
200
|
+
mcp dev drews_xcode_mcp/__main__.py
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
This opens an inspector interface where you can test tools directly. Provide paths as quoted strings: `"/Users/you/Projects/MyApp.xcodeproj"`
|
|
204
|
+
|
|
205
|
+
## Limitations
|
|
206
|
+
|
|
207
|
+
- AppleScript syntax may need adjustments for specific Xcode versions
|
|
208
|
+
- Some operations require the project to be open in Xcode first
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Drew's Xcode MCP Server (drews-xcode-mcp)
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/drews-xcode-mcp/)
|
|
4
|
+
[](https://pypi.org/project/drews-xcode-mcp/)
|
|
5
|
+
[](https://pepy.tech/project/drews-xcode-mcp)
|
|
6
|
+
[](https://modelcontextprotocol.io)
|
|
7
|
+
[](https://www.apple.com/macos/)
|
|
8
|
+
[](https://developer.apple.com/xcode/)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
|
|
11
|
+
[](https://github.com/drewster99/drews-xcode-mcp/commits)
|
|
12
|
+
|
|
13
|
+
An MCP (Model Context Protocol) server that enables AI assistants to control and interact with Xcode for Apple platform development.
|
|
14
|
+
|
|
15
|
+
> **Renamed from `xcode-mcp-server`.** With several unrelated projects sharing that
|
|
16
|
+
> name — and Xcode itself now shipping a built-in MCP server — this project is now
|
|
17
|
+
> `drews-xcode-mcp`. **Existing setups keep working:** the old PyPI name is a
|
|
18
|
+
> compatibility package that forwards to this one, and all settings carry over.
|
|
19
|
+
> When convenient, update your MCP configuration to run `drews-xcode-mcp` (keep
|
|
20
|
+
> your existing server key/name so tool permissions are unaffected).
|
|
21
|
+
|
|
22
|
+
## What It Does
|
|
23
|
+
|
|
24
|
+
This server allows AI assistants (like Claude, Cursor, or other MCP clients) to:
|
|
25
|
+
|
|
26
|
+
- **Discover and navigate** your Xcode projects and source files
|
|
27
|
+
- **Build and run** iOS, macOS, tvOS, and watchOS applications
|
|
28
|
+
- **Execute and monitor tests** with detailed results
|
|
29
|
+
- **Debug build failures** by retrieving errors and warnings
|
|
30
|
+
- **Capture console output** from running applications
|
|
31
|
+
- **Take screenshots** of Xcode windows and iOS simulators
|
|
32
|
+
- **Manage simulators** and view their status
|
|
33
|
+
|
|
34
|
+
The AI can perform complete development workflows - from finding a project, to building it, running tests, debugging failures, and capturing results.
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- **macOS** - This server only works on macOS
|
|
39
|
+
- **Xcode** - Xcode must be installed
|
|
40
|
+
- **Python 3.10+** - For running the server (uvx will fetch a compatible Python automatically if your system Python is older)
|
|
41
|
+
|
|
42
|
+
## Security
|
|
43
|
+
|
|
44
|
+
The server implements path-based security to control which directories are accessible:
|
|
45
|
+
|
|
46
|
+
- **With restrictions:** Set `XCODEMCP_ALLOWED_FOLDERS=/path1:/path2:/path3` to limit access to specific directories
|
|
47
|
+
- **Default:** If not specified, allows access to your home directory (`$HOME`)
|
|
48
|
+
|
|
49
|
+
Security requirements:
|
|
50
|
+
- All paths must be absolute (starting with `/`)
|
|
51
|
+
- No `..` path components allowed
|
|
52
|
+
- All paths must exist and be directories
|
|
53
|
+
|
|
54
|
+
## Setup
|
|
55
|
+
|
|
56
|
+
First, ensure `uv` is installed (required for all methods below):
|
|
57
|
+
```bash
|
|
58
|
+
which uv || brew install uv
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 1. Claude Code (Recommended)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
claude mcp add --scope user --transport stdio -- drews-xcode-mcp `which uvx` drews-xcode-mcp
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
To run a specific version, use:
|
|
68
|
+
```bash
|
|
69
|
+
# Example: How to run v1.3.0b6
|
|
70
|
+
claude mcp add --scope user --transport stdio -- drews-xcode-mcp `which uvx` drews-xcode-mcp==1.3.0b6
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
That's it! Claude Code handles the rest automatically.
|
|
74
|
+
|
|
75
|
+
### 2. Claude Desktop
|
|
76
|
+
|
|
77
|
+
Edit your Claude Desktop config file (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"drews-xcode-mcp": {
|
|
83
|
+
"command": "uvx",
|
|
84
|
+
"args": [
|
|
85
|
+
"drews-xcode-mcp"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If you'd like to allow only certain projects or folders to be accessible by drews-xcode-mcp, add the `env` option, with a colon-separated list of absolute folder paths, like this:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"mcpServers": {
|
|
97
|
+
"drews-xcode-mcp": {
|
|
98
|
+
"command": "uvx",
|
|
99
|
+
"args": [
|
|
100
|
+
"drews-xcode-mcp"
|
|
101
|
+
],
|
|
102
|
+
"env": {
|
|
103
|
+
"XCODEMCP_ALLOWED_FOLDERS": "/Users/andrew/my_project:/Users/andrew/Documents/source"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Cursor AI
|
|
111
|
+
|
|
112
|
+
In Cursor: Settings → Tools & Integrations → + New MCP Server
|
|
113
|
+
|
|
114
|
+
Or edit `~/.cursor/mcp.json` directly:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"drews-xcode-mcp": {
|
|
120
|
+
"command": "uvx",
|
|
121
|
+
"args": ["drews-xcode-mcp"]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Optional:** Add folder restrictions with an `env` section (same format as Claude Desktop above).
|
|
128
|
+
|
|
129
|
+
## Usage
|
|
130
|
+
|
|
131
|
+
Once configured, simply ask your AI assistant to help with Xcode tasks:
|
|
132
|
+
|
|
133
|
+
- "Find all Xcode projects in my home directory"
|
|
134
|
+
- "Build the project at /path/to/MyProject.xcodeproj"
|
|
135
|
+
- "Run tests for this project and show me any failures"
|
|
136
|
+
- "What are the build errors in this project?"
|
|
137
|
+
- "Show me the directory structure of this project"
|
|
138
|
+
- "Take a screenshot of the Xcode window"
|
|
139
|
+
|
|
140
|
+
Most tools work with paths to `.xcodeproj` or `.xcworkspace` files, or with regular directory paths for browsing and navigation.
|
|
141
|
+
|
|
142
|
+
## Advanced Configuration
|
|
143
|
+
|
|
144
|
+
### Command Line Arguments
|
|
145
|
+
|
|
146
|
+
When running the server directly (for development or custom setups), these options are available:
|
|
147
|
+
|
|
148
|
+
**Build output control:**
|
|
149
|
+
- `--no-build-warnings` - Show only errors, exclude warnings
|
|
150
|
+
- `--always-include-build-warnings` - Always show warnings (default)
|
|
151
|
+
|
|
152
|
+
**Notifications:**
|
|
153
|
+
- `--show-notifications` - Enable macOS notifications for operations
|
|
154
|
+
- `--hide-notifications` - Disable notifications (default)
|
|
155
|
+
|
|
156
|
+
**Access control:**
|
|
157
|
+
- `--allowed /path` - Add allowed folder (can be repeated)
|
|
158
|
+
|
|
159
|
+
Example:
|
|
160
|
+
```bash
|
|
161
|
+
drews-xcode-mcp --no-build-warnings --show-notifications --allowed ~/Projects
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Note:** When using MCP clients (Claude, Cursor), configure these via the `env` section in your client's config file instead.
|
|
165
|
+
|
|
166
|
+
## Development
|
|
167
|
+
|
|
168
|
+
The server is built with FastMCP and uses AppleScript to communicate with Xcode.
|
|
169
|
+
|
|
170
|
+
### Local Testing
|
|
171
|
+
|
|
172
|
+
Test with MCP Inspector:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
export XCODEMCP_ALLOWED_FOLDERS=~/Projects
|
|
176
|
+
mcp dev drews_xcode_mcp/__main__.py
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This opens an inspector interface where you can test tools directly. Provide paths as quoted strings: `"/Users/you/Projects/MyApp.xcodeproj"`
|
|
180
|
+
|
|
181
|
+
## Limitations
|
|
182
|
+
|
|
183
|
+
- AppleScript syntax may need adjustments for specific Xcode versions
|
|
184
|
+
- Some operations require the project to be open in Xcode first
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Xcode MCP Server - Model Context Protocol server for Xcode integration"""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.3.16b1"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
"""Entry point that delegates to CLI"""
|
|
8
|
+
from drews_xcode_mcp.cli import initialize_server
|
|
9
|
+
return initialize_server()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__all__ = ["main", "__version__"]
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Command-line interface and server initialization"""
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import subprocess
|
|
7
|
+
import argparse
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from drews_xcode_mcp import __version__
|
|
11
|
+
from drews_xcode_mcp.server import mcp, LEGACY_PACKAGE_NAME
|
|
12
|
+
from drews_xcode_mcp.security import get_allowed_folders, set_allowed_folders
|
|
13
|
+
from drews_xcode_mcp.utils.applescript import set_notifications_enabled, show_notification
|
|
14
|
+
from drews_xcode_mcp.utils.xcresult import set_build_warnings_enabled, freeze_build_warnings_settings
|
|
15
|
+
|
|
16
|
+
_LEGACY_RENAME_NOTIFICATION_INTERVAL_SECONDS = 24 * 60 * 60
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _show_legacy_rename_notification_if_needed():
|
|
20
|
+
"""Show a macOS notification about the package rename, at most once a day.
|
|
21
|
+
|
|
22
|
+
This pop-up is the migration channel the user sees directly; the LLM-facing
|
|
23
|
+
channels (server instructions, version tool, migration prompt) live in
|
|
24
|
+
server.py. Throttled via a marker file because MCP clients start a fresh
|
|
25
|
+
server process per session, which could otherwise nag on every restart.
|
|
26
|
+
"""
|
|
27
|
+
if not LEGACY_PACKAGE_NAME:
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
# Constructing the ConfigManager first lets it migrate ~/.xcode-mcp-server
|
|
31
|
+
# to ~/.drews-xcode-mcp; touching the marker path directly here would create
|
|
32
|
+
# the new directory prematurely and strand the old settings.
|
|
33
|
+
from drews_xcode_mcp.config_manager import ConfigManager
|
|
34
|
+
try:
|
|
35
|
+
marker = ConfigManager()._config_dir / "legacy-rename-notified"
|
|
36
|
+
if marker.exists() and time.time() - marker.stat().st_mtime < _LEGACY_RENAME_NOTIFICATION_INTERVAL_SECONDS:
|
|
37
|
+
return
|
|
38
|
+
marker.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
marker.touch()
|
|
40
|
+
except OSError:
|
|
41
|
+
# A notification is never worth failing startup over.
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
show_notification(
|
|
45
|
+
"Xcode MCP Server renamed",
|
|
46
|
+
subtitle=f"'{LEGACY_PACKAGE_NAME}' is now 'drews-xcode-mcp'",
|
|
47
|
+
message="Your current setup still works. When convenient, update your MCP config to run 'drews-xcode-mcp'.",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def initialize_server():
|
|
52
|
+
"""Entry point for the drews-xcode-mcp command"""
|
|
53
|
+
# Debug
|
|
54
|
+
print(f"Drew's Xcode MCP Server (drews-xcode-mcp) v{__version__}", file=sys.stderr)
|
|
55
|
+
|
|
56
|
+
# Parse command line arguments
|
|
57
|
+
parser = argparse.ArgumentParser(description="Drew's Xcode MCP Server")
|
|
58
|
+
parser.add_argument("--version", action="version", version=f"drews-xcode-mcp {__version__}")
|
|
59
|
+
parser.add_argument("--configure", action="store_true", help="Launch configuration UI")
|
|
60
|
+
parser.add_argument("--allowed", action="append", help="Add an allowed folder path (can be used multiple times)")
|
|
61
|
+
parser.add_argument("--show-notifications", action="store_true", help="Enable notifications for tool invocations")
|
|
62
|
+
parser.add_argument("--hide-notifications", action="store_true", help="Disable notifications for tool invocations")
|
|
63
|
+
parser.add_argument("--no-build-warnings", action="store_true", help="Exclude warnings from build output")
|
|
64
|
+
parser.add_argument("--always-include-build-warnings", action="store_true", help="Always include warnings in build output")
|
|
65
|
+
args = parser.parse_args()
|
|
66
|
+
|
|
67
|
+
# Handle --configure flag
|
|
68
|
+
if args.configure:
|
|
69
|
+
from drews_xcode_mcp.config_ui import run_configuration_ui
|
|
70
|
+
run_configuration_ui()
|
|
71
|
+
sys.exit(0)
|
|
72
|
+
|
|
73
|
+
# Handle notification settings
|
|
74
|
+
if args.show_notifications and args.hide_notifications:
|
|
75
|
+
print("Error: Cannot use both --show-notifications and --hide-notifications", file=sys.stderr)
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
elif args.show_notifications:
|
|
78
|
+
set_notifications_enabled(True)
|
|
79
|
+
print("Notifications enabled", file=sys.stderr)
|
|
80
|
+
elif args.hide_notifications:
|
|
81
|
+
set_notifications_enabled(False)
|
|
82
|
+
print("Notifications disabled", file=sys.stderr)
|
|
83
|
+
|
|
84
|
+
# Handle build warning settings
|
|
85
|
+
if args.no_build_warnings and args.always_include_build_warnings:
|
|
86
|
+
print("Error: Cannot use both --no-build-warnings and --always-include-build-warnings", file=sys.stderr)
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
elif args.no_build_warnings:
|
|
89
|
+
set_build_warnings_enabled(False, forced=True)
|
|
90
|
+
print("Build warnings forcibly disabled", file=sys.stderr)
|
|
91
|
+
elif args.always_include_build_warnings:
|
|
92
|
+
set_build_warnings_enabled(True, forced=True)
|
|
93
|
+
print("Build warnings forcibly enabled", file=sys.stderr)
|
|
94
|
+
|
|
95
|
+
# Construct the ConfigManager up front so the one-time migration of
|
|
96
|
+
# ~/.xcode-mcp-server to ~/.drews-xcode-mcp happens at startup, where its
|
|
97
|
+
# stderr note lands in the launch log, rather than lazily inside the first
|
|
98
|
+
# tool call. This also protects any future startup code that touches the
|
|
99
|
+
# config directory from stranding the legacy settings.
|
|
100
|
+
from drews_xcode_mcp.config_manager import ConfigManager
|
|
101
|
+
try:
|
|
102
|
+
ConfigManager()
|
|
103
|
+
except OSError as e:
|
|
104
|
+
# An unusable config directory is not worth failing startup over;
|
|
105
|
+
# before this eager construction the same failure surfaced at the
|
|
106
|
+
# first tool call, and it still will (the singleton is only cached
|
|
107
|
+
# on successful construction).
|
|
108
|
+
print(f"Warning: could not initialize config directory: {e}", file=sys.stderr)
|
|
109
|
+
|
|
110
|
+
# After notification settings are applied, so --hide-notifications is honored
|
|
111
|
+
_show_legacy_rename_notification_if_needed()
|
|
112
|
+
|
|
113
|
+
# Initialize allowed folders from environment and command line
|
|
114
|
+
allowed_folders = get_allowed_folders(args.allowed)
|
|
115
|
+
set_allowed_folders(allowed_folders)
|
|
116
|
+
|
|
117
|
+
# Check if we have any allowed folders
|
|
118
|
+
if not allowed_folders:
|
|
119
|
+
error_msg = """
|
|
120
|
+
========================================================================
|
|
121
|
+
ERROR: Xcode MCP Server cannot start - No valid allowed folders!
|
|
122
|
+
========================================================================
|
|
123
|
+
|
|
124
|
+
No valid folders were found to allow access to.
|
|
125
|
+
|
|
126
|
+
To fix this, you can either:
|
|
127
|
+
|
|
128
|
+
1. Set the XCODEMCP_ALLOWED_FOLDERS environment variable:
|
|
129
|
+
export XCODEMCP_ALLOWED_FOLDERS="/path/to/folder1:/path/to/folder2"
|
|
130
|
+
|
|
131
|
+
2. Use the --allowed command line option:
|
|
132
|
+
drews-xcode-mcp --allowed /path/to/folder1 --allowed /path/to/folder2
|
|
133
|
+
|
|
134
|
+
3. Ensure your $HOME directory exists and is accessible
|
|
135
|
+
|
|
136
|
+
All specified folders must:
|
|
137
|
+
- Be absolute paths
|
|
138
|
+
- Exist on the filesystem
|
|
139
|
+
- Be directories (not files)
|
|
140
|
+
- Not contain '..' components
|
|
141
|
+
|
|
142
|
+
========================================================================
|
|
143
|
+
"""
|
|
144
|
+
print(error_msg, file=sys.stderr)
|
|
145
|
+
|
|
146
|
+
# Show macOS notification
|
|
147
|
+
try:
|
|
148
|
+
subprocess.run(['osascript', '-e',
|
|
149
|
+
'display alert "Drew\'s Xcode MCP Server Error" message "No valid allowed folders found. Check your configuration."'],
|
|
150
|
+
capture_output=True)
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
sys.exit(1)
|
|
155
|
+
|
|
156
|
+
# Debug info
|
|
157
|
+
print(f"Total allowed folders: {allowed_folders}", file=sys.stderr)
|
|
158
|
+
cwd = os.getcwd()
|
|
159
|
+
print(f"Working directory: {cwd}", file=sys.stderr)
|
|
160
|
+
|
|
161
|
+
# Import all tools to register them with the MCP server
|
|
162
|
+
# This must be done before mcp.run()
|
|
163
|
+
from drews_xcode_mcp import tools
|
|
164
|
+
|
|
165
|
+
# Show startup notification
|
|
166
|
+
from drews_xcode_mcp.utils.applescript import show_notification
|
|
167
|
+
|
|
168
|
+
# Format the working directory relative to home if possible
|
|
169
|
+
home = os.path.expanduser("~")
|
|
170
|
+
if cwd.startswith(home):
|
|
171
|
+
# Make it relative to home with ~ prefix
|
|
172
|
+
display_cwd = "~" + cwd[len(home):]
|
|
173
|
+
else:
|
|
174
|
+
display_cwd = cwd
|
|
175
|
+
|
|
176
|
+
show_notification(
|
|
177
|
+
f"Drew's Xcode MCP Server - v{__version__}",
|
|
178
|
+
|
|
179
|
+
message="Working dir: " + display_cwd,
|
|
180
|
+
subtitle="✅ Server started"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Lock startup-only globals so any later mutation surfaces as a
|
|
184
|
+
# RuntimeError instead of silently racing concurrent tool readers.
|
|
185
|
+
freeze_build_warnings_settings()
|
|
186
|
+
|
|
187
|
+
# Run the server
|
|
188
|
+
mcp.run()
|