Skip to content

fix(discovery): inventory centrally managed MCP servers - #128

Merged
peterj merged 2 commits into
agentdesktop-dev:mainfrom
devmittal02:fix/inventory-managed-mcp-servers
Sep 29, 2026
Merged

peterj merged 2 commits into
agentdesktop-dev:mainfrom
devmittal02:fix/inventory-managed-mcp-servers

Conversation

@devmittal02

Copy link
Copy Markdown
Contributor

Fixes #127

Problem

Discovery only reads user-level mcpServers, so servers distributed via the managedMcpServers managed setting — including the ones Agentdesktop's own reconciler writes from daemonConfig — never show up in inventory. On a device with 15 managed Claude Desktop connectors, Tools reports 0 MCP.

Changes

Claude Code (provider/claude_code/discovery.rs)

  • Read managedMcpServers from managed-settings.json and each managed-settings.d/*.json (sorted, matching Claude Code's drop-in order), in addition to the existing managed-mcp.json.
  • New managed_mcp_servers_from_value accepts all three shapes seen in practice:
    • object keyed by server name (Claude Code settings),
    • array of entries with a name field (Claude Desktop),
    • either of the above encoded as a JSON string (the MDM/plist convention). Unnamed array entries and nested strings are skipped.
  • Factored per-entry parsing into mcp_server_from_entry; transport is accepted as a fallback for type.

Claude Desktop (provider/claude_desktop/discovery.rs)

  • Read managedMcpServers from the system managed settings (default_claude_desktop_managed_settings_path) — plist on macOS, JSON elsewhere.
  • Also scan ~/Library/Application Support/Claude-3p/claude_desktop_config.json on macOS (only ~/.config/Claude-3p was checked before).

Testing

  • cargo fmt --check, cargo clippy --all-targets clean.
  • cargo test -p agent unit tests pass, including three new ones:
    • reads_claude_code_managed_servers_keyed_by_name
    • reads_claude_desktop_managed_servers_encoded_as_a_json_string
    • ignores_malformed_managed_servers
  • The integration / managed_gateway_lifecycle tests need a Linux-built daemon binary and fail on macOS both with and without this change, so they weren't run locally.
  • Haven't yet run end-to-end agentdesktop-headless discover on a managed device with this build.

🤖 Generated with Claude Code

Claude Code and Claude Desktop inventory only read user-level config
files, so servers pushed through the `managedMcpServers` managed setting
(including the ones Agentdesktop itself writes) were reported as 0 MCP.

- Claude Code: also read `managedMcpServers` from managed-settings.json
  and managed-settings.d/*.json (object keyed by server name).
- Claude Desktop: also read `managedMcpServers` from the system-managed
  settings (property list on macOS, JSON elsewhere). Desktop uses an
  array of named entries, encoded as a JSON string in MDM payloads.
- Claude Desktop: scan the third-party deployment directory
  (~/Library/Application Support/Claude-3p) on macOS.
- Accept `transport` as well as `type` for the transport field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Discovery ignores configured path overrides and can report duplicate managed servers instead of effective settings.

Review effort: Balanced
Findings: 3 Medium severity

Open (3)
What changed in this PR

Adds centrally managed MCP servers to Claude Code and Claude Desktop inventory.

Changes:

  • Parses managed settings and supported MCP server shapes.
  • Scans Claude Code drop-ins and macOS Claude-3p configuration.
File Description
claude_code/​discovery.rs Discovers managed MCP configurations.
claude_desktop/​discovery.rs Reads system-managed and Claude-3p settings.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +46 to +51
if let Some(root) = managed_root() {
servers.extend(mcp_servers_from_json(&root.join("managed-mcp.json")));
// Servers pushed through the `managedMcpServers` managed setting — including the
// ones Agentdesktop itself writes to `managed-settings.d/50-agentdesktop.json`.
for path in managed_settings_files(&root) {
servers.extend(managed_mcp_servers_from_json(&path));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b699852. ClaudeCode::discover now passes self.settings_path into discovery, and managed_settings_sources appends the configured file (merged last) when it is not already one of the files under the managed root, so a daemon.claudeCode.config override is inventoried. Covered by configured_settings_path_outside_the_managed_root_is_inventoried_last.

Comment on lines +50 to +51
for path in managed_settings_files(&root) {
servers.extend(managed_mcp_servers_from_json(&path));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b699852. merged_managed_mcp_servers now merges managedMcpServers across managed-settings.json and the lexically sorted drop-ins by server name, with later files overriding earlier ones, so each effective server is reported once with the source of the file that won. Covered by later_managed_settings_files_override_servers_by_name.

Comment on lines +94 to +95
let managed = default_claude_desktop_managed_settings_path();
let mut servers = managed_settings(&managed)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b699852. ClaudeDesktop::discover now passes self.managed_settings_path into discovery, which reads it in the platform-native format (plist on macOS, JSON elsewhere). Covered by inventories_managed_servers_from_the_configured_settings_path.

@peterj peterj left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the PR! could you address the comments?

Scan the Claude Code and Claude Desktop settings files the reconciler is
configured to write, so daemon config path overrides are inventoried from
the same place. Merge Claude Code managedMcpServers across the base file
and drop-ins by server name with later files winning, so each effective
server is reported once.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@devmittal02
devmittal02 requested a review from peterj September 29, 2026 00:38
@devmittal02

Copy link
Copy Markdown
Contributor Author

fixed it can you check once @peterj

@peterj
peterj merged commit 15b8b50 into agentdesktop-dev:main Sep 29, 2026
3 checks passed
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.

Inventory reports 0 MCP servers for managedMcpServers pushed via daemonConfig (Claude Desktop / Claude Code)

3 participants