xcode-mcp-proxy-server spawns xcrun mcpbridge as an upstream process.
If it fails:
- Confirm Xcode is installed and selected (
xcode-select -p). - Confirm
xcrun mcpbridge -hworks in Terminal.
Ensure the proxy server is running. Increase startup_timeout_sec in the client config if needed.
If you see an error like:
timed out awaiting tools/list after 10s
it’s usually because the upstream (xcrun mcpbridge / Xcode) was slow on the first tools/list.
xcode-mcp-proxy-serverprewarms and cachestools/listin memory once it’s ready, and serves it immediately on subsequent requests.- The tool list cache is not persisted to disk. It survives repeated Codex restarts as long as the proxy server stays running.
tools/listis intentionally treated as stable for the lifetime of the proxy process (no background refresh), to avoid upstream churn and surprise Xcode permission dialogs.
- Ensure
xcode-mcp-proxy-serveris running. - Confirm the URL is correct (default:
http://localhost:8765/mcp). - If you changed the listen address/port, check the discovery file:
~/Library/Caches/XcodeMCPProxy/endpoint.json. - Confirm
pidis alive andupdatedAtis recent; stale data should be ignored.
Another process is already listening on the same port (default: 8765).
- Stop the existing proxy server and retry:
pkill -x xcode-mcp-proxy-server
- Or rerun with
--force-restartto terminate an existingxcode-mcp-proxy-serverautomatically:xcode-mcp-proxy-server --force-restart
Ensure the proxy server is running and you are launching the adapter with xcode-mcp-proxy.
If you changed the server URL, pass it explicitly:
xcode-mcp-proxy --url http://localhost:9000/mcp
or set XCODE_MCP_PROXY_ENDPOINT to the server URL. The discovery file should exist at ~/Library/Caches/XcodeMCPProxy/endpoint.json.
Increase tool_timeout_sec in ~/.codex/config.toml (this is client-side and separate from the proxy --request-timeout).
[mcp_servers.xcode]
command = "xcode-mcp-proxy"
args = []
tool_timeout_sec = 300If you configured Codex via --url, set tool_timeout_sec on the URL server entry instead:
[mcp_servers.xcode]
url = "http://localhost:8765/mcp"
tool_timeout_sec = 300If you see an error like:
tools/call failed: Transport closed
it usually means the MCP server process (xcode-mcp-proxy) was terminated while Codex was waiting (often due to the default tool_timeout_sec being too short for slow Xcode operations).
- Set
tool_timeout_sec(see above) to a value that covers the slowest Xcode tool calls you expect. - Ensure the proxy server (
xcode-mcp-proxy-server) is running and the discovery file is fresh:~/Library/Caches/XcodeMCPProxy/endpoint.json. - If it keeps happening, restart the local processes:
pkill -f xcode-mcp-proxypkill -f mcpbridge
When the proxy runs in --refresh-code-issues-mode upstream, Xcode's live diagnostics service is prone to transient failures when XcodeRefreshCodeIssuesInFile is fired in bursts for the same tabIdentifier.
- The default mode is
proxy, which servesXcodeRefreshCodeIssuesInFilethroughXcodeListNavigatorIssues-style diagnostics to avoid switching Spaces. - In
upstreammode,xcode-mcp-proxy-serverserializesXcodeRefreshCodeIssuesInFilepertabIdentifierand retries the specificSourceEditorCallableDiagnosticError error 5response a small number of times. - This reduces cold-start contention, but it can increase latency when many refresh requests target the same tab at once.
- Queued refreshes are no longer rejected because of a fixed queue cap, but they still consume the request's end-to-end timeout budget while waiting for their turn.
- If the request deadline is reached before a queued refresh starts running, the proxy returns the same timeout response it would use for an in-flight timeout.
- If you need Xcode's native live diagnostics behavior, start the proxy with
--refresh-code-issues-mode upstream(orMCP_XCODE_REFRESH_CODE_ISSUES_MODE=upstream).
Ensure the client is using the same session.