Skip to content

[BUG] cursor: .cursor/mcp.json emitted with Copilot schema (type: "local") — stdio MCP servers fail to start in Cursor #844

@denifilatoff

Description

@denifilatoff

Describe the bug

When a package is installed with --client cursor, APM generates .cursor/mcp.json using the GitHub Copilot CLI server shape instead of Cursor's. The output contains "type": "local" plus Copilot-only fields ("tools", "id"). Cursor's MCP loader does not recognise "type": "local" for stdio servers, and the server silently fails to register. Manually changing "type": "local""type": "stdio" (and removing the Copilot fields) fixes the server.

Per Cursor docs — Model Context Protocol, stdio entries in .cursor/mcp.json must use "type": "stdio", together with command, and optionally args / env.

Root cause. CursorClientAdapter inherits from CopilotClientAdapter and reuses _format_server_config, which hard-codes the Copilot shape:

config = {
    "type": "local",
    "tools": ["*"],
    "id": server_info.get("id", ""),
}

For self-defined stdio deps (_raw_stdio) the adapter only appends command / args / env on top of this Copilot skeleton, so the resulting file is never valid for Cursor.

To Reproduce

Steps to reproduce the behavior:

  1. Use any package that declares a self-defined stdio MCP server — e.g. vlsi/troubleshooting-cliai-packages/troubleshooting/apm.yml.
  2. Install it targeting Cursor: apm install ... --client cursor.
  3. Open the generated .cursor/mcp.json — it contains "type": "local".
  4. Open the project in Cursor → the MCP server does not appear / fails to register.
  5. Manually replace "type": "local" with "type": "stdio" → the server works immediately.

Expected behavior

.cursor/mcp.json should follow Cursor's documented stdio schema, e.g.:

{
  "mcpServers": {
    "troubleshooting": {
      "type": "stdio",
      "command": "./tscli",
      "args": ["mcp"]
    }
  }
}

Copilot-only fields ("tools", "id") should not be written for Cursor.

Environment (please complete the following information)

  • OS:
  • Python Version:
  • APM Version:
  • Cursor Version:

Logs

Actual .cursor/mcp.json generated by APM (broken in Cursor):

{
  "mcpServers": {
    "troubleshooting": {
      "type": "local",
      "tools": ["*"],
      "id": "",
      "command": "./tscli",
      "args": ["mcp"]
    }
  }
}

After manual fix (works):

{
  "mcpServers": {
    "troubleshooting": {
      "type": "stdio",
      "command": "./tscli",
      "args": ["mcp"]
    }
  }
}

Additional context

Scope. This is an APM adapter bug — the consumer package's apm.yml is correct; only the Cursor output is wrong.

Suggested fix. Override _format_server_config (and/or the type mapping) in CursorClientAdapter so that:

  • type is set to "stdio" for stdio transports (and "http" for HTTP/SSE transports, per Cursor docs);
  • Copilot-only fields (tools, id) are not emitted.

Workaround for users today. After apm install --client cursor, edit .cursor/mcp.json and replace "type": "local" with "type": "stdio"; optionally drop "tools" and "id".

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/mcp-configMCP server configuration depth, transports, variable resolution.bugDeprecated: use type/bug. Kept for issue history; will be removed in milestone 0.10.0.good first issueGood for newcomersneeds-triageDeprecated: use status/needs-triage. Kept for issue history; will be removed in milestone 0.10.0.priority/highShips in current or next milestonestatus/acceptedDirection approved, safe to start work.status/triagedInitial agentic triage complete; pending maintainer ratification (silence = approval).theme/portabilityOne manifest, every target. Multi-target deploy, marketplace, packaging, install.type/bugSomething does not work as documented.

    Type

    No type

    Projects

    Status

    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions