Project scope MCP

Resolved 💬 16 comments Opened Sep 1, 2025 by yaroslavyaroslav Closed Nov 11, 2025
💡 Likely answer: A maintainer (yaroslavyaroslav, contributor) responded on this thread — see the highlighted reply below.

What feature would you like to see?

The codex cli is so powerful in working with plain bash, yet there're still options where using MCP servers are the most convenient way to work with.

One of such is fixing diagnostic issues through LSP servers instances. But such servers are project related and should not leak in codex global scope.

Thus I suggest to either add project/session related mcp servers setup or profile related mcp servers as more general solution.

like:

[profiles.gpt-5]
model = "gpt-5"
model_provider = "openai"
approval_policy = "on-failure"
disable_response_storage = false
model_reasoning_effort = "medium"

[profiles.gpt-5.mcp_servers.dash]
command = "uvx"
args = ["--from", "git+https://github.com/Kapeli/dash-mcp-server.git", "dash-mcp-server"]

Are you interested in implementing this feature?

It strictly depends on chances it's being merged afterwards 😅

Additional information

_No response_

View original on GitHub ↗

16 Comments

avxkim · 10 months ago

oh, i thought project-scoped mcp servers already supported :(

pidgeon777 · 10 months ago

I would be great indeed.

yaroslavyaroslav contributor · 10 months ago

I guess this won't be a lucky one.

0xdevalias · 10 months ago
I was surprised to find that profile scoped MCP servers wasn't already a thing. I feel like not having this currently is a bit of a security / privacy risk as well; as unless a user goes and manually comments out all the MCP servers each time; it's increasing the potential exposure in all of their codex sessions. Allowing MCP servers to be defined per profile (or at the very least disabled globally and enabled per profile) would definitely be something worth prioritising getting merged sooner rather than later. (Also, I haven't deeply reviewed the changes in this PR to see if it already does it, but from a UX perspective, something I tried today and was surprised to find didn't work was codex --profile foo mcp add bar -- baz. The help text for codex mcp add does explicitly say 'global' right now; but to make that profile scope aware would be a really nice UX tweak) _Originally posted by @0xdevalias in https://github.com/openai/codex/issues/3106#issuecomment-3315558494_
0xdevalias · 10 months ago

Here's my workaround in the meantime using shell functions:

Basic:

codex-beeper() {
  codex \
    -c 'mcp_servers.beeper.command="npx"' \
    -c 'mcp_servers.beeper.args=["-y", "@beeper/mcp-remote"]' \
    --cd /tmp/codex-beeper \
    "$@"
}

Advanced, with secure token storage/retrieval built in (on macOS):

codex-github() {
  local keychain_token_service_name="codex-github-mcp-token"
  local GITHUB_PERSONAL_ACCESS_TOKEN
  local github_args='["stdio"]'

  # Handle --help and --clear-token flags
  if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    cat <<EOF
Usage: $0 [OPTIONS] [CODEX_ARGS...]

Wraps Codex with GitHub MCP server configuration, using a GitHub PAT
stored securely in macOS Keychain.

Options:
  --clear-token    Remove the stored token from Keychain.
  --read-only      Run github-mcp-server in read-only mode.
  -h, --help       Show this help message.

Examples:
  $0 --clear-token
  $0 --read-only
  $0 status
EOF
    return 0
  elif [[ "$1" == "--clear-token" ]]; then
    security delete-generic-password -s "$keychain_token_service_name" 2>/dev/null \
      && echo "Deleted token from Keychain (service=$keychain_token_service_name)." \
      || echo "No token found in Keychain (service=$keychain_token_service_name)."
    return 0
  elif [[ "$1" == "--read-only" ]]; then
    github_args='["stdio","--read-only"]'
    shift
  fi

  # Try to read from Keychain
  GITHUB_PERSONAL_ACCESS_TOKEN=$(security find-generic-password -s "$keychain_token_service_name" -w 2>/dev/null)

  # If missing, guide the user
  if [[ -z "$GITHUB_PERSONAL_ACCESS_TOKEN" ]]; then
    echo "GitHub Personal Access Token not found in Keychain (service=$keychain_token_service_name)."
    echo "Opening GitHub token settings page (https://github.com/settings/tokens)..."
    open "https://github.com/settings/tokens"

    # GUI prompt for user input
    GITHUB_PERSONAL_ACCESS_TOKEN=$(
      osascript -e '
        Tell application "System Events"
          display dialog "Enter your GitHub Personal Access Token (create one at https://github.com/settings/tokens):" ¬
            default answer "" ¬
            with hidden answer ¬
            buttons {"OK"} ¬
            default button "OK"
          text returned of result
        end tell
      '
    )

    if [[ -z "$GITHUB_PERSONAL_ACCESS_TOKEN" ]]; then
      echo "Error: No token provided."
      return 1
    fi

    # Save into Keychain for future runs
    security add-generic-password \
      -s "$keychain_token_service_name" \
      -a "$USER" \
      -w "$GITHUB_PERSONAL_ACCESS_TOKEN" \
      -U
    echo "Saved new token into Keychain (service=$keychain_token_service_name)."
    echo "💡 You can clear it later with:"
    echo "    $0 --clear-token"
  fi

  codex \
    -c 'mcp_servers.github.command="github-mcp-server"' \
    -c "mcp_servers.github.args=$github_args" \
    -c "mcp_servers.github.env.GITHUB_PERSONAL_ACCESS_TOKEN=\"$GITHUB_PERSONAL_ACCESS_TOKEN\"" \
    "$@"
}
nick-youngblut · 9 months ago

It would also be great to have MCP configurations that could be selected on-demand in the chat (CLI or VS Code/Cursor extension). I often want to enable/disable MCPs for particular tasks, instead of having all of the MCPs & tools in the context window for every task in a project.

Example configs

Full-Stack Web Development

  • github - PR reviews, issue tracking, repository management
  • filesystem - code editing and navigation
  • postgres/sqlite - database operations
  • playwright - E2E testing and browser automation

DevOps & Infrastructure

  • github - repository and workflow management
  • filesystem - config file editing
  • kubernetes - cluster management
  • docker - container operations
  • aws/gcp - cloud resource management

Backend API Development

  • github - code reviews and CI/CD
  • filesystem - project navigation
  • postgres/mongodb - database work
  • fetch - API testing and integration
  • memory - API specification context

Frontend Development

  • github - component library management
  • filesystem - asset and component access
  • playwright - visual regression testing
  • fetch - API mocking and testing
  • puppeteer - screenshot generation

Documentation Writing

  • github - docs repository access
  • filesystem - markdown files
  • brave-search - research and fact-checking
  • memory - style guide retention
abadruddin1 · 9 months ago

any update on this?

0xdevalias · 9 months ago

I saw that 0.46.0 added an enabled config item to MCP definitions. So theoretically you could have that disabled for everything and then just toggle it on with --config as an interim workaround:

tiagoefreitas · 9 months ago

this is really important, developers should not spend time enabling mcp servers needed by a specific project or app folder!

LaelLuo contributor · 8 months ago

I submitted PR #3864 with similar functionality\! It added flag support and config merging logic where project configs override globals. Unfortunately it was closed due to the team's current policy on new features. The LSP server use case you mentioned is perfect - those should definitely be project-scoped rather than global. Would love to see this feature get implemented\! ⭐

yaroslavyaroslav contributor · 8 months ago

There's a closed branch from me somewhere above, which is also closed but by me this time. So u can use it if u build codex locally. Luckily the code and the build system pretty straightforward thus it's no mess to manage such approach.

Just to mention. As I said in a closing comment in the mine pr, I'm kinda disappointed in MCP in overall in favor to local tinny cli wrappers for whatever tools u can imagine. I assume the team is kinda same here, thus I won't be expected drastic improvement in this part of codex in foreseeable future

0xdevalias · 8 months ago
I'm kinda disappointed in MCP in overall in favor to local tinny cli wrappers for whatever tools u can imagine. I assume the team is kinda same here, thus I won't be expected drastic improvement in this part of codex in foreseeable future

/2c: As an unrelated outsider, but keeping watch on the changes being made to codex, I don't think that conclusion aligns with reality. In recent versions the codex team has been putting in major effort to refactoring and improving the core of their MCP support, from the legacy (self implemented?) system, to switching out to the 'official' rust package / implementation.

If I was to guess / bet, I would say that there is a much higher chance that they are more focussed on finishing that core refactor work before adding little extra bits of polish like this; than that they believe MCP is dissapointing and not a direction worth pursuing / maintaining well.

jtippett · 8 months ago

To add my 2c to this, the workflow I use in elixir language development relies on running an MCP server (tidewave.ai) inside each project, which provides source code locations, in-context evaluations, DB access, etc. It's very useful but it relies on running on the development web server port of each project. The MCP server runs inside the project and shares its own local HTTP port.

Having a per-project MCP config is necessary for this development style. Currently, it's not supported in codex, it would be very nice if it was!

0xdevalias · 8 months ago
Currently, it's not supported in codex, it would be very nice if it was!

As a workaround, you can define the MCP config globally and disable it; then enable it per project via the CLI arg to toggle the enabled property.

Alternatively you can provide the full MCP config via that same CLI arg without needing it in your global config at all.

To make that a bit cleaner per-project you can wrap it in a shell script or similar.

Obviously not the most ideal long term solution; but works pretty well as an interim workaround.

etraut-openai contributor · 8 months ago

Closing this in favor of #2628, which has more upvotes.