# MCP Least Privilege Detection in SkillSpector: Complete Technical Guide

> Master MCP Least Privilege detection in SkillSpector. Learn how this static analysis tool audits Model Control Plane skills, flagging violations by comparing declared vs. actual permissions.

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

---

**MCP Least Privilege detection in SkillSpector is a static analysis capability that audits Model Control Plane skills by comparing declared permissions in [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) against actual runtime capabilities extracted from source code, flagging violations across four specific rule categories (LP1-LP4).**

SkillSpector, NVIDIA's open-source skill auditing framework, implements MCP Least Privilege detection through a dedicated analyzer node that enforces the principle of least privilege. This security mechanism inspects executable files using regex pattern matching to ensure that skills cannot request broader permissions than their code actually requires, nor hide capabilities behind incomplete manifest declarations.

## How the MCP Least Privilege Analyzer Works

The analyzer is implemented as the **`mcp_least_privilege`** node in [`src/skillspector/nodes/analyzers/mcp_least_privilege.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/mcp_least_privilege.py). During pipeline execution, it receives a `SkillspectorState` object containing three critical structures: the **`manifest`** (parsed [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) with declared permissions), **`file_cache`** (source file contents for static analysis), and **`component_metadata`** (flags indicating executable files).

### The LP1-LP4 Rule Set

According to the MCP least-privilege specification as implemented in NVIDIA/SkillSpector, the analyzer evaluates four distinct violation patterns:

| Rule | Violation Type | Detection Mechanism | Severity |
|------|---------------|---------------------|----------|
| **LP1** | Under-declared capabilities | Code contains capabilities not covered by declared permissions | **HIGH** |
| **LP2** | Wildcard permissions | Manifest contains `"*"`, `"all"`, `"full"`, or `"any"` | **MEDIUM** |
| **LP3** | No permissions declared | Capabilities detected but `permissions` field is missing or empty | **MEDIUM** |
| **LP4** | Over-declared permissions | Declared permissions have no matching code capability | **LOW** |

### Detection Workflow

The node executes a four-phase analysis pipeline:

1. **Executable Validation** – If no component metadata marks files as executable or the manifest is absent, the analyzer returns immediately (lines 72-81).

2. **Capability Extraction** – For each executable file, `_detect_capabilities()` applies regex patterns from `_CAPABILITY_PATTERNS` using `re.search(..., content, re.IGNORECASE)` to identify shell, network, file I/O, environment, and MCP-specific API usage (lines 40-90).

3. **Permission Mapping** – `_map_permissions_to_categories()` normalizes declared permission strings and matches them against `_PERM_TO_CAPABILITY` using word-boundary regexes (lines 93-110).

4. **Finding Generation** – The analyzer compares declared categories against detected capabilities, creating `Finding` objects with descriptive messages, severity levels, and remediation advice (lines 96-152, 184-210, 222-280, 292-350).

## Key Implementation Details

### Wildcard Detection (LP2)

The `_has_wildcard()` function scans the `permissions` list for dangerous blanket values. When detected, the analyzer emits a **MEDIUM** severity finding to warn against overly permissive configurations.

```python

# From src/skillspector/nodes/analyzers/mcp_least_privilege.py (lines 93-100)

if _has_wildcard(permissions):
    findings.append(Finding(
        message="Wildcard permission detected",
        severity="MEDIUM",
        # ... remediation advice

    ))

```

### Under-Declared Capabilities (LP1)

This **HIGH** severity check identifies capabilities present in code that lack corresponding manifest entries. After gathering per-file capabilities into `all_caps`, the analyzer maps declared permissions to categories and reports any gap. Test-only capabilities receive reduced confidence scores (line 84).

```python

# Capability comparison logic (lines 66-90)

declared_categories = _map_permissions_to_categories(permissions)
for cap in all_caps:
    if cap not in declared_categories:
        findings.append(Finding(
            severity="HIGH",
            message=f"Capability {cap} not declared in permissions"
        ))

```

### Over-Declared Permissions (LP4)

Conversely, LP4 triggers when permissions exist in the manifest without supporting code evidence. Each permission maps to a capability category; if absent from `all_caps`, a **LOW** finding is emitted (lines 112-130).

### Missing Permissions (LP3)

When `_detect_capabilities()` finds executable capabilities but the manifest lacks a `permissions` entry entirely, the analyzer raises a **MEDIUM** finding (lines 35-38). This catches cases where dangerous functionality exists without any security documentation.

## Practical Examples

### Running the Analyzer from CLI

Execute the MCP Least Privilege analyzer independently using the SkillSpector command-line interface:

```bash
skillspector analyze --analyzer mcp_least_privilege /path/to/skill

```

This command loads the skill's [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md), populates the file cache, and outputs a SARIF report containing LP1-LP4 findings.

### Sample SKILL.md Violations

The following manifest configuration triggers multiple rule violations:

```yaml
name: dangerous-tool
description: Demonstrates MCP least-privilege detection
permissions:
  - "*"
  - network
  - env

```

- The `"*"` entry triggers **LP2** (Wildcard permission)
- Declaring `env` without environment access in code triggers **LP4** (Over-declared)
- Omitting shell permissions while using `subprocess` triggers **LP1** (Under-declared)

### Code That Triggers LP1

Consider this Python implementation where the skill executes shell commands:

```python

# file: dangerous_tool.py

import subprocess

def run():
    subprocess.Popen(["/bin/ls", "-l"])

```

If [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) only declares `network` permission, the analyzer reports an under-declared **shell** capability with **HIGH** severity, as the code performs shell execution without explicit permission.

## Source File Reference

The MCP Least Privilege detection system spans these key files in the NVIDIA/SkillSpector repository:

- **[`src/skillspector/nodes/analyzers/mcp_least_privilege.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/mcp_least_privilege.py)** – Core analyzer implementing LP1-LP4 detection logic
- **[`src/skillspector/models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/models.py)** – Definition of the `Finding` data model used for violation reporting
- **[`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py)** – Analyzer registration (`"mcp_least_privilege"` ID)
- **[`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py)** – CLI entry point wiring the analyzer to the `skillspector analyze` command
- **[`tests/test_mcp_least_privilege.py`](https://github.com/NVIDIA/SkillSpector/blob/main/tests/test_mcp_least_privilege.py)** – Unit tests verifying correct detection of each LP rule

## Summary

- **MCP Least Privilege detection** validates that skill permissions match actual code capabilities through static analysis.
- The analyzer implements **four violation rules (LP1-LP4)** with severity rankings from HIGH (under-declared) to LOW (over-declared).
- Detection relies on **`_CAPABILITY_PATTERNS`** regex matching against executable files and **`_PERM_TO_CAPABILITY`** mapping for manifest validation.
- Findings are generated as structured `Finding` objects containing severity, confidence, and remediation guidance.
- The analyzer can be invoked independently via **`skillspector analyze --analyzer mcp_least_privilege`**.

## Frequently Asked Questions

### What is the difference between LP1 and LP4 in MCP Least Privilege detection?

**LP1 (Under-declared capabilities)** occurs when code contains capabilities (such as shell execution or network access) that are not covered by any permission declared in [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md), warranting a **HIGH** severity finding. **LP4 (Over-declared permissions)** occurs when the manifest lists permissions that have no corresponding capability detected in the source code, resulting in a **LOW** severity finding.

### How does SkillSpector determine which files to analyze for capabilities?

The analyzer checks **`component_metadata`** to identify files marked as executable. Only executable components undergo capability extraction via `_detect_capabilities()`, while non-executable files are skipped to reduce false positives and improve performance.

### What severity levels does the MCP Least Privilege analyzer assign to findings?

The analyzer uses a tiered severity system: **HIGH** for LP1 (under-declared capabilities that could enable unauthorized access), **MEDIUM** for LP2 (wildcard permissions) and LP3 (missing permissions declarations), and **LOW** for LP4 (over-declared permissions that represent principle-of-least-privilege violations but lower security risk).

### Can the MCP Least Privilege analyzer run independently from other SkillSpector checks?

Yes. According to the CLI implementation in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py), you can isolate the analyzer using the `--analyzer` flag: `skillspector analyze --analyzer mcp_least_privilege /path/to/skill`. This produces a focused SARIF report containing only LP1-LP4 findings without running other analysis nodes.