
Gulliver
io.github.laaielichter由 GitHub 帳號 laaielichter 發布v0.3.0更新於 Nov 3, 2026
agent SQL 的預演:成本預檢、自動修復、1% 取樣執行、預算門控執行。
AI 翻譯由 AI 模型根據下方的原文描述翻譯,可能有誤。
原文描述
Dress rehearsal for agent SQL: cost preflight, auto-fix, 1% sample runs, budget-gated execution.
概覽
Gulliver 的本機 MCP 服務;無需登入;STDIO。
暫無 AI 概覽:以下資訊來自註冊中心條目和服務本身。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Gulliver,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Gulliver
Test on tiny data before you run on giant data.
An open-source MCP server and CLI that gives AI agents a dress rehearsal for SQL: estimate the cost, fix the slow parts, rehearse on 1% → 3% → 10% of the data, predict what 100% will do, and only run the full query inside a budget.
[CI] [PyPI version] [npm version] [Python 3.10 to 3.13] [MIT license] [Good first issues]
Website · Quick start · Install · Auto-fix · Guards · CI · Compare · FAQ · Roadmap
Works with Claude Code, Codex, Cursor, Gemini CLI, Claude Desktop, VS Code, Windsurf and any MCP client, on DuckDB, Postgres, BigQuery and Snowflake.
New in 0.3.0: a read-only gate that also blocks side-effect functions, SQL hidden in strings and file access, with DuckDB sandboxed in the engine. A result guard for personal data and prompt injection in rows. A runaway guard for loops and per-agent budgets. Lint for CI (SARIF, pre-commit),
gulliver fix --verify,gulliver top, andgulliver reviewwith a GitHub Action. One breaking change: DuckDB can no longer read files outside the database folder and the current folder unless you allow them (details). See the changelog.
A real recording of the CLI on the demo database (script: docs/demo.sh).
In Gulliver's Travels, Gulliver visits Lilliput, a land of tiny people, and Brobdingnag, a land of giants. Gulliver does the same with your data: it tries your query in Lilliput first, and only walks into Brobdingnag when it knows what will happen there.
Why
Agents write SQL that works on a small table and breaks on a big one. They do not know that events has
5 billion rows, that a join multiplies rows, or that a forgotten partition filter scans every day since 2019.
Benchmarks score agents on is the answer right, never on what did it cost or does it still work at 100x.
One unlucky query can burn a monthly budget.
Gulliver sits between the agent and the warehouse:
Every answer has a status and a next_step, so even small models know what to do next.
Gulliver does not only say no. gulliver_fix rewrites the SQL for the agent and labels every change.
same (exactly the same rows) is only claimed when Gulliver has checked the column types on the connection;
everything else (assumes, nulls, changes) needs mode=all and says what may differ. With a connection it
estimates the old and the new query side by side, so nobody has to trust the saving blindly. With --verify it
also tests every rewrite on generated edge-case data and shows a counterexample when the rows differ.
Agents also fail in ways that have nothing to do with size. Gulliver guards those too (details in Guards for agents):
And for the pipeline around the query (details in Pipeline tools and In CI and on pull requests):
Quick start (2 minutes, no warehouse needed)
The last one is the classic agent mistake: a self-join on a non-unique key. The rehearsal predicts the full result (about 255 million rows from a 5-million-row table) and warns that the query multiplies rows, before you run it.
The real full run returns 254,966,150 rows.
Add --json to any command for machine-readable output. Exit codes: 0 ok, 1 error, 2 blocked,
3 needs rehearsal or approval, 4 a data check failed, so it also works as a CI check.
Install the MCP server
Gulliver is an MCP server (stdio or Streamable HTTP), published on PyPI and npm. Run it with uv, or through npx (which uses uv under the hood):
Point it at a database with --dsn, or at a gulliver.toml with connections and budgets
(--config). No warehouse yet? Run gulliver demo and use gulliver_demo.duckdb.
Claude Code
Or install it as a plugin, which adds the MCP server and a skill with the rehearsal workflow:
Claude Desktop, Cursor and Windsurf
Add this to the client's MCP config (claude_desktop_config.json, ~/.cursor/mcp.json or
~/.codeium/windsurf/mcp_config.json):
VS Code
In .vscode/mcp.json:
Codex CLI
In ~/.codex/config.toml:
Gemini CLI
In ~/.gemini/settings.json, the same mcpServers block as for Claude Desktop above.
Any HTTP client or remote agent
gulliver-mcp --http --port 8765 serves http://127.0.0.1:8765/mcp (Streamable HTTP).
Without MCP: OpenAI and Gemini function calling
Every tool is also a CLI command with --json, and gulliver tools --format openai or --format gemini prints
ready-made function-calling definitions for the OpenAI or Gemini APIs.
More of MCP than tools
All 16 tool schemas take about 25.6 KB of the agent's context. gulliver-mcp --toolset core loads only the
8 query tools (about 10.9 KB); --toolset pipeline loads the pipeline tools; a comma list mixes sets and tool
names. The server also offers resources (gulliver://rules, gulliver://status, table metadata, receipts),
prompts (safe-query-loop, refactor-and-prove, make-incremental), progress during a rehearsal, and a typed
outputSchema on every tool.
A human can let approvals happen in the MCP client instead of the terminal: with
[approval] channel = "elicitation" in gulliver.toml, gulliver_run shows the human a form (the statement,
cost and SQL) before it answers needs_approval. It is off by default, and the agent cannot fill the form.
Turn it on only for clients that show these forms to a person. Details:
docs/features/mcp-native.md.
How it compares
Based on each project's public docs and READMEs in November 2026 (sources below). Gulliver's own numbers were measured in this repository. Open an issue if something here is wrong or out of date.
MCP servers that let agents query databases
SQL in CI and on pull requests
Where others are ahead today: Postgres MCP Pro does index tuning and health checks; a real read-only database user (as Supabase uses) is a stronger guarantee than any parser; SQLFluff checks style and many more dialects; Recce and Datafold diff two real builds and Datafold follows lineage into BI tools; DBHub's tool schema is much smaller. Gulliver has no Databricks or ClickHouse engine yet, and BigQuery and Snowflake have only been tested against fakes.
What Gulliver does not do: run your pipelines, replace dbt, or give you a hosted service.
Sources
cost-guard-mcp · Postgres MCP Pro · MCP Toolbox · BigQuery MCP · DBHub and its schema-size review · Supabase MCP and defense in depth · Altimate Code · SQLFluff releases · Squawk · dbt-costgate · Recce · Datafold
Engines
Install the drivers you need: pip install "gulliver-mcp[bigquery]", [snowflake], [postgres] or [all].
Every estimate says how much to trust it: exact, upper_bound or heuristic. A heuristic is never called exact.
Configuration
Copy gulliver.example.toml to gulliver.toml:
The example file also shows the settings for the read-only gate (allowed_paths, allow_remote,
allow_functions), the result guard (policy), the runaway guard, [lint], [review] and [approval].
A read-only Postgres role
Gulliver refuses writes itself, but a role that can only read is a good second layer. Run this once as an admin
and put gulliver_ro in the DSN:
Or skip the file: GULLIVER_DSN, GULLIVER_MAX_QUERY_USD, GULLIVER_DAY_USD and friends.
Credentials never go in the config: Gulliver uses each engine's own environment variables and credential chains
(Google ADC, SNOWFLAKE_PASSWORD, PGPASSWORD, ...). The agent only ever sees connection names.
Safety model
- Read-first. Only
SELECT(andWITH ... SELECT) runs by default.DELETE,UPDATE,DROP,TRUNCATE,ALTER,MERGE, several statements at once and unparsable SQL are refused by a parser, not a regex. - A SELECT is not automatically safe. Functions with side effects (
pg_terminate_backend,set_config,nextval), SQL hidden in a string (dblink_exec, DuckDBquery(), BigQueryEXTERNAL_QUERY) and file or URL access (pg_read_file,read_csv('~/.aws/credentials')) are refused with codes GS001-GS004, anywhere in the statement. - DuckDB is sandboxed in the engine. Every DuckDB connection runs with
allowed_directoriesset to the database folder and the current folder (orallowed_paths), external access off, extension auto-loading off and the configuration locked, so the agent cannotSETit back. For Postgres, BigQuery and Snowflake the parser is Gulliver's only check, so also use a read-only role.gulliver selftest securityruns the bypass test set that ships with Gulliver (151 cases) and checks the sandbox live. - Writes need two keys.
CREATE TABLE ... AS SELECTandINSERT ... SELECTrun only when the call saysallow_writeand a human setallow_write = trueon that connection. Rehearsals never write. - Budgets fail closed. Over the per-query, per-day, per-session, per-agent, bytes or runtime limit means
block. Money above the approval limit needsgulliver approve <receipt_id>, a CLI command for humans that is not exposed as an MCP tool (or, when the human turned it on, a form in the MCP client that the agent cannot fill). - Rows are data, not instructions. Run results are marked
untrusted: true, secrets are masked, personal data is flagged, and text that reads like instructions to an AI is listed indata_warnings. - Engine-side caps where they exist: BigQuery
maximum_bytes_billed, Snowflake and Postgres statement timeouts, a DuckDB interrupt timer. - Local state only. Receipts, the spend ledger and approvals live in
./.gulliver/as JSON, hash-chained sogulliver audit verifycan detect edits. No telemetry.
The threat model is in SECURITY.md; the full list of what the gate refuses is in docs/features/security.md.
Breaking change in 0.3.0. DuckDB connections can no longer read files outside the database folder and the current folder, read remote URLs, or auto-load extensions. If you read Parquet or CSV files elsewhere, add the folder to
allowed_paths(or the bucket toallow_remote) on the connection ingulliver.toml. When the database folder or the current folder is/, your home folder or above it, it is left out of the default; setallowed_pathsthen.sandbox = falseturns the engine sandbox off (the parser still checks). Queries that call the refused functions getblock;allow_functionslifts that per connection.
How the prediction works
Each rung measures runtime, output rows and (where the engine reports it) bytes. Gulliver fits
metric = a * fraction^k in log-log space and reads off the value at 100%.
k ≈ 1: grows with the data (scans, filters, key joins against a full table).k ≈ 0: flat (aggregations). Group counts saturate, so grouped results are capped by what was observed and the planner estimate.k > 1.3: grows faster than the data: a big sort, or (with--sample all) a join between two sampled sides that multiplies rows. Flagged. In the default mode a multiplying join keepsk ≈ 1and is flagged by size instead: output much larger than the biggest input table.
Runtime first subtracts the fixed per-query overhead (measured with SELECT 1). Confidence is high, medium
or low, with a range of x0.7-1.5, x0.5-2 or x0.25-4. After a real run, the receipt shows predicted vs actual.
By default only the largest table is sampled and the others stay complete, which keeps key joins honest.
When the query reads that table more than once (a self-join, an IN (SELECT ...) on the same table, a CTE used
twice), only the first occurrence is sampled and the others are read in full on every rung. Two samples of one
table drawn with the same seed would hold the same rows, so every row would meet itself and small rungs would come
out too big. With one side sampled the output grows linearly and the prediction stays unbiased; the price is a full
read of the other side per rung. A result much larger than the biggest input table is flagged as a join that
multiplies rows. On the 5M-row demo self-join, five seeds predicted 252M-257M rows against 254,966,150 real ones.
--sample all samples every table and every occurrence, each with its own seed. That is cheaper, but a join
between two sampled sides grows with fraction² and the noise of both samples multiplies, so those predictions get
low confidence. When a table is read more than once, --method auto uses row (bernoulli) sampling. When the
smallest rung reads fewer than 2,000 rows, the range is widened one level. For BigQuery the money prediction uses
the exact dry-run bytes of the full query.
Limits, honestly: block (system) sampling is cheap but can be skewed on clustered data; use --method bernoulli
when that matters. On DuckDB a system sample takes whole 2,048-row vectors and is not repeatable even with a seed,
so --method auto always uses bernoulli on DuckDB (a local scan costs nothing); on BigQuery and Snowflake it keeps
the cheap system sample for tables of a million rows or more. Extrapolating 10x always has uncertainty; Gulliver shows it instead of hiding it. Databricks,
ClickHouse and Spark are not supported yet.
Pipeline tools
These reuse the same connections, budget gate and receipts. Every query they run is generated, parsed, estimated and gated like your own queries.
Impact: what breaks if a column changes
Plain *.sql files and dbt models ({{ ref() }}, {{ source() }}, {{ config() }}, {% if %}) both work.
Columns used only in filters or joins are reported too, and SELECT * models are flagged because their shape
follows the source. gulliver lineage --models models/ prints the whole graph.
Drift: schema changes since last time
Removed and retyped columns are warn and are mapped to impacted models; row counts that move more than 20%
are listed too.
Diff: prove two queries return the same rows
Each side is reduced inside its engine to 256 buckets of (row count, sum of MD5 row hashes) keyed by the key's hash, so it scales to billions of rows and costs about one scan per side. Only buckets that differ are opened (with a finer second pass when they are big) to list keys that are missing, extra or changed. MD5 is the same on every engine, so you can diff across engines; values are compared as text, so cast or round in your queries where engines format numbers or timestamps differently. Use it after a refactor, a migration or an incremental switch.
Translate: SQL between dialects
Functions the translator does not know are copied as-is and listed as warnings, so nothing is silently wrong.
Incremental: stop rebuilding everything
It also measures the saving on the real source ("each run would read about 172,800 of 5,000,000 rows, 96.5% fewer")
and, on billed engines, compares dry-run bytes, telling you when you need to partition or cluster the source to
turn fewer rows into less money. Prove the result with gulliver diff.
Check: data quality in one scan
All checks become one aggregate query (one scan), budget-gated like any other. Status fail (exit code 4)
when a check fails, so it drops into CI or an orchestrator. Row-count history is kept per target, so
--max-change catches a load that suddenly lost half its rows.
Top: the most expensive repeated queries
It reads Gulliver's receipts, pg_stat_statements, BigQuery JOBS_BY_PROJECT, Snowflake QUERY_HISTORY or a
CSV/JSONL export, groups the queries by shape (literals become ?), and ranks them by cost or runtime. The top
groups get lint, a rewrite that returns exactly the same rows, and a saving per month labeled exact (both
estimates are BigQuery dry runs) or heuristic. Repeated aggregates that could read a summary table are listed
too. Reading the history is a query like any other, so it goes through the budget gate. Details and limits:
docs/features/top.md.
Auto-fix
same is a promise, so Gulliver keeps it narrow. It never rewrites a date filter on text columns,
TIMESTAMP WITH TIME ZONE (a day can start twice when the clocks change at midnight), intervals, TRY_ and
BETWEEN SYMMETRIC variants, filters with a time-zone or format argument, or periods that run past year 9999.
A column only counts as typed when it clearly comes from one table with metadata, not from a CTE or subquery
that could redefine it. Every same rewrite is tested against real data: DATE and TIMESTAMP columns, NULLs,
infinity, the last microsecond of a day and leap days.
What it will not do: guess a date range for a missing partition filter (GV004) or a join key for a
cartesian join (GV003). Those need a decision, so they stay in remaining.
Where it pays off: Postgres cannot use a plain index or range partitions on ts for ts::date = ..., and
BigQuery, Snowflake and Parquet readers prune best on the raw column. DuckDB already optimizes this case on its
own tables, so there the estimate stays the same.
Test every rewrite: --verify
Labels are reasoning; --verify adds evidence. It runs the original and each rewrite on small generated tables
full of the data that breaks rewrites (NULLs, duplicates, date boundaries, infinity, daylight-saving jumps) in a
private in-memory DuckDB, and shows the rows when they disagree, shrunk to a repro you can paste:
A test is not a proof, so labels never move up: an assumes change with no counterexample stays assumes. A
counterexample against a same rewrite drops that change and says so (that would be a Gulliver bug). It reads
none of your data and costs nothing. gulliver_preflight runs a quick version on the autofix it hands over.
Details: docs/features/verify.md.
Guards for agents
These run on every query, with no extra tool call. The settings live in gulliver.toml, so only the human
can change them.
Read-only gate
Names are matched in every part of the statement (CTEs, subqueries, UNION branches, the SELECT of a write),
after removing quotes, schemas and escapes. On top of that, DuckDB runs in an engine sandbox (see the
Safety model). It is a denylist plus a path allowlist, not a proof: functions defined in the
database can call anything. Settings per connection: allowed_paths, allow_remote, allow_functions,
sandbox. Details: docs/features/security.md.
Result guard: personal data, untrusted rows and output size
Every gulliver_run preview is checked before the agent or the receipt on disk sees it:
- Sensitive columns by name (
email,iban,card_number,password,api_key, Dutch names too), through your SQL (aliases, CTEs,SELECT *, a whole row as one value), and by validated value patterns (email, phone, IBAN mod-97, Luhn card numbers, BSN 11-check, IP, JWT, API-key shapes). - Untrusted envelope. The result has
untrusted: true. Text that reads like instructions to an AI ("ignore previous instructions",gulliver_*tool names, hidden Unicode, base64) is listed ininjectionanddata_warnings. - Output size. Long cells are cut (
max_cell_chars, default 1,000) and a preview overmax_output_chars(default 50,000) keeps fewer rows plus acolumn_summary, so one wide result does not fill the context.
By default secrets are masked and personal data is shown but flagged (status: warn), so existing queries keep
returning the same values. A policy per connection can allow, warn, mask, hash, last4 or deny by
kind, category or column; deny blocks at preflight. gulliver inspect --sensitive lists the columns that look
sensitive, and lint rule GV014 flags them without a database. This is a mitigation, not a data-loss prevention
product: the injection scan uses patterns, so the agent must still treat rows as data. Details:
docs/features/guard.md.
Runaway guard: loops, per-agent and per-session budgets
Cheap repeats (under $0.01 and under 1 GB) never count as a loop. The agent comes from MCP clientInfo,
--agent or GULLIVER_AGENT (set by the human, it wins). Names are self-reported, so per-agent budgets are
accounting, not a security boundary; the per-query and per-day limits always apply. Queries are tagged in the
warehouse (Postgres application_name, Snowflake QUERY_TAG, BigQuery job labels), gulliver spend --by agent
(or day, table, session, task) shows who spent what, and gulliver audit verify checks the hash chain over
the ledger, receipts and approvals. Details:
docs/features/runaway.md.
In CI and on pull requests
Lint every SQL file
Accept a pattern on purpose with -- gulliver: ignore GV001 reason (or ignore-file); a typo in the rule list
ignores nothing and is reported as GV901. Rules, severities and excludes go in [lint] in gulliver.toml.
A pre-commit hook ships with the repo:
Fixes are applied as small text edits (comments, line endings and Jinja stay) and are only accepted when the edited statement re-parses to exactly the rewritten tree. Details: docs/features/lint-ci.md.
gulliver review and the GitHub Action
For every changed model it reports new lint, the change type (cosmetic, non_breaking, breaking), the
downstream models that use a removed or changed column, the scan and money per run and per month before vs
after, and with --rehearse a superlinear flag when output rows now grow faster than the data. A [review]
policy maps the flags to ok, warn or block (exit code 2). A missing base ref or base manifest blocks instead of
reviewing everything.
The action posts one PR comment and updates it on every push, writes the job summary, and fails the job on
block. Classification is static, so a new LEFT JOIN on a unique key is still called breaking; prove it with
gulliver diff. Details: docs/features/review.md.
Scale lint rules
gulliver lint works without any database; gulliver rules prints the list with descriptions. GV015 flags
SUM, AVG or COUNT of a column from the one side of a join like orders.id = order_items.order_id, which
repeats each order once per item; it only fires in that naming pattern, to keep false alarms rare.
The read-only gate uses its own codes. A GS finding is always a block with the code in statement.code:
CLI reference
Exit codes: 0 ok, 1 error, 2 blocked (also: a lint finding at --fail-on, a rewrite found by
fix --check, a review that says do not merge), 3 needs rehearsal or approval, 4 a check failed (data
checks, selftest, audit verify).
SQL can be an argument, -f file.sql, or - for stdin. Global flags: --dsn, --config, -c NAME,
--agent NAME, --json.
FAQ
Does Gulliver send my data or my SQL anywhere?
No. It runs on your machine and only talks to the databases you configure. Receipts, the spend ledger and
approvals are JSON files in ./.gulliver/. There is no telemetry.
Do I need a warehouse to try it?
No. gulliver demo builds a DuckDB database with 5 million events in seconds, and gulliver lint works without
any database at all.
Which agents and models does it work with?
Any MCP client: Claude Code, Codex, Cursor, Gemini CLI, Claude Desktop, VS Code, Windsurf. Without MCP, use the CLI
with --json, or gulliver tools --format openai|gemini for function calling. Every answer is short JSON with a
status and a next_step, so smaller models can follow the loop too.
How accurate is the prediction? It is a growth curve fitted on three samples, so it comes with a confidence level and a range (x0.7-1.5 when confidence is high, up to x0.25-4 when it is low). On BigQuery the money estimate uses the exact dry-run bytes of the full query. After a real run, the receipt shows predicted versus actual. Joins and skewed data can grow faster than the data; Gulliver flags that (growth exponent above 1.3) instead of hiding it.
Can the agent change or delete data?
Not by default. Only SELECT runs. Writes (CREATE TABLE ... AS SELECT, INSERT ... SELECT) need both the call
and a human-set allow_write = true on the connection, and the agent cannot approve its own runs.
How is this different from EXPLAIN or a BigQuery dry run?
Gulliver uses those for the preflight. On top of that it rehearses on samples to show how runtime and output rows
grow, rewrites slow SQL with a stated guarantee, enforces a budget, and writes a receipt, in one JSON format across
four engines.
Is the read-only gate enough on its own?
On DuckDB the engine sandbox does not depend on function names, so a file outside the allowed folders is refused
by DuckDB itself. On Postgres, BigQuery and Snowflake the parser is Gulliver's only check, and functions or views
defined in the database can call anything, so keep a read-only database role as well. Run
gulliver selftest security to see the bypass test set pass on your install.
Will the agent see personal data from my tables?
Secrets (passwords, tokens, API keys) are masked by default. Personal data such as emails is shown but flagged
in data_warnings, so queries like "find the customer with this email" keep working. Set a policy per
connection to mask, hash or deny it. Masking happens on the preview after the query ran; the engine still reads
and bills the data.
Can text in my data hijack the agent?
It can try. Gulliver marks every result untrusted: true, lists text that reads like instructions in
data_warnings, and can redact it (injection = "redact"). The scan uses patterns, so a determined attacker can
get past it; the envelope tells the agent to treat rows as data, never as instructions.
My agent keeps re-running the same query. Can Gulliver stop it?
Yes. After max_repeats identical runs on tables that did not change, gulliver_run returns block with
reason loop and the last result for free. Budgets per session and per agent stop one agent from spending the
whole day's budget.
Can I use it in CI without a warehouse?
Yes. gulliver lint models/ and gulliver review (without --dsn) need no database. Add a connection to get
partition checks, same-rows fixes and cost per pull request.
Is it ready for production on BigQuery and Snowflake? Not yet. Both are beta and have been tested against fakes, not live accounts. DuckDB and Postgres are tested in CI, Postgres against a live server. Reports from real warehouses are very welcome.
Roadmap
Ideas for what comes next, not promises. Each one is open for help:
- Live tests for BigQuery and Snowflake, so they can leave beta. The new query tags, history reads for
gulliver topand review cost estimates on those engines are also tested only against fakes so far. - GS005: look up the user functions a Postgres query calls in
pg_proc, and block those in untrusted languages or withSECURITY DEFINER. It needs a live-server test setup. - More same-rows rewrites in
gulliver_fix, and more--verifycoverage (window functions with ties are skipped today). - Stopping the engine job when a rehearsal is cancelled from the MCP client.
- Databricks and ClickHouse engines.
Have a case where an agent's SQL went wrong at scale? Open an issue. Real examples shape the next lint rules.
Contributing
Contributions are welcome. Start with a good first issue, and read CONTRIBUTING.md and the Code of Conduct. See AGENTS.md for the agent-facing guide and SECURITY.md to report a vulnerability.
Thanks to everyone who helps:
License
MIT, see LICENSE.
來源:README.md,提交 d41ae06
工具
0版本歷史
1- v0.3.0最新Nov 3, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分