# How to Use SkillSpector with LangGraph: Integration Guide and API Reference

> Integrate SkillSpector with LangGraph by invoking its compiled StateGraph for security scans. Learn how to use SkillSpector via API or as a subgraph in your workflows.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: integration-guide
- Published: 2026-06-21

---

**SkillSpector exposes a compiled LangGraph StateGraph that executes security scans through a series of nodes, allowing you to invoke it directly, run it from the CLI, or embed it as a subgraph in larger LangGraph workflows.**

SkillSpector is an open-source security scanner from NVIDIA built on top of LangGraph, a Python framework for composing stateful graph workflows. The repository implements a complete analysis pipeline as a LangGraph StateGraph, making it trivial to integrate into existing agentic systems or run standalone. Understanding how SkillSpector leverages LangGraph's node-based architecture enables you to customize the security scanning workflow or compose it into complex multi-agent systems.

## Understanding the SkillSpector LangGraph Architecture

The core workflow lives in [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py), where the `create_graph()` function constructs a StateGraph using the `SkillspectorState` Pydantic model defined in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py). The graph follows a linear progression with branching analyzer nodes:

```

START → resolve_input → build_context → [analyzers] → meta_analyzer → report → END

```

Each node performs a distinct function in the security scan pipeline.

### State Management with SkillspectorState

The workflow state is strictly typed via the `SkillspectorState` Pydantic model in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py). This state object tracks:

- `input_path` / `skill_path`: The original skill location provided by the user
- `temp_dir_for_cleanup`: Temporary directory requiring post-execution cleanup
- `component_metadata`: Extracted metadata gathered by the `build_context` node
- `findings`: Detector outputs from each analyzer node
- `risk_score`: Aggregated numeric risk rating computed by the `meta_analyzer`
- `sarif_report` / `report_body`: Final rendered artifacts from the `report` node

### Node Structure and Execution Flow

The graph executes six distinct node types defined in `src/skillspector/nodes/`:

1. **`resolve_input`**: Normalizes user input (directories, zip files, URLs, or git repos) into a temporary path
2. **`build_context`**: Walks the resolved path and gathers component metadata (executables, manifests) into the state
3. **Analyzer nodes**: Static YARA rules, AST checks, and LLM-driven semantic analyzers registered in [`src/skillspector/nodes/analyzers.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers.py)
4. **`meta_analyzer`**: Aggregates all findings, computes the risk score, and optionally enriches results with LLM-generated observations
5. **`report`**: Renders output in SARIF, JSON, Markdown, or terminal formats based on the `output_format` parameter

The wiring in `create_graph()` programmatically adds edges from `build_context` to each analyzer in `ANALYZER_NODE_IDS`, then from each analyzer to `meta_analyzer`. This design allows adding new analyzers by simply registering their node IDs.

## Running SkillSpector from the Command Line

The CLI entry point in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) provides the most common interface. The CLI parses arguments, invokes the compiled graph, and handles cleanup of temporary directories.

```bash
skillspector scan /path/to/skill \
    --output_format json \
    --use_llm

```

Supported formats include `json`, `markdown`, `terminal`, and `sarif`. The `--use_llm` flag enables LLM-based semantic analysis in the relevant analyzer nodes.

## Programmatic Usage with LangGraph

For integration into Python applications, SkillSpector exports the compiled graph as a module-level variable `graph` from [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py).

### Direct Graph Invocation

Import the graph and state definition, then invoke with a payload dictionary:

```python
from skillspector import graph
from skillspector.state import SkillspectorState

payload = {
    "input_path": "https://github.com/example/my_skill/archive/refs/heads/main.zip",
    "output_format": "markdown",
    "use_llm": True,
}

result = graph.invoke(payload)
print(result["report_body"])
print("Risk score:", result["risk_score"])

```

The `graph.invoke()` method returns a dictionary matching the `SkillspectorState` schema, containing the final report and risk assessment.

### Embedding as a Subgraph

You can embed SkillSpector as a node within larger LangGraph workflows by treating the compiled graph as a subgraph:

```python
from langgraph.graph import START, END, StateGraph
from skillspector import graph as skill_graph
from skillspector.state import SkillspectorState

def create_security_pipeline():
    workflow = StateGraph(SkillspectorState)
    workflow.add_node("skillscan", skill_graph)
    workflow.add_edge(START, "skillscan")
    workflow.add_edge("skillscan", END)
    return workflow.compile()

pipeline = create_security_pipeline()
result = pipeline.invoke({
    "input_path": "./my_skill",
    "output_format": "json"
})

```

This composition pattern allows you to integrate security scanning into multi-agent systems, CI/CD pipelines, or complex analysis workflows while maintaining LangGraph's state management guarantees.

## Summary

- SkillSpector implements a LangGraph StateGraph in [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) with a strictly typed `SkillspectorState` schema
- The workflow progresses through `resolve_input`, `build_context`, analyzers, `meta_analyzer`, and `report` nodes
- Register new analyzers by adding node IDs to `ANALYZER_NODE_IDS` in [`src/skillspector/nodes/analyzers.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers.py)
- Use `graph.invoke(payload)` for direct Python execution or embed the graph as a node in larger workflows using `workflow.add_node("skillscan", skill_graph)`
- Always cleanup `temp_dir_for_cleanup` after execution when calling programmatically (the CLI handles this automatically)

## Frequently Asked Questions

### How do I add a custom analyzer to the SkillSpector LangGraph?

Create a new node function that accepts the current state and returns updated state with findings, then register it in `ANALYZER_NODE_IDS` and `ANALYZER_NODES` within [`src/skillspector/nodes/analyzers.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers.py). The `create_graph()` function automatically wires edges from `build_context` to your new analyzer and from your analyzer to `meta_analyzer`.

### Can I run SkillSpector without the LLM components?

Yes. Omit the `use_llm` key or set it to `False` in your invocation payload. When disabled, the graph skips LLM-driven semantic analysis nodes while still executing static YARA and AST-based analyzers, reducing execution time and API costs.

### What output formats does the SkillSpector graph support?

The `report` node in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) supports four output formats: `sarif` (Static Analysis Results Interchange Format), `json`, `markdown`, and `terminal`. Specify your desired format in the `output_format` field of the input payload.

### How do I handle temporary directory cleanup when using SkillSpector programmatically?

The `SkillspectorState` includes a `temp_dir_for_cleanup` field containing the path to temporary directories created during `resolve_input`. When invoking `graph.invoke()` directly (not via CLI), you must delete this directory after execution. The CLI in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) performs this cleanup automatically.