Skip to content

Where MCP Config Lives: User or Project Scope

Adityo Guni Waluyo

Where MCP configuration belongs: workspace files travel with the repo and get team review, user profiles stay personal and skip review entirely.

While reviewing a configuration update on a portal project, one file stood out: a Model Context Protocol (MCP) server definition stored inside the project's .vscode directory. The finding raised a question more fundamental than repository tidiness. A local MCP server can execute code directly on a developer's machine, read files, or connect to outside services. Deciding where MCP configuration lives, user scope or project scope, is not a personal preference. It is a security boundary decision.

The common first assumption goes like this: user-level configuration is just a convenience feature for personal tool preferences, while project-level configuration is automatically better because the whole team shares it. Real usage shows both assumptions miss the consequences in both directions.

Security Boundaries and Config Locations

The official VS Code documentation describes several storage locations [5]. Workspace-level configuration lives in the .vscode/mcp.json file or the portable .mcp.json format at the project root. User-level configuration lives in the editor profile, and its portable format is an mcp-config.json file under the Copilot configuration directory in the home folder, active across all of that user's workspaces [5].

The consequences differ sharply. Workspace configuration travels with the repository and is available to everyone who opens it. User configuration stays personal and never enters commit history. The GitHub Copilot documentation summarizes the split concisely: repository-level configuration is shared with everyone who opens the project, while personal configuration is visible only to its owner yet active in all workspaces [6].

One example clarifies the split. An MCP server connecting to the team's development database with shared team credentials belongs in project scope because every member genuinely needs it. A personal calendar reader or a connector to a personally billed service belongs in user scope; forcing it into the repository exposes credential paths to every repository reader. A new team member cloning the repository will not realize an extra server came along with the definition until the editor surfaces it.

Duplication also deserves attention. The same server definition in two locations can trigger conflicts or unexpected behavior. A healthy habit: one server, one location, with the placement decision recorded in the project documentation so every member knows which one is official.

LocationReachImplication
.vscode/mcp.json or .mcp.jsonWhole team opening the repoReviewed via pull request, subject to Workspace Trust
mcp-config.json in the user profileLocal user onlyNo team review, active in all workspaces

Configuration in project scope can be reviewed through pull requests. The team can see which servers will run on every member's machine and reject suspicious definitions before any code runs. Configuration in user scope bypasses that review entirely. Protection for personal credentials is paid for with the loss of team verification over the tools being run.

The trust side is asymmetric too. MCP servers in a workspace inherit Workspace Trust. In restricted mode, workspace configuration is blocked and its servers do not start. The VS Code documentation closes this section with a warning worth pinning to a wall: review workspace MCP configuration before trusting a repository, because local MCP servers can execute code on the machine [5].

When Browser Verification Is Needed

For servers that interact with interfaces or external services, unit tests alone are not enough. The dividing criterion is simple: if a server authenticates to an outside service or manipulates browser state, verification must run through a real, isolated browser session. A static workspace file-reader server can settle for unit tests.

The verification flow can be kept simple. Run one complete scenario: open the application, trigger the action that calls the MCP server, then check the final result on screen, not just the logs. A common finding from this flow is not a connection failure but behavior drifting from the definition, for example a server modifying data more broadly than its definition promises.

One final rule that must never be broken: no credentials in workspace configuration. Explicit placeholders go in project files; the real values live in user scope or a secret manager.

Sources

Related articles