MCP Server Configuration Priority Order in jcode: The Complete Hierarchy

The MCP server configuration priority order in jcode follows a strict four-step hierarchy: first-run imports from Claude Code or Codex CLI populate ~/.jcode/mcp.json only when no existing config is present, followed by the global user configuration, then the project-local .jcode/mcp.json which overrides global entries via HashMap::extend, and finally the legacy .claude/mcp.json fallback.

The jcode editor implements the Model Context Protocol (MCP) through a layered configuration system that determines which server definitions take precedence when multiple sources exist. Understanding the MCP server configuration priority order is essential for developers migrating from Claude Code or managing both global and project-specific tool setups. According to the jcode source code in src/mcp/protocol.rs, the McpConfig::load() method orchestrates this merging process using a deterministic precedence chain.

How jcode Loads MCP Server Configuration

The configuration loading process centers on the McpConfig::load() function implemented in [src/mcp/protocol.rs](https://github.com/1jehuang/jcode/blob/master/src/mcp/protocol.rs). This function constructs the final configuration by consulting multiple sources sequentially, with each subsequent source potentially overwriting entries from previous steps. The merging relies on HashMap::extend, meaning that when the same server name appears in multiple files, the later source in the chain replaces the earlier definition entirely.

The Four-Level MCP Server Configuration Priority

The precedence chain follows a strict order from most general to most specific, ensuring that project-local settings always take precedence over global defaults.

Level 1: First-Run Import from External Tools

During the initial setup, jcode checks for existing MCP configurations from compatible tools only if ~/.jcode/mcp.json does not yet exist. The function scans for:

  • Claude Code: ~/.claude/mcp.json
  • Codex CLI: ~/.codex/config.toml

Any servers found in these locations are imported once to seed the new global configuration file. This import happens exclusively on first run; subsequent loads skip this step and read directly from the established jcode configuration files.

Level 2: Global User Configuration

After the optional import step, jcode always reads the global user configuration located at ~/.jcode/mcp.json. This file stores server definitions that apply across all projects on the machine. Entries loaded here persist unless overridden by more specific configuration sources later in the chain.

Level 3: Project-Local Configuration

The ./.jcode/mcp.json file relative to the repository root receives the highest priority among active configuration files. When this file exists, its entries are merged into the configuration using HashMap::extend, which overwrites any overlapping server names from the global config. This behavior ensures that project-specific MCP server settings take precedence over user defaults, allowing different projects to use different server versions or environment variables.

Level 4: Legacy Fallback

For backward compatibility with older Claude-only setups, jcode includes a final fallback to .claude/mcp.json in the project directory. This source is consulted only if a specific server name has not been defined in any of the previous three levels. It provides a migration path for projects that previously stored MCP configurations in Claude-specific paths.

Understanding the HashMap::extend Merge Mechanism

The priority order is enforced through Rust's HashMap::extend method. When McpConfig::load() processes each configuration source, it extends the accumulator hashmap with the new set of server definitions. Because extend replaces existing keys with new values, the sequential processing of global followed by project-local configurations naturally results in project settings overriding global ones. This mechanism guarantees that the final McpConfig struct contains the most specific configuration available for each server name.

Inspecting Your Loaded MCP Configuration

You can programmatically verify which configuration sources are active and inspect the merged results using the McpConfig API. The following example loads the complete configuration according to the priority order described above:

use jcode::mcp::protocol::McpConfig;

// Load configuration following the four-level priority order
let config = McpConfig::load();

// Inspect the resolved servers (name → McpServerConfig)
for (name, server) in &config.servers {
    println!("Server \"{}\": command = {}", name, server.command);
}

Running this code prints the server definitions that the jcode instance will actually use, after all precedence rules and imports have been applied.

Key Source Files Defining the Priority Order

Three primary files in the jcode repository govern this configuration behavior:

Summary

  • First-run imports from Claude Code or Codex CLI seed ~/.jcode/mcp.json only when no existing global config is present.
  • Global configuration at ~/.jcode/mcp.json provides the baseline server definitions for all projects.
  • Project-local configuration at ./.jcode/mcp.json overrides global entries via HashMap::extend, giving it the highest active priority.
  • Legacy fallback to ./.claude/mcp.json supplies server definitions only for names not defined in higher-priority sources.
  • The merge mechanism uses HashMap::extend, ensuring later sources in the chain replace earlier ones for the same server name.

Frequently Asked Questions

Which configuration file takes the highest priority in jcode's MCP server setup?

The project-local .jcode/mcp.json file takes the highest priority among standard configuration sources. When this file exists in the repository root, its server definitions override any entries with the same name in the global ~/.jcode/mcp.json configuration, as the loading process uses HashMap::extend to merge configurations sequentially.

How does jcode import existing MCP configurations from Claude Code or Codex CLI?

On first run, if ~/.jcode/mcp.json does not exist, McpConfig::load() automatically imports server definitions from ~/.claude/mcp.json (Claude Code) and ~/.codex/config.toml (Codex CLI). This import happens exactly once to populate the initial global configuration, after which jcode reads exclusively from its own configuration files unless manually edited.

Why does the project-local configuration override global settings instead of merging deeply?

The override behavior occurs because McpConfig::load() uses HashMap::extend to combine configuration sources, which replaces existing keys with new values rather than performing a deep merge. This design ensures that project-local .jcode/mcp.json entries take complete precedence over global entries for the same server name, allowing projects to fully redefine server commands and arguments.

What is the purpose of the legacy .claude/mcp.json fallback?

The legacy fallback provides backward compatibility for projects that previously configured MCP servers using Claude-specific paths before migrating to jcode. According to the source code in src/mcp/protocol.rs, this file is consulted only if a server name is not defined in the global ~/.jcode/mcp.json or project-local .jcode/mcp.json files, ensuring existing Claude Code setups continue to function without immediate migration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →