Skip to content

feat(cli): Model Context Protocol (MCP) support — client, TUI overlay, config & basic test #824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

jagzmz
Copy link

@jagzmz jagzmz commented May 5, 2025

This PR integrates Model Context Protocol (MCP) into Codex CLI, letting any MCP server’s tools appear as agent‑callable functions.


✨ Key additions

Area Change
Runtime MCPClient & MCPManager manage connections, cache server metadata, flatten tools for OpenAI function‑calling, and clean up on exit.
UI (Ink/React) MCPProvider, useMcpManager hook, and mcp‑overlay panel show live server status & tool lists; /mcp slash‑command “List MCP servers”.
Config loading AgentLoop now accepts an optional mcpTools array; quiet‑mode path instantiates/initialises MCPManager.
Package deps Adds @modelcontextprotocol/sdk ^1.11.0; updates lock‑file.
Tests New Jest suites for manager initialisation, tool‑flattening, and adjusted TerminalChatInput signature.
Polish Warn earlier when context budget is > 25 %; TerminalChatInput callbacks simplified to return void.

🛠️ Example Configuration

Add an mcpServers block to ~/.codex/config.json
Each key is a friendly name; values mirror a spawn‑style process descriptor:

{
  // …existing config …
  "mcpServers": {
    "jina ai": {
      "command": "npx",
      "args": [
        "-y",
        "jina-ai-mcp-server"
      ],
      "env": {
        "JINA_API_KEY=xxx"          // <- your key here
      }
    },
    "memory": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-memory"
      ]
    }
  }
}

📸 Demo

Attached: TUI listing two live MCP servers

718120

Copy link

github-actions bot commented May 5, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@jagzmz
Copy link
Author

jagzmz commented May 5, 2025

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request May 5, 2025
@jagzmz
Copy link
Author

jagzmz commented May 5, 2025

Tagging maintainers @tibo-openai @bolinfest for review. Thank you!

@bolinfest
Copy link
Collaborator

@jagzmz this is exciting stuff and obviously a complex change! Incidentally, I am actively working on making the analogous change in the Rust CLI: #829.

@bolinfest
Copy link
Collaborator

@jagzmz in your example, I see JINA_API_KEY=xxx in args, but shouldn't that be in env?

@jagzmz
Copy link
Author

jagzmz commented May 6, 2025

@jagzmz in your example, I see JINA_API_KEY=xxx in args, but shouldn't that be in env?

Yes, it should be, i picked up an old example i had with me : P, anyways, I have updated the example.

@jagzmz
Copy link
Author

jagzmz commented May 6, 2025

this is exciting stuff and obviously a complex change! Incidentally, I am actively working on making the analogous change in the Rust CLI:

Nice! Are new feature updates to the TS variant paused ?

@jagzmz
Copy link
Author

jagzmz commented May 8, 2025

Hi @bolinfest , would appreciate a review on this pull request. Thanks!

I am wondering if new features are halted on the TS variant?

@bolinfest
Copy link
Collaborator

@jagzmz Hi, sorry for dragging our feet here: we're actively discussing how we want to balance TS versus Rust going forward (and to publish the plan).

That said, I think @fouad-openai was going to try to review a number of the TS PRs in once he gets a free moment...

@Damecek
Copy link

Damecek commented May 9, 2025

hey @jagzmz thanks for your work, really looking forward to this change.

I've tried build from your fork and using following config I get errors and cannot proceed with the mcp.

  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@tokenizin/mcp-npx-fetch"],
      "env": {}
    }
  }

getting this error:

adam@Mac:~/IdeaProjects/codex-ts-mcp-pr|main⚡ ⇒  node codex-cli/dist/cli.js
│ ● OpenAI Codex (research preview) v0.1.2504301751            │

│ localhost session: 3e4ca93b94f94519a9545e04876d935e          │
│ ↳ workdir: ~/IdeaProjects/codex-ts-mcp-pr                    │
│ ↳ model: o4-mini                                             │
│ ↳ provider: openai                                           │
│ ↳ approval: auto-edit                                        │
│ ↳ mcp: ● 1/1 servers, 4 tools                                │

user
what is the current time in czech republic? use google.com

    system
    ⚠️  OpenAI rejected the request (request ID: req_d9e984a3b425c539eb4e011f5c763ad6). Error details: Status: 400, Code: invalid_function_parameters, Type:
    invalid_request_error, Message: 400 Invalid schema for function 'fetch__MCP__TOOL__fetch_html': In context=(), 'required' is required to be supplied and
    to be an array including every key in properties. Extra required key 'headers' supplied.. Please verify your settings and try again.

