
PandaWard
io.github.ratomirjovanovic由 GitHub 账号 ratomirjovanovic 发布v0.2.13更新于 Nov 5, 2026
Local, evidence-based application security assessment with an evidence ledger and retests.
概览
在本地对自己代码做基于证据的安全评估,让助手执行被动扫描、维护证据账本、分诊并复测。
- 可以做什么
- 对代码仓库执行只读的被动安全扫描,并给出哪些已检查、哪些未判定的诚实摘要
- 查看带脱敏哈希证据、指纹和生命周期状态的发现项,并记录分诊决定
- 对自动化无法判定的控制项提出带文件与行号引用的佐证建议,交由人工接受或拒绝
- 生成有序修复计划,改动后复测并显示差异,导出 HTML、Markdown、JSON、SARIF 或 CSV 报告
- 查看发现的入口点、控制项目录与跨域关联,并检查评估状态与覆盖度
- 适用场景
- 适合希望让助手评估自己拥有的代码库安全状况、跨会话保留发现记录,并在修复后复测而不是只看一次性告警列表的场景。
- 运行要求
- 以本地进程在用户机器上运行,仅支持桌面端。插件会安装预编译二进制,也可通过包管理器或发布版二进制使用独立 CLI。无需账号或云端后端。可选外部扫描器(gitleaks、semgrep、osv-scanner、trivy、apktool、ZAP、MobSF)仅在已安装时使用;部分需在配置中开启网络访问,MobSF 需要 MOBSF_API_KEY。
安装
在 SourceWeft 中
- 打开 控制台中的 PandaWard,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
PandaWard
Local, evidence-based application security assessment for your own code.
A standalone Go CLI and a Claude Code plugin. Passive by default. Honest about what it did not test.
[CI] [OpenSSF Scorecard] [License: AGPL-3.0] [Go 1.26+] [Status: alpha]
Website and demo · Documentation · Quick start · Limitations
Most scanners print a list of alerts and stop. PandaWard keeps a ledger: every control it could check, how it checked it, the redacted evidence, and every control it could not decide. Findings are fingerprinted across runs, so a fix becomes REMEDIATED only when the check runs again and no longer sees the problem, and a moved or renamed file keeps its findings, their IDs and your triage instead of reading as fixed.
[Terminal session on the bundled demo project: pandaward init detects the stack, pandaward scan reports which adapters ran and which are BLOCKED, 38% decisive coverage and 33 open findings, then findings, the cross-domain graph and an ordered fix plan]
A real session on the bundled demo project, generated by tools/termdemo.
[PandaWard findings explorer for the bundled acme-shop fixture: 20 confirmed findings, 11 suspected, 38% decisive coverage, with a critical pull_request_target finding and hardcoded secrets at the top]
Findings from a real scan of the bundled vulnerable fixture. Open the live demo for the terminal replay and the full report.
Why PandaWard
Formerly PenSec. The project was renamed to PandaWard in 0.2.0. If you used PenSec, see Moving from PenSec.
Quick start
As a Claude Code plugin
You can also run the same steps from a terminal with claude plugin marketplace add ratomirjovanovic/pandaward and claude plugin install pandaward-windows@pandaward (pandaward@pandaward on macOS and Linux). Restart Claude Code afterwards; /mcp should list plugin:pandaward:pandaward as connected. Install only one of the two plugins. If something goes wrong, see Troubleshooting.
Updating. Claude Code does not update third-party marketplaces on its own unless you turn it on. Either turn on auto-update once (/plugin, then Marketplaces, pandaward, Enable auto-update), or update by hand:
Then restart Claude Code. /plugin shows the installed version.
Uninstalling. claude plugin uninstall pandaward-windows@pandaward (or pandaward@pandaward), then claude plugin marketplace remove pandaward. Results stay in each project's .pandaward/ directory until you delete it. The uninstall guide covers the CLI packages and every file PandaWard creates.
Then, in your project, ask Claude to check its security, or run:
That is the only command. Claude scans the project, has specialist reviewers look at what automation could not decide, triages the results, builds the fix plan and writes the reports, with a live checklist. At the end it asks one question - fix the plan, record the triage results, install missing scanners - and does what you choose, retesting after every fix. Later in the session it retests on its own whenever code changes. Commands that change a finding's status still show you a confirmation prompt, and network tests always need a scope you approve in your own terminal.
Individual skills
The plugin installs prebuilt, checksum-verified binaries from the
pluginandplugin-windowsbranches, which the release workflow publishes on every version tag (how to verify them). To use PandaWard without Claude Code, see below.
As a CLI
With a package manager:
Or download a binary from the releases page (Linux and macOS on amd64 and arm64, Windows on amd64). For example on Linux:
On Windows (PowerShell), save pandaward-windows-amd64.exe as pandaward.exe in a folder on your PATH:
Or install with Go 1.26 or later: go install github.com/ratomirjovanovic/pandaward/cmd/pandaward@latest. The binary has no runtime dependencies.
Update with brew upgrade pandaward or scoop update pandaward; for a downloaded binary, replace the file with the new release. Remove with brew uninstall pandaward or scoop uninstall pandaward, or delete the binary. pandaward version shows what you have.
Then, in your project:
Release binaries are reproducible and come with checksums, a CycloneDX SBOM and signed build provenance; docs/VERIFYING.md shows how to check them.
How it works
- Inventory walks the repository read-only and records files, routes, manifests, workflows, IaC, mobile manifests and AI/MCP usage.
- Plan maps the control catalog (domains A to R) onto what was found. Controls without matching assets become
NOT_APPLICABLEwith a reason you can review. - Adapters run. Built-in checks are offline and always available; gitleaks, semgrep, osv-scanner, trivy and apktool are used only if you installed them. osv-scanner and trivy also need
scan.allow_tool_network: true, which is off by default: osv-scanner then sends the package names and versions from your lockfiles to api.osv.dev, and trivy only downloads its vulnerability database. Until it is set they are BLOCKED with a reason that says this, and/pandaward:startoffers the switch once. When an override in the workspace root (pnpm.overrides,overridesorresolutionsin package.json, oroverridesin pnpm-workspace.yaml) replaces a package with a local one (link:,file:,workspace:orportal:), an osv-scanner result for that package is dropped if the lockfile entry is that local package, since the registry package's advisories do not apply to code that is not installed; the adapter line counts them and names the overrides. A result is kept, and named in the adapter line, when the lockfile still pins a registry version or the override is annpm:alias. A gitleaks match whose value is shaped like a placeholder (a run of 8 or more sequential or repeated characters, a word such as dummy, example or changeme, a value starting withtest_, a JWT with a short signature or dummy claims, or the fallback aftersecrets.NAME ||in a workflow) is kept but listed as info for review instead of counting against E-005; the value is judged in memory and never stored, aservice_roleJWT is never treated as a placeholder, and the adapter line says how many were listed. apktool decodes.apkfiles found in the project (resources only, never the app's code) so the manifest checks also run on what you ship (K-005). If you run MobSF yourself on this machine, setscan.mobsf_url(for examplehttp://127.0.0.1:8000) and export its REST API key asMOBSF_API_KEY; PandaWard uploads the.apkand.ipafiles it finds to that server, runs the static scan and reports MobSF's high and warning items as hypotheses under K-006 (APK) and L-005 (IPA). Code findings that MobSF reports only in bundled library code, outside the app's own package namespace, are listed for review instead. Only loopback addresses are accepted, proxies and redirects are ignored, and the key never appears in evidence, logs or reports. The adapter is tested against MobSF 4.5.3. When semgrep is installed it runs PandaWard's bundled offline rules (seerules/README.md) plus any rules you configure. SARIF 2.1.0 files from analyzers you ran yourself (CodeQL or other SAST tools) are imported from.pandaward/sarif/*.sarifand any paths listed inscan.sarif_files; PandaWard never runs those tools. Imported results are hypotheses under control R-002, with snippets read and redacted from your files rather than taken from the SARIF. The directories ininventory.exclude(build output such as.next/anddist/,node_modules/and the like) apply to every adapter: results a scanner reports there are dropped, and the adapter line in the summary says how many. - Findings are redacted, fingerprinted and linked to evidence. Repeated runs update their lifecycle:
OPEN,REMEDIATED,REOPENED,FALSE_POSITIVE,RISK_ACCEPTED. Identical hits in one file are told apart by position, so fixing one of them remediates that one; a finding whose file was moved or renamed keeps its ID and status and is reported as moved, never as fixed. - Edges between domains are created only from shared assets and get their status from the linked controls.
- Reports show confirmed findings, suspected signals, coverage by domain, every undecided control and the evidence index. Decisive coverage (PASS or FAIL over applicable controls) is split by how each control was decided: automatic (static and external adapters in the passive scan), runtime (an approved runtime profile: production-observe, staging-active or local-runtime) and attested (a manual control a person accepted after review, see Attested manual controls). Not applicable controls are counted separately and stay outside the denominator. Every undecided control gets one next step, built from its method, status and stored reason, such as "install osv-scanner (see
pandaward doctor), then runpandaward retest", and a Path to 100% section groups the undecided controls by that step. Some steps say a control cannot be decided in this release (runtime checks without an adapter); those keep coverage below 100% on purpose. Manual controls are on the path through attestation.
In Claude Code, hooks keep the ledger current without any command. Edited files are marked stale as they change, and when Claude finishes a turn that edited files, PandaWard runs a changed-only passive retest (bounded at 40 seconds) and hands any new or reopened findings back to Claude, which explains them and offers a fix. A clean retest stays silent; one that runs out of time or fails says so instead of claiming anything is fixed. Set hooks.auto_retest: false in .pandaward/config.yaml to turn it off.
While the specialist reviewers run, you can see what each one is doing. Their rows in the subagent panel below the prompt show the elapsed time, files read, searches, recorded hypotheses and the file or pattern they are on, refreshed by Claude Code. In the chat, Claude passes on a line when a reviewer starts, records a hypothesis or finishes, gives a short summary about once a minute in between, and warns when a reviewer has gone quiet for 10 minutes. The chat lines need Claude Code's Monitor tool, which on Windows needs Git Bash. Hooks record this to .pandaward/private/progress.jsonl for subagents named pandaward:* only. They record file names and search patterns, never file contents, and pandaward progress shows the same view in a terminal.
Attested manual controls
Five controls cannot be decided by automation: A-004 (threat model), C-003 (authorization of every route), F-001 (business invariants), O-001 (security event alerting) and Q-001 (rate limiting). They are BLOCKED until a person attests them:
- A reviewer, usually a
/pandaward:reviewagent, proposes PASS or FAIL withpandaward_propose_attestation, citing file and line evidence and optionally a test or command that shows it. PandaWard checks every cited file is inside the project and every line exists, reads and hashes the files itself and redacts the text. The proposal is pending and decides nothing. A proposal can also come from a file:pandaward attest C-003 --propose --file proposal.json. - You decide:
pandaward attest C-003 --showlists the evidence, thenpandaward attest C-003 --accept --by "Jane" --note "walked every route"or--reject. When an agent runs this for you, the PandaWard hook shows the proposal and asks you to confirm; no MCP tool can accept. An accept is refused when a cited file changed since the proposal. - From the next scan the control is PASS or FAIL with
decided_by: attested, and reports list the reviewer, the date and every citation. A FAIL attestation creates no finding by itself; the concrete gaps are the hypotheses the reviewer recorded, which you confirm withpandaward findings apply. - The attestation becomes STALE, with the reason, when a cited file changes (the file is named), when the control catalog version changes, or after
attest.max_age_days(180 by default; it can be lowered, never raised beyond 365). It stays STALE until a fresh proposal is accepted.
What it checks
pandaward capabilities prints the full catalog with each adapter's maturity. All adapters are currently implemented_unvalidated. The optional tool adapters are exercised in CI on every pull request against gitleaks 8.30.1, semgrep 1.182.0, osv-scanner 2.7.0 and trivy 0.76.1: the job scans the bundled vulnerable fixture and fails when an adapter does not complete or its parser misses the expected findings. Other versions may work but are not checked.
pandaward benchmark runs every built-in rule against a versioned corpus of vulnerable and safe cases and prints TP, FP, FN, TN, precision and recall per rule. CI fails when a rule misses a vulnerable case or fires on a safe one, and each release attaches benchmark.json. A rule counts as implemented_and_benchmarked only with precision and recall of at least 0.95 on at least 3 vulnerable and 3 safe cases. Today every rule has one of each, so none qualifies yet. The corpus is PandaWard's own, so the numbers describe these cases, not real-world accuracy. On the public OWASP Benchmark for Java the built-in rules score 0.00: they match single lines and do not follow data flow, so they find none of its test cases (and raise no false alarms). Use Semgrep or another data flow aware analyzer through PandaWard for Java injection findings; docs/BENCHMARKS.md has the numbers and how to reproduce them.
Commands
Scans show how far they got. The first line is the plan: files, adapters and the expected time. Every line after it has the step, a percentage and the time left, such as [7/8 27%] semgrep: running; about 4 min left, and an adapter that runs long reports every 20 seconds. The percentage is weighted by how long each adapter is expected to take: on the first scan of a project it is estimated from the size of the code each adapter reads, and later scans use the durations recorded in the ledger. --quiet and --json turn the lines off; the MCP scan and retest tools send them as progress notifications.
Human decisions are explicit and recorded:
remediated is for a fix that no scanner can confirm, mostly findings from the specialist reviewers: a finding a rule reported becomes REMEDIATED by itself when the rule runs again and no longer sees it. If the rule still sees it, or a reviewer records the same issue again, the finding becomes REOPENED.
false-positive dismisses a signal for the control it belongs to, but only through the next scan: triage never changes a control status. On the next full scan (pandaward retest or pandaward scan), a signal whose finding a person marked FALSE_POSITIVE and whose fingerprint is unchanged (same rule, same file, same code on the flagged line) no longer counts, and the control is decided from the signals that remain. If none remain, the control is PASS with a reason such as check completed; 3 signal(s) dismissed as false positive by Jane; PASS applies to this check only, which the reports show in the control ledger. The finding itself stays listed as FALSE_POSITIVE. If the flagged code changes, the signal has a new fingerprint and counts again. RISK_ACCEPTED findings still count, because accepted risk is real. Signals that carry no code snippet (file-level checks such as a missing lockfile or a workflow without a permissions block, and dependency advisories) keep their fingerprint when the code changes, so they are never dismissed this way and still count. After a triage that leaves a control with only dismissed signals, the CLI names that control and the command that re-decides it. pandaward retest --changed keeps the decisions of adapters whose inputs did not change, so run a full pandaward retest to apply a dismissal.
decisions.json is an array of {"finding_id", "action", "note", "expires"} with action one of confirm, false-positive, accept-risk (needs expires), remediated or reopen. Every entry is checked before anything is written, so one bad entry rejects the batch. In Claude Code this is how the guided assessment records triage results: you see the whole list in one confirmation prompt instead of one prompt per finding.
Network tests
Network tests are off until you turn them on yourself:
pandaward test --help prints what each profile covers, the controls it decides, what it needs and whether it may run against your own machine. The names are kept as they are because scope manifests and scripts use them; note that the permission checks live in staging-active, which also accepts a local target, while local-runtime is for mobile apps only:
pandaward scope init reads the project and drafts the manifest. It never overwrites an existing scope.yaml, and --print writes the draft to stdout instead. The draft has:
- targets: local dev URLs from package scripts (
next dev -p 3001,vite,astro devand others, with their default ports) and loopback URLs in.env.examplefiles. A non-local URL only gets in when you pass--target, so a draft never points at production. With only local targets the draft setsenvironment: localandallow_private_addresses: true. - identities: commented, one per role found in code (role enums and union types, zod enums, Postgres and Prisma enums, role checks such as
role === 'admin'), plus one in another tenant and one revoked. Tables with RLS policies are noted. - authorization_checks: commented, one per readable route from the route inventory, with dynamic segments as
<placeholders>and dynamic routes first.
The authorization block stays empty and acknowledged: false, so the draft cannot run until a person reviews it and approves it.
The engine sends at most max_requests_total GET requests to the listed origins at the configured rate, never follows redirects, and checks every resolved address at connection time. Loopback, private and link-local addresses are refused unless the manifest explicitly allows a local fixture, and cloud metadata addresses are always refused. pandaward scope approve shows the exact line to type, APPROVE followed by the first 8 characters of the manifest's SHA-256 (for example APPROVE ab26dcf2), so the approval is tied to that file; anything else cancels and the error says what was expected and what was typed. Editing scope.yaml invalidates the approval. Approvals are also bound to a per-user key kept outside the project (approval.key in your user config directory), so a scope file or ledger that arrives with a repository never counts as approved.
staging-active runs your installed ZAP (it needs Java 17+; PandaWard never installs it, and when it is missing the BLOCKED reason gives the install command for your OS: winget install --id ZAP.ZAP -e, brew install --cask zap or sudo snap install zaproxy --classic) through its automation framework: a spider and the passive scan decide M-001, and with zap.active_scan: true in the manifest the active scan also decides D-005 (injection). ZAP is chained to a PandaWard proxy on loopback that terminates TLS and sends each request through the same scope guard, so origins, excluded paths, allowed methods, the request budget, the rate limit and the address checks apply to every ZAP request. The guard also stops after three consecutive 429 or 5xx answers. A ZAP run that fails is ERROR, a run cut short by the budget or the guard is INCONCLUSIVE, and targets marked environment: production are refused. Set runtime.zap_path in .pandaward/config.yaml when ZAP is not on PATH or in its default install location.
staging-active also runs the manifest's authorization_checks before ZAP. You list test identities (name, tenant, the header that carries the credential and the environment variable that holds it; the credential itself never goes in the file) and read-only requests to objects or functions that exist for the test, each with the identities allowed to reach it:
Each check is sent once as every identity and once without credentials. The allowed identities must get a 2xx answer, otherwise the check cannot be judged and is INCONCLUSIVE. Any other identity that also gets a 2xx is a finding: CONFIRMED when its body matches what the allowed identities got, STRONGLY_SUPPORTED when it differs. Object checks decide C-001 (BOLA), function checks C-002, and identities marked revoked decide B-004 on every check. Only GET and HEAD are allowed, so no data changes and nothing needs cleaning up. Evidence keeps the status, size, content type and a body hash per identity, never headers, bodies or credentials. A missing credential variable stops the run before the first request.
Instead of exporting each credential yourself, the manifest can name project commands that create the test identities before the run and remove them after it:
Each command is an argument list, run without a shell from the project root, and only for an approved manifest. provision prints {"credentials": {"PANDAWARD_ID_ALICE": "Bearer ...", ...}} on stdout. The keys must be value_env names of the manifest's identities, and anything else stops the run. A key it leaves out is read from the environment as before. cleanup gets the same JSON on stdin and runs after the test, also when the test failed. The values stay in memory: they are never written to the ledger, evidence, reports or progress output, and a failing command's stderr is not repeated. The approval binds the commands and the content of every project file they name, so editing scripts/pandaward-identities.mjs after the approval invalidates it. pandaward scope approve lists the commands and the bound files before you type the approval line.
Emulator and simulator checks
pandaward test --profile local-runtime looks at what a test build actually stored. It sends no network traffic, so it needs no scope manifest:
On Android it uses adb with an emulator-* serial that also reports ro.kernel.qemu=1, and reads the app's shared_prefs through run-as, which only works for debuggable builds. On iOS it uses xcrun simctl get_app_container booted and only accepts a container inside CoreSimulator, then reads the app's preferences plist. A non-empty value under a credential-like key (token, password, session and similar) is a finding for K-003 or L-002; PandaWard records the key name and never the value. Real devices are refused, and a missing emulator, simulator, tool or setting makes the control BLOCKED with the reason. Transport security and Keychain accessibility are not tested at runtime.
How long a runtime result lasts
A passive scan or retest cannot observe what a runtime profile tested, so it carries the last runtime verdict (PASS, FAIL or SUSPECTED) of each control over, marked decided_by: runtime and with a reason that names the profile and time of the run. Its findings stay open. The verdict holds only while everything it ran under is unchanged:
- for
staging-activeandproduction-observe, the exactscope.yamland the approval it ran under, which must still be valid (not expired, not revoked); - the PandaWard config and control catalog;
- every source file in the project, every file linked to the control's domain and every file behind the asset the control needs (route files,
AndroidManifest.xml,Info.plist, built packages), compared by SHA-256 with the run.
When any of these changes, the control becomes STALE with a reason that says which (for example the scope approval apr_... it ran under expired or 1 file(s) it depends on changed since the runtime run (src/server.js)), in pandaward status and the reports at once and in every later scan. It counts as decided again only after the profile runs again. A run that ends BLOCKED, ERROR or INCONCLUSIVE replaces the earlier verdict too, so an old PASS never outlives a newer run that could not decide.
In CI
The action downloads a release binary, checks it against SHA256SUMS, scans, writes SARIF, HTML, Markdown and JSON reports to pandaward-report/, and adds a short job summary with counts only (summary: full lists findings; job summaries of public repositories are public). With new-only, the base commit is scanned in a separate worktree and only findings whose fingerprints are new count. Inputs and outputs are documented in action.yml.
Before each commit
With pre-commit, add this to .pre-commit-config.yaml and run pandaward init once in the project:
The hook runs pandaward scan --quiet --fail-on high and blocks the commit when open high or critical findings exist. It scans the working tree, not only the staged files.
What PandaWard will not tell you
- That your application is secure. No tool can prove the absence of vulnerabilities.
- Anything about controls it reports as
BLOCKED,UNSUPPORTED,SUSPECTED,INCONCLUSIVE,ERRORorSTALE. - Results from runtime tests that are not implemented yet: login, reset and MFA flows (B-003), API contract versus runtime (G-002) and prompt-injection tests against an LLM endpoint (P-003) are reported as
UNSUPPORTEDtoday.
A PandaWard report is an automated technical assessment. It is not a certification, an attestation, a legal opinion or an independently signed penetration test.
Roadmap
See the issues for details.
Moving from PenSec
PandaWard 0.2.0 is PenSec renamed. Your results carry over:
- The first
pandawardcommand in a project moves.pensec/to.pandaward/with its ledger, evidence, reports, config and scope manifest. Commit the renamed files if you had committed.pensec/config.yamlorscope.yaml. - Approvals stay valid: the approval key is taken over from the old
pensecfolder in your user config directory. PENSEC_*environment variables are still read when thePANDAWARD_*ones are not set.- Existing finding IDs such as
PSEC-0007keep working; new findings getPW-IDs.
Switch the tools once:
CLI: brew uninstall pensec && brew untap ratomirjovanovic/pensec, then install pandaward as above (scoop uninstall pensec; scoop bucket rm pensec on Windows). In CI, point uses: at ratomirjovanovic/pandaward; GitHub redirects the old name for now, but pin the new one.
Wrong or missed findings
Tell us, and the rule gets fixed. PandaWard is open source and its rules improve from these reports. The first /pandaward:start in a project asks once whether you want to send them; with batch, PandaWard collects them after triage and sends them in one step after you confirm. It groups the false positives you closed by rule and finds missed issues itself: problems a reviewer found and you confirmed that no rule caught. A report holds rule metadata, counts and file types only. With the GitHub CLI signed in, pandaward feedback submit files the reports (or adds to an open report about the same rule); without it, you get prefilled issue links. By hand: pandaward feedback false-positive <PW-ID>, pandaward feedback false-negative --rule <id> or /pandaward:feedback. Reports are prioritized automatically and every fix adds a benchmark case. See docs/FEEDBACK.md.
Contributing and security
Contributions are welcome. Start with CONTRIBUTING.md. Please report vulnerabilities in PandaWard itself privately as described in SECURITY.md.
License
PandaWard is free and open source software under the GNU Affero General Public License v3.0 (AGPL-3.0-only).
You may use, study, modify and share it, including inside companies. If you distribute PandaWard or a modified version, or let others use a modified version over a network (for example as a hosted scanning service), you must publish the complete corresponding source code under the same license. Commercial licensing for uses that cannot meet these terms is available from the copyright holder.
Third-party scanners that PandaWard can call keep their own licenses. The license does not apply to the projects you assess or to the reports PandaWard produces about them.
来源:README.md,提交 3d00a11
工具
0版本历史
6- v0.2.13最新Nov 5, 2026
- v0.2.12Nov 5, 2026
- v0.2.11Nov 4, 2026
- v0.2.9Oct 31, 2026
- v0.2.8Oct 30, 2026
- v0.2.7Oct 29, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分