How to Audit and Secure MCP Server Connections in Your AI Stack
Last updated: March 2026
Key Takeaways:
- MCP (Model Context Protocol) servers run executable code on your machine with broad permissions, and a compromised MCP plugin was the entry point for the LiteLLM supply chain attack on March 24, 2026 — the largest AI infrastructure attack of the year so far.
- Every MCP server you connect is a trust decision. This guide walks you through auditing your current connections, locking down permissions, isolating MCP traffic on your network, and hardening your local AI stack against transitive dependency attacks.
- You do not need to abandon MCP to stay safe. You need to treat MCP servers like any other executable software on your network: verify the source, limit permissions, isolate the environment, and monitor the traffic.
Why MCP Security Matters Right Now
On March 24, 2026, a threat actor called TeamPCP published two poisoned versions of LiteLLM — one of the most widely used Python libraries for routing requests across AI model providers — to the PyPI package registry. The malicious versions contained a credential stealer that harvested SSH keys, cloud tokens, API keys, cryptocurrency wallets, and every environment variable on the affected machine.
The detail that matters for this guide: the researcher who first discovered the attack found it because a Cursor IDE MCP plugin pulled in LiteLLM as a transitive dependency. He never ran pip install litellm himself. An MCP server integration did it for him, silently, as part of its own dependency chain.
This is not an abstract risk. MCP adoption is accelerating across every major AI tool — Claude, Cursor, VS Code, Figma, Slack, and dozens of enterprise platforms. Each MCP server you connect is a piece of executable code that runs on your machine (or in your cloud environment) with whatever permissions your user account has. If that code pulls in a compromised dependency, your entire environment is exposed.
If you are running a local AI stack — Ollama, LiteLLM Proxy, n8n, AnythingLLM, OpenClaw, Home Assistant, or similar tools — this guide is for you. We will walk through exactly how to audit your MCP connections and lock them down. Read our full breakdown of the LiteLLM supply chain attack here.
What MCP Is and Why It Creates an Attack Surface
Model Context Protocol (MCP) is an open standard introduced by Anthropic in late 2024 that defines how AI models connect to external tools, data sources, and services. Think of it as a universal adapter between an AI assistant and the rest of your software stack. When you connect an MCP server in Claude or Cursor, you are giving the AI model the ability to read files, query databases, call APIs, execute commands, or interact with third-party services on your behalf.
MCP servers come in two forms:
- Local MCP servers run on your machine. They execute operating system commands, read your filesystem, and interact with local services. This is the more dangerous category from a security perspective because a compromised local server has access to everything your user account can touch.
- Remote MCP servers run on a third party's infrastructure. They still access your data through API calls, but they do not execute code directly on your machine. The risk here is data exfiltration rather than local system compromise.
The core security problem is straightforward: MCP servers are executable code, and most users connect them with the same trust level they would use for installing a browser extension — which is to say, very little scrutiny. Unlike browser extensions, MCP servers often run with full user-level permissions, pull in their own dependency trees, and have no standardized sandboxing.
Step 1: Inventory Every MCP Server You Have Connected
Before you can secure anything, you need to know what you are running. Open every AI tool you use and list every MCP server connection.
In Claude Desktop: Open Settings, then navigate to the Developer or MCP section. Every connected MCP server will be listed with its name, transport type (stdio or HTTP), and the command used to launch it. Write down each one.
In Cursor: Open Settings and search for MCP. Cursor lists connected MCP servers along with the packages they depend on. Pay special attention to servers that were installed via npx or pip commands — these pull dependencies from public registries every time they run unless you have pinned versions.
In VS Code with Copilot or other MCP-enabled extensions: Check your settings.json file for any MCP server configurations. Also check the extensions themselves — some extensions bundle their own MCP servers internally.
On your local AI stack: If you are running LiteLLM Proxy, OpenClaw, n8n, or similar tools, check their configuration files for any MCP integrations. LiteLLM's config lives in litellm_config.yaml. OpenClaw configurations vary by deployment but typically reference MCP endpoints in their tool definitions.
Create a simple spreadsheet or text file with four columns: Server Name, Source (where you installed it from), Transport Type (local stdio vs. remote HTTP), and Last Verified Version. This is your MCP inventory. You will reference it for every step that follows.
Step 2: Verify the Source and Integrity of Each Server
For every MCP server on your inventory list, answer three questions:
1. Who maintains it? Check the GitHub repository (or npm/PyPI package page) for the MCP server. Is it maintained by the tool vendor themselves (e.g., Anthropic, Figma, Slack), a well-known open-source organization, or an unknown third party? Vendor-maintained servers are generally lower risk. Community-maintained servers with a single maintainer are higher risk — especially if that maintainer's credentials are compromised, which is exactly how the LiteLLM attack worked.
2. Is the version pinned? If your MCP server was installed via pip install or npx without a specific version number, you are pulling whatever the latest version is every time it runs. This is how transitive dependency attacks work. Check your install commands and configuration files. If you see pip install litellm instead of pip install litellm==1.82.6, you have a version pinning problem.
3. Can you verify the package hash? For critical MCP servers in your stack, compare the installed package hash against the known-good hash published by the maintainer. For Python packages:
pip show litellm
pip hash /path/to/package.whl
For npm packages:
npm ls --all
npm audit
If you cannot verify the source or the hash does not match, remove the server from your environment and reinstall from a verified source.
Step 3: Apply the Principle of Least Privilege
Most MCP servers request broad permissions because it is easier for the developer — not because the server needs all of those permissions to function. This is the "confused deputy" problem in MCP security: the server acts on your behalf with your full permissions, even when it only needs a fraction of them.
For each MCP server on your inventory, ask: what does this server actually need access to?
- A file-reading MCP server does not need write access to your filesystem.
- A database query server does not need access to your SSH keys or cloud credentials.
- A code execution server should never run outside of a sandboxed environment.
Where your MCP client supports it, restrict permissions to the minimum required scope. In tools that use OAuth-based MCP authorization, request only the specific scopes the server needs rather than accepting the default broad scopes.
For local MCP servers that run as shell commands, consider running them under a dedicated user account with restricted filesystem access rather than under your primary user account. On Linux systems:
# Create a restricted user for MCP servers
sudo useradd -r -s /usr/sbin/nologin mcp-runner
# Run the MCP server under the restricted user
sudo -u mcp-runner /path/to/mcp-server
This limits the blast radius if the server is compromised. A credential stealer running under mcp-runner cannot access your personal SSH keys, cloud tokens, or browser cookies stored under your primary account.
Step 4: Isolate MCP Servers in Containers
The most effective way to limit MCP server access is to run each one inside a container. Containers provide filesystem isolation, network isolation, and resource limits — all of which reduce the impact of a compromised dependency.
For Python-based MCP servers (which includes most of the AI ecosystem), use Docker:
# Example Dockerfile for an isolated MCP server
FROM python:3.12-slim
# Create a non-root user
RUN useradd -r -s /usr/sbin/nologin mcpuser
# Install only the specific pinned dependency
RUN pip install --no-cache-dir litellm==1.82.6
# Drop to non-root
USER mcpuser
# Run the server
CMD ["python", "-m", "litellm.proxy"]
Run the container with strict limits:
docker run --rm \
--read-only \
--network=mcp-isolated \
--cap-drop=ALL \
--memory=512m \
--env-file=./mcp-env-minimal.env \
mcp-server-litellm
Key flags explained:
-
--read-onlyprevents the container from writing to the filesystem, blocking persistence mechanisms used by malware like the TeamPCP credential stealer. -
--network=mcp-isolatedplaces the container on a dedicated Docker network (which you will create in Step 5) so it cannot reach your LAN or other services without explicit routing. -
--cap-drop=ALLremoves all Linux capabilities, preventing privilege escalation. -
--env-filepasses only the specific environment variables the server needs (such as API keys for model providers) rather than inheriting your full shell environment. Never use--envto pass your entire environment. This is how the LiteLLM stealer harvested credentials — it read every environment variable available to the process.
If Docker is not practical for your setup, Python virtual environments (venv) provide dependency isolation but not filesystem or network isolation. A venv is better than a global install but significantly weaker than a container.
Step 5: Segment Your Network for MCP Traffic
Even inside containers, MCP servers need network access to function — they need to reach AI model provider APIs, and your MCP client needs to communicate with the server. The goal is to ensure that this traffic flows only where it needs to go and nowhere else.
If you are running a home AI stack on a mini PC or dedicated server, configure your router or firewall to create a dedicated VLAN or subnet for AI infrastructure traffic. On most consumer routers that support VLANs (such as those running OpenWrt or other open-source firmware, pfSense, or OPNsense):
1. Create a dedicated AI infrastructure VLAN (for example, VLAN 40 on subnet 192.168.40.0/24). Assign your AI server's network interface to this VLAN.
2. Configure firewall rules for the VLAN:
- Allow outbound HTTPS (port 443) to specific AI provider API endpoints only:
api.openai.com,api.anthropic.com,generativelanguage.googleapis.com, and any other providers you use. - Block all other outbound traffic from the VLAN. This prevents a compromised MCP server from exfiltrating data to an attacker-controlled domain — which is exactly what the LiteLLM stealer did when it sent harvested credentials to
models.litellm.cloud, a domain that is not an official LiteLLM endpoint. - Allow inbound traffic only from your primary workstation's IP address (or VLAN) on the specific ports your MCP client uses.
3. Use DNS-level filtering as an additional layer. If you are running Pi-hole or AdGuard Home on your network, create a group for your AI infrastructure VLAN and configure a strict allowlist of domains rather than the default blocklist approach. Only the specific API endpoints your stack needs should resolve. Everything else returns NXDOMAIN. See our full Pi-hole setup guide.
For users without VLAN-capable routers, Docker's network isolation provides a reasonable substitute. Create a custom bridge network and attach only the containers that need to communicate with each other:
# Create an isolated network for MCP containers
docker network create --internal mcp-isolated
# Create a network with controlled external access
docker network create \
--driver bridge \
--opt com.docker.network.bridge.enable_icc=false \
mcp-external
Containers on the mcp-isolated network cannot reach the internet at all. Containers that need API access get attached to mcp-external with egress rules controlled by your host firewall (iptables or nftables).
Step 6: Monitor and Log MCP Activity
Security without monitoring is security you cannot verify. Set up basic logging for your MCP server activity so you can detect anomalies and investigate incidents.
At the network level: If you are running Pi-hole or AdGuard Home, check your query logs for DNS requests originating from your AI infrastructure VLAN or container network. Any domain request you do not recognize — especially to recently registered domains — is a red flag. The LiteLLM stealer exfiltrated data to a domain registered specifically for the attack.
At the container level: Docker's built-in logging captures stdout and stderr from every container. Review these logs periodically:
# View recent logs for a specific MCP container
docker logs --since 24h mcp-server-litellm
# Watch logs in real time
docker logs -f mcp-server-litellm
At the application level: Some MCP clients (including Claude Desktop) log MCP server interactions. Check your client's log directory for records of which tools were invoked, what parameters were passed, and what responses were returned. Unusual tool invocations or unexpected parameters can indicate prompt injection or tool poisoning attacks.
At the package level: Set up a recurring check for your pinned dependencies. A simple cron job or scheduled script that runs pip list --outdated or npm outdated and emails you the results gives you early warning when a new version is published — so you can investigate before blindly upgrading.
Step 7: Establish an MCP Server Approval Process
The hardest part of MCP security is not the technical controls — it is the habit of connecting new servers without thinking. Every MCP server you add is a trust decision, and trust decisions should be deliberate.
Before connecting any new MCP server to your environment, run through this checklist:
- Source verification: Is the server maintained by the tool vendor or a known, reputable organization? Is the source code available for inspection?
-
Dependency audit: What does the server depend on? Run
pip show --verbose [package]or inspect thepackage.jsonto see the full dependency tree. Fewer dependencies means a smaller attack surface. - Permission scope: What access does the server need? Does it need filesystem access, network access, or the ability to execute arbitrary commands? Can you restrict it to the minimum required?
- Transport type: Is it a local server (stdio) or remote server (HTTP)? Local servers carry higher risk to your system; remote servers carry higher data exposure risk.
- Update policy: Will you pin to a specific version and manually review updates, or will the server auto-update? For anything touching your local AI stack, manual review is strongly recommended.
This does not need to be a formal process. A simple text file that records each server you have approved — with the date, version, and your reasoning — gives you an audit trail and forces a moment of deliberation before each new connection.
What to Do If You Think You Are Already Compromised
If you installed or upgraded LiteLLM via pip between 10:39 UTC and 16:00 UTC on March 24, 2026, or if any MCP plugin in your environment pulled in LiteLLM as a transitive dependency during that window, assume compromise and take these steps immediately:
- Check your installed version:
pip show litellm. Versions 1.82.7 and 1.82.8 are confirmed malicious. Version 1.82.6 is the last known clean release. - Search for persistence mechanisms: look for
~/.config/sysmon/sysmon.pyand~/.config/systemd/user/sysmon.serviceon your system. If running Kubernetes, audit thekube-systemnamespace for pods matchingnode-setup-*. - Rotate every credential that was accessible from the affected machine: SSH keys, cloud provider tokens (AWS, GCP, Azure), API keys stored in
.envfiles, database passwords, and cryptocurrency wallet keys. - Remove the malicious package and purge your package manager cache:
pip uninstall litellm && pip cache purge. - Reinstall from a verified clean version:
pip install litellm==1.82.6. - If you cannot determine the full scope of exposure, rebuild the affected system from a known clean state. This is the safest option.
Read our full LiteLLM supply chain attack breakdown for complete incident details.
Frequently Asked Questions
What is MCP and why does it affect my home AI setup?
MCP (Model Context Protocol) is the standard that lets AI assistants like Claude and tools like Cursor connect to external services — databases, APIs, file systems, and other software. If you use any AI tool that connects to outside services, you are likely using MCP. Each connection is a piece of software running on your machine or accessing your data, which means each one is a potential attack vector if compromised.
Do I need to disconnect all my MCP servers?
No. MCP is a useful and increasingly necessary protocol for getting real work done with AI tools. The goal is not to avoid MCP but to treat MCP servers with the same security scrutiny you would apply to any software you install on your machine. Verify the source, pin the version, isolate the environment, and monitor the traffic.
How did the LiteLLM attack involve MCP specifically?
The researcher who discovered the LiteLLM supply chain attack found it because a Cursor IDE MCP plugin pulled in LiteLLM as a transitive dependency — meaning the plugin depended on LiteLLM, which was automatically installed without the user explicitly requesting it. The malicious code in LiteLLM then executed on every Python process startup, harvesting credentials from the entire environment. The user never ran pip install litellm directly.
Is Ollama affected by MCP security risks?
Ollama itself runs local AI models and does not use MCP natively. However, if you connect Ollama to other tools through MCP servers — for example, using an MCP server that routes prompts to your local Ollama instance — the MCP server layer introduces its own risks. The Ollama model inference is safe, but the plumbing around it needs to be secured. Running Ollama on an isolated VLAN or in a container with restricted network access is still good practice.
What is a transitive dependency and why should I care?
A transitive dependency is a package that your software depends on indirectly. If you install Package A, and Package A requires Package B, then Package B is a transitive dependency — it gets installed automatically even though you never asked for it. The LiteLLM attack exploited this: users who installed an MCP plugin unknowingly pulled in LiteLLM, and LiteLLM had been poisoned. Pinning versions and auditing your full dependency tree are the primary defenses against this class of attack.
Can I use Pi-hole to protect my MCP connections?
Yes, and we recommend it. Pi-hole operates at the DNS level, which means it can block MCP servers (or compromised dependencies within them) from reaching attacker-controlled domains. For your AI infrastructure, set up a dedicated Pi-hole group with a strict allowlist of the API domains your stack actually needs. This will not prevent all attacks, but it blocks the exfiltration step — which is where the actual damage happens. See our Pi-hole setup guide for detailed instructions. See our full Pi-hole setup guide.
How often should I audit my MCP connections?
At minimum, audit your MCP inventory whenever you add a new server, upgrade an existing one, or learn about a supply chain attack affecting tools in your stack. For active local AI setups, a monthly review of your inventory spreadsheet, pinned versions, and DNS logs takes about 15 minutes and is well worth the effort.

