MCP servers are not recognized with cursor-cli in a CI environment

Where does the bug appear (feature/product)?

Cursor CLI

Describe the Bug

We have been experiencing issues when trying to integrate Cursor-CLI in a GitHub Actions CI pipeline to work with our configured mcp servers which runs on ubuntu-latest.

we have checked and verified that the mcp servers are configured and displayed within the pipeline so no issues seems to be related with the mcp servers.

however when running the ``cursor-agent mcp list`it always results with a`No MCP servers configured (expected in .cursor/mcp.json or ~/.cursor/mcp.json)``` no matter what solution or workaround we try

note that locally, when configuring mcp servers for the first time it asks as to trust this workspace, so we thought that maybe this is the issue that we need to trust the project in order to call the mcp servers via the cursor cli

so we created a local script to trust this workspace on MacOS in an automatic way without a manual intervention script can be found and this script works as expected, it prompts the trust shell, trusts the workspace and closes automatically:

#!/usr/bin/env bash
set -euo pipefail

command -v expect >/dev/null || { echo “brew install expect”; exit 1; }
command -v cursor-agent >/dev/null || { echo “Install Cursor CLI: curl -fsSL CLI · Cursor | bash”; exit 1; }
: “${CURSOR_API_KEY:?Export CURSOR_API_KEY first}”

rm -rf ~/.cursor/projects/my-project-name

cat > /tmp/approve_cursor.exp << ‘EOF’
#!/usr/bin/expect -f
set timeout 30

spawn /usr/bin/script -q /dev/null cursor-agent

Wait for the trust prompt to actually appear

expect {
-re “Trust this workspace” {
puts “\n=== Trust prompt detected, sending Enter ===”
send – “\r”
}
timeout {
puts “\n=== ERROR: Trust prompt never appeared ===”
exit 1
}
}

Give it time to write the files and show the agent prompt

sleep 10

Now force exit by closing the terminal

puts “\n=== Force exiting ===”
exit 0

expect eof
EOF

chmod +x /tmp/approve_cursor.exp
/tmp/approve_cursor.exp || true

we tried to implement the same script but for the linux CI environment and it is not solving the issue and try to tweak things here and there, increase timeouts and etc but always results with the same error that no mcp servers configured.

  • name: Setup MCP configuration
    shell: bash
    run: |

    Create MCP config directory

    mkdir -p ~/.cursor
    cp .cursor/mcp.json ~/.cursor/mcp.json
    echo “MCP configuration copied to ~/.cursor/mcp.json”
    cat ~/.cursor/mcp.json

  • name: Approve workspace trust and MCP servers interactively
    env:
    CURSOR_API_KEY: ${{ secrets.CURSOR_API_TOKEN }}
    shell: bash
    run: |
    set -euo pipefail

       SANITIZED="$(printf '%s' "$GITHUB_WORKSPACE" | sed -e 's#^/##' -e 's/[.]/-/g' -e 's#/#-#g')"
       TARGET="$HOME/.cursor/projects/$SANITIZED"
       
       # Clean slate - remove any existing trust/approvals
       rm -rf "$TARGET"
       mkdir -p "$TARGET"
    
       # Install expect if not present
       sudo apt-get update && sudo apt-get install -y expect
    
       # Create expect script to approve workspace trust interactively
       cat > approve_cursor.exp << 'EOF'
       #!/usr/bin/expect -f
       set timeout 30
    
       spawn script -q -c "cursor-agent" /dev/null
    
       # Wait for the trust prompt to actually appear
       expect {
         -re "Trust this workspace" {
           puts "\n=== Trust prompt detected, sending Enter ==="
           send -- "\r"
         }
         timeout {
           puts "\n=== ERROR: Trust prompt never appeared ==="
           exit 1
         }
       }
    
       # Give it time to write the files and show the agent prompt
       sleep 10
    
       # Now force exit by closing the terminal
       puts "\n=== Force exiting ==="
       exit 0
    
       expect eof
       EOF
    
       chmod +x approve_cursor.exp
       ./approve_cursor.exp || true
    
       # Verify trust and approval files were created
       echo "=== Files created in $TARGET ==="
       ls -la "$TARGET" || true
       
       echo ""
       echo "=== .workspace-trusted ==="
       cat "$TARGET/.workspace-trusted" || echo "NOT FOUND"
       
       echo ""
       echo "=== mcp-approvals.json ==="
       cat "$TARGET/mcp-approvals.json" || echo "NOT FOUND"
    

we tried maybe forcing the mcp list command via cursor-agent mcp list --force and this results with === Listing MCP servers === Failed to load MCP server “context7”: Error: MCP server “context7” has not been approved. Please approve it before loading.

so it seems to be a trust/approval issue and there is no workaround for it, and it seems on cursor-cli side, when configuring the cursor-cli locally it creates a .workspace-trusted file along with mcp-approvals.json that has the configured mcp server along with a hashed id that I assume changes each time when a new machine is spun up in CI so creating them manually would not solve it.

what can we do in order to work around it? or is it not implemented yet on cursor’s side?

NOTE THAT WE HAVE LOGS AND WE EE IN THE LOGS THAT THE MCP SERVERS ARE RUNNING AND WE PRINT THE MCP.JSON file so it does not seem an issue with the mcps or configuration.

thanks!

Steps to Reproduce

  1. create a .github/workflows/workflow-name.yml
  2. setup a simple workflow that checks out the current repo branch and instals the cursor cli like in this link Code Review with Cursor CLI | Cursor Docs
  3. configure simple mcp server such as context7 in your .cursor/mcp.json and copy that file in your workflow i.e:

 - name: Setup MCP configuration
        shell: bash
        run: |
          # Create MCP config directory
          mkdir -p ~/.cursor
          cp .cursor/mcp.json ~/.cursor/mcp.json
          echo "MCP configuration copied to ~/.cursor/mcp.json"
          cat ~/.cursor/mcp.json

and use the cursor cli to call the mcp server with a simple prompt i.e


 - name: 🔍 use context7 mcp
        timeout-minutes: 5
        env:
          MODEL: claude-4.5-sonnet
          CURSOR_API_KEY: ${{ secrets.CURSOR_API_TOKEN }}
          GH_TOKEN: ${{ secrets.BOT_TOKEN }}
          BRANCH_PERFIX: feature/
     
        run: cursor-agent -p "get and display the latest docs on playwright fixtures using context7 mcp" -force --model "$MODEL" --output-format=text


Expected Behavior

  • should call the configured mcp server and call it’s tools

Operating System

Linux

Current Cursor Version (Menu → About Cursor → Copy)

Version: 1.7.52 (Universal)

For AI issues: which model did you use?

claude-4.5-sonnet

Does this stop you from using Cursor

No - Cursor works, but with this issue

1 Like

Hey, thanks for the report. I see you’ve mentioned this issue in a few places.

Unfortunately, this is a known limitation: MCP approvals for cursor-cli aren’t implemented yet in headless/CI environments.

The --force flag is mentioned in the docs as a workaround, but based on your tests it doesn’t fully bypass MCP approval (you’re still seeing “MCP server has not been approved”).

Current status:

@deanrie Hey thank you for the response!

yes ``–force``` did not seem to solve this issue it displays an error that says that I need to approve the MCPs.

