はじめに
同僚から NVIDIA SkillSpector を紹介してもらい、興味を持ったことが本稿のきっかけです。これまで、スキルやプラグインを導入する前のチェックは、目視だけで行っていました。具体的には、SKILL.md に加えて、同梱のスクリプトや references も読んでいました。しかし、明文化した判断基準はなく、目立った違和感がなければ導入していました。
そこで、NVIDIA SkillSpector を Claude Code のプラグインとして実装し、社内マーケットプレイスに配置しました。本稿では、その取り組みを紹介します。
NVIDIA SkillSpector とは
NVIDIA が公開している、AI エージェント向けスキルのセキュリティスキャナです。
https://github.com/NVIDIA/SkillSpector
検出パターンの説明は、取り組み当時の v2.9.3(2026/08/12) の README から引用します。
68 vulnerability patterns across 17 categories: prompt injection, data exfiltration, privilege escalation, supply chain, excessive agency, output handling, system prompt leakage, memory poisoning, tool misuse, rogue agent, anti-refusal, trigger abuse, dangerous code (AST), taint tracking, YARA signatures, MCP least privilege, and MCP tool poisoning
検査対象は、スキルのプロンプトからコード、MCP まで多岐にわたります。
主な仕様は次の通りです。
- 入力: Git リポジトリ、URL、zip、ディレクトリ、単一ファイル
- 出力: ターミナル表示に加えて JSON / Markdown / SARIF
- 解析: 静的解析に加え、オプションで LLM による解析も実行できます
個別の指摘では、severity が深刻度、confidence が検出の確度を表します。スキル全体では、0〜100のリスクスコア(Score)、深刻度(Severity)、導入目安(Recommendation)が示されます。
| スコア | 深刻度 | 導入目安 |
|---|---|---|
| 0–20 | LOW | SAFE |
| 21–50 | MEDIUM | CAUTION |
| 51–80 | HIGH | DO NOT INSTALL |
| 81–100 | CRITICAL | DO NOT INSTALL |
cisco-ai-defense/skill-scanner との比較
同種のツールとして cisco-ai-defense/skill-scanner があります。
https://github.com/cisco-ai-defense/skill-scanner
プラグインを追加する PR の中で、両者を扱った記事を参考にしながら比較しました。
https://dev.classmethod.jp/articles/nvidia-skillspector-cisco-skill-scanner-agent-skills-vulnerability-scan
比較した上で、NVIDIA SkillSpector を選んだ理由は2つあります。
- 想定ユースケースに、cisco-ai-defense/skill-scanner の強みが活きない
- 標準出力で個別の指摘を確認できる
1. 想定ユースケースに、cisco-ai-defense/skill-scanner の強みが活きない
想定していた使い方は、各自のローカル環境で Claude Code を使う開発者が、Web 上のスキルを使う前に 1 つずつスキャンする形です。CI/CD でスキャンを実行する予定はありません。cisco-ai-defense/skill-scanner は SARIF 出力・GitHub Actions・pre-commit フックを備え、CI/CD 対応が手厚いツールです。push や PR ごとにスキャンする運用には適していますが、今回はその強みを活かせません。
2. 標準出力で個別の指摘を確認できる
cisco-ai-defense/skill-scanner の README に掲載されている実行例は、次のとおりです。
Status: [OK] No findings
Max Severity: NONE
Total Findings: 0
Scan Duration: 0.15s
cisco-ai-defense/skill-scanner の標準出力は件数の要約にとどまり、個別の指摘を確認するには出力形式を切り替える必要があります。
NVIDIA SkillSpector では、AS1 - Agent Config Directory Access のようなルール ID と名称、深刻度、確度、修正方法が標準出力に表示されます。そのため、出力形式を切り替えずに個別の指摘を確認できます。
なぜプラグインにしたのか
公式の導入手順は 2 通りです。1 つは Python 3.12 以上を用意し、仮想環境を作って uv か pip でインストールする方法です。もう 1 つは、Dockerfile を同梱した「Docker (No Python Required)」の手順です。ただし Docker の手順でも、利用者はイメージをビルドし、スキャン対象に応じたマウント設定と引数を指定して、毎回 docker run を実行します。個人で設定するだけなら許容できますが、社内メンバー全員に同じ作業を求める運用は非現実的です。
プラグインにすれば、利用者は社内マーケットプレイスから /plugin install の1コマンドで導入できます。初回実行時のイメージビルドと、対象形式に応じたマウント設定・引数の組み立ても自動化されます。利用者に必要な準備は、Docker Desktop を起動しておくことだけです。
プラグインの実装
ファイルは plugin.json、SKILL.md、scan.sh、README.md の 4 つで、合計しても 200 行に届きません。
主要な実装は、SKILL.md と scan.sh の2ファイルに集約されています。
SKILL.md: 起動条件と実行手順
description には、「GitHub の URL からスキルを追加しようとしている場面では常に使う」「目視レビューだけに頼らない」といった起動条件を記載しました。
本文では、scan.sh の呼び出し方や、対応する入力形式、実行時の注意点を説明しています。bash を明示している理由は、BASH_REMATCH を使用しているためです。macOS のデフォルトのシェルである zsh で実行すると、エラーを表示せずに正しく動作しません。
実際の SKILL.md は、次のとおりです。
---
name: skill-spector
description: AIエージェント向けスキル/プラグインをインストール・利用する前に、NVIDIA SkillSpector(68種類の既知の脆弱性パターン + YARA + AST解析)を使ってDocker上で体系的なセキュリティスキャンを実行する。目視でコードを読むだけで済ませず、必ずこのツールを使うこと — 新しいClaude Codeのスキル・プラグイン・MCPサーバーを、マーケットプレイス、GitHubのURL(`tree/<branch>/<path>`形式のサブディレクトリURLを含む)、zipファイル、ローカルパスのいずれかから追加・インストールしようとしている場面では常に使う。ユーザーがスキルのURL/パスを共有して「これは安全?」「インストールしていい?」と聞いてきたり、プロンプトインジェクション・データ持ち出し・悪意あるコードの有無を確認したい場合も、「scan」という単語を使っていなくても使う。目視レビューだけに頼らないこと — このツールは決定的でバージョン管理されたパターンマッチングを実行し、手動レビューでは見逃す問題を検出する。静的解析のみ(LLM呼び出し・APIキー不要)、ローカルでDocker Desktopが起動している必要がある。呼び出し方: "/skill-spector scan <target>"。
allowed-tools: Bash
---
# skill-spector
[SkillSpector](<https://github.com/NVIDIA/skillspector>) を使って、Docker上だけでスキルのセキュリティ脆弱性をスキャンする。
現在対応しているのは `scan` サブコマンドのみ(`baseline`/`mcp` は未対応) — それ以外のサブコマンドや `help`/`-h`/`--help` を指定した場合は、Dockerを実行せず使い方を表示するだけになる。
同梱のスクリプトを実行し、その出力をそのままユーザーに見せること。必ず `bash` を明示して呼び出す(`$SHELL` ではなく) — このスクリプトはbash専用の構文(`BASH_REMATCH`)を使っており、macOSの既定ログインシェルであるzshだと黙って壊れる:
```bash
bash "${CLAUDE_SKILL_DIR}/scan.sh" $ARGUMENTS
```
`$ARGUMENTS` は必ずリテラルのサブコマンド `scan` から始まり、続けて `<target>` を指定する:
- ローカルパス(ファイル/ディレクトリ) — 絶対パスに解決され、読み取り専用でコンテナにマウントされる
- gitリポジトリのURL
- GitHubのサブディレクトリURL(`.../tree/<branch>/<path>`) — 対象サブディレクトリだけがスキャンされる。publicリポジトリのみ対応、ブランチ名に`/`を含むものは未対応(`feature/foo`はブランチ`feature`・パス`foo`以降と誤解釈される)
- `.zip` ファイルのhttp(s) URL
補足:
- Dockerデーモンが起動している必要がある。起動していなければ、Docker Desktopを起動して再試行するよう伝えるエラーで終了する — 自動起動はしない。
- 初回実行時、pinされたupstreamコミット(現在 `v2.9.3`)からイメージをビルドする。default branchを追従するわけではないので、将来悪意あるコミットや挙動が変わるコミットを黙って取り込むことはない。ビルドには初回のみ~30秒程度かかる(pin先を更新した場合は次回また再ビルドされる)。新しいSkillSpectorのリリースを取り込みたい場合は、`scan.sh` 内の `UPSTREAM_REF`/`IMAGE` を意図的に更新すること。
- 常に `--no-llm` で実行される: 静的解析のみ(regex/AST/YARA)。ファイル内容が外部に送信されることはなく、APIキーも不要。
- 終了コード: `0` = SAFE/CAUTION、`1` = DO NOT INSTALL、`2` = エラー。SkillSpector の `0` と `1` はスキャンが正常に完了した結果であり、`1` はスキャン処理の失敗ではない。ただし、`scan.sh` はビルド失敗などの終了コードもそのまま返すため、出力内容を確認して判定結果とエラーを区別すること。
- `skillspector scan` の追加フラグ(例: `--format json`)はtargetの後に追加できる。`--output`はコンテナ内のパスに書き込むため使わないこと — スキャン対象は読み取り専用でマウントされ、コンテナも`--rm`で終了するので、書き込みに失敗するか、書けてもホストには残らない。ファイルに保存したい場合は標準出力をリダイレクトする(例: `bash scan.sh scan <target> --format json > report.json`)。
- `--baseline <file>`はホスト側の任意パスを指定できない。コンテナにマウントされるのはスキャン対象のディレクトリ/ファイルだけなので、baselineファイルもスキャン対象ディレクトリの中に置き、コンテナ内パス(ローカルディレクトリスキャンなら`/scan/<file>`)で指定する必要がある。tree URL/git URLのスキャンではそもそも指定できない。
scan.sh: Docker でのスキャン実行
プラグインには NVIDIA SkillSpector を同梱せず、初回実行時に v2.9.3 のコミット SHA を指定して Docker イメージをビルドします。scan.sh は、スキャン対象を外部の LLM に送信せず、API キーの配布や管理も不要にするため、静的解析に固定しています。
今回はスキルの導入前チェックに用途を限定し、未検証のサブコマンドによる想定外の動作を避けるため、scan のみ対応しました。
実際の scan.sh は、次のとおりです。
#!/usr/bin/env bash
# SkillSpectorのサブコマンドをDocker経由でディスパッチする。現在は`scan`のみ対応。
# Usage: scan.sh scan <path-to-skill|git-url|zip-url|github-subdir-url> [extra skillspector scan args...]
set -euo pipefail
print_help() {
cat >&2 <<'EOF'
skill-spector: `scan` サブコマンドのみ対応しています。
使い方:
scan.sh scan <target> [extra skillspector scan flags...]
<target> に指定できるもの:
- ローカルのファイル/ディレクトリパス
- gitリポジトリのURL
- GitHubのサブディレクトリURL (.../tree/<branch>/<path>)。publicリポジトリのみ、ブランチ名に / を含むものは未対応
- .zipファイルのhttp(s) URL
追加フラグは `skillspector scan` にそのまま渡される(例: --format json, --baseline <file>)。
常に --no-llm で実行される: 静的解析のみ、APIキー不要。
EOF
}
usage_error() {
if [ $# -gt 0 ]; then
echo "$1" >&2
echo >&2
fi
print_help
exit 2
}
if [ $# -lt 1 ]; then
usage_error
fi
SUBCOMMAND="$1"
shift
case "$SUBCOMMAND" in
help|-h|--help)
print_help
exit 0
;;
scan)
if [ $# -lt 1 ]; then
usage_error
fi
TARGET="$1"
shift
;;
*)
usage_error "未対応のサブコマンドです: $SUBCOMMAND"
;;
esac
if ! docker info >/dev/null 2>&1; then
echo "Error: Dockerデーモンが起動していません。Docker Desktopを起動してから再試行してください。" >&2
exit 2
fi
# defaultブランチを追従せず特定コミットにpinし、悪意あるコミットの混入を防ぐ。
# 新しいリリースを取り込む場合はここを更新する。
UPSTREAM_REF="1dbfef031e8d505b7e2e2f961c09696c2e4a86ff" # v2.9.3
IMAGE="skillspector:v2.9.3-${UPSTREAM_REF:0:12}"
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
echo "Dockerイメージ '$IMAGE' が見つかりません。https://github.com/NVIDIA/skillspector.git@$UPSTREAM_REF からビルドします..." >&2
docker build -t "$IMAGE" "https://github.com/NVIDIA/skillspector.git#$UPSTREAM_REF"
fi
SCAN_FLAGS=(--no-llm "$@")
# GitHubのtree URLはサブディレクトリを指しており、そのままではcloneできない。
# skillspectorにgitが同梱されているので、1つのコンテナ内でclone・sparse-checkout・
# スキャンまで完結させる。ホストのファイルシステムには触れない。
if [[ "$TARGET" =~ ^https://github\.com/([^/]+)/([^/]+)/tree/([^/]+)/(.+)$ ]]; then
OWNER="${BASH_REMATCH[1]}"
REPO="${BASH_REMATCH[2]}"
BRANCH="${BASH_REMATCH[3]}"
SUBPATH="${BASH_REMATCH[4]}"
if [[ "$SUBPATH" == /* || "$SUBPATH" == *".."* ]]; then
usage_error "不正なサブディレクトリパスです: $SUBPATH"
fi
echo "GitHubのサブディレクトリURLを検出しました。$OWNER/$REPO@$BRANCH をコンテナ内でcloneして '$SUBPATH' をスキャンします..." >&2
docker run --rm --entrypoint sh "$IMAGE" -c '
set -e
git clone --filter=blob:none --sparse --depth 1 --branch "$1" "$2" /clone >&2
git -C /clone sparse-checkout set -- "$3" >&2
SUBDIR="$3"
shift 3
exec skillspector scan "/clone/$SUBDIR" "$@"
' _ "$BRANCH" "https://github.com/$OWNER/$REPO.git" "$SUBPATH" "${SCAN_FLAGS[@]}"
exit
fi
# 遠隔ターゲットはマウント不要。
case "$TARGET" in
http://*|https://*|git@*|ssh://*|git://*)
docker run --rm "$IMAGE" scan "$TARGET" "${SCAN_FLAGS[@]}"
exit
;;
esac
# ローカルターゲット: 存在確認のうえ絶対パスに解決し、その場所だけをマウントする。
# --mountを使うのは、-vだと":"がフィールド区切りのため、パスに":"を含む場合に
# 解釈が壊れるため。
if [ -d "$TARGET" ]; then
ABS_PATH="$(cd "$TARGET" && pwd)"
docker run --rm --mount "type=bind,source=$ABS_PATH,target=/scan,readonly" "$IMAGE" scan /scan "${SCAN_FLAGS[@]}"
elif [ -f "$TARGET" ]; then
ABS_PATH="$(cd "$(dirname "$TARGET")" && pwd)/$(basename "$TARGET")"
SCAN_PATH="/scan/$(basename "$TARGET")"
docker run --rm --mount "type=bind,source=$ABS_PATH,target=$SCAN_PATH,readonly" "$IMAGE" scan "$SCAN_PATH" "${SCAN_FLAGS[@]}"
else
usage_error "対象が見つかりません: $TARGET"
fi
使い方
スキルは、コマンドを入力して直接呼び出すことができます。また、会話の内容に応じて Claude Code が使用する場合もあります。
コマンドで実行する場合は、/skill-spector scan <target> と入力します。<target> には、次のいずれかを指定します。
- ローカルパス
- Git リポジトリの URL
- GitHub のサブディレクトリ URL(
.../tree/<branch>/<path>) .zipの http(s) URL
コマンドを入力せず、Claude Code に自然言語でスキャンを依頼できます。description には、GitHub の URL からスキルを追加する場面や、URL を共有して安全性を確認する場面を起動条件として記載しています。
スキャンの実行例
NVIDIA SkillSpector で 2 つのスキルをスキャンしました。いずれも、スキャン対象には GitHub のサブディレクトリ URL を指定しています。
grill-me
grill-me は、計画や設計について質問を重ね、内容を練り上げるスキルです。
/skill-spector scan https://github.com/mattpocock/skills/tree/main/skills/productivity/grill-me
GitHubのサブディレクトリURLを検出しました。mattpocock/skills@main をコンテナ内でcloneして 'skills/productivity/grill-me' をスキャンします...
Cloning into '/clone'...
╭───────────────────────────────────────╮
│ SkillSpector Security Report │
╰───────────────────────────── v2.9.3 ──────╯
Skill: grill-me
Source: /clone/skills/productivity/grill-me
Scanned: 2026-08-19 03:45:07 UTC
Risk Assessment
Score 0/100
Severity LOW
Recommendation SAFE
Components (2)
┏━━━━━━━━━━┳━━━━━┳━━━━┳━━━━━━┓
┃ File ┃ Type ┃ Lines ┃ Executable ┃
┡━━━━━━━━━━╇━━━━━╇━━━━╇━━━━━━┩
│ SKILL.md │ markdown │ 7 │ No │
│ agents/openai.yaml │ yaml │ 5 │ No │
└──────────┴─────┴────┴──────┘
No security issues detected.
Inspection Completeness
Execution successful
Coverage 100.0%
Fully inspected 2
Partially inspected 0
Entirely uninspected 0
Analyzer statuses
- no_applicable_files : No files matched this analyzer's applicability
contract.
- completed :
- disabled_by_configuration : Analyzer was disabled by the requested
configuration.
(以下、completed が続く。全 24 アナライザのうち no_applicable_files 4、
disabled_by_configuration 3、残りは completed)
Limitations
- Analyzer was disabled by the requested configuration.
(同じ行が 3 件)
Executable scripts: No
SKILL.md と agents/openai.yaml のみで構成され、実行可能なスクリプトは含まれていません。指摘は 0 件で、導入目安は SAFE でした。シンプルなスキルなので、予想通りの結果です。
skill-creator
skill-creator は、スキルの新規作成や改善、評価を支援する Anthropic 公式スキルです。複数の Python スクリプトを同梱しているため、実行可能なコードを含む例としてスキャンしました。
/skill-spector scan https://github.com/anthropics/skills/tree/main/skills/skill-creator
GitHubのサブディレクトリURLを検出しました。anthropics/skills@main をコンテナ内でcloneして 'skills/skill-creator' をスキャンします...
Cloning into '/clone'...
╭───────────────────────────────────────╮
│ SkillSpector Security Report │
╰───────────────────────────── v2.9.3 ──────╯
Skill: skill-creator
Source: /clone/skills/skill-creator
Scanned: 2026-08-19 03:44:24 UTC
Risk Assessment
Score 76/100
Severity HIGH
Recommendation DO NOT INSTALL
Components (18)
┏━━━━━━━━━━━━━━━━┳━━━━━┳━━━━┳━━━━━━┓
┃ File ┃ Type ┃ Lines ┃ Executable ┃
┡━━━━━━━━━━━━━━━━╇━━━━━╇━━━━╇━━━━━━┩
│ LICENSE.txt │ text │ 202 │ No │
│ SKILL.md │ markdown │ 485 │ No │
│ agents/analyzer.md │ markdown │ 274 │ No │
│ agents/comparator.md │ markdown │ 202 │ No │
│ agents/grader.md │ markdown │ 223 │ No │
│ assets/eval_review.html │ other │ 146 │ No │
│ eval-viewer/generate_review.py │ python │ 471 │ Yes │
│ eval-viewer/viewer.html │ other │ 1325 │ No │
│ references/schemas.md │ markdown │ 430 │ No │
│ scripts/__init__.py │ python │ 0 │ Yes │
│ scripts/aggregate_benchmark.py │ python │ 401 │ Yes │
│ scripts/generate_report.py │ python │ 326 │ Yes │
│ scripts/improve_description.py │ python │ 247 │ Yes │
│ scripts/package_skill.py │ python │ 136 │ Yes │
│ scripts/quick_validate.py │ python │ 103 │ Yes │
│ ... and 3 more │ │ │ │
└────────────────┴─────┴────┴──────┘
Issues (9)
MEDIUM: AST4 - subprocess module call...
Location: eval-viewer/generate_review.py:291–294
Confidence: 70%
Remediation: Use subprocess.run() with shell=False and an explicit argument
list. Validate all inputs and avoid passing user-controlled data to commands....
MEDIUM: AST4 - subprocess module call...
Location: scripts/improve_description.py:35–42
Confidence: 70%
MEDIUM: AST4 - subprocess module call...
Location: scripts/run_eval.py:85–91
Confidence: 70%
MEDIUM: LP3 - Skill has no declared permissions but code capabilities were...
Location: SKILL.md:1
Confidence: 70%
Remediation: Add a 'permissions' field to SKILL.md listing the capabilities
this skill requires....
HIGH: AS1 - Agent Config Directory Access...
Location: scripts/run_eval.py:23
Confidence: 85%
Remediation: Remove all code or instructions that access agent configuration
directories (.claude/, .codex/, .gemini/). If configuration values are needed,
pass th...
HIGH: E2 - Env Variable Harvesting...
Location: scripts/improve_description.py:33
Confidence: 70%
Remediation: Read only explicitly required environment variables by name.
Avoid enumerating or copying the full environment, and never log or transmit
credentials ...
HIGH: E2 - Env Variable Harvesting...
Location: scripts/run_eval.py:83
Confidence: 70%
LOW: EA3 - Scope Creep...
Location: LICENSE.txt:56
Confidence: 70%
Remediation: Limit the skill's scope to its documented purpose. Remove
instructions that enable the agent to perform actions outside its stated
functionality....
LOW: EA3 - Scope Creep...
Location: LICENSE.txt:161
Confidence: 70%
Inspection Completeness
Execution successful
Coverage 100.0%
Fully inspected 18
Partially inspected 0
Entirely uninspected 0
Analyzer statuses
(全 23 アナライザのうち disabled_by_configuration 4、残りは completed)
Limitations
- Analyzer was disabled by the requested configuration.
(同じ行が 4 件)
Executable scripts: Yes
注: Analyzer statuses と Limitations は同じ行の繰り返しなので、件数に要約して掲載しています。また、Issues の Remediation は、同じ ID の 2 件目以降を省略しています。
結果は、スコア 76、深刻度 HIGH、導入目安 DO NOT INSTALL でした。
Anthropic 公式のスキルでも、DO NOT INSTALL と表示されてしまいました。よく使われているスキルでもインストールできないという結果には違和感が残ります。
そこで、導入目安のみでなく、より詳細に実行結果を確認する必要があります。
導入目安だけでなく、個別の指摘も確認する
DO NOT INSTALL は、静的解析で危険になりうるパターンが検出された場合に示される導入目安です。コードの意図や実際の挙動まで評価したものではないため、この表示だけでスキルの導入可否を判断できません。
静的解析では、正当な機能も危険になりうる処理として検出されるため、実行可能なコードを含むスキルはスコアが高くなる傾向にあります。実際、Anthropic のスキルを同じ条件でスキャンしたところ、webapp-testing は 68 点、pptx と docx は 75 点、skill-creator は 76 点でした。skill-creator の 76 点は、ほかの 3 つと比べても大きな差はありません。
9 件の指摘を深刻度別に整理すると、次のようになります。
- HIGH 3 件:AS1 の 1 件は設定ディレクトリへのアクセス、E2 の 2 件は環境変数の読み取りを検出しています。E2 では、外部への送信は検出されていません。
- MEDIUM 4 件:AST4 の 3 件は
subprocessの呼び出しを検出しています。LP3 の 1 件は、スキルが必要とする権限を示すpermissionsが宣言されていないという指摘です。 - LOW 2 件:いずれも、Apache License 2.0 の条文を「スキルの目的を超えた指示」と判定した EA3 の誤検出です。
プロンプトインジェクションに関する指摘や、YARA のルールによる不審なパターンの検出はありませんでした。
まず、HIGH の AS1 1 件と E2 2 件を優先して確認します。指摘された 2 ファイルの 3 か所を読み、設定ディレクトリへのアクセスや環境変数の読み取りが、スキルの用途に必要かを確認します。
NVIDIA SkillSpector の導入目安を最終判断とせず、目視で確認する箇所を絞るための一次フィルタとして利用します。
おわりに
これまで、スキル導入前のチェックは 個々人の属人性に依存した、SKILL.md や同梱ファイルの目視に頼っていました。そこで、NVIDIA SkillSpector を Claude Code のプラグインとして実装した結果、検出結果を根拠に導入可否を判断する、導入コストを低減することができました。
最後まで読んでいただき、ありがとうございました!
参考文献
- NVIDIA/SkillSpector
- cisco-ai-defense/skill-scanner
- NVIDIA SkillSpector と Cisco Skill Scanner で Agent Skills の脆弱性をスキャンする
- mattpocock/skills: grill-me
- anthropics/skills: skill-creator
- anthropics/skills: webapp-testing
- anthropics/skills: pptx
- anthropics/skills: docx
- Static Analysis Results Interchange Format (SARIF) Version 2.1.0