Skip to content

Bug: MCP server source_tool is misattributed after deduplication when same server name exists in multiple tools #47

@FZ2000

Description

@FZ2000

Summary

apc mcp list shows incorrect Source attribution for MCP servers that exist in multiple tools. The deduplication logic uses server name as the only key, so whichever tool was collected last "wins" — overwriting the true source with a different tool name.

Steps to Reproduce

# Setup: have the same MCP server name in both claude-code and cursor configs
# (This can happen naturally after apc mcp sync writes all servers to all tools)

apc collect -y
apc mcp list

# Shows:
# test-claude-mcp  stdio  echo  cursor   ← WRONG! Should be claude-code

Actual Behavior

┏━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┓
┃    # ┃ Name              ┃ Transport ┃ Command ┃ Source     ┃
┡━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━┩
│    6 │ test-claude-mcp   │ stdio     │ echo    │ cursor     │  ← wrong!

test-claude-mcp was originally defined in claude-code's ~/.claude.json but appears as cursor because cursor was processed after claude-code during collection.

Root Cause

# src/cache.py
def _key_mcp(s: Dict) -> str:
    """Deduplicate MCP servers by name only.\n\n    ...last collected wins...\n    """
    return s.get("name", "")  # ← only name, ignores source_tool

When the same server name appears in multiple tools, the last-collected source_tool value wins.

Expected Behavior

Option A: Keep deduplication by name (single canonical entry), but preserve the original source_tool — e.g., keep the first occurrence's source_tool instead of overwriting with each collection.

Option B: Add a source_tools: ["claude-code", "cursor"] list field to track all tools that have the server configured.

Option C: Document in apc mcp list that Source shows "last collected tool" not necessarily the original source.

Environment

  • macOS Darwin 25.2.0 (arm64)
  • apc version 0.1.0

Severity

Low — Cosmetic / traceability issue, doesn't affect functionality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions