Cleanframe
The reproducible data-cleaning engine for Python. Profile messy CSVs, detect issues, generate a YAML recipe (with or without an LLM), and replay it with zero AI calls.
Install / Use
claude mcp add inboxpraveen -- npx -y github:inboxpraveen/CleanframeIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AutomationSupported Platforms
Our assessment of Cleanframe
Cleanframe scores 83/100 on our quality scale, 2217th of 2,887 Automation skills we index.
Its MCP Server is 22 KB long, well organised into 20 sections with 12 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated yesterday, so Cleanframe is actively maintained.
- It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Cleanframe compared with similar skills
All 4 of these similar skills score higher than Cleanframe; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| Cleanframe (this skill)by inboxpraveen | 83 | 3 | 1d ago | MCP Server |
| Agent-Reachby Panniantong | 100 | 100.2k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 76.7k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.5k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 88.9k | 1d ago | MCP Server |
Frequently asked questions
- How do I install Cleanframe?
- Run
claude mcp add inboxpraveen -- npx -y github:inboxpraveen/Cleanframe. The install tabs above show the steps for each supported agent. - Which AI agents does Cleanframe work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is Cleanframe safe to use?
- It is Apache-2.0-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is Cleanframe still maintained?
- The repository was last updated yesterday, so Cleanframe is actively maintained.
Skill content
View source on GitHubEvery team has that file. The vendor spreadsheet that arrives monthly with dates in three formats. The CRM export where Bengaluru, Bangalore, and BLR are three different cities. The finance sheet with ₹1,20,000 in a column typed as text.
You clean it by hand. Next month, it arrives broken in a new way, and you clean it again.
CleanFrame ends that loop. It profiles your data, detects issues, proposes a cleanup plan (with an LLM's help — or without one), executes it with pure pandas, and saves the whole thing as a recipe: a versionable YAML file that replays on every future file with zero AI calls, and alerts you when the incoming schema drifts.
AI suggests. Pandas executes. Rules validate. You approve. Everything is reproducible.
Documentation
| | | |--|--| | Wiki (full docs) | Getting started, API, recipe/schema specs, production guide | | docs/ | Same guides in-repo | | CONTRIBUTING.md | Invariants + how to add detectors/ops | | SECURITY.md | Vulnerability reporting | | CHANGELOG.md | Release notes |
Why not just use an LLM agent on my dataframe?
Because you can't ship "the model probably fixed it" to production. Chat-with-your-data tools are great for exploration and say so themselves — they are not built for pipelines. CleanFrame is built on one rule:
The LLM never touches your data. It only writes the plan.
The plan compiles to deterministic pandas operations. Same input → same output, every time. Every changed cell is tracked. Every step is reviewable, reversible, and exportable as plain Python you can read.
30-second demo
No API key, no sample files to download. The demo data ships inside the package:
pip install cleanframe-engine
cleanframe demo
It profiles a messy customer file (HTML report + quality score), cleans it into a recipe, then replays that recipe on next month's file. That file has a renamed column and a new date format, so the replay stops and tells you why. Finally the demo drafts the patch that makes it replay cleanly. Every step prints the command to run on your own data.
The same thing in Python:
import pandas as pd
import cleanframe as cf
df = pd.read_csv("cleanframe-demo/messy_customers.csv") # written by `cleanframe demo`
result = cf.clean(
df,
target_schema="cleanframe-demo/customer.schema.yaml", # or: cf.infer_schema(df)
mode="review", # review | auto | strict
# decide="typesafe/jev-latest", # optional decision model for judgment calls (TYPESAFE_API_KEY)
)
result.diff.show() # cell-level before/after, git-diff style
result.recipe.save("customer.recipe.yaml") # ← the durable artifact
result.code.save("clean_customers.py") # plain pandas, no cleanframe dependency
clean_df = result.dataframe
result.quarantine # rows validation held back, with reasons — never deleted
The sample file has one genuinely invalid email, so the demo quarantines that row and cleans the other five.
Next month, the file comes back. No LLM, no tokens, no variance:
cleanframe apply new_customers.csv --recipe customer.recipe.yaml --out clean.csv
If the new file's schema drifted (a renamed column, a new currency format), CleanFrame stops and tells you instead of silently corrupting data:
⚠ Schema drift detected in new_customers.csv
• Column "Amt (INR)" is new — 94% match to recipe column "amount_inr"
• 312 value(s) in "signup_date" match no allowed date format (new: 'Jan 5, 26')
• 40 of 312 numeric value(s) in "Amount" do not fit the recipe's number format
(decimal '.', thousands ','; new: '€1.200,50')
Run `cleanframe suggest new_customers.csv --recipe <recipe.yaml> --update` to review a patch.
Decision models: AI makes the judgment calls, under a 0.9 bar
Some cleaning steps are judgment calls, not parsing. Is BLR another name for Bangalore? Is Banglore
a typo, or a different place? Does none in an allergies column mean "missing" or "no allergies"? Which
column is the schema's amount_inr? Rules can't settle these safely. With decide=, a decision model
answers each one as a typed question (pick an option, or yes/no) with a probability. That can be
Jev, an open "System One" model, or any LLM through an adapter.
cleanframe clean vendor.csv --decide typesafe/jev-latest --llm-exposure sample
- An answer changes data only at p ≥ 0.9 (
decision_threshold). Below that it is recorded as a suggestion in the recipe and never executed. A confident "no, these differ" vetoes a typo merge the rules would have made. - Asked once, at planning time. Accepted answers become ordinary recipe ops (
normalize_values,to_na,rename_to), and every answer is logged inrecipe.meta.decisions. Replay makes zero AI calls. - Privacy follows
llm_exposure. Category values are sent only undersample, and only for columns whose values repeat. Dates and numbers are never asked: they stay with the deterministic parsers. - Backends:
typesafe/…,openrouter/typesafe/…, self-hostedsystemone/…, offlinerules, or any--llmspec. No SDK is needed.
How good are decision models at this? CleanBench measures it on hand-labelled messy columns full of traps, scoring safe-apply precision: of the answers that would change your data, how many are right. See Decision models.
Bring your own API key (or no key at all)
CleanFrame is LLM-optional and provider-agnostic.
| Mode | What runs | Data leaves your machine? |
|---|---|---|
| Rules-only (default) | Deterministic detectors + heuristics | Never |
| Metadata | LLM sees column names, dtypes, and value patterns (regex sketches) — never raw values | Only metadata |
| Sample | LLM sees a small shuffled sample of values. Emails, phones and long strings are redacted; other short values (names, cities) are sent verbatim. Passing llm_exposure="sample" is the opt-in — there is no separate approval step | Sample values, per the redaction above |
| Replay | Saved recipes | Never — recipes need no LLM |
| Decisions (decide=) | Typed questions to a decision model while planning; same exposure rules | Metadata only by default; distinct category values under sample |
- Keys come from environment variables (
ANTHROPIC_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY,GROQ_API_KEY, …). CleanFrame never stores or logs them, and each provider reads only its own variable —OPENAI_API_KEYis never sent to another provider. - Any provider that speaks OpenAI Chat Completions works out of the box —
Anthropic (native), OpenAI, OpenRouter, Groq, Together, Fireworks, DeepSeek,
Mistral, Google Gemini, xAI, Perplexity, Cohere, plus local Ollama / LM Studio
or any custom
OPENAI_BASE_URL. Spec format:provider/model(e.g.openrouter/anthropic/claude-sonnet-4,groq/llama-3.3-70b-versatile). - Cost cap:
cf.clean(..., max_tokens_budget=50_000)is checked before each call (against an estimate) and again against the usage the provider reports — leave headroom, since a call that overshoots has already been billed. - Fully offline / air-gapped operation is a supported first-class mode, not a degraded one.
What it cleans
| Problem | Example |
|---|---|
| Invisible characters | zero-width spaces, BOMs, non-breaking spaces and decomposed accents (café typed two ways) → one normalised form |
| Column name chaos | Cust Name, customer_name, CustomerName → customer_name |
| Date formats | 12/01/24, 1 Jan 2024, 2024-01-01 → ISO dates |
| Currency & numbers | ₹1,20,000, $1,200, -$5, (1,200), 1.234,56, 1200 INR → typed floats (+ a currency column); a value whose grouping is invalid or ambiguous becomes a counted, warned null, never a guess |
| Category variants | Bengaluru / bengaluru / BENGALURU and typos (Banglore, one edit away) → one canonical value; look-alikes such as Austria/Australia stay apart; abbreviations such as BLR need a seed map or a decision model |
| Emails & phones | validation, normalization, 00/+ international prefixes, optional default country code |
| Duplicates | exact duplicates are dropped (tracked in the diff); fuzzy near-duplicates and key collisions are reported with keep/drop proposals for you to act on |
| Missing values | detected and explained; strategies proposed, never silently applied |
| Units | 5kg, 5000 g, 5 KG → normalized |
| Schema mapping | messy file → your target schema, with confidence scores |
| Outliers | flagged with evidence — detected, never auto-"fixed" |
Production-ready defaults
CleanFrame is built for pipelines, not just demos:
- Plan once, replay forever — commit recipes; fail on schema drift
- Multi-sheet workbooks — clean every Excel tab into one reviewable recipe; write-back refuses to overwrite the source in place
- Out-of-core streaming — replay row-independent recipes over larger-than-RAM CSVs at chunk-bounded memory
- **Format
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
100.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
76.7kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.5kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Scrapling
88.9k🕷️ A Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