1 Like

Where does the bug appear (feature/product)?

Cursor CLI

Describe the Bug

I’m trying to use an mcp-server with the cursor-agent cli - i’ve added mcp.json and the server is detected but when I try to use it in a prompt I get an

Error: MCP server “XXX” has not been approved error

I can’t find any CLI command to manually approve an mcp server (or its tools) - do I need to include some additional config files to make this work?

Thanks for any insights!

Steps to Reproduce

  • set up a build pipeline in github actions/etc that installs the cursor-agent cli and include an .cursor/mcp.json file that defines an MCP server
  • try to run cursor-agent mcp list

Expected Behavior

i expect to have some means of approving an mcp server in a build pipeline without having to copy config files from cursor desktop

Operating System

MacOS

Current Cursor Version (Menu → About Cursor → Copy)

Version: 2025.10.17-e060db4

For AI issues: which model did you use?

n/a

Does this stop you from using Cursor

No - Cursor works, but with this issue

You can add “ApprovalKey“ to mcp-approvals.json manually.

Workaround:

  1. find curor-cli executor soruce code
    ls ~/.local/share/cursor-agent/versions/2025.10.28-0a91dc2/index.js

  2. find “const approvalKey = generateApprovalKey(serverName, server, this.cwd);“ and dump it

```# add console.log(approvalKey);
const approvalKey = generateApprovalKey(serverName, server, this.cwd);
console.log(approvalKey);
```

  1. execute mcp list command
    `cursor agent mcp list`

