Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

XcodeMCPKit

XcodeMCPKit is a local proxy for Xcode MCP. It gives your MCP clients one stable endpoint and automates the mcpbridge approval flow.

Requirements

  • macOS 15.4+
  • Swift 6.3+

Install

From GitHub Releases

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh
Other install options

Custom install directory:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/latest/download/install.sh | sh -s -- --bindir "$HOME/bin"

Install a specific version:

curl -fsSL https://github.com/lynnswap/XcodeMCPKit/releases/download/v0.11.0/install.sh | sh

From Source

Installs both the proxy server and the STDIO adapter:

swift run -c release xcode-mcp-proxy-install

Custom install directory:

swift run -c release xcode-mcp-proxy-install --prefix "$HOME/.local"
swift run -c release xcode-mcp-proxy-install --bindir "$HOME/bin"

Add to PATH:

echo'export PATH="$HOME/.local/bin:$PATH"'>>~/.zshrc
source~/.zshrc

Set Up Your MCP Client

1. Enable Xcode MCP Access

XcodeMCPKit automatically uses Xcode 27's headless MCP service when it is available and enabled. This lets the proxy start before a project or workspace is open in the Xcode app. Enabling the service is an optional, one-time system setup performed by you:

sudo xcrun mcp-server enable

XcodeMCPKit never runs sudo or changes Xcode MCP permissions. If Xcode 27 provides the service but it is disabled, startup prints the command above and continues with GUI Xcode routing. Older Xcode versions also continue with GUI routing.

For GUI routing, open your project in Xcode, choose Xcode > Settings > Intelligence, and turn on Allow external agents to use Xcode tools under Model Context Protocol. See Giving external agents access to Xcode.

This global Xcode setting is separate from the per-connection Allow dialog. --auto-approve handles the GUI dialog; it does not enable headless MCP access. The first headless XcodeOpenWorkspace call can separately ask you to approve the agent and containing folder. Review that request in Xcode Service and approve it manually; XcodeMCPKit does not broaden headless permissions.

2. Start the Proxy Server

xcode-mcp-proxy-server --auto-approve

In GUI mode, --auto-approve clicks the Xcode Allow button automatically. In System Settings > Privacy & Security > Accessibility, allow the app that launches the proxy (for example, Terminal or iTerm).

Without Accessibility permission, omit --auto-approve and click Allow yourself:

xcode-mcp-proxy-server

3. Register the Client

Replace xcrun mcpbridge with the proxy endpoint.

Codex

codex mcp remove xcode
# Recommended: Streamable HTTP
codex mcp add xcode --url http://localhost:8765/mcp
# Compatibility mode: STDIO
codex mcp add xcode -- xcode-mcp-proxy

Claude Code

claude mcp remove xcode
# Recommended: Streamable HTTP
claude mcp add --transport http xcode http://localhost:8765/mcp
# Compatibility mode: STDIO
claude mcp add --transport stdio xcode -- xcode-mcp-proxy

Configuration

CLI help:

xcode-mcp-proxy-server --help
xcode-mcp-proxy --help

Server Options

OptionDescription
--listen host:portListen address. Defaults to localhost:8765.
--host host / --port portListen host and port when --listen is not used.
--upstream-processes nUpstream mcpbridge count: per running Xcode in GUI mode, or total unbound pool size in headless/custom mode. Default: 1, max: 10.
--request-timeout secondsRequest timeout. 0 disables non-initialize timeouts; initialize still has a bounded handshake timeout.
--config pathTOML config path.
`--xcode-mode automaticgui
--auto-approveAutomatically approve the Xcode permission dialog. Requires Accessibility permission.
`--refresh-code-issues-mode proxyupstream`
--force-restartTerminate an existing xcode-mcp-proxy-server on the listen port and start a new one.

Environment Variables

VariableDescription
LISTENListen address, for example 127.0.0.1:8765.
HOST / PORTListen host and port when LISTEN is unset.
MCP_XCODE_PIDSet by the proxy on GUI process-bound upstream mcpbridge children. Headless routing leaves the stock bridge unbound. An inherited value is only passed through when process-bound Xcode routing is not active.
MCP_XCODE_SESSION_IDOptional explicit upstream Xcode MCP session ID.
MCP_XCODE_CONFIGTOML config path. --config takes precedence.
MCP_XCODE_REFRESH_CODE_ISSUES_MODEproxy or upstream.
MCP_LOG_LEVELtrace, debug, info, notice, warning, error, or critical.
XCODE_MCP_PROXY_ENDPOINTSTDIO adapter upstream URL. --url takes precedence.
XCODE_MCP_PROXY_DISCOVERY_FILEDiscovery file override for isolated local/live test runs.
XCODE_MCP_PROXY_CACHE_ROOTCache root used to derive the discovery path when XCODE_MCP_PROXY_DISCOVERY_FILE is unset.

TOML Configuration

[upstream_handshake]
clientName = "XcodeMCPKit"
[tools]
disabled = ["RunAllTests", "RunSomeTests"]
KeyTypeDefault
upstream_handshake.clientNamestring"XcodeMCPKit"
upstream_handshake.clientVersionstring"dev"
upstream_handshake.capabilitiestable{}
tools.disabledarray of strings[]
  • Omitted clientVersion: resolved from Xcode's matching IDEChat*Version defaults entry when available.
  • Disabled tools: removed from tools/list and rejected on direct tools/call.
  • Config changes require restarting xcode-mcp-proxy-server.

Migration

v0.14.0

  • The Swift client and embedded proxy APIs now use typed connection state, Duration deadlines, explicit async lifecycle completion, and a smaller server/adapter public surface.
  • Deprecated wrappers are not retained.
  • CLI users can keep the normal server and adapter commands, but must replace the adapter's old --stdio alias with --url.
  • See the v0.14.0 migration guide for the complete old-to-new symbol and behavior mapping.

v0.11.0

If you use the proxy through Codex or Claude Code, no migration is required. Only the following cases need changes:

  • Direct Streamable HTTP clients: after initialize, send the server-issued MCP-Session-Id and MCP-Protocol-Version: 2025-06-18. Include Accept: application/json, text/event-stream on POST /mcp, and do not send JSON-RPC batch requests.

Troubleshooting

Maintainers

Local checks:

swift test -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter XcodeMCPProcessRuntimeTests -Xswiftc -strict-concurrency=minimal
XCODE_MCP_RUN_PROCESS_TESTS=1 swift test --no-parallel --filter ProxyStdioAdapterTests -Xswiftc -strict-concurrency=minimal
scripts/check.sh

To diagnose Xcode permission dialogs without launching mcpbridge, run the package-only maintainer tool with explicit existing process identities:

swift run xcode-mcp-permission-approver \
--xcode-pid <xcode-pid> \
--agent-pid <proxy-server-pid> \
--agent-path <proxy-server-path> \
--assistant-name XcodeMCPKit

Release:

gh workflow run release.yml --ref main -f version=v0.11.0

Edit the draft release notes, then publish the release manually.

Documentation

License

LICENSE

About

Local Xcode MCP proxy with a stable endpoint and approval automation

Topics

Resources

Stars

25 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages