BAS Guard (bas-guard)
English | 中文
Local, offline security scan + junk cleanup for AI agent environments. Gives Claude Code users an "antivirus for agents": — one command, nothing leaves the machine.
Power your agent
คำสั่งของผู้เผยแพร่เอง ไม่ใช่เอนด์พอยต์ของ PlugMCP
Host a copy with our keys and logs.
npx -y @bas.io/[email protected]Claude Code ไม่มีลิงก์ติดตั้งสำหรับคำสั่งแบบโลคัล ให้คัดลอกคำสั่งด้านล่างแล้วรันในเทอร์มินัล
claude mcp add bas.io-guard -- npx -y @bas.io/guard@0.33.1รันในเทอร์มินัล
{ "mcpServers": { "bas.io-guard": { "command": "npx", "args": [ "-y", "@bas.io/[email protected]" ] } }}claude_desktop_config.json
URL แบบรีโมตหรือคำสั่งบนเครื่องของคุณ? การติดตั้งสองแบบต่างกันอย่างไร
รันบน PlugMCP
A new server you create. It is not this listing's official endpoint. Use the publisher install when you want their URL and their credentials.
เปิดจากผู้เผยแพร่
bas-guard)English | 中文
Local, offline security scan + junk cleanup for AI agent environments. Gives Claude Code users an "antivirus for agents": — one command, nothing leaves the machine.
Local, offline security scan for AI agent setups: audit the skills, MCP servers, hooks and permission grants an agent auto-loads, and vet one before installing it.
scan and check are strictly read-only. clean is the only command that writes, and it only ever MOVES things inside your config root — it never deletes.
AI coding agents auto-load a lot of external things — skills, MCP servers, hooks, subagents, instruction files (CLAUDE.md) — each handed your real tools and permissions, and any of them can hide a malicious directive. BAS Guard statically scans those artifacts on your machine and produces a risk report + cleanup suggestions.
Positioning: a body-check + alerting + cleanup tool, not "guaranteed removal." The score is a relative risk signal, not a safety certification. See "Capability boundary" below.
clean) moves and never deletes.CGO_ENABLED=0 — curl it down and run.clean only ever MOVES things into a trash directory inside your config root, records every step, and --undo replays it. Deleting stays your call.docs/install-gate.md./bas-guard-setup, /bas-guard-scan, /bas-guard-vet, /bas-guard-gate, /bas-guard-help, /bas-guard-llm) so you can ask for an audit in plain language and get the findings triaged, not just printed.<REDACTED> before the report is built — raw credentials never reach the output.From npm (macOS / Linux, no platform to pick). The binary ships inside the package, so there is no install script and nothing is fetched at install time:
npx --yes @bas.io/guard@latest check ./some-skill # vet one thing before installing it
npx --yes @bas.io/guard@latest scan --report # audit this machine's whole setup
npm i -g @bas.io/guard # or install it: `bas-guard` on your PATH
check is the one to start with: it judges the artifact you point at, so its answer does not
depend on which machine is running it. scan is a statement about the machine it runs on.
Do not install the load-time gate from an
npxrun.bas-guard hook installregisters the absolute path of the binary it ran from, and npx's path is a cache npm later reclaims — after which every skill loads unaudited while the setup still looks protected (GATE-001). The command warns you when it notices. Usenpm i -g, or a release binary, for the gate.
Prebuilt binary (macOS / Linux, no toolchain needed). Pick your platform from
darwin-arm64 · darwin-amd64 · linux-amd64 · linux-arm64:
REPO=basdotio/bas-guard
PLAT=darwin-arm64 # <- yours
curl -fsSLO "https://github.com/$REPO/releases/latest/download/bas-guard-$PLAT"
curl -fsSLO "https://github.com/$REPO/releases/latest/download/SHA256SUMS.txt"
# Verify before running it — this tool has no business asking for trust it won't demonstrate.
shasum -a 256 --ignore-missing -c SHA256SUMS.txt # Linux: sha256sum
chmod +x "bas-guard-$PLAT" && sudo mv "bas-guard-$PLAT" /usr/local/bin/bas-guard
There is deliberately no
curl … | shinstaller. This tool reportscurlpiped to a shell asEXEC-001, high severity, in anybody else's repository. Publishing one here would be asking you to do the exact thing it will warn you about, on the machine it is meant to protect. Download, verify, then run — three lines instead of one, and the only install path a security scanner can honestly recommend.
From source (Go 1.23+):
git clone https://github.com/basdotio/bas-guard && cd bas-guard
make build # produces bin/aguard
# or directly:
CGO_ENABLED=0 go build -o bin/aguard ./cmd/bas-guard
Every release ships the four static binaries plus SHA256SUMS.txt, all built by
.github/workflows/release.yml from a version tag — the same
make dist a maintainer runs locally.
Windows is build-from-source only, on purpose. It cross-compiles fine; nothing has ever
run the test suite on it, there is no GOOS branch in the code, and the symlink boundary the
scanner relies on behaves differently there. A published binary no test has executed, for a
tool whose verdicts people act on, is worse than a missing platform.
The fastest way to get started. A bundled plugin ships three skills and six slash commands, so
you can ask in plain language ("is my ~/.claude safe?", "check this skill before I install
it") instead of memorising flags:
In the terminal Claude Code, as slash commands:
/plugin marketplace add basdotio/bas-guard
/plugin install basguard@bas-guard
In the VS Code / JetBrains extension, /plugin is not available — run the same two
steps from a shell with the claude CLI instead:
claude plugin marketplace add basdotio/bas-guard
claude plugin install basguard@bas-guard
Third-party marketplaces do not auto-update by default in the terminal. Turn it on once so skill
and command updates arrive on their own — /plugin → Marketplaces → bas-guard → Enable
auto-update (the desktop app's "Sync automatically" toggle is the same thing). The binary is
separate and never updates itself; bas-guard version says when it has fallen behind the plugin.
Installed the plugin before v0.30.0? It was aguard@AgentGuard (v0.17.0 to v0.29.x) or
agentguard@AgentGuard (before v0.17.0). The marketplace lists neither, so Claude Code stops
loading either once the marketplace refreshes ("Plugin aguard not found in marketplace
AgentGuard"). aguard went with the rename to BAS Guard; agentguard collided with the
marketplace name AgentGuard in Claude Code's install cache on a case-insensitive filesystem —
macOS by default — where installing it fails with EINVAL
(issues/022). Switch once; bas-guard version
prints the exact command for your install, which from the AgentGuard marketplace is:
claude plugin uninstall aguard@AgentGuard # agentguard@AgentGuard before v0.17.0
claude plugin marketplace remove AgentGuard
claude plugin marketplace add basdotio/bas-guard
claude plugin install basguard@bas-guard
The repository is public and the plugin ships from main, so the plain form above is the one to
use — no #… suffix, no repo access, no git credentials.
Then restart Claude Code (the extension: reload the window) and run /bas-guard-setup. It
brings up the bas-guard binary if it is missing, runs the first scan, triages the findings
with you, and offers the load-time gate. The curl download needs no token: the releases it
reads are public. Building from source (make build, Go 1.23+) stays available. See
docs/rules.md for what a finding means once a scan runs.
The three skills (bas-guard-audit, bas-guard-vet, bas-guard-gate) also fire on their
own when a request matches, and they carry the part a --help cannot: how to read the two
scores, which findings are shapes rather than verdicts, why a dimension-0 note is not a risk,
and what a clean report still does not prove.
The plugin is the plugin/ subtree — skills and commands only, deliberately
excluding this repo's own docs. Those docs quote every attack pattern the engine detects, so
shipping them would make bas-guard scan report its own plugin as high-risk in every user's
environment. The subtree scans 100/100 at --fail-on low, and a change that breaks that is
a bug in the change.
Needs the bas-guard binary on PATH (the skills install it for you). The plugin adds no MCP
server and registers no hooks of its own — bas-guard hook install stays an explicit,
--dry-run-previewed step.
bas-guard scan # full scan of the current user's ~/.claude
bas-guard scan --root ~/.claude # specify the root
bas-guard scan --verbose # also print every coverage note in full, where the scan looked, the inventory
bas-guard scan --html report.html # also write a self-contained HTML report
bas-guard scan --md report.md # also write the report as markdown, for a PR comment or an issue ("-" = stdout)
bas-guard scan --json # machine-readable output
bas-guard scan --fail-on high # CI/gate: exit 1 when a finding is ≥ high
bas-guard clean # cleanup: list junk + reclaimable tokens (read-only)
bas-guard clean --zombie # also look for never-used skills (weak signal, opt-in)
bas-guard clean --zombie --apply # MOVE them to <root>/.aguard-trash (never deletes)
bas-guard clean --undo last # put a batch back, re-deriving every safety check
bas-guard clean --ask # answer duplicate pairs one at a time (↑/↓ or 1/2)
bas-guard check ./some-skill # pre-install gate: statically scan one skill/dir/file (defaults to --fail-on high)
bas-guard hook install # load-time gate: audit each skill before an agent loads it
bas-guard approve ./some-skill # trust those exact bytes, so the gate stops asking
bas-guard approvals # list what has been trusted
bas-guard version
The terminal report shows every finding by default and folds the coverage notes into one
line that still carries their count, their highest severity and their rule IDs. --verbose
prints those notes in full — reach for it when the question is what the scan did not read.
The default view is ordered for a reader who does not write code: each finding comes with a next step
(which file and line to read, and for a skill the load-time gate can stop, the exact bas-guard approve
command), the judge's view of it in plain words, and one line says why the score is what it is; a
result with nothing to look at prints its title and its score. --verbose adds where the scan looked,
the inventory, the judge's versions and the hygiene list.
That includes a note attached to one item, such as a settings.json that does not parse: the
summary then names the item as not fully checked, and does the same for a file that could not be
read. When something Claude Code loads was not fully read — a file that could not be read or parsed,
an item carrying its own coverage note, a skill folder the scan could not open, a file over the size
cap, a hook script it could not follow, a project's .claude under the root (the root is one level too
high: point --root at the .claude) — the summary says coverage is incomplete instead of calling
the setup safe. Notes about things the scan skips by design (your own session history at the top of
the config directory, a plugin's node_modules/) are listed but do not change that sentence. When
the inventory has nothing to count — bas-guard check on a single file or a plain folder — the summary
says what it checked ("Checked 1 file.") rather than that nothing was found. Coverage notes never change the score, and change the exit code in two cases only, both 4 (below): with --fail-on, a root that held nothing to check or held a project's .claude it did not read; with --fail-on-llm, a judge that could not answer for every artifact. Findings are never folded in either mode, and --json / --html / --md always carry everything, so
what a CI job sees never depends on which flag a human passed.
Exit codes: 0 below threshold · 1 a finding at/above --fail-on · 2 runtime error
(and, for clean only, 3 = acted partially, with every refusal named; 4 = a gate could not be evaluated, with the
reason on stderr: with --fail-on, the root held nothing to check, or held a project's .claude it did not read; with
--fail-on-llm, the judge did not run, a call failed or was never made, or (on check) it has no question for the
target: a plain folder, or a plugin holding no skill, command or agent. 4 is not a pass, and a finding at either
threshold still exits 1). A run stopped by a
signal ends as 128 + signal — 130 for Ctrl-C, 141 for a closed output pipe — through the
npm launcher exactly as for the bare binary.
scan does not exit non-zero on findings by default (informational mode); check defaults to --fail-on high (gate mode).
Got a finding and want to know what it means? docs/rules.md lists every
rule ID the tool can print — dimension, severity, and why it fires. It is generated from the
engine's own rule set and CI fails if it drifts, so the severity you read there is the severity
that will gate your build. Its header names the rules version, the same value a report carries
as rules_version (--json) and bas-guard version prints: when two reports differ and their rules
versions differ too, the rules changed between them.
clean)clean is the only command that writes, and the boundary is narrow enough to state in full:
<root>/.aguard-trash/, with the
move recorded before it happens. --undo puts it back, re-deriving every safety decision from
the filesystem rather than trusting the record. rm -rf is yours to run when you are satisfied.skills/. settings.json, settings.local.json, .claude.json, .mcp.json and
anything under hooks/ are never moved and never restored over — checked after resolving
symlinks, because a decision made on a path as written is a decision a symlink can lie to.clean --apply
would be the shortest path to turning a red --fail-on high green.--resolve <id> --keep <name>, --keep-both, or walk them with --ask. A
reversible action on a guess is still a guess.--zombie ("installed but never used") is opt-in and never rated high confidence: it can only see
this machine's history, and it says how many sessions that was.
Full guide, including the safety boundary and what it deliberately does not do:
docs/clean-guide.zh-CN.md. Implementation and the invariant/test table:
docs/internals/clean-internals.md.
bas-guard hook)check answers when you remember to ask. The gate answers at the moment a skill is about to
be loaded, whether or not anyone remembered:
bas-guard hook install # merges into ~/.claude/settings.json (backs it up), then restart Claude Code
Claude Code has no hook for INSTALLATION, and one would not be complete anyway — a skill also
arrives by git clone, by cp, and by hand. Loading is the boundary that can be held, and it
is the one that matters: a skill on disk is inert until an agent reads it into context.
Approvals are keyed by the artifact's canonical hash, so editing an approved skill re-opens
the question by itself. Full contract, including what it deliberately does not cover:
docs/install-gate.md.
skills (SKILL.md + scripts + resources) · MCP config (statically: injection text and interpreter-preload env such as NODE_OPTIONS; an unpinned package or a credential written into env is reported only by the optional LLM judge, LLM-009) · hooks (settings.json — can silently run shell, a focus area) · permission allowlists · subagents · slash commands · installed plugins · CLAUDE.md · Claude Desktop's own store (plugins added in Customize → Plugins and the skills in Customize → Skills live under ~/Library/Application Support/Claude/, not ~/.claude, and are handed to the CLI as --plugin-dir; they are collected and marked "via Claude Desktop"). The default root honours $CLAUDE_CONFIG_DIR. Downloads are checked too: agent-shaped items under ~/Downloads (a skill folder, a plugin, an MCP config, an instructions file, or a .zip holding one) are each checked on their own and listed in a separate Downloads section — they are not installed, so they never enter the score; everything else in the folder is counted, never read, never named. --inbox <dir> points elsewhere, --inbox off disables. bas-guard check foo.zip checks a downloaded archive directly. Install-symlink skills (e.g. ~/.agents/skills/*) are resolved to their real target and audited; a symlink escaping to a system path is skipped with a warning.
Two surfaces get extra treatment, because both hand over execution while looking narrow:
PreToolUse[Bash]#1 that carries it. A hook that just points at a script
(sh "$CLAUDE_PROJECT_DIR/.claude/hooks/pre.sh") has that script read and scanned too —
otherwise a filename hides the payload. Referenced scripts are only read inside your home
directory; anything outside is not read (COV-000) and scores as HOOK-002 — a coverage
gap and an unaudited silent-execution point are different facts. PermissionRequest raises
that to high, because the hook takes the authorization decision. An HTTP hook (type: http)
is a first-class artifact: posting events to loopback is HOOK-003 low, posting
PermissionRequest to loopback or posting anything off-box is high. A hook command that
chains shell (; && || | backticks $() is HOOK-001 — unremarkable in a script,
telling in a hook, so that rule runs on hook commands only.PERM-006):
Bash(git *) is arbitrary execution (git -c core.pager=…) wearing a narrow-looking
disguise, and so are open-ended grants over find awk tar docker ssh npm make
xargs rsync and friends. Fully specified grants (Bash(git status)) stay clean. A grant
naming one of your scripts (Bash(./scripts/deploy.sh *)) has that script read and scanned
too — the grant is only as narrow as what the script does. Same containment as hooks: inside
your home directory only, anything else is a coverage note.Static rules can't catch "the description says A but the code does B," nor prompt injection
phrased to dodge keyword rules. With --llm an isolated model runs a set of passes chosen by
artifact kind:
CLAUDE.md, subagents, slash commands and hooks, alwaysIt is source-agnostic — every artifact is judged on its content, official or not. A flagged verdict must quote what triggered it, and the quote is checked against the text that was actually sent; anything unquotable is discarded and counted, so a confident hallucination can't reach your report.
The judge is treated as adversarial: the scanned content is untrusted and reaches the
prompt, so a nonce barrier fences it as inert data and the model is told to ignore (and
report) any instruction inside it. Per the iron law, the LLM can only push risk up — it can
never remove or downgrade a static finding, move overall, or trip --fail-on. Triage
annotates; it never deletes.
Setting it up takes one command and no YAML — a hosted, OpenAI-compatible model you have an
account with (deepseek, openai, qwen, or any endpoint with --base-url/--model):
bas-guard llm setup --provider deepseek # prompts for the key with hidden input; --key-stdin for pipes
bas-guard llm test # one call: does the endpoint answer for that model?
bas-guard scan --llm # the config is found at ~/.config/bas-guard/config.yaml from now on
The key goes to ~/.config/bas-guard/llm.key (mode 0600, refused if anyone else can read it); an
api_key_env variable still works and takes precedence, for CI. A setup made before the rename to BAS Guard
lives in ~/.config/aguard/ and is still read there when it is the only one; nothing is moved. Inside Claude Code, /bas-guard-llm
walks through the same three steps in conversation.
To see what would leave the machine before you decide, bas-guard llm preview ./some-skill prints every
call check --llm would make for it, with the exact text each would carry (with no path: every call
scan --llm would make). It sends nothing and needs no key; see the judge's privacy notes.
Hard constraints: off by default (needs both config and --llm), sends only redacted excerpts (raw secrets never leave the box), and the verdict is
advisory — Source=llm findings never move overall and never trip --fail-on, so
scoring stays reproducible.
A judge run does report a second number, overall_effective, next to the real one: the same
formula with its findings folded in. It is always lower or equal, not reproducible, and
gates nothing — it exists so you can see what the judge saw without that opinion leaking into
the number CI depends on. Since the environment score is averaged and bucket-capped, the
report also names the individual artifacts the judge moved, which is where the signal actually
shows.
# config.yaml
llm:
enabled: true
provider: openai_compatible
base_url: http://localhost:11434/v1 # default: a local model (e.g. Ollama)
api_key_env: AGUARD_LLM_KEY # key read from this env var only, never disk (BAS_GUARD_LLM_KEY wins when set)
model: llama3.1
bas-guard scan --llm --config config.yaml
A judge outage never fails silently: unreachable/unconfigured runs surface an LLM-000
coverage note, so "judge off" can't masquerade as "no intent issues."
Full reference: docs/llm-judge.md (models, endpoints, privacy, rule
IDs) · copy-ready config.example.yaml.
This release is a static scanner; its ceiling is "surface discovery + cleanup." It cannot:
Coverage caveats worth knowing:
--llm judges them; the score counts a plugin and its children
as one item, and a finding both carry is printed once), its hooks per (event, command), its MCP servers per server.
Its output styles and inline manifest commands are read only as text in the tree; check <plugin> does not split
its hooks and MCP servers the way scan does.HOOK-002.sessions/,
history.jsonl, file-history/), and pulling them into a report would trade a blind spot for
a leak. They are named in a COV-000 rather than skipped in silence. Loose files that look
like code or instructions are read, and so is anything under skills/, agents/ or
commands/ even with its manifest missing — those are the paths an agent actually loads from.dist/, build/, out/, node_modules/, vendor/,
coverage/) are not read, and are excluded from the canonical hash so an artifact's identity
survives a rebuild. The scan says so once, as a COV-000 note. And because the skip is decided
by a name the artifact's author chose, an artifact that points the agent INTO one — a
SKILL.md saying "run dist/setup.sh" — is reported as SUP-004 and scores.Dimension 7/8 hits (backdoor / resource abuse) are always labeled "advisory: not confirmed."
So is EXFIL-002, the cross-file credentials→network pair: unrelated files legitimately do
each half, so it is a pair worth reading, not a verdict.
The exfiltration check is structural rather than a pattern: one file that reads credentials AND
makes an outbound call is EXFIL-001; one that also encodes in between is EXFIL-003 plus
an OBF-004 in the obfuscation dimension, because what leaves the box is then unreadable to
whoever is watching the wire. If every network target in that file is loopback (127.0.0.1,
localhost, ::1), the chain stays visible but drops to the same low + advisory band as
EXFIL-002 — the data has not left the machine. Outbound means more than an HTTP client — a
DNS lookup, nc, /dev/tcp, scp and ssh carry data just as well. None of it is proof:
encoding a payload has honest uses, so the finding says "this is the shape the attack has",
never "this is the attack".
.aguardignore)Once you've reviewed the findings for an environment, silence the acceptable ones so repeat
scans stay signal-only. scan and clean read <root>/.aguardignore (or --ignore <file>):
# one rule per line — blank lines and # comments ignored
INJ-001 # suppress this rule everywhere
EXEC-004 vendor/* # suppress this rule only under matching evidence paths
* dist/* # suppress ANY rule under a path glob
Suppressed findings are dropped before scoring, and the count is reported as an
IGN-000 note — a baseline can't silently hide a genuinely new risk.
check does not auto-discover a baseline. Its target is the thing you are vetting, so a
.aguardignore found inside it was written by whoever wrote the artifact, not by you — a
skill shipping one that names its own rule IDs would otherwise score itself 100/100. For
check, only an explicit --ignore <file> applies.
BAS Guard ships a small, versioned, offline reputation list keyed by an artifact's canonical hash — no network, on by default:
rm -rf/curl|bash examples don't drown the report. A REP-GOOD
note records the count + highest suppressed severity (never silent).REP-BAD finding is raised even if static rules found nothing.What is actually in it today: the allowlist half. The blocklist is mechanically wired
(hash-exact, REP-BAD is critical, it gates) and empty — curating known-bad hashes is
ongoing work, and the file ships no example entry standing in for one, because this list feeds
the score and a demonstration record would be a false record. bas-guard version prints the real
entry count. Treat the value of reputation today as noise suppression on trusted toolkits, not
as malware coverage; detection comes from the static rules.
Because the list is embedded and versioned, it is deterministic and feeds the score.
Disable with --no-reputation. A maintainer adds an entry by computing its hash:
bas-guard hash ./some-skill # prints the canonical hash to add to the reputation list
A cloud reputation service (fresh allowlist + community blocklist, hash-only, opt-in) is planned — see the design doc; the embedded list is its always-available offline subset.
Claude Desktop's built-in skills (docx, xlsx, pptx, skill-creator, import-memory, …) are the one
allowlisted source that is not a repository: several are published nowhere a commit could be pinned.
Their entries pin the desktop's own per-skill updatedAt stamp instead (source: claude-desktop),
carry the same review and fingerprint, and renew only on a machine that has the desktop store.
check returns a non-zero exit code when a finding meets --fail-on, so it drops into any gate:
# git pre-commit hook (scans staged skills)
cp hack/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
# CI (GitHub Actions)
cp hack/github-action.yml .github/workflows/bas-guard.yml
See hack/ for both. A single skill: bas-guard check ./some-skill (defaults to --fail-on high).
The workflow's first line picks --root: the repository itself (.) when it keeps skills/ at its top level or has
no .claude, otherwise the project's .claude, which holds its skills, settings.json and agents (the project's
.mcp.json and CLAUDE.md next to it are read from there too). Replace it with a fixed root if you prefer. Pointed one
level too high — at a project's top level — a --fail-on gate exits 4 and says to scan the .claude it did not read,
rather than passing over skills nobody read; so does a root with nothing to check at all.
bas-guard scan --html report.html writes a self-contained (offline, no-script) HTML report:
score gauge, environment tiles, findings grouped by artifact+rule with line-level evidence,
and the junk/hygiene section. bas-guard scan --report writes the same report without a path to
invent — to ~/.config/bas-guard/reports/scan-<timestamp>.html (or under $XDG_CONFIG_HOME),
outside the scan root, and prints where. The plugin does this on every scan and opens the
report at the end of /bas-guard-setup. Reports stay on the machine; they hold your own paths
and redacted snippets.
--md <path> writes the same report as GitHub-flavoured markdown, for the place a scan result
usually needs to go next: a pull request comment or an issue. - writes it to stdout instead of
the terminal report, so a reviewer can post the result of vetting a new skill without retyping it:
bas-guard check ./new-skill --md - | gh pr comment 42 --body-file -
bas-guard check ./new-skill --md review.md # or write a file and paste it
Every name, path and snippet from the scanned tree is emitted inside a code span, so a file
named @someone or <img src=…> cannot ping a person or load an image from your comment; the
findings table, the plain-language verdict, the advisory labels and the "not checked" notes are
all there, in the same order as the terminal. Paste the result of check or scan --root .;
a whole-machine scan also lists what it saw under ~/Downloads, so pass --inbox off before
posting one publicly.
make test # go test -race -cover ./...
make lint # golangci-lint
make dist # cross-compile release binaries + SHA256SUMS.txt into dist/
New to the codebase? docs/architecture.md is the as-built map: the
pipeline and why its stage order is load-bearing, the package layout, the invariants and where
each is enforced, and an honest account of what is not implemented yet.
See CONTRIBUTING.md: one branch per change, a pull request against main,
and make verify green before you ask for review. make hooks installs the pre-commit gate that
scans any skill you stage with bas-guard itself.
Local, offline security scan for AI agent setups: audit the skills, MCP servers, hooks and permission grants an agent auto-loads, and vet one before installing it.
{ "mcpServers": { "bas.io-guard": { "command": "npx", "args": [ "-y", "@bas.io/[email protected]" ] } }}เครื่องมือ
ยังไม่มีรายการเครื่องมือ เซิร์ฟเวอร์แบบรีโมตจะได้รายการหลังการตรวจสอบสถานะครั้งแรก
FAQ
คัดลอกคอนฟิก stdio สำหรับ Cursor, Claude Desktop, Claude Code หรือ VS Code ได้ในหน้านี้ คอนฟิกนี้ใช้การติดตั้งของผู้เผยแพร่ ไม่ใช่พร็อกซีของ PlugMCP
ระเบียนนี้ไม่ได้ระบุตัวแปรสภาพแวดล้อมที่จำเป็น
@bas.io/guard ทำงานแบบโลคัลผ่าน stdio
ตรวจสอบล่าสุดเมื่อ 2026-11-13 Local, offline security scan for AI agent setups: audit the skills, MCP servers, hooks and permission grants an agent auto-loads, and vet one before installing it.