
Scherlok
io.github.rbmuller由 GitHub 帳號 rbmuller 發布v1.3.0更新於 Nov 5, 2026
Zero-config data-quality monitoring: profile a warehouse, detect anomalies, gate CI.
概覽
Scherlok 為資料倉儲資料表建立概況、學習正常狀態,讓助理偵測資料異常並為流程把關。
- 可以做什麼
- 列出資料表並建立概況以學習基準
- 偵測資料量驟降、NULL 暴增、結構漂移、資料新鮮度不足等異常
- 執行唯讀的 verify 檢查,與已存基準比對且不改動基準
- 將輸出表與來源表對帳,核對列數、鍵值與加總
- 查看狀態以及歷史異常與執行紀錄
- 適用情境
- 適合助理參與資料管線或 dbt 專案時,確認資料表內容是否仍屬正常;也適合 CI 或代理流程需要一個不會更動基準的唯讀資料品質關卡。
- 執行需求
- 以 Python 套件(需 Python 3.10+)在本機透過 stdio 執行。需要 SCHERLOK_CONNECTION 環境變數中的倉儲連線字串(PostgreSQL、BigQuery、Snowflake、MySQL 或 DuckDB),部分倉儲需另裝額外相依套件,並需能連線至資料庫的網路。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Scherlok,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Scherlok
Zero-config anomaly detection for your database tables.
No YAML, no rules, no thresholds. Scherlok learns what "normal" looks like, then tells you when something changes.
No database handy? The demo seeds one, learns it, breaks it, and catches it, in about a second:
Works with PostgreSQL, BigQuery, Snowflake, MySQL, DuckDB and dbt. Alerts go to Slack, Discord, Teams, email, or your CI exit code.
The Problem
Every data team has the same nightmare:
A source API silently changes from dollars to cents. Revenue dashboards show wrong numbers for 3 weeks before anyone notices.
A column starts returning NULLs. A table stops updating. Row counts drop 40% on a Tuesday. Nobody knows until the CEO asks why the report looks weird.
Current tools (Great Expectations, Soda, dbt tests) require you to define what "correct" looks like before you can detect what's wrong. Hundreds of rules. Dozens of YAML files. And you still miss things — because you can't write rules for problems you haven't imagined yet.
What It Catches
Every anomaly is auto-scored: INFO, WARNING, or CRITICAL. No thresholds to configure.
A table seen for the first time has nothing to compare against, so it gets the new-table checks instead, from the profile already collected. They report WARNING (INFO for a constant column), so a legitimately empty table doesn't fail ci with the default --fail-on critical; once the table has a baseline they never run again. scherlok verify --table treats the tables it names as just built, so an empty table, an all-NULL column or a duplicate key in one of them is CRITICAL.
How It Works
Scherlok takes the opposite approach of rule-based tools: learn first, then detect.
Three commands. Five minutes. Done. (scherlok ci <url> runs all three in one step for pipelines.)
After five valid profiles, Scherlok learns per-metric variability from the latest 30 profiles using robust historical baselines for volume, numeric mean shifts, NULL rates, and distinct counts. During cold start or when history is not usable, it keeps the conservative fixed defaults.
Every run is learned, except one that finds a CRITICAL anomaly on a table:
that table keeps its baseline, so the alert repeats on every run until the
data recovers, and the broken state never becomes the new normal. WARNING and
INFO findings are learned. When the change is intended, such as a planned
backfill, a person makes it the new normal with scherlok accept (below).
1. investigate — Learn the patterns
Scherlok profiles every table: row counts, column types, NULL rates, value distributions, freshness cadence, cardinality. Stores everything locally in SQLite, as aggregates only: no value from your rows is saved (what Scherlok stores).
2. watch — Detect anomalies
3. Alert — Slack, CI/CD, or both
Auto-detects Slack, Discord, and Teams from the URL and formats the payload accordingly. Any other URL receives a generic JSON payload.
CI/CD Integration
Use Scherlok as a data quality gate on pull requests. The GitHub Action checks the change against the stored baseline, fails the check on anomalies and keeps one comment on the pull request up to date with the table, column, metric, baseline, current value and severity of each:
The connection is passed through the environment and masked, the comment never holds a value read from a row, and fork pull requests, which get no secrets, are skipped with a notice. 📖 GitHub Action guide →
Anywhere else, the ci command does it in one line. If Scherlok detects a critical anomaly, the pipeline fails:
ci learns every run without a CRITICAL anomaly, so after a failure on --fail-on warning the new state becomes the baseline and a retry passes. When a retry must keep failing until the data is fixed, as with an AI agent or a CI job that retries, gate with verify. It compares against the stored baseline and saves no profiles, no anomalies and no config, and it never uploads a remote store; it only records the run.
--against compares the connection's tables, such as a dev build, with another database's baseline in the same store, such as production's, and saves nothing under either: a dropped column fails before the change ships. --ignore volume is for builds on sampled data: row counts are not compared, and the column checks only flag what a sample can't explain.
Tables without a baseline are listed under tables_without_baseline, never counted as verified. Those you name with --table count as just built: an empty table, a column NULL in every row or a duplicate key there is CRITICAL, so an agent can gate on a table it just created. Every watch, ci, check and verify run is recorded, passing or not: scherlok history --runs lists them. Every anomaly in the JSON also carries column, metric, baseline, current, change_pct and a fixed hint, so it can be acted on without parsing the message. 📖 CI/CD gate guide →
Reconcile output against input
A table's own history can't catch a join that fans out on its first build, or a total that changes while the row count stays the same. reconcile compares a pipeline's output with its input, in the same database, and exits 1 when they don't add up:
It reports row_count_mismatch, duplicate_keys (a key repeated in the target: join fan-out), missing_keys, extra_keys and sum_mismatch (totals apart by more than the absolute --tolerance), all CRITICAL, with --output json for CI. It needs no baseline and saves nothing, and it reports counts and totals only, never a key value. On BigQuery and Snowflake every run scans both tables in full. 📖 Reconcile guide →
Accepting a change
A CRITICAL reading is never learned, so an intended change (a new column, a planned backfill) keeps alerting until a person accepts it:
accept re-profiles the table, shows its rows, columns and anomalies against the current baseline, and on confirmation saves the new state as the baseline with one row in an append-only approvals table: who approved (git config user.email, else $USER), the reason, and the before/after summary. --reason is required.
To keep agents and scheduled runs from moving baselines at all, lock them: scherlok config --baseline-locked or SCHERLOK_BASELINE_LOCKED=1. Then only accept writes a baseline, including a new table's first one; watch, ci, check, dbt and the MCP tools compare without saving profiles, and investigate refuses. accept is deliberately not an MCP tool.
This is a guardrail, not a security boundary. An agent with shell access can run scherlok accept or edit the SQLite file itself. Real enforcement means running verify in CI against a store the agent has no credentials for, with accept run from a workflow a person triggers. 📖 Accepting a change →
Works with dbt
Already running dbt? Scherlok complements dbt test with automatic anomaly detection — no rules to write.
Scherlok reads target/manifest.json, discovers every materialized model (table, incremental, view), auto-resolves the connection from your profiles.yml, and profiles each model:
Use it as a CI gate after dbt run:
Or collapse both steps into one with the wrapper:
The wrapper runs dbt run by default and uses the successful model nodes recorded in
target/run_results.json, so partial runs profile only what dbt actually built. Use
--build to run dbt build; successful models are still profiled when a test failure
causes downstream models to be skipped on dbt's handled failure path (exit 1), while
the wrapper preserves dbt build's exit code. Unhandled failures fail fast without
reading the artifact.
Both dbt and dbt-run-and-watch accept --output json for CI parsers — a single JSON document on stdout, nothing else.
Supported adapters: postgres, bigquery, snowflake, mysql, duckdb. For others, pass --connection-string explicitly.
📖 Full docs: dbt integration guide →
dbt Package — native tests
Prefer staying inside dbt? Install Scherlok as a dbt package for native data quality tests — no Python CLI needed.
Once the dbt Package Hub listing lands (dbt-labs/hubcap#456), this becomes package: rbmuller/scherlok with version: [">=1.0.0", "<2.0.0"].
Tier 1 — Instant (no setup): not_null_proportion, row_count_between, recency, unique_proportion
Tier 2 — Auto-learning (Shewhart control limits): volume_anomaly, null_anomaly — require the scherlok_metrics model to build baseline history.
📖 Full docs: dbt package README →
HTML dashboard
One self-contained HTML file (~28 KB): KPIs, per-table incidents grouped with first-seen timestamps, +/−/~ schema-drift diff, sparklines, and full anomaly history. Auto dark/light theme via prefers-color-scheme.
📖 Full docs: dashboard guide →
Use it from an AI agent (MCP)
Let Claude Code / Claude Desktop run data-quality checks directly.
Claude Desktop: download scherlok-<version>.mcpb from the latest release and open it. One click, one setting (your connection string, stored as a secret).
Any other client:
The agent gets list_tables, investigate, watch, status, history, check, verify and reconcile as tools; verify is the read-only gate that never changes the baseline, so an agent that retries can't pass a broken table, and reconcile checks a table it built against the table it built it from. There is no accept tool: a person approves baseline changes, and with baselines locked no tool writes one. Credentials are resolved server-side (never passed by the model), every operation is read-only on the warehouse, and there's no arbitrary-SQL tool.
📖 Full docs: MCP server guide →
Check an agent's dbt changes (Claude Code)
An agent that finishes dbt run reports success: the SQL ran. The Claude Code plugin makes it check the data. After every dbt run or dbt build, a hook runs scherlok verify on the models that run built and hands Claude the findings; the verify-data-pipeline skill has it fix the cause, verify again, and leave accepting a new baseline to a person.
Demo: a dbt project on DuckDB where the agent adds a join that fans out, the hook fires, the agent fixes the join and the check passes.
The hook stays silent until Scherlok is installed and has a connection, and it never fails the session. Lock the baselines for agent sessions with SCHERLOK_BASELINE_LOCKED=1. Other coding agents get the same instructions from an AGENTS.md snippet, and scherlok verify --dbt-project . scopes a check to the last dbt run anywhere, CI included. 📖 Coding agents guide →
AI-explained alerts (--explain)
Your alert says what broke. --explain adds why — and what to check next.
When anomalies fire, Scherlok makes one Claude call for the whole batch and injects a short root-cause hypothesis into the same Slack/Discord/Teams/email/JSON alert:
Works on watch, ci, check, dbt, and dbt-run-and-watch. On dbt projects the hypothesis is lineage-aware: upstream parents from manifest.json go into the prompt, so cascading failures get traced to the source model instead of alerting on every downstream symptom.
- What it costs — one call per fired run (not per anomaly), Claude Haiku 4.5 by default: well under a cent per run (~$0.003). Override the model with
SCHERLOK_EXPLAIN_MODEL. Runs with zero anomalies make no API call. - What it sends — aggregates only: the anomaly type/severity/message strings already in your alert, dbt model names, detection timestamps. Never warehouse rows, cell values, or credentials — the test suite pins this as a contract.
- How to turn it off — it's opt-in; don't pass
--explain. If the API call fails (no key, timeout, rate limit), the original alert is delivered unchanged with a one-line note. Alerting never blocks on the LLM.
📖 Full docs: explainer guide →
Email alerts
Connectors
Remote Storage
Share profiles across CI runs and team members:
One store can hold several databases: baselines are kept per database (adapter, host, port and path of the connection, never credentials), so orders in staging never shares a baseline with orders in production. 📖 Where things live →
How it compares
Every claim links to the other tool's own documentation in the full comparison.
CLI Reference
Install
Requires Python 3.10+.
Run via Docker
A pre-built image with every warehouse extra (dbt, bigquery, snowflake) is published to GitHub Container Registry on every release tag:
Mount your project directory and inject connection details the same way your CI does it; the entrypoint is the scherlok CLI:
The image is built from python:3.12-slim and runs unprivileged (USER scherlok).
Contributing
Contributions welcome! See CONTRIBUTING.md.
We're especially looking for:
- New database connectors (e.g. Databricks — see #37)
- Anomaly detection improvements
- Documentation and examples
Star History
License
MIT — Developed by Robson Bayer Müller
來源:README.md,提交 9782e03
工具
0版本歷史
7- v1.3.0最新Nov 5, 2026
- v1.0.5Oct 19, 2026
- v1.0.4Sep 25, 2026
- v1.0.3Sep 22, 2026
- v1.0.2Sep 19, 2026
- v1.0.1Sep 18, 2026
- v0.7.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分