@jagzmz
Copy link
Author

jagzmz commented May 10, 2025

Hey @Damecek 👋🏻 , thanks for reporting this. OpenAI's tool calling is a little strict for it's tool call definition and doesn't seem to accept the flexibility of the JSON Schema, for example: It necessitates you to have all the parameters of your tool call to be required, etc. I have created a file to-openai.ts which handles these things.

Coming to your issue, looks like this tools JSON schema was not complaint with the OpenAI's tool call here, where each property needs to be marked as required. I have pushed a commit to handle this case, which should resolve your issue.

╭──────────────────────────────────────────────────────────────╮
│ ● OpenAI Codex (research preview) v0.1.2504301751            │
╰──────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ localhost session: bc710ed7241b4f6e950e9f87c623cd08          │
│ ↳ workdir: ~/mithya/crewstack/codex/codex-cli                │
│ ↳ model: o4-mini                                             │
│ ↳ provider: openai                                           │
│ ↳ approval: suggest                                          │
│ ↳ mcp: ● 1/1 servers, 4 tools                                │
╰──────────────────────────────────────────────────────────────╯
user
https://github.com/openai/codex/pull/824#issuecomment-2867655795 what does this issue comment mention ?

    command

    $ 'fetch: fetch_html' 'Args: {"url":"https://github.com/openai/codex/pull/824#issuecomment-2867655795"}'

    command.stdout (code: 0, duration: 0s)

    [
      {
        "type": "text",
        "text": "\n\n\n\n\n\n\n<!DOCTYPE html>\n<html\...
      }
    ]
    ... (6 more lines)

    codex
    That comment (by @Damecek) says:

        * They thanked you and tried your fork locally with this in their `~/.codex/config.json`:

              "mcpServers": {
                "fetch": {
                  "command": "npx",
                  "args": ["-y", "@tokenizin/mcp-npx-fetch"],
                  "env": {}
                }
              }
        * When they ran the CLI and invoked the `fetch__MCP__TOOL__fetch_html` tool, they got an OpenAI 400 error:

              invalid_function_parameters (invalid_request_error):
              400 Invalid schema for function 'fetch__MCP__TOOL__fetch_html':
                In context=(), 'required' is required to be supplied
                and to be an array including every key in properties.
                Extra required key 'headers' supplied.

    They’re blocked by that schema validation error and can’t proceed with the MCP fetch tool.

Please take a pull for the recent changes and try it out. Thanks!

steipete added a commit to steipete/codex that referenced this pull request May 11, 2025
steipete added a commit to steipete/codex that referenced this pull request May 11, 2025
@Damecek
Copy link

Damecek commented May 11, 2025

hey @jagzmz thanks for quick fix. Playing a bit more with it and stumbled upon another one.

user
tell me on what jira ticket I am working right now

    system
    ⚠️  OpenAI rejected the request (request ID: req_856c1a0141a918b11c0d743f631dc2c9). Error details: Status: 400, Code: invalid_function_parameters, Type:
    invalid_request_error, Message: 400 Invalid schema for function 'mcp-atlassian__MCP__TOOL__jira_get_issue': In context=('properties', 'comment_limit'),
    'minimum' is not permitted.. Please verify your settings and try again.

trying to use this mpc https://github.com/sooperset/mcp-atlassian,

"mcp-atlassian": {
  "command": "docker",
  "args": [
    "run",
    "-i",
    "-e",
    "JIRA_URL",
    "-e",
    "JIRA_USERNAME",
    "-e",
    "JIRA_API_TOKEN",
    "ghcr.io/sooperset/mcp-atlassian:latest"
  ],
  "env": {
    "CONFLUENCE_URL": "https://your-company.atlassian.net/wiki",
    "CONFLUENCE_USERNAME": "[email protected]",
    "CONFLUENCE_API_TOKEN": "your_confluence_api_token",
    "JIRA_URL": "xxx.atlassian.net",
    "JIRA_USERNAME": "[email protected]",
    "JIRA_API_TOKEN": "xxx"
  }
}

@Damecek Damecek mentioned this pull request May 12, 2025
@jasonkneen
Copy link

can we get this tested and approved, we need MCP support please!

@bpawnzZ
Copy link

bpawnzZ commented May 18, 2025

hey @jagzmz thanks for your work, really looking forward to this change.

I've tried build from your fork and using following config I get errors and cannot proceed with the mcp.

  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@tokenizin/mcp-npx-fetch"],
      "env": {}
    }
  }

