Codex App triggers Xcode 26.3 agent access prompt multiple times

Resolved 💬 7 comments Opened Feb 6, 2026 by dvdchr Closed Mar 29, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

I'm trying out the latest Xcode 26.3 RC with Codex app.

After setting up xcode MCP, the Codex app seems to trigger the "Allow Codex to access Xcode?" prompt multiple times, often causing Codex to time out and leading it to believe the MCP is not set up correctly.

This is not the case with the Codex CLI, where the prompt is only shown once and remains that way for the entire session.

<img width="361" height="444" alt="Image" src="https://github.com/user-attachments/assets/6ca81e22-6609-40a4-b26c-0fcd09e7aef0" />

thread ID 019c30e2-9401-77a1-a6ef-b36df52576e0

View original on GitHub ↗

7 Comments

github-actions[bot] contributor · 5 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #10741
  • #10735
  • #10321
  • #10187
  • #10319

Powered by Codex Action

cyupa · 5 months ago

You gotta pump those numbers up. Those are rookie numbers.

<img width="343" height="1076" alt="Image" src="https://github.com/user-attachments/assets/033c1496-ffc2-4b1f-bfb4-cf4f8549d5d5" />

ruibeard · 5 months ago

Codex itself told that was a lack of entitlement in the codex macos app.
com.apple.security.automation.apple-events

Codex :

Ran this command locally against your installed app:
codesign -d --entitlements :- "/Applications/Codex.app" 2>/dev/null
That dumps the app’s signed entitlements plist.  
In your output, I saw keys like:
- com.apple.security.app-sandbox = false  
- com.apple.security.cs.allow-jit = true  
- com.apple.security.network.client = true  
But did not see:
- com.apple.security.automation.apple-events
Then I cross-checked with TCC logs, which explicitly said:
- kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing ... identifier=com.openai.codex
lewismoss · 5 months ago

This is so bad, it makes the codex app unusable with Xcode MCP. Literally have to approve once every 30 s

jdelaire · 5 months ago

no fix in sight?

tabletcorry contributor · 5 months ago

I think this is a duplicate of #10741, and I talked about a temporary workaround there.

sstklen · 4 months ago

Hey! I ran into a similar pattern in our bug knowledge base and thought this might help.

What's happening: Codex App spawns a new MCP server subprocess (or reconnects) for each tool invocation, so Xcode 26.3's per-connection agent authorization prompt fires every time. The CLI reuses a single long-lived MCP connection, so the prompt appears only once. This is NOT a missing entitlement issue — com.apple.security.automation.apple-events controls Apple Events, not Xcode's new MCP agent-access authorization gate.

What worked for us:

The proposed fix correctly identifies the need for a single persistent MCP connection and a retry mechanism. To make this production-ready, specific code changes are required. The fix should involve modifying the Codex App's MCP client initialization to ensure it's a singleton or session-scoped object. The connection should be established once at the start of a user session or tool-invocation sequence and explicitly closed on session end. The retry-with-backoff mechanism needs to be implemented around the MCP call that might trigger the prompt, specifically handling potential timeouts or errors indicating the user hasn't yet authorized.

```swift
// Example (conceptual, actual implementation depends on existing architecture)
// Assume 'MCPClient' is the class managing connections to Xcode agent

// 1. Modify Codex App's session management to hold a single MCPClient instance
class CodexSessionManager {
    static let shared = CodexSessionManager() // Singleton for session management
    private var mcpClient: MCPClient? // Persistent client instance
    private let mcpClientQueue = DispatchQueue(label: "com.codex.mcp.queue") // For thread safety

    func getOrCreateMCPClient() -> MCPClient {
        return mcpClientQueue.sync {
            if let client = self.mcpClient {
                return client
            } else {
                let newClient = MCPClient() // Initialize MCP client once
                self.mcpClient = newClient
                // Perform initial connection here if necessary, or lazily
                return newClient
            }
        }
    }

    func invalidateMCPClient() {
        mcpClientQueue.sync {
            self.mcpClient?.disconnect() // Disconnect cleanly
            self.mcpClient = nil
        }
    }
}

// 2. Modify tool invocation logic to use the persistent client
// Instead of:
// let client = MCPClient()
// client.invokeTool(...)
// 
// Use:
func invokeCodexTool(toolName: String, arguments: [String]) async throws -> ToolResult {
    let client = CodexSessionManager.shared.getOrCreateMCPClient()
    
    let maxRetries = 3
    let initialBackoffMs = 500 // Start with 0.5 second
    
    for retryAttempt in 0..<maxRetries {
        do {
            return try await client.invokeTool(toolName: toolName, arguments: arguments)
        } catch let error as MCPError where error.isAuthorizationPendingError && retryAttempt < maxRetries - 1 {
            // Assume MCPError has a way to identify pending authorization
            let backoffTime = initialBackoffMs * Int(pow(2.0, Double(retryAttempt)))
            print("Xcode agent authorization pending. Retrying in \(backoffTime)ms...")
            try await Task.sleep(nanoseconds: UInt64(backoffTime) * 1_000_000)
        } catch {
            throw error // Re-throw other errors or final retry error
        }
    }
    throw SomeSpecificError.maxRetriesExceeded // Should ideally not be reached if last retry throws
}

// 3. Ensure `invalidateMCPClient()` is called on session termination (e.g., app quit, user logout)
// e.g., in AppDelegate/SceneDelegate or when a user closes a project.

Hope this helps! Let me know if it doesn't match your case — happy to dig deeper. 🦞

> _Disclosure: This analysis is from [Confucius Debug](https://api.washinmura.jp/confucius), an AI-powered community KB for agent bugs. Please verify before applying._

---
<sub>🦞 [Confucius Debug](https://api.washinmura.jp/confucius) — community knowledge base for AI agent bugs. Free to search via [MCP](https://api.washinmura.jp/mcp/debug).</sub>