You can find “ApprovalKey“ after change cursor code.
e.g.
my_mcp_server-a16be8f3b47c244f

  1. create mcp-approvals.json
    ls ~/.cursor/projects/
  • find the folder named with path (workspace name) that you ran the cursor agent command

ls ~/.cursor/projects/$workspace
touch ~/.cursor/projects/$workspace/mcp-approvals.json

  1. add all “ApprovalKey“ to the mcp-approvals.json
    e.g.
    [
    ”my_mcp_server-a16be8f3b47c244f”
    ]

6.Just try cursor command again, it should be work
`cursor agent mcp list`

1 Like

thanks @Markhuang3310 - not sure how to automate all that in CI but it definitely helps understand what’s going on!

I have managed to get it to work in my CI based on what @Markhuang3310 said. In this case GH actions:

- name: Extract approval key and create approvals file
  env:
    CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
  run: |
    # Find cursor-agent index.js
    CURSOR_INDEX=$(find ~/.local/share/cursor-agent/versions -name "index.js" | head -1)
    echo "Found cursor-agent at: $CURSOR_INDEX"
    
    # Backup original
    cp "$CURSOR_INDEX" "$CURSOR_INDEX.backup"
    
    # Add console.log to dump approval key
    sed -i 's/const approvalKey = generateApprovalKey(serverName, server, this.cwd);/const approvalKey = generateApprovalKey(serverName, server, this.cwd);\n        console.log("APPROVAL_KEY:", approvalKey);/g' "$CURSOR_INDEX"
    
    # Run mcp list to get the approval key
    echo "Running mcp list to extract approval key..."
    APPROVAL_OUTPUT=$(cursor-agent mcp list 2>&1 || true)
    echo "$APPROVAL_OUTPUT"
    
    # Extract the approval key from output
    APPROVAL_KEY=$(echo "$APPROVAL_OUTPUT" | grep "APPROVAL_KEY:" | sed 's/.*APPROVAL_KEY: //' | tr -d ' ')
    echo "Extracted approval key: $APPROVAL_KEY"
    
    # Restore original index.js
    mv "$CURSOR_INDEX.backup" "$CURSOR_INDEX"
    
    # Determine workspace path for mcp-approvals.json
    # GitHub workspace is /home/runner/work/repo-owner/repo-name
    # We need to convert to home-runner-work-repo-owner-repo-name
    WORKSPACE_NAME=$(echo "$GITHUB_WORKSPACE" | sed 's/\//-/g' | sed 's/^-//')
    echo "Workspace name: $WORKSPACE_NAME"
    
    # Create project-specific approvals directory
    mkdir -p ~/.cursor/projects/"$WORKSPACE_NAME"
    
    # Create mcp-approvals.json with the extracted key
    cat > ~/.cursor/projects/"$WORKSPACE_NAME"/mcp-approvals.json <<EOF
    [
      "$APPROVAL_KEY"
    ]
    EOF
    
    echo "Created mcp-approvals.json with approval key"
    cat ~/.cursor/projects/"$WORKSPACE_NAME"/mcp-approvals.json

something like this! Anyway it’s bloated, this is just created by Cursor but it works until it will be offiically supported

1 Like

Hi @joostboon ! Thank you for this workaround! Could you please share your whole YAML file or the Cursor related parts of it? I’ve tried to use your step in my workflow, but it didn’t work unfortunately, maybe I incorporate it incorrectly.

Well I can share, however I was only able to do successfully:

cursor-agent mcp login
cursor-agent list-tools

when I did an actual prompt I got auth issues. So it still doesn’t look like the best solution.

(coderabbit was the answer for me who support MCP’s natively). Sharing the full GH workflow (there is probably quite some unnecesarry code in there, it was just a POC for me):

name: Run Cursor Agent

on:
  push:
    branches:
      - cursor-agent-action
      - trying-elementary-mcp
  workflow_dispatch:
    inputs:
      prompt:
        description: 'The prompt for the Cursor Agent to execute.'
        required: true
        default: 'Describe the project in three sentences.'

jobs:
  run-cursor-agent:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Cursor Agent
        run: |
          curl https://cursor.com/install -fsS | bash
          echo "$HOME/.cursor/bin" >> $GITHUB_PATH
      - name: create cursor config file
        env:
          ELEMENTARY_BEARER_TOKEN: ${{ secrets.ELEMENTARY_BEARER_TOKEN }}
        run: |
          mkdir -p ~/.cursor
          cat > ~/.cursor/mcp.json <<EOF
          {
            "mcpServers": {
              "elementary-remote": {
                "command": "npx",
                "args": [
                  "-y",
                  "mcp-remote@latest",
                  "https://xxx.api.elementary-data.com/mcp/",
                  "--header",
                  "Authorization: ${ELEMENTARY_BEARER_TOKEN}"
                ]
              }
            }
          }
          EOF
          cat << EOF > ~/.cursor/cli-config.json
          {
            "permissions": {
              "allow": [
                "*"
              ],
              "deny": []
            }
          }

          EOF

      - name: Extract approval key and create approvals file
        env:
          CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
        run: |
          # Find cursor-agent index.js
          CURSOR_INDEX=$(find ~/.local/share/cursor-agent/versions -name "index.js" | head -1)
          echo "Found cursor-agent at: $CURSOR_INDEX"
          
          # Backup original
          cp "$CURSOR_INDEX" "$CURSOR_INDEX.backup"
          
          # Add console.log to dump approval key
          sed -i 's/const approvalKey = generateApprovalKey(serverName, server, this.cwd);/const approvalKey = generateApprovalKey(serverName, server, this.cwd);\n        console.log("APPROVAL_KEY:", approvalKey);/g' "$CURSOR_INDEX"
          
          # Run mcp list to get the approval key
          echo "Running mcp list to extract approval key..."
          APPROVAL_OUTPUT=$(cursor-agent mcp list 2>&1 || true)
          echo "$APPROVAL_OUTPUT"
          
          # Extract the approval key from output
          APPROVAL_KEY=$(echo "$APPROVAL_OUTPUT" | grep "APPROVAL_KEY:" | sed 's/.*APPROVAL_KEY: //' | tr -d ' ')
          echo "Extracted approval key: $APPROVAL_KEY"
          
          # Restore original index.js
          mv "$CURSOR_INDEX.backup" "$CURSOR_INDEX"
          
          # Determine workspace path for mcp-approvals.json
          # GitHub workspace is /home/runner/work/repo-owner/repo-name
          # We need to convert to home-runner-work-repo-owner-repo-name
          WORKSPACE_NAME=$(echo "$GITHUB_WORKSPACE" | sed 's/\//-/g' | sed 's/^-//')
          echo "Workspace name: $WORKSPACE_NAME"
          
          # Create project-specific approvals directory
          mkdir -p ~/.cursor/projects/"$WORKSPACE_NAME"
          
          # Create mcp-approvals.json with the extracted key
          cat > ~/.cursor/projects/"$WORKSPACE_NAME"/mcp-approvals.json <<EOF
          [
            "$APPROVAL_KEY"
          ]
          EOF
          
          echo "Created mcp-approvals.json with approval key"
          cat ~/.cursor/projects/"$WORKSPACE_NAME"/mcp-approvals.json
          
          # Create tool approvals file to auto-approve all tool calls
          cat > ~/.cursor/projects/"$WORKSPACE_NAME"/tool-approvals.json <<EOF
          {
            "approvedTools": ["*"]
          }
          EOF
          
          echo "Created tool-approvals.json"
          cat ~/.cursor/projects/"$WORKSPACE_NAME"/tool-approvals.json

      - name: Verify MCP config
        env:
          ELEMENTARY_BEARER_TOKEN: ${{ secrets.ELEMENTARY_BEARER_TOKEN }}
        run: |
          echo "Contents of ~/.cursor/mcp.json:"
          cat ~/.cursor/mcp.json
          echo "---"
          echo "Contents of ~/.cursor/cli-config.json:"
          cat ~/.cursor/cli-config.json
          echo "---"
          echo "Project directories:"
          ls -la ~/.cursor/projects/ || echo "No projects directory"
          echo "---"
          echo "Project-specific approval files:"
          find ~/.cursor/projects -name "*-approvals.json" -exec sh -c 'echo "File: {}"; cat {}; echo ""' \;

      - name: Test MCP connection
        env:
          CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
        run: |
          echo "Testing MCP server connection..."
          cursor-agent mcp login elementary-remote
          cursor-agent list-tools elementary-remote
          cursor-agent "I want to understand what BI assets will be impacted by my code changes"


Also running into this issue. It’d be nice if --force actually worked, or if we have some way of approving MCP tools :sob:.

Using the below 2 will resolve the issue, only works for non-interactive/headless mode (with -p)

–-approve-mcps and —force together