AI content quality gate for marketing teams. CLI + web dashboard that returns plagiarism, AI-detection, SEO score, fact-check, tone-of-voice, legal risk, brief matching, and content summary — before you publish. Supports context management (tone guides, briefs, legal policies), MCP server for AI agent integration, batch checking, CI mode, JSON output, tags, search, report export, and a local web dashboard for browsing results and managing skills.
CheckApp is a pluggable CLI tool that runs a configurable set of quality checks on any article — a Google Doc URL or a local .md/.txt file — before it goes live.
Each check is a skill you can enable or disable. Results appear in the terminal and are automatically saved as an HTML report and to a local SQLite history database.
Every flagged issue ships with evidence + rewrite + citation:
- Fact-check now carries
sources[](Exa highlights with url/title/quote) on every finding. Upgrade to deep-reasoning with--deep-fact-check. - Grammar & Style (LanguageTool + LLM fallback) produces a
rewriteper finding. LLM-fallback rewrites are grammar-checked a second time to catch mechanical errors. - Academic Citations (OpenAlex recommended, Semantic Scholar legacy) merges citations onto matching fact-check findings with scientific/medical/financial claim types. Free, no API key — see Academic Citations below.
- Self-Plagiarism (Cloudflare Vectorize + OpenRouter embeddings) flags overlap with your past articles. Run
checkapp index <dir>once to ingest your archive.
Pick a provider per skill from the Settings → Providers dashboard. CheckApp never holds API tokens — users bring their own keys.
Pre-flight cost estimate: checkapp --estimate-cost article.md or the Run Check page in the dashboard shows "Estimated cost: $0.0320" before spending anything.
See docs/security.md for the BYOK-alpha threat model.
| Skill | Engine | Cost/check | Enabled by default |
|---|---|---|---|
| Plagiarism | Copyscape · Gemini Grounded Plagiarism | ~$0.09 / ~$0.04 estimate | ✅ |
| AI Detection | Copyscape (English) · Gemini 3 Pro Preview (multilingual) | ~$0.03 / ~$0.01 estimate | ✅ |
| SEO | Offline (no API) | free | ✅ |
| Grammar & Style | LanguageTool + LLM fallback | free tier / ~$0.002 | ❌ disabled by default (enable in Settings; LanguageTool free tier works without any API key) |
| Academic Citations | OpenAlex (default) / Semantic Scholar (legacy) | free | ❌ disabled by default (augments fact-check findings when enabled; OpenAlex/SS both free) |
| Self-Plagiarism | Cloudflare Vectorize + OpenRouter embeddings | ~$0.0001 | ❌ disabled by default — requires index (checkapp index <dir>), OPENROUTER_API_KEY, and Cloudflare Vectorize provider config |
| Fact Check | Tiered: Basic = Exa + LLM; Standard = Gemini + Google Search; Deep Audit = Gemini Deep Research | varies | Basic is available by default; Standard is opt-in; Deep Audit is async |
| Tone of Voice | Claude/MiniMax | ~$0.002 | ❌ requires LLM key + tone guide file |
| Legal Risk | Claude/MiniMax | ~$0.002 | ❌ requires LLM key |
| Content Summary | Claude/MiniMax | ~$0.002 | ❌ requires LLM key |
| Brief Matching | MiniMax/Claude | ~$0.002 | ❌ requires LLM key + brief context |
| Content Purpose | MiniMax/Claude | ~$0.002 | ❌ requires LLM key |
All enabled skills run in parallel. Adding more skills does not increase total time significantly.
CheckApp finds peer-reviewed supporting papers for scientific, medical, and financial claims.
Recommended provider: OpenAlex. Free, ~250M indexed works, no API key required. Set OPENALEX_MAILTO=your@email.com in your .env to enable it — this both activates the routing (skill is skipped if unset and no explicit provider is configured) and joins the polite pool (100k req/day).
Legacy provider: Semantic Scholar. Users with an explicit providers.academic = { provider: "semantic-scholar" } config continue to hit SS. Note: the free tier of SS has aggressive per-IP rate limiting and is effectively unusable on shared IPs — that's why OpenAlex is the new default. Authenticated (paid) SS requests are not currently wired in the client; support for a paid SS API key is a separate workstream.
See poc-replacement/03-academic-citations/RESULTS.md for the comparison data that drove this decision.
Standard is opt-in and stays off by default until Gate 2 passes. Basic remains the default tier unless factCheckTierFlag is explicitly enabled.
| Tier | Engine | Cost per article | Typical time | Notes |
|---|---|---|---|---|
| Basic (default) | Exa + LLM | $0.04 | ~15s | Requires Exa plus an LLM key for claim extraction/assessment |
| Standard (opt-in) | Gemini 3 Pro Preview + Google Search grounding | $0.16 | ~45s | Requires Gemini. Enable with factCheckTierFlag=true and factCheckTier="standard", or set providers["fact-check"].provider = "gemini-grounded". |
| Deep Audit (async) | Gemini Deep Research | $1.50 | 5–15 min | Premium async audit workflow. The normal sync check still runs Basic unless Standard is selected. Initiate via dashboard button or deep_audit_article MCP tool. |
Research basis: the Standard tier was selected based on an internal benchmark on a 20-claim synthetic corpus. That benchmark is directional, not definitive - see its LIMITATIONS.md before relying on the results for your own decisions.
CheckApp reports evidence confidence, not certainty. Gemini grounded fact-check has the strongest signal on concrete dates, statistics, named entities, and claims where Google Search returns source URLs. If Gemini or Exa marks a claim as supported but no source URL is attached, CheckApp downgrades that claim to unverified. “No issues found” does not prove the article is accurate or original across the whole web.
Gemini grounded plagiarism is stricter than a general similarity prompt: matched URLs that appear in Gemini grounding metadata are treated as grounded matches. If Gemini returns plausible match JSON without grounding metadata, CheckApp reports a reduced-confidence review finding instead of a clean pass. Exact public-source English and Hebrew copying is the highest-confidence path we validate. Translated or paraphrased plagiarism is lower confidence and should still receive human review.
| Feature | Details |
|---|---|
| Pluggable skills | Enable/disable any skill via config. Add custom skills by implementing one TypeScript interface. |
| Plagiarism check | Checks against Copyscape's indexed web data by default, or Gemini Grounded Plagiarism when selected. Returns 0–100% similarity + matched sources. |
| AI detection | Copyscape AI detector by default, or Gemini 3 Pro Preview when explicitly configured for multilingual checks. Returns 0–100% probability per sentence and an overall verdict. |
| SEO analysis | Offline. Checks word count (800–2500 ideal), H1/H2 headings, average sentence length, Flesch-Kincaid readability. |
| Fact check | Basic extracts specific claims, searches each with Exa AI, and uses the configured LLM to assess evidence. Standard uses Gemini 3 Pro Preview with Google Search grounding. |
| Tone of voice | Loads your brand voice guide (.md file), sends article + guide to the configured LLM, returns violations with quotes and rewrite suggestions in your brand voice. |
| Legal risk | Scans for unsubstantiated health claims, defamation, false promises, GDPR risks, price misrepresentation. Findings include actionable "Fix:" suggestions. |
| Content summary | Analyzes topic, main argument, target audience, and tone (informational/persuasive/conversational/technical/promotional). |
| SEO keyword detection | Extracts the top keyword and checks whether it appears in the first paragraph. |
| Fact-check confidence | Each claim now shows high/medium/low confidence based on the number of supporting sources found. |
| Batch checking | Check all .md/.txt files in a directory with checkapp --batch ./articles/. |
| Configurable thresholds | Custom pass/warn/fail score cutoffs per skill via config.json. |
| HTML report | Self-contained, no-dependency HTML file. Score bars, verdict badges, per-finding citations. Opens in browser automatically. |
| SQLite history | Every check is saved to ~/.checkapp/history.db. Query with --history. |
| Google Doc support | Paste a publicly-shared Google Doc URL including ?tab=t.xxx for specific tabs. No Google auth required. |
| Local file support | Pass a .md or .txt file path. Works offline for the fetch step. |
| Single binary | No Node.js, Bun, or runtime required. |
| Web dashboard | Local Next.js UI — overview stats, report browser, run checks, manage skills and settings, in-app docs. Start with checkapp --ui. |
--ui flag |
Launches the dashboard dev server and opens http://localhost:3000 in your browser. |
--output export |
--output report.md or --output report.html — save the report to a file. |
| Tags + search | Attach tags to checks, search across all history by text or tag via dashboard or API. |
| JSON API | RESTful API at localhost:3000/api for running checks, managing tags, toggling skills. See docs/api.md. |
| Context system | Upload tone guides, content briefs, legal policies, and style guides. Contexts are stored in SQLite and automatically loaded by relevant skills. Manage via CLI (checkapp context add/list/show/remove) or the dashboard Contexts page. |
| MCP server | 8 tools for AI agent integration (Claude Code, Cursor, Windsurf). Start with checkapp --mcp. Tools: check_article, list_reports, get_report, upload_context, list_contexts, get_skills, toggle_skill, regenerate_article. |
CI mode (--ci) |
Exits with code 1 if any skill returns a fail verdict. Designed for CI/CD pipelines. |
JSON output (--json) |
Outputs structured JSON instead of the Ink terminal UI. Ideal for scripts, agents, and piping. |
| Brief matching | Checks article against an uploaded content brief. Verifies coverage of required topics, audience alignment, and tone match. Requires a brief context. |
| Content purpose detection | Detects article type (tutorial, product announcement, case study, thought leadership, etc.) and provides purpose-specific recommendations for missing elements. |
| Regenerate/fix | checkapp --fix <file> runs all checks then generates AI-suggested rewrites for every flagged sentence, using tone guide and legal policy contexts. |
| Cross-platform | Mac (Apple Silicon + Intel), Linux, Windows. |
An article about Vitamin D with 3 verbatim sentences from Wikipedia. Live output with the default 3 skills:
────────────────────────────────────────────────
Words checked: 310
API cost: $0.080
❌ Plagiarism Check: 33% similarity — 18 sources matched (34/100)
✅ AI Detection: 10% AI probability — human (90/100)
❌ SEO: 310 words · avg 17-word sentences · readability: Medium (49/100)
────────────────────────────────────────────────
Overall: 58/100
Report: checkapp-report.html
────────────────────────────────────────────────
HTML report: Each skill gets a card with a circular score indicator, engine badge, and a list of findings. The report links to all engines used (Copyscape, Gemini, Exa AI, MiniMax) and includes an MIT disclaimer.
Three sentences from the Hebrew Wikipedia article on Vitamin D:
────────────────────────────────────────────────
Words checked: 119
Plagiarism: 39% (46 / 118 words matched)
Top match: he.wikipedia.org/wiki/ויטמין_D
↳ "ויטמין D הוא קבוצה של חמש תרכובות מסיסות בשמן..."
↳ "המחלה הנפוצה ביותר הנגרמת כתוצאה ממחסור בוויטמין D..."
AI detection: 12% probability AI-generated
────────────────────────────────────────────────
❌ REWRITE — similarity too high
✍️ HUMAN — 12% AI probability
────────────────────────────────────────────────
Hebrew content and RTL rendering are supported. Provider configuration still matters: Copyscape AI detection is English-only, so use gemini-ai-detection for Hebrew AI detection; use gemini-grounded-plagiarism for Hebrew plagiarism checks when Copyscape cannot cover the language.
Only 2 sentences copied out of ~220 words of original Hebrew content:
────────────────────────────────────────────────
Words checked: 222
Similarity: 33% (76 / 224 words matched)
Top match: ynet.co.il/articles/0,7340,L-4870486,00.html 76 words
(syndicated copy also found at news08.net)
────────────────────────────────────────────────
❌ REWRITE — similarity too high
────────────────────────────────────────────────
2 sentences in 220 words of original content was enough to trigger REWRITE. Both the original source and a syndicated copy were identified.
| Similarity | Verdict | What to do |
|---|---|---|
| 0 – 15% | ✅ PASS | No significant matches detected by this check. Ready for editorial review. |
| 16 – 25% | Some overlap. Check listed sources and rewrite matching passages. | |
| 26%+ | ❌ REWRITE | Too similar to existing content. Rewrite before publishing. |
CheckApp supports two plagiarism providers:
| Provider | Best for | Cost | When used |
|---|---|---|---|
| Copyscape | Deterministic indexed-web plagiarism checks | ~$0.09 per 800 words | Default |
| Gemini Grounded Plagiarism | Grounded web-search evidence, especially multilingual/Hebrew checks | ~$0.04/check in-app estimate | Explicitly configured, or explicit fallback from Copyscape |
To select Gemini Grounded Plagiarism:
{
"providers": {
"plagiarism": {
"provider": "gemini-grounded-plagiarism"
}
}
}To keep Copyscape as the primary provider but explicitly fall back to Gemini when Copyscape skips, for example insufficient credits:
{
"providers": {
"plagiarism": {
"provider": "copyscape",
"extra": {
"fallbackProvider": "gemini-grounded-plagiarism"
}
}
}
}| AI probability | Verdict | What to do |
|---|---|---|
| 0 – 29% | ✍️ HUMAN | Content reads as human-written. |
| 30 – 69% | 🔍 MIXED | Contains AI-like passages. Review highlighted sentences. |
| 70%+ | 🤖 AI-GENERATED | High probability of AI authorship. Rewrite or disclose. |
CheckApp supports two AI detection providers:
| Provider | Languages | Cost | When used |
|---|---|---|---|
| Copyscape AI | English only | ~$0.03/check | Default |
| Gemini 3 Pro Preview | All languages incl. Hebrew | ~$0.01/check in-app estimate | Explicitly configured (required for non-English) |
Copyscape only supports English. For non-English articles, set Gemini as the ai-detection provider in ~/.checkapp/config.json and provide either GEMINI_API_KEY, geminiApiKey, or a provider-scoped apiKey:
{
"providers": {
"ai-detection": {
"provider": "gemini-ai-detection"
}
}
}| Score | Verdict |
|---|---|
| 75+ | ✅ Pass |
| 50–74 | |
| <50 | ❌ Fail |
Checks: word count (800–2500 ideal), H1/H2 headings present, average sentence length ≤20 words, Flesch-Kincaid readability.
Go to the Releases page and download for your platform:
| File | Platform |
|---|---|
checkapp-mac-arm64 |
Mac — Apple Silicon (M1/M2/M3/M4) |
checkapp-mac-x64 |
Mac — Intel |
checkapp-linux-x64 |
Linux x64 |
checkapp-win-x64.exe |
Windows x64 |
chmod +x ~/Downloads/checkapp-mac-arm64
mv ~/Downloads/checkapp-mac-arm64 /usr/local/bin/checkappCreate a .env file in your working directory:
# Required — plagiarism + AI detection
COPYSCAPE_USER=your-copyscape-username
COPYSCAPE_KEY=your-copyscape-api-key
# Optional — multilingual AI detection when configured as the AI Detection provider
GEMINI_API_KEY=your-gemini-api-key
# Optional — passage-level evidence (free tier: 16k requests)
PARALLEL_API_KEY=your-parallel-api-key
# Optional — fact check + tone + legal skills (use one LLM provider)
EXA_API_KEY=your-exa-api-key
MINIMAX_API_KEY=your-minimax-api-key # preferred — cheaper, Anthropic-compatible
ANTHROPIC_API_KEY=your-anthropic-api-key # fallback if MINIMAX_API_KEY not set
OPENROUTER_API_KEY=your-openrouter-key # alternative — one key for 200+ models
LLM_PROVIDER=minimax # minimax (default), anthropic, or openrouter
# Optional — tone of voice skill (path to your brand voice .md file)
TONE_GUIDE_FILE=/path/to/brand-voice.mdOr run the interactive setup wizard:
checkapp --setup# Check a Google Doc (must be publicly shared)
checkapp "https://docs.google.com/document/d/XXXX/edit"
# Check a local file
checkapp ./my-article.md
# Check all articles in a directory
checkapp --batch ./articles/
# View check history
checkapp --historyOne account for both plagiarism and AI detection checks.
- Go to copyscape.com → Sign up for Premium
- Add credits (minimum $5 deposit — ~27 full checks)
- My Account → API — your key is listed there
- Your username is the email you signed up with
Cost per 800-word check:
| Check | Cost |
|---|---|
| Plagiarism (first 200 words) | $0.03 |
| Plagiarism (each 100 words after) | $0.01 |
| AI detection (first 200 words) | $0.03 |
| AI detection (each 100 words after) | $0.01 |
| Total — 800 words, both checks | ~$0.18 |
Exa is a neural search engine built for AI agents. Used to search for evidence supporting or refuting each factual claim in the article.
- Go to dashboard.exa.ai
- Create an account and generate an API key
- Add to
.env:EXA_API_KEY=your-key
Cost: ~$0.007 per search. The fact-check skill searches 4 claims per article → ~$0.028 per check.
Free trial credits available on signup.
Fact check, tone, and legal skills need an LLM. Set one of these — MiniMax is preferred (cheaper):
MiniMax M2.7 is an extended-thinking model with an Anthropic-compatible API. Used via the Anthropic SDK with a custom base URL.
- Go to platform.minimax.io → API Keys
- Create an API key
- Add to
.env:MINIMAX_API_KEY=your-key
Cost per check: ~$0.001–0.002.
Used automatically if MINIMAX_API_KEY is not set.
- Go to console.anthropic.com
- Create a new API key
- Add to
.env:ANTHROPIC_API_KEY=your-key
Cost per check: ~$0.001–0.002 (Haiku pricing).
OpenRouter lets you use any LLM (GPT-4o, Llama, Mistral, etc.) with a single API key.
- Go to openrouter.ai/settings/keys
- Create an API key
- Add to
.env:OPENROUTER_API_KEY=your-key - Optionally set preferred provider:
LLM_PROVIDER=openrouter
Cost: Varies by model. See openrouter.ai/models for per-model pricing.
Fetches the full text of flagged URLs to find exactly which sentences in your article appear on those pages.
- Go to platform.parallel.ai
- Create a free account → API Keys → Create new key
- Add to
.env:PARALLEL_API_KEY=your-key
Cost: $0.001 per URL (free tier: 16,000 requests).
# Check a Google Doc (publicly shared)
checkapp "https://docs.google.com/document/d/XXXX/edit"
# Check a local Markdown or text file
checkapp ./my-article.md
# Check all articles in a directory
checkapp --batch ./articles/
# Export report to a file
checkapp ./my-article.md --output report.md
# Open the web dashboard
checkapp --ui
# Re-run setup wizard
checkapp --setup
# Show the last 20 checks from history
checkapp --history# Manage contexts (tone guide, brief, legal policy)
checkapp context add tone-guide ./brand-voice.md
checkapp context add brief ./campaign-brief.md
checkapp context add legal-policy ./legal-requirements.md
checkapp context list
checkapp context show tone-guide
checkapp context remove brief
# CI mode — exit 1 on fail (for CI/CD pipelines)
checkapp --ci ./my-article.md
# JSON output — structured result for scripts and agents
checkapp --json ./my-article.md
# Fix flagged sentences with AI-suggested rewrites
checkapp --fix ./my-article.md
# MCP server — for Claude Code / Cursor / Windsurf
checkapp --mcpGoogle Docs: Share → Change to "Anyone with the link" → Viewer → Done.
Article input (Google Doc URL or local .md/.txt)
│
▼
┌───────────────────────────────────────┐
│ Article fetch (gdoc.ts) │
│ Google Docs export URL / local file │
└───────────────────┬───────────────────┘
│
┌───────────┼───────────────────┐
▼ ▼ ▼ (all parallel)
┌──────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Plagiarism │ │ AI Detect │ │ SEO (offline) │ …
│ (Copyscape) │ │ (Copyscape) │ │ word/heading/ │
└──────┬───────┘ └──────┬───────┘ │ readability │
│ │ └────────┬────────┘
└────────────────┴──────────────────┘
│
▼
┌────────────────────┐
│ SkillRegistry │
│ aggregates all │
│ results │
└─────────┬──────────┘
│
┌───────────┼────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────────────┐
│ Terminal │ │ SQLite │ │ HTML Report │
│ report │ │ history │ │ (self-contained)│
│ (Ink UI) │ │ .db │ │ opens in browser│
└──────────────┘ └──────────┘ └──────────────────┘
CheckApp includes a local web dashboard for browsing check history, running new checks, and managing skills and settings from the browser.
Start the dashboard:
# Via CLI flag
checkapp --ui
# Or directly from source
cd dashboard && bun run devThe dashboard runs at http://localhost:3000 and includes:
| Page | Description |
|---|---|
| Overview | Total checks, average scores, cost chart, verdict distribution |
| Reports | Browse and search check history, view full report details |
| Run Check | Paste text or URL, attach tags, run a check from the browser |
| Skills | Toggle skills on/off, view engine labels and API key status |
| Settings | Manage API keys, configure thresholds per skill |
| Docs | In-app onboarding, skill reference, score explanations |
The dashboard also exposes a JSON API for programmatic access. See docs/api.md for the full reference.
CheckApp works with AI agents via MCP tools or CLI. See AGENTS.md for the full integration guide.
Approximate cost per 800-word article check with all skills enabled:
| Skill | Engine | Cost |
|---|---|---|
| Plagiarism | Copyscape / Gemini Grounded Plagiarism | ~$0.09 / ~$0.04 estimate |
| AI Detection | Copyscape / Gemini | ~$0.03 / ~$0.01 estimate |
| SEO | Offline | free |
| Fact Check | Basic: Exa + configured LLM; Standard: Gemini Grounded | ~$0.04 / ~$0.16 |
| Tone of Voice | Configured LLM | ~$0.002 |
| Legal Risk | Configured LLM | ~$0.002 |
| Content Summary | Configured LLM | ~$0.002 |
| Brief Matching | Configured LLM | ~$0.002 |
| Content Purpose | Configured LLM | ~$0.002 |
| Passage evidence (optional) | Parallel AI | ~$0.003 |
| Total — all skills | ~$0.22 |
For a team publishing 100 articles per month: ~$22/month in API costs.
Enable or disable skills via the skills section of ~/.checkapp/config.json, or set them directly in your .env:
{
"skills": {
"plagiarism": true,
"aiDetection": true,
"seo": true,
"factCheck": true,
"tone": true,
"legal": true,
"summary": true,
"brief": true,
"purpose": true
}
}Skills that require unconfigured API keys skip gracefully with a skipped verdict. Skipped skills are excluded from score averages; if every enabled skill is skipped, the overall score is reported as N/A.
Override the default pass/warn/fail cutoffs for any skill in ~/.checkapp/config.json:
{
"thresholds": {
"seo": { "pass": 80, "warn": 60 },
"plagiarism": { "pass": 90, "warn": 70 }
}
}Scores >= pass result in a PASS verdict, scores >= warn result in WARN, and anything below warn is FAIL. Only skills listed in thresholds are overridden; all others use their built-in defaults.
CheckApp is tuned and tested for English and Hebrew. Other scripts (Arabic, Chinese, Japanese, Korean, Russian, etc.) are detected, but SEO tokenization, passage-matching (MIN_WORDS uses whitespace tokens), and sentence splitting are NOT tuned for them. Non-Latin / non-Hebrew content may produce approximate or misleading scores. Full CJK + Arabic support is planned for Phase 8.
The tone skill compares your article against a brand voice document — a .md file that describes how your brand writes. Example:
# Brand Voice Guide
- Write in second person ("you", "your")
- Conversational and warm, never clinical
- Avoid jargon and acronyms without explanation
- Short paragraphs — max 3 sentences
- Use contractions (it's, we're) — formal language feels distantSet the path: TONE_GUIDE_FILE=/path/to/brand-voice.md
- Readability score (Flesch-Kincaid)
--output report.md/--output report.htmlexport- Local web dashboard (
checkapp --ui) with overview, reports, check, skills, settings, docs pages - Tags, search, and JSON API
- Dark mode
- Context system — tone guides, briefs, legal policies stored in SQLite, managed via CLI or dashboard
- MCP server — 8 tools for AI agent integration (Claude Code, Cursor, Windsurf)
- Brief Matching skill — checks article against uploaded content brief
- CI mode (
--ci) — exit 1 on fail for CI/CD pipelines - JSON output (
--json) — structured output for scripts and agents - Headless check engine (
runCheckHeadless()) for MCP, CI, and dashboard API - AGENTS.md — full agent integration guide
- Dashboard Contexts page — upload, edit, preview contexts in browser
- OpenRouter integration — one API key for 200+ models, configurable via
LLM_PROVIDERenv var - Language support — tuned for English and Hebrew; other scripts detected but not optimized (CJK + Arabic in Phase 8)
- Tone improvement suggestions — rewrite suggestions in brand voice alongside violation flags
- Citation recommendations — verified fact-check claims include source domain citations
- Content purpose detection — classifies article type with purpose-specific recommendations
- Regenerate/fix engine —
--fixflag generates AI-suggested rewrites for flagged sentences
- Private index — register your own published articles with Copyscape so future checks exclude them from results
- Second AI detector — Originality.ai integration for cross-validation of AI detection
- CMS integrations — WordPress plugin, Ghost webhook, Webflow integration
- Team dashboard — multi-user web interface with per-writer stats and trends
- Custom skill packages — publish your own validator as an npm package, install with
checkapp skill add <package> - Ranking score — overall article quality score combining all skill signals, calibrated for SEO impact
- Additional LLM providers — OpenAI (GPT-4o-mini) configurable per user (Google Gemini already ships in 1.3.0 via the Standard + Deep Audit fact-check tiers)
| Layer | Technology |
|---|---|
| Runtime & compiler | Bun |
| Terminal UI | Ink — React for CLIs |
| Plagiarism + AI detection | Copyscape Premium API; Gemini Grounded Plagiarism is available as a selectable/fallback plagiarism provider |
| SEO analysis | Offline — custom metrics engine |
| Fact checking | Exa AI search + MiniMax M2.7 or Claude Haiku assessment |
| Tone + Legal | MiniMax M2.7 (preferred) or Claude Haiku (fallback) |
| Passage evidence | Parallel Extract API |
| Article fetch | Google Docs public export URL or local file |
| History database | bun:sqlite (CLI) / better-sqlite3 (dashboard) — stored at ~/.checkapp/history.db |
| HTML reports | Self-contained inline HTML/CSS — no external dependencies |
| Language | TypeScript strict |
checkapp/
├── src/
│ ├── index.tsx # Entry point — routes to setup, history, check, or --ui
│ ├── setup.tsx # First-run credential wizard (Ink UI)
│ ├── check.tsx # Check flow UI — SkillRegistry + HTML report + SQLite
│ ├── gdoc.ts # Input reader — Google Docs or local .md/.txt
│ ├── config.ts # Config: credentials, skill toggles
│ ├── db.ts # SQLite history — openDb, insertCheck, queryRecent
│ ├── report.ts # Self-contained HTML report generator
│ ├── copyscape.ts # Copyscape plagiarism API client + XML parser
│ ├── aidetector.ts # Copyscape AI detector API client + XML parser
│ ├── parallel.ts # Parallel Extract API client
│ ├── passage.ts # Passage matcher — finds copied sentences
│ ├── batch.ts # Batch checking — runs all .md/.txt files in a directory
│ ├── checker.ts # Headless check engine — runCheckHeadless() for MCP/CI/API
│ ├── regenerate.ts # Regenerate/fix engine — AI rewrites for flagged sentences
│ ├── mcp-server.ts # MCP server — 8 tools for agent integration
│ ├── thresholds.ts # Configurable pass/warn/fail score cutoffs
│ ├── language.ts # Language detection — English, Hebrew, Arabic, Chinese, Japanese, Korean
│ └── skills/
│ ├── types.ts # Skill interface, SkillResult, Finding types
│ ├── registry.ts # SkillRegistry — parallel execution, error isolation
│ ├── plagiarism.ts # PlagiarismSkill — wraps copyscape.ts
│ ├── aidetection.ts # AiDetectionSkill — wraps aidetector.ts
│ ├── seo.ts # SeoSkill — offline word/heading/readability check
│ ├── factcheck.ts # FactCheckSkill — Exa search + Claude assessment
│ ├── tone.ts # ToneSkill — Claude brand voice validator
│ ├── legal.ts # LegalSkill — Claude legal risk scanner
│ ├── summary.ts # SummarySkill — topic, argument, audience, tone analysis
│ ├── brief.ts # BriefSkill — checks article against content brief
│ ├── purpose.ts # PurposeSkill — detects article type with recommendations
│ └── llm.ts # Shared LLM client factory for MiniMax/Claude/OpenRouter
├── dashboard/ # Local web dashboard (Next.js)
│ ├── src/app/ # Pages: overview, reports, check, skills, settings, docs
│ ├── src/app/api/ # JSON API routes
│ └── src/lib/ # Shared DB, config, and utility modules
├── docs/
│ ├── api.md # Dashboard API reference
│ ├── features.md # Full feature list
│ ├── custom-skills.md # Custom skill authoring guide
│ └── ROADMAP-IDEAS.md # Roadmap and future ideas
├── demo/
│ ├── english-demo.md # English article with Wikipedia passages (33% — REWRITE)
│ ├── hebrew-demo.md # Hebrew article with Hebrew Wikipedia passages (39% — REWRITE)
│ └── superpharm-demo.md # Hebrew article with Ynet sentences (33% — REWRITE)
├── build.sh # Compiles four platform binaries to dist/
├── package.json
└── README.md
Add any validator by creating a class that implements the Skill interface:
// src/skills/my-skill.ts
import type { Skill, SkillResult } from "./types.ts";
import type { Config } from "../config.ts";
export class MySkill implements Skill {
readonly id = "my-skill";
readonly name = "My Custom Check";
async run(text: string, config: Config): Promise<SkillResult> {
// your logic here
return {
skillId: this.id,
name: this.name,
score: 85, // 0–100
verdict: "pass", // "pass" | "warn" | "fail"
summary: "All good",
findings: [], // Array of { severity, text, quote? }
costUsd: 0,
};
}
}Then add it to the allSkills array in src/check.tsx and wire the toggle in src/config.ts.
See docs/custom-skills.md for the full guide with examples.
- API Reference — all dashboard JSON endpoints with curl examples
- Feature List — complete feature inventory by category
- Custom Skills Guide — how to write your own skill
- Roadmap — planned features by phase
Requires Bun.
git clone https://github.com/sharonds/checkapp
cd checkapp
bun install
# Run with a local file
bun src/index.tsx ./demo/english-demo.md
# View check history
bun src/index.tsx --history
# Run tests
bun test
# End-to-end tests (mocked providers, real Next.js dashboard + CLI + MCP)
bun run test:e2e:browser
# Build all platform binaries
bash build.shEnvironment variables (create a .env file in the project root):
COPYSCAPE_USER=your-username
COPYSCAPE_KEY=your-api-key
PARALLEL_API_KEY=your-parallel-key # optional
EXA_API_KEY=your-exa-key # optional — enables fact check
MINIMAX_API_KEY=your-minimax-key # optional — preferred LLM for fact check, tone, legal
ANTHROPIC_API_KEY=your-anthropic-key # optional — fallback LLM if MINIMAX_API_KEY not set
OPENROUTER_API_KEY=your-openrouter-key # optional — one key for 200+ models
LLM_PROVIDER=minimax # optional — minimax (default), anthropic, or openrouter
TONE_GUIDE_FILE=/path/to/voice.md # optional — enables tone of voice skill- Credentials are stored locally only at
~/.checkapp/config.json, or read from environment variables — never stored remotely - Article text is sent to Copyscape (plagiarism + AI detection), optionally to Gemini (AI detection, grounded plagiarism, and grounded fact-check tiers), Parallel AI (source page fetching), Exa AI (fact checking), and MiniMax or Anthropic (fact check, tone, legal) — all over HTTPS
- The HTML report and SQLite database are stored locally in the current directory and
~/.checkapp/ - No analytics, no telemetry, no logging
See CONTRIBUTING.md for guidelines. Issues and PRs welcome.
Built by Sharon Sciammas — full-stack developer and AI automation specialist based in the Netherlands. Sharon builds AI-powered SaaS products including event management platforms, marketing automation pipelines, and CRM infrastructure for AI agents.
This tool was built as part of a content quality pipeline for agencies using AI-generated marketing content.