# MCP Server Configuration Priority Order in jcode: The Complete Hierarchy

> Understand the MCP server configuration priority order in jcode Explore the four-step hierarchy from first-run imports to project-local overrides and master the hierarchy for optimal setup.

- Repository: [Jeremy Huang/jcode](https://github.com/1jehuang/jcode)
- Tags: internals
- Published: 2026-04-30

---

**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`](https://github.com/1jehuang/jcode/blob/main/.jcode/mcp.json) which overrides global entries via `HashMap::extend`, and finally the legacy [`.claude/mcp.json`](https://github.com/1jehuang/jcode/blob/main/.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`](https://github.com/1jehuang/jcode/blob/main/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/main/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`](https://github.com/1jehuang/jcode/blob/main/./.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`](https://github.com/1jehuang/jcode/blob/main/.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:

```rust
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:

- **[[`src/mcp/protocol.rs`](https://github.com/1jehuang/jcode/blob/main/src/mcp/protocol.rs)](https://github.com/1jehuang/jcode/blob/master/src/mcp/protocol.rs)**: Contains the `McpConfig` struct, `McpServerConfig` definitions, and the `load()` method that implements the priority chain.
- **[[`src/mcp/manager.rs`](https://github.com/1jehuang/jcode/blob/main/src/mcp/manager.rs)](https://github.com/1jehuang/jcode/blob/master/src/mcp/manager.rs)**: Consumes the loaded configuration to instantiate MCP server connections, demonstrating how the merged settings drive runtime behavior.
- **[[`src/tool/mcp.rs`](https://github.com/1jehuang/jcode/blob/main/src/tool/mcp.rs)](https://github.com/1jehuang/jcode/blob/master/src/tool/mcp.rs)**: Exposes the MCP management commands that interact with the loaded configuration when users execute `mcp` subcommands.

## 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`](https://github.com/1jehuang/jcode/blob/main/./.jcode/mcp.json) overrides global entries via `HashMap::extend`, giving it the highest active priority.
- **Legacy fallback** to [`./.claude/mcp.json`](https://github.com/1jehuang/jcode/blob/main/./.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`](https://github.com/1jehuang/jcode/blob/main/.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`](https://github.com/1jehuang/jcode/blob/main/.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`](https://github.com/1jehuang/jcode/blob/main/.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`](https://github.com/1jehuang/jcode/blob/main/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`](https://github.com/1jehuang/jcode/blob/main/.jcode/mcp.json) files, ensuring existing Claude Code setups continue to function without immediate migration.