getting this error:

adam@Mac:~/IdeaProjects/codex-ts-mcp-pr|main⚡ ⇒  node codex-cli/dist/cli.js
│ ● OpenAI Codex (research preview) v0.1.2504301751            │

│ localhost session: 3e4ca93b94f94519a9545e04876d935e          │
│ ↳ workdir: ~/IdeaProjects/codex-ts-mcp-pr                    │
│ ↳ model: o4-mini                                             │
│ ↳ provider: openai                                           │
│ ↳ approval: auto-edit                                        │
│ ↳ mcp: ● 1/1 servers, 4 tools                                │

user
what is the current time in czech republic? use google.com

    system
    ⚠️  OpenAI rejected the request (request ID: req_d9e984a3b425c539eb4e011f5c763ad6). Error details: Status: 400, Code: invalid_function_parameters, Type:
    invalid_request_error, Message: 400 Invalid schema for function 'fetch__MCP__TOOL__fetch_html': In context=(), 'required' is required to be supplied and
    to be an array including every key in properties. Extra required key 'headers' supplied.. Please verify your settings and try again.

OpenAI 4.1 mini and nano I get the same errors. apparently atleast those models dont work with MCP tools.. Works fine with deepseek-chat via deepseek api

@bpawnzZ
Copy link

bpawnzZ commented May 18, 2025

can we get this tested and approved, we need MCP support please!

No kidding.. I second this all day.. most needed feature of this tool by far. This works as expected or it should.

@jasonkneen
Copy link

This updated version (synced with main) should fix this issue #1013

jagzmz added 8 commits May 18, 2025 20:55
This commit introduces a new MCP (Model Context Protocol) management system within the Codex CLI. Key changes include:

- Added MCPClient and MCPManager classes for handling connections to MCP servers and managing tools.
- Implemented functionality to initialize MCP connections and retrieve tools from connected servers.
- Enhanced the CLI to support new commands for interacting with MCP servers, including a dedicated overlay for server status.
- Updated the configuration to allow users to define MCP servers and their connection details.
- Introduced new utility functions for flattening tools and parsing tool calls.

This feature enhances the extensibility of the Codex CLI by allowing it to interact with external tools via MCP, improving the overall user experience and functionality.
…ions

This commit introduces several improvements to the MCP (Model Context Protocol) integration within the Codex CLI:

- Added `MCPProvider` and `useMcpManager` hook for managing MCP connections and state in a React context.
- Refactored MCP client and manager functionalities to streamline server connections and tool retrieval.
- Implemented utility functions for sanitizing tool names and flattening tools from multiple MCP clients.
- Updated various components to utilize the new MCP context, enhancing the user interface with real-time server status and tool availability.

These changes improve the overall architecture and usability of the MCP features, allowing for a more seamless interaction with external tools.
Changed the description of the "/mcp" command from "Open MCP server selection panel" to "List MCP servers" to better represent its purpose in the Codex CLI.
- Changed the return type of `submitInput` and `onCompact` props from `CompletionResult` and `Promise<void>` to `void` for better clarity and consistency.
- Enhanced context display logic to provide clearer feedback when context is low, adjusting thresholds for color changes and messages.
- Updated tests to reflect changes in props and ensure proper functionality of the TerminalChatInput component.
- Updated the `disconnectAll` method in `MCPManager` to be asynchronous, allowing for graceful disconnection of all clients.
- Added a call to `mcpManager.disconnectAll()` in the `onExit` function to ensure all MCP clients are properly closed when the terminal exits.
- Modified the MCP client instantiation to include `stderr: 1` for better error handling during command execution.
…ing display

- Refactored the HelpOverlay to enhance the presentation of available commands and keyboard shortcuts.
- Consolidated command descriptions and added new commands for better user guidance.
- Improved layout and styling for clarity, including padding adjustments and color coding for commands and shortcuts.
- Updated exit instructions for consistency with the new design.
- Updated the HelpOverlay component to use non-breaking hyphens in the term "slash‑commands" for improved readability.
- Adjusted command descriptions to maintain consistency in formatting, ensuring clarity in the display of available commands.
- Replaced hyphens with en dashes in the HelpOverlay component for consistency and improved readability.
- Updated command descriptions to ensure uniform formatting across the help overlay.
jagzmz added 8 commits May 18, 2025 20:58
…for MCP overlay

- Updated the `convertTools` function to set tool parameters to `undefined` if not provided, ensuring consistent behavior.
- Added `openMcpOverlay` to multiple test files to enhance coverage for MCP-related functionalities.
- Updated the `pnpm-lock.yaml` to ensure the correct resolution and engine compatibility for `[email protected]`.
- Removed the `package-lock.json` file from the `codex-cli` directory as it is no longer needed, streamlining the dependency management process.
- Updated the MCPClient constructor to merge the provided environment variables with the existing process environment, ensuring that all necessary variables are available during command execution.
- Updated the MCPClient constructor to inherit default environment variables using `getDefaultEnvironment()`, ensuring all necessary variables are available during command execution while still allowing for custom environment overrides.
- Changed the `stderr` option in the MCPClient constructor from `1` to `"pipe"` so the error is PassThrough'd and doesn't pollute the user interface
- Added an en dash separator to the terminal chat input instructions for improved readability and clarity in user guidance.
- Introduced helper functions to streamline the schema processing within the mcpToOpenaiTools function.
- Added functions to validate properties, determine required fields, and apply base schema structure, improving code readability and maintainability.
- Replaced the previous ensureBaseSchema function with a more modular approach using the new helper functions.
jagzmz added 3 commits May 18, 2025 21:20
- Updated the `allTools` array in the AgentLoop class to directly include the tools from the `tools` array, enhancing flexibility and maintainability in tool management.
- Enhanced the command array construction in the parseToolCall function to conditionally include the server name only if it is defined, ensuring cleaner output and better readability.
- Updated the parseToolCall function to assign the command from toolCallArgs to cmd if cmd is undefined, improving command handling and ensuring compatibility with different input formats.
@jagzmz
Copy link
Author

jagzmz commented May 18, 2025

hey @jagzmz thanks for your work, really looking forward to this change.
I've tried build from your fork and using following config I get errors and cannot proceed with the mcp.

  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@tokenizin/mcp-npx-fetch"],
      "env": {}
    }
  }

getting this error:

adam@Mac:~/IdeaProjects/codex-ts-mcp-pr|main⚡ ⇒  node codex-cli/dist/cli.js
│ ● OpenAI Codex (research preview) v0.1.2504301751            │

│ localhost session: 3e4ca93b94f94519a9545e04876d935e          │
│ ↳ workdir: ~/IdeaProjects/codex-ts-mcp-pr                    │
│ ↳ model: o4-mini                                             │
│ ↳ provider: openai                                           │
│ ↳ approval: auto-edit                                        │
│ ↳ mcp: ● 1/1 servers, 4 tools                                │

user
what is the current time in czech republic? use google.com

    system
    ⚠️  OpenAI rejected the request (request ID: req_d9e984a3b425c539eb4e011f5c763ad6). Error details: Status: 400, Code: invalid_function_parameters, Type:
    invalid_request_error, Message: 400 Invalid schema for function 'fetch__MCP__TOOL__fetch_html': In context=(), 'required' is required to be supplied and
    to be an array including every key in properties. Extra required key 'headers' supplied.. Please verify your settings and try again.

OpenAI 4.1 mini and nano I get the same errors. apparently atleast those models dont work with MCP tools.. Works fine with deepseek-chat via deepseek api

Hey @bpawnzZ , I tried to replicate this with OpenAI 4.1 nano and it seems to be working, here are the logs:

Shell Logs
❯ pnpm build:dev

> @openai/[email protected] build:dev /Users/mahesh/codex/codex-cli
> NODE_ENV=development node build.mjs --dev && NODE_OPTIONS=--enable-source-maps node dist/cli-dev.js

╭──────────────────────────────────────────────────────────────╮
│ ● OpenAI Codex (research preview) v0.0.0-dev                 │
╰──────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ localhost session: acd863b579104689b81ee4d37417ac25          │
│ ↳ workdir: ~/codex/codex-cli                │
│ ↳ model: gpt-4.1-nano                                        │
│ ↳ provider: openai                                           │
│ ↳ approval: suggest                                          │
│ ↳ mcp: ● 1/1 servers, 4 tools                                │
╰──────────────────────────────────────────────────────────────╯
user
what is the current time in czech republic? use time.is web search

    command

    $ 'fetch: fetch_html' 'Args: {"url":"https://time.is/Czech_Republic"}'

    command.stdout (code: 0, duration: 0s)

    [
      {
        "type": "text",
        "text": "<!DOCTYPE html><html xmlns=\"http://w...
      }
    ]
    ... (6 more lines)

codex
The current time in Czechia (Czech Republic) is approximately 18:13:49.

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                                                                                                  │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  ctrl+c to exit | "/" to see commands | enter to send — 98% context left
</details>

