Abdolmadjid Masoomi

MCP Server Security: A Config File Is Now Executable Code

Cloning a repository can launch tools with your privileges before you have read a line.

Signed
Abdolmadjid Masoomi
Published
2026-09-14
Length
9 min read · 1,865 words
Status
opinion

Project-level MCP configuration turns a JSON file into a process launcher that runs with your operating-system privileges. The trust decision has moved from running code to opening a folder, requiring teams to treat these configs with the same rigour as build scripts. This article examines the mechanisms behind mcp server security and how to mitigate the risks.

The Model Context Protocol (MCP) was designed to standardise how AI models interact with external data sources and tools. It promises a unified interface for developers to connect their models to databases, file systems, and APIs. This standardisation reduces friction and allows for more powerful agent-based workflows. However, the convenience of this standardisation introduces a significant shift in the threat model for developers.

When you integrate an MCP server into your development environment, you are not merely configuring a data connector. You are defining a process that executes with the privileges of your user account. The configuration file that describes these connections becomes executable code in all but name. It dictates which processes start, which commands run, and which resources are accessible. This is a fundamental change in how we perceive trust in software projects.

The core issue is that the trust decision has quietly moved from 'do I run this code' to 'do I open this folder'. In traditional development, you review source code before execution. With MCP, the configuration file itself triggers the execution of external processes. This creates a scenario where trust issues in executable configuration files become immediate and unavoidable. Developers must recognise that a JSON file is no longer just data; it is a set of instructions for the operating system.

What an MCP server is allowed to do

An MCP server acts as a bridge between the AI model and the host environment. It exposes tools, resources, and prompts that the model can invoke. When a developer configures an MCP server, they specify the command to launch the server process. This command can be a simple script, a compiled binary, or a complex pipeline of shell commands. The server then runs within the context of the developer’s user session.

This context includes access to environment variables, file system permissions, and network interfaces. If the configuration specifies a tool that writes to a file, the server writes to that file with the developer’s permissions. If it specifies a tool that executes a shell command, that command runs with the same rights as the developer. The AI model does not need to execute these actions directly; it only needs to request them. The server handles the execution.

The implications are profound. A tool defined in the configuration can read sensitive files, modify project dependencies, or send network requests. The model can chain these tools together to perform complex actions across the system. This capability is powerful for automation but dangerous if the configuration is untrusted. The server becomes an extension of the developer’s own capabilities, amplified by the model’s reasoning.

When opening a project runs a process

The risk of unreviewed server initialisation depends on the specific IDE, AI coding assistant, and user settings rather than being a universal norm. While some tools may automatically detect and load project configurations upon opening a repository, many major clients now require explicit approval before starting servers defined in project config. The real danger lies not in an inherent default behaviour, but in tools, settings, or habitual one-click approvals that allow these servers to start with little or no review.

This automatic initialisation is convenient but risky. It assumes that the repository is safe and that the configuration is benign. In open-source projects, this assumption is often incorrect. A malicious actor can push a configuration file that launches a server with harmful instructions. When a developer clones and opens the repository, the server starts running. The damage can occur before the developer is aware of the threat.

The speed of this process is critical. Modern IDEs are optimised for rapid feedback, often loading configurations instantly to provide immediate AI assistance. This speed can leave little time for manual review, particularly when auto-start is enabled or approval prompts are accepted without scrutiny. In such cases, the server may already be running, connected to the network, and potentially exfiltrating data or modifying files. The developer is presented with a working AI interface, unaware that the underlying infrastructure is compromised. This represents a supply chain attack vector, adapted for the AI era.

Tool descriptions as a second injection channel

The risk extends beyond the configuration file itself. MCP servers expose tools to the AI model, and these tools come with descriptions. The model uses these descriptions to decide which tool to invoke. If the descriptions are crafted maliciously, they can influence the model’s behaviour. This is known as tool poisoning, a vulnerability that highlights the risks of unvetted tool integrations within the wider supply chain of dependencies you did not choose. A tool might be described as a benign utility, but its actual function could be destructive.

The model trusts the tool description provided by the server. It assumes that the description accurately reflects the tool’s capabilities. If the description is misleading, the model may invoke the tool for reasons that seem safe based on the text. For example, a tool described as 'format code' might actually contain logic to overwrite critical files. The model sees the request, the description, and the action. It does not see the underlying code of the server.

This creates a second layer of injection. The first layer is the configuration file, which launches the server. The second layer is the tool schema, which guides the model’s actions. Both layers must be trusted. If either is compromised, the developer’s environment is at risk. The model becomes an unwitting agent for the attacker, executing actions that appear justified by the tool descriptions. This is why securing development environments against injection is essential.

Pinning, allowlists and approval prompts

To mitigate these risks, developers must adopt stricter controls over MCP configurations. The first step is pinning. Instead of allowing the IDE to fetch the latest version of a server, developers should pin to a specific commit or version. This prevents automatic updates from introducing new vulnerabilities or malicious changes. Pinning ensures that the configuration remains stable and predictable.

The second step is allowlisting. Developers should maintain a list of approved servers and tools. The IDE should only load configurations that reference these approved sources. Any deviation from the allowlist should trigger an error or a warning. This reduces the attack surface by limiting the sources of potential threats. It forces developers to explicitly approve new integrations.

The third step is approval prompts. When a configuration is detected, the IDE should ask for explicit permission before initialising the server. This pause gives the developer a chance to review the configuration. They can inspect the commands, check the network requests, and verify the tool definitions. This manual review is critical for catching malicious configurations. It shifts the burden of trust back to the developer, where it belongs.

Sandboxing servers away from your home directory

Running MCP servers with full user privileges is unnecessary and dangerous. These servers do not need access to the developer’s entire home directory. They do not need access to sensitive personal files or other projects. Sandboxing limits the damage that a compromised server can cause. By restricting the server’s access to a specific directory, we contain the blast radius.

Most operating systems provide mechanisms for sandboxing. Containers, virtual machines, or restricted user accounts can isolate the server process. The server runs in a limited environment with minimal permissions. It can access only the files and resources required for its specific task. If the server is compromised, the attacker gains access only to the sandboxed environment.

This approach requires careful configuration. The sandbox must be granted enough access to be useful, but no more. Network access should be restricted to only the necessary endpoints. File system access should be limited to the project directory. This minimises the risk of data exfiltration or lateral movement. It ensures that the server’s privileges are proportional to its function.

A review checklist for MCP configs

Before integrating an MCP server, developers should perform a thorough review. This checklist helps identify potential risks and ensures that the configuration is safe.

  • Verify the source of the server. Is it from a trusted organisation or repository?
  • Check the command that launches the server. Does it run unexpected scripts or binaries?
  • Review the tool definitions. Do the descriptions match the expected functionality?
  • Inspect the network requests. Does the server connect to unknown endpoints?
  • Confirm the file system permissions. Does the server access only necessary files?
  • Ensure the configuration is pinned to a specific version.
  • Validate the configuration against the allowlist.

This process takes time, but it is essential for maintaining security. Automated tools can help, but human review is still necessary. The complexity of MCP configurations means that automated checks may miss subtle threats. Developers must remain vigilant and critical of every integration.

Questions people ask

Is mcp secure for developer workflows?

MCP is not inherently secure or insecure; its security depends on how it is configured and managed. The protocol itself provides a standard interface, but the trust model relies on the developer to vet the servers and tools. Without proper controls like pinning and allowlisting, the risk of executing untrusted code is high. Developers must treat MCP configurations as executable code and review them accordingly.

What is mcp tool poisoning?

MCP tool poisoning occurs when a malicious actor manipulates the tool definitions or descriptions exposed by an MCP server. The AI model uses these descriptions to decide which tools to invoke. If the descriptions are misleading, the model may execute harmful actions under the guise of benign operations. This is a form of injection where the attacker exploits the model’s trust in the tool schema.

How to secure mcp servers effectively?

Securing MCP servers involves a combination of technical controls and operational practices. Pin configurations to specific versions, allowlist trusted sources, and require approval prompts for new integrations. Sandboxing the server process limits its access to sensitive resources. Regularly review tool definitions and network requests to detect anomalies. Treat the configuration file as executable code and apply the same rigour as you would to source code.

Close

The integration of MCP into development workflows offers significant benefits for productivity and automation. It allows AI models to interact with the real world in meaningful ways. However, this power comes with responsibility. The configuration file is no longer just data; it is a set of instructions that the operating system will execute. Developers must recognise this shift and adapt their security practices accordingly.

The threat model has changed. Trust is no longer granted by default when opening a project. It must be earned through careful review and strict controls. Pinning, allowlisting, and sandboxing are not optional extras; they are essential components of a secure workflow. Developers who ignore these measures risk exposing their systems to untrusted code.

The future of AI-assisted development depends on our ability to manage these risks. We must build systems that are secure by default, not by accident. This requires a cultural shift in how we view configuration files and external integrations. We must treat them with the same respect and scrutiny as we treat source code. Only then can we harness the power of MCP without compromising our security.