# How SkillSpector Detects MCP Tool Poisoning: Four Static Analysis Methods Explained

> Discover how SkillSpector detects MCP tool poisoning using four static analysis methods: covert instruction extraction, Unicode deception, parameter injection scanning, and LLM semantic verification.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: deep-dive
- Published: 2026-06-20

---

**SkillSpector employs four specialized detection patterns—covert instruction extraction (TP1), Unicode deception analysis (TP2), parameter injection scanning (TP3), and LLM-powered semantic verification (TP4)—to identify malicious capabilities embedded in NVIDIA Skill Manifests.**

NVIDIA SkillSpector is a static analysis framework designed to validate skill manifests against security threats before deployment. The tool implements comprehensive **MCP tool poisoning detection** through a dedicated analyzer node that processes textual fields, Unicode properties, parameter definitions, and code semantics to surface hidden attack vectors.

## The MCP Tool Poisoning Analyzer Architecture

The analyzer implementation lives in [`src/skillspector/nodes/analyzers/mcp_tool_poisoning.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/mcp_tool_poisoning.py). This node extracts all textual content from a manifest—including **names**, **descriptions**, **triggers**, and **parameter fields**—then routes them through four specialized threat detection routines. Each detection pattern targets a specific attack vector used to inject malicious instructions into tool definitions.

The main `node(state)` function orchestrates the analysis by first calling `_extract_metadata_texts()` to gather metadata, then executing TP1 and TP2 checks across every text field, TP3 specifically against the parameters list, and optionally TP4 when LLM validation is enabled.

## TP1 – Hidden Instruction Detection

The `_check_tp1()` function scans for covert payloads embedded in manifest text using specialized regex patterns. This detection layer identifies:

- **HTML comments** (e.g., `<!-- hidden instruction -->`)
- **Markdown comments** using the `[//]: #(...)` syntax
- **Zero-width Unicode characters** that render invisibly
- **Base64 encoded blobs** that may hide executable content
- **Data-URI payloads** embedded in text fields

The implementation uses the regex constants `_HTML_COMMENT_RE`, `_MARKDOWN_COMMENT_RE`, `_ZERO_WIDTH_RE`, `_BASE64_RE`, and `_DATA_URI_RE` to build a `Finding` object for each match discovered in the manifest.

## TP2 – Unicode Deception Analysis

The `_check_tp2()` function identifies visual spoofing attacks that use Unicode properties to disguise malicious tool names or descriptions. This check processes each text field with the following logic:

First, it scans for characters defined in the `_CONFUSABLES`, `_RTL_CHARS`, and `_INVISIBLE_CHARS` sets to detect **Cyrillic/Greek homoglyphs**, **right-to-left override characters**, and **invisible formatting characters**. Second, it uses the `_get_script_prefix()` helper to identify **mixed-script identifiers** that combine visually similar characters from different alphabets to deceive users.

## TP3 – Parameter Description Injection

The `_check_tp3()` function specifically examines the `parameters` list in the manifest for injection attacks targeting the tool's input layer. This method applies regex patterns to detect:

- **Instruction-override phrases** that attempt to redirect tool behavior
- **System-prompt tokens** embedded in parameter descriptions
- **Exfiltration cues** suggesting data theft mechanisms
- **Overly long descriptions** that may contain hidden payloads
- **Malicious defaults** including URLs or shell commands

The detection uses `_TP3_INSTRUCTION_OVERRIDE_RE`, `_TP3_SYSTEM_TOKEN_RE`, `_TP3_EXFILTRATION_RE`, `_TP3_MALICIOUS_URL_RE`, and `_TP3_SHELL_CMD_RE` to flag suspicious parameter definitions that could compromise the execution environment.

## TP4 – LLM-Based Semantic Verification

The `_check_tp4()` function performs deep semantic analysis to detect **description-to-behavior mismatches**. Unlike the pattern-based TP1-TP3 checks, this method uses an LLM to validate whether the tool's declared functionality matches its actual implementation.

The function collects code snippets from the state's `file_cache`, constructs a detailed comparison prompt, and calls `chat_completion()` from [`src/skillspector/llm_utils.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/llm_utils.py). It parses the JSON response to emit a `Finding` when the LLM reports a significant mismatch between the manifest description and the executable code with sufficient confidence.

## Running the Analyzer

You can execute the MCP tool poisoning analyzer from the command line:

```bash
skillSpector analyze --analyzer mcp_tool_poisoning path/to/skill/

```

For programmatic use within a Python environment:

```python
from skillspector.graph import build_graph
from skillspector.nodes.analyzers.mcp_tool_poisoning import node as mcp_node

# Load a skill directory into a SkillspectorState

graph = build_graph("path/to/skill")
state = graph.state

# Run only the MCP-tool-poisoning analyzer

result = mcp_node(state)
print(result["findings"])   # list of Finding objects

```

To inspect individual findings returned by the analyzer:

```python
finding = result["findings"][0]
print(f"Rule: {finding.rule_id}")
print(f"Message: {finding.message}")
print(f"Severity: {finding.severity}")
print(f"Location: {finding.matched_text}")

```

## Summary

- **TP1** detects hidden instructions using regex patterns for HTML comments, Markdown comments, zero-width characters, Base64 blobs, and Data-URIs in [`src/skillspector/nodes/analyzers/mcp_tool_poisoning.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/mcp_tool_poisoning.py).
- **TP2** identifies Unicode deception through homoglyph detection (`_CONFUSABLES`), RTL character analysis (`_RTL_CHARS`), and mixed-script identification via `_get_script_prefix()`.
- **TP3** scans parameter descriptions for injection attacks, system token overrides, and malicious defaults using specialized TP3 regex constants.
- **TP4** leverages `chat_completion()` to perform semantic validation between manifest descriptions and actual code stored in the `file_cache`.
- All findings are emitted as `Finding` objects defined in [`src/skillspector/models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/models.py) and registered in the node system via [`src/skillspector/nodes/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/__init__.py).

## Frequently Asked Questions

### What is MCP tool poisoning?

MCP (Malicious Capability Poisoning) refers to attacks where adversaries embed hidden instructions, deceptive Unicode characters, or semantic misrepresentations in tool manifests to manipulate AI system behavior or exfiltrate data. SkillSpector detects these attempts through static analysis before the tools are deployed.

### How does SkillSpector detect hidden text in manifests?

The `_check_tp1()` function in [`mcp_tool_poisoning.py`](https://github.com/NVIDIA/SkillSpector/blob/main/mcp_tool_poisoning.py) applies regex patterns including `_HTML_COMMENT_RE`, `_MARKDOWN_COMMENT_RE`, and `_ZERO_WIDTH_RE` to detect HTML comments, Markdown metadata comments, and zero-width Unicode characters that could hide malicious payloads from casual review.

### Can SkillSpector detect visually similar but malicious tool names?

Yes, through **TP2 Unicode deception analysis**. The `_check_tp2()` function checks for confusable Cyrillic/Greek homoglyphs, RTL directional-override characters, and mixed-script identifiers using character sets defined in `_CONFUSABLES`, `_RTL_CHARS`, and `_INVISIBLE_CHARS` to catch visual spoofing attacks.

### What role does the LLM play in TP4 detection?

TP4 uses the `chat_completion()` utility to compare the skill's declared description and triggers against the actual executable code retrieved from the state's `file_cache`. This semantic validation identifies behavioral mismatches that pattern-based detection might miss, such as a tool claiming to "read files" while actually executing shell commands.