jagzmz added 2 commits May 18, 2025 21:51
- Added support for using Model Context Protocol (MCP) tools in the agent loop, allowing for extended functionalities when servers are connected. This enhances the agent's ability to interact with external systems and improves overall task execution.
- Updated the `removeUnsupportedKeysFromJsonSchemaParametersRecursive` function to support multiple unsupported keys.
- Introduced a new `fixRequiredFields` function to ensure that required fields only include valid properties and exclude fields of type "object", addressing compatibility issues with OpenAI's API.
- Adjusted the `determineSchemaRequired` function to use all property keys for the required array, improving schema validation and compliance.
@jagzmz
Copy link
Author

jagzmz commented May 18, 2025

hey @jagzmz thanks for quick fix. Playing a bit more with it and stumbled upon another one.

user
tell me on what jira ticket I am working right now

    system
    ⚠️  OpenAI rejected the request (request ID: req_856c1a0141a918b11c0d743f631dc2c9). Error details: Status: 400, Code: invalid_function_parameters, Type:
    invalid_request_error, Message: 400 Invalid schema for function 'mcp-atlassian__MCP__TOOL__jira_get_issue': In context=('properties', 'comment_limit'),
    'minimum' is not permitted.. Please verify your settings and try again.

trying to use this mpc https://github.com/sooperset/mcp-atlassian,

"mcp-atlassian": {
  "command": "docker",
  "args": [
    "run",
    "-i",
    "-e",
    "JIRA_URL",
    "-e",
    "JIRA_USERNAME",
    "-e",
    "JIRA_API_TOKEN",
    "ghcr.io/sooperset/mcp-atlassian:latest"
  ],
  "env": {
    "CONFLUENCE_URL": "https://your-company.atlassian.net/wiki",
    "CONFLUENCE_USERNAME": "[email protected]",
    "CONFLUENCE_API_TOKEN": "your_confluence_api_token",
    "JIRA_URL": "xxx.atlassian.net",
    "JIRA_USERNAME": "[email protected]",
    "JIRA_API_TOKEN": "xxx"
  }
}

Hi @Damecek , thanks for reporting this! Apologies for the delay, been busy with work!
Fix for this has been pushed the latest commit of my fork.

Run Output
╭──────────────────────────────────────────────────────────────╮
│ ● OpenAI Codex (research preview) v0.0.0-dev                 │
╰──────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ localhost session: 79401b7a6eb44f68bbe2b841d8c85d7e          │
│ ↳ workdir: ~/codex/codex-cli                │
│ ↳ model: o4-mini                                             │
│ ↳ provider: openai                                           │
│ ↳ approval: suggest                                          │
│ ↳ mcp: ● 2/2 servers, 40 tools                               │
╰──────────────────────────────────────────────────────────────╯
user
tell me on what jira ticket I am working right now

    command (/Users/mahesh/codex/codex-cli)

    $ git rev-parse --abbrev-ref HEAD

    command.stdout 

    aborted
user
use mcp tool

    command

    $ 'mcp-atlassian: jira_search' 'Args: {"jql":"assignee = currentUser() AND status not in (Done,Closed,Resolved) ORDER BY updated
    DESC","fields":"key,summary,status","limit":1,"start_at":0,"projects_filter":"","expand":""}'

    command.stdout (code: 0, duration: 0s)

    [
      {
        "type": "text",
        "text": "{\n  \"total\": 1,\n  \"start_at\": -...
      }
    ]
    ... (6 more lines)

codex
You’re currently working on JIRA ticket EX-2 (“Support New document format for scrapping exporters data”), which is in status “In Progress.”

Really really weird thing with OpenAI's api for tool calling, it mentions that all tool parameters are required, but if it encounters a parameter with a type: 'object' it starts throwing error. I've added a comment here.

- Revised the description of MCP tools in the agent loop to emphasize their role in extending capabilities through the Model Context Protocol.
- Updated guidance on using tools based on the user's request, ensuring better alignment with available tool functionalities.
@JLFEL
Copy link

JLFEL commented May 27, 2025

Hi, is there any way I can help with the advancement of this mcp feature so it can be approved?

I am very happy for mcp to be included in the codex

@denyskuzin
Copy link

Hi guys, any ETA for this PR?

@bolinfest
Copy link
Collaborator

Hi, we're still in the process of disseminating/updating the comms, but #1174 explains that we are moving forward with the Rust CLI, which has MCP support a number of net new features over the TypeScript one.

We're still deliberating what to do with the open issues/PRs for the TypeScript codebase. /cc @fouad-openai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants