Skip to content

Codex Desktop sometimes does not inject configured project MCP tools into a thread #24168

Open

Description

@jarvanstack

What version of the Codex App are you using (From “About Codex” dialog)?

Codex Desktop / CLI: 0.133.0-alpha.1

What subscription do you have?

pro

What platform is your computer?

23.6.0 arm64 arm

What issue are you seeing?

What happened?

Codex Desktop sometimes starts a thread without exposing configured MCP tools to the model, even though the same MCP server is correctly detected by the Codex CLI.

In this state, the model cannot call the MCP tools because they are absent from session_meta.dynamic_tools. This looks like a Desktop tool injection / MCP manager state issue rather than an MCP server outage.

Environment

  • Codex Desktop / CLI: 0.133.0-alpha.1
  • OS: macOS arm64
  • MCP transport: streamable_http
  • Workspace has project-level .codex/config.toml

Project config:

[mcp_servers.cysj-ai-support]
url = "https://example.com/mcp/project/mcp"
bearer_token_env_var = "AI_SUPPORT_TOKEN"

### What steps can reproduce the bug?

1. Configure a project-level streamable HTTP MCP server in `.codex/config.toml`.
2. Open the workspace in Codex Desktop.
3. Create a new thread.
4. Compare `codex mcp list` / `codex doctor` with the thread's available `dynamic_tools`.
5. Sometimes the CLI reports the MCP server as enabled, but Desktop does not inject any `mcp__...` tools into the thread.

### What is the expected behavior?

_No response_

### Additional information

_No response_

Activity

  1. added
    appIssues related to the Codex desktop app
    on May 23, 2026
  2. added
    bugSomething isn't working
    mcpIssues related to the use of model context protocol (MCP) servers
    configIssues involving config.toml, config keys, config merging, or config updates
    on May 23, 2026
  3. github-actions commented on May 23, 2026

    @github-actions
    Contributor

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

    Powered by Codex Action

  4. jshaofa-ui commented on May 23, 2026

    @jshaofa-ui

    openai/codex #24168: Desktop MCP Tools Not Injected Into Thread

    🔍 Root Cause Analysis

    Severity: P1 — MCP tools intermittently absent from thread, model cannot call configured tools

    Codex Desktop sometimes starts a thread without exposing configured MCP tools to the model, even though the same MCP server is correctly detected by the Codex CLI. The tools are absent from session_meta.dynamic_tools.

    Root Cause Chain

    1. Desktop vs CLI tool injection divergence: The Desktop app's tool injection pipeline has a race condition or state synchronization gap that the CLI does not have
    2. MCP manager state not propagated: The MCP server connection is established (CLI sees it), but the tool definitions are not injected into the thread's dynamic_tools
    3. Thread creation timing: The thread may be created before the MCP manager finishes loading/validating the server
    4. streamable_http transport specific: The issue occurs with streamable_http MCP servers — possibly a connection timing issue with HTTP-based MCP

    🛠️ Proposed Fix

    Fix 1: MCP Tool Injection Verification Gate (Critical)

    // In ThreadManager — verify MCP tools are injected before thread starts
    class ThreadManager {
      async createThread(config: ThreadConfig): Promise<Thread> {
        // Wait for MCP manager to be ready
        await this.mcpManager.waitForReady();
    
        // Get MCP tool definitions
        const mcpTools = await this.mcpManager.getAllToolDefinitions();
    
        // NEW: Verify tools are injected into session_meta
        const thread = await this.doCreateThread(config);
        const injectedTools = thread.session_meta.dynamic_tools || [];
    
        const expectedToolNames = mcpTools.map(t => `mcp__${t.name}`);
        const missingTools = expectedToolNames.filter(
          name => !injectedTools.some(t => t.name === name)
        );
    
        if (missingTools.length > 0) {
          this.logger.error('MCP tools not injected into thread', {
            threadId: thread.id,
            missingTools,
            injectedTools: injectedTools.map(t => t.name),
            mcpServers: await this.mcpManager.getServerList(),
          });
    
          // Retry injection
          await this.retryMcpToolInjection(thread, mcpTools);
        }
    
        return thread;
      }
    
      private async retryMcpToolInjection(thread: Thread, tools: McpToolDef[]): Promise<void> {
        for (const tool of tools) {
          const toolName = `mcp__${tool.name}`;
          if (!thread.session_meta.dynamic_tools.some(t => t.name === toolName)) {
            thread.session_meta.dynamic_tools.push({
              name: toolName,
              description: tool.description,
              parameters: tool.parameters,
              source: 'mcp',
            });
          }
        }
      }
    }

    Fix 2: MCP Manager Ready Signal (Important)

    // In McpManager — emit ready signal when all servers are loaded
    class McpManager {
      private readyPromise: Promise<void> | null = null;
      private servers: Map<string, McpServerConnection> = new Map();
    
      async waitForReady(): Promise<void> {
        if (!this.readyPromise) {
          this.readyPromise = this.initializeAllServers();
        }
        return this.readyPromise;
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingconfigIssues involving config.toml, config keys, config merging, or config updatesmcpIssues related to the use of model context protocol (MCP) servers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions