Skip to main content
Glama

AppLedger honest check

Honest security feedback, in plain language, for apps people build with AI tools such as Claude Code, Codex, Cursor and Lovable.

AppLedger checks your app folder with independent scanners and explains what they find in everyday words: what is wrong, why it matters, and what to do. It also writes a fix request you can hand straight to the AI tool that built the app, then checks again.

What it checks

Scanner

Finds

Trivy

Leaked passwords and keys, outdated libraries with known security problems, risky container setup

Opengrep

Dangerous code patterns: SQL injection, command injection, unsafe data loading, debug mode left on

SonarQube (optional, local mode)

Code quality and more security hotspots, if you already run a SonarQube server

Each run produces, in <your-app>/.appledger/:

  • report.html: a score, who may use the app right now (only you, your team, the whole company), and every problem in plain words

  • fix-prompt.md: a ready-made fix request for your coding agent

  • findings.json: the same findings for tools and dashboards

Related MCP server: supership-scan

Two ways to run

Mode

What you install

Where your code goes

Hosted (default)

Only this package

Source files Git would commit are zipped, sent over HTTPS to appledger.net, scanned and deleted right after. Secret files are never sent. You confirm before the first upload of each folder

Local (--local or APPLEDGER_MODE=local)

Also Trivy, Opengrep and the Opengrep rules

Stays on your computer. With a connection key, only a summary goes to your dashboard (see below); --no-dashboard skips even that

What gets uploaded in hosted mode

  • Sent: files Git would commit (git ls-files, including new files that aren't ignored). Outside a Git repository, .gitignore is still honoured.

  • Never sent: .env and .env.* (except .env.example, .env.sample, .env.template), *.pem, *.key, *.p12, *.pfx, SSH keys, .npmrc, .pypirc, .netrc, *credentials*.json, service-account*.json, secrets.*, the folders cert, certs, secrets, .ssh and .aws, .claude/settings.local.json, Terraform state, password files, Ansible Vault files, Kubernetes/Helm secret manifests, certificates and similar (full list in src/appledger/uploadpolicy.py). The server drops such files again as a second safety net.

  • Skipped: dependencies, build output, media, documents and data files (CSV, spreadsheets, slides, SQL, logs, data dumps) and files over 1 MB.

If a secret file is committed to Git or not ignored, the check reports it as a problem by file name. Its content is never read or sent.

See exactly what would be sent, and what is left out and why, without uploading anything:

python -m appledger path/to/your-app --list-files

The first hosted check of a folder asks you to confirm. In scripts and scheduled runs, pass --yes. If the code belongs to your employer or a client, make sure you're allowed to upload it, or use local mode.

Install

Claude Code plugin (recommended: adds the guided check-my-app skill):

claude plugin marketplace add contentasoftware/appledger
claude plugin install appledger@appledger

In the Claude Code desktop app, add the marketplace contentasoftware/appledger in the plugin settings instead. Start a new session, then ask: "Is my app safe to share?" or "Add this app to AppLedger".

MCP server only (needs uv):

claude mcp add appledger -- uvx --from appledger appledger-mcp

Command line:

pip install appledger
python -m appledger path/to/your-app

Step-by-step guide with troubleshooting: https://appledger.net/docs/

Version 0.2.0 (upload preview, consent, secret-file exclusion, scheduling) is being released to PyPI; until then pip install appledger gets 0.1.x.

Company dashboard

Create a free account at appledger.net to keep every app your people check in one ledger: owner, grade, score trend, who may use it and which AI tool built it. Create a connection key under "Connect a computer", then save it on each computer:

python -m appledger --connect al_your_key

Or tell Claude: "Connect AppLedger with this key: al_…". The key is saved in ~/.appledger/key; APPLEDGER_KEY overrides it and --disconnect removes it.

From then on each check also saves a summary to your dashboard: the app's name, score, grade, problem counts, the list of problems found (level and short title, up to 60; never code or file paths), and the scanners used. Never the code.

Not connected yet? From 0.2.3, a hosted check from a computer without a key ends with a save link, also shown in report.html:

Save this result to a free AppLedger ledger (link works for 24 hours): https://appledger.net/app/claim.php?t=...

Open it, create a free account or log in, and the check is in your ledger; the page then offers a key for that computer. Until the link is used, the service keeps only the check's summary (app name, score, the problems' levels and titles; never code), for up to 24 hours. A link works once; --no-dashboard turns it off.

You can also add an app in the web app with Add app: register it without code, or upload a zip to check it in the browser (the zip is scanned and deleted the same way).

Scheduled checks

python -m appledger path/to/your-app --schedule weekly --yes   # or daily
python -m appledger --schedules                                 # list
python -m appledger path/to/your-app --schedule off             # stop

Uses Windows Task Scheduler on Windows and cron on macOS and Linux. Hosted scheduled checks need the one-time --yes consent; add --local to schedule local checks instead. --quiet prints one line per check.

Local mode setup

  1. Trivy: winget install AquaSecurity.Trivy (Windows) or brew install trivy (Mac)

  2. Opengrep: download from the releases page and put it on your PATH

  3. Rules: git clone --depth 1 https://github.com/opengrep/opengrep-rules.git ~/.appledger/opengrep-rules

  4. Check: python -m appledger --doctor

Repository layout

Path

What

src/appledger/scanner.py

Scanners, plain-language translation, report and fix request

src/appledger/client.py

Picks the files to send (honouring .gitignore) and sends them to the hosted service

src/appledger/uploadpolicy.py

The full list of secret files that are never uploaded, used by client and server

src/appledger/service.py

Server side: unpacks an upload safely and scans it

src/appledger/server.py

Local MCP server used by the plugin

plugin/

Claude Code / Codex plugin with the check-my-app skill

tests/mcp_smoke.py

Calls every MCP tool like an agent would

License

MIT. The Opengrep community rules used by the scanner have their own license (Commons Clause); check it before using them in a paid service.

Available Tools

5 tools
check_appA
Idempotent

Scan an app folder with independent security scanners and explain the findings in plain language.

Hosted mode sends the project's files over HTTPS to the AppLedger scanning service, where they are scanned with Trivy and Opengrep and deleted right after. Only files git would commit are sent; secrets files (.env, keys, certificates, local settings), dependencies, media and files over 1 MB never are. The first check of a folder returns needs_confirmation and an upload_preview instead of uploading: show the preview to the user and ask. Only after they agree, call again with confirm_upload=true; later checks of that folder don't ask again. Results are written to /.appledger (report.html, fix-prompt.md, findings.json). Returns the score (0-100), grade, who may use the app right now, and every finding with why it matters and what to do. A hosted check from a computer that isn't connected to a dashboard also returns save_link: a link (valid 24 hours, works once) that saves this result to a free AppLedger ledger. Offer it to the user once, in one line.

Args: path: absolute path to the app's folder. app_name: a friendly name for the app, shown in the report. confirm_upload: true only after the user agreed to send this folder's files to appledger.net. save_to_dashboard: false to keep this check out of the user's AppLedger dashboard.

NameRequiredDescriptionDefault
pathYes
app_nameNo
confirm_uploadNo
save_to_dashboardNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: files are sent over HTTPS to appledger.net, scanned with Trivy and Opengrep, deleted right after, and only git-committable files under 1 MB are sent (with explicit exclusions). It also discloses the side effects — results written to <path>/.appledger — and the two-step consent gate, which the openWorldHint/destructiveHint annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then the upload/consent flow, then outputs, then args — a sensible order with no filler. It is long, and the save_link instructions are arguably operational guidance rather than tool description, but nearly every sentence adds information the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description states the return contents (score 0-100, grade, who may use the app, findings with why and remedy), the on-disk artifacts, and the conditional save_link with its 24-hour single-use constraint. Nothing material is missing for a tool with this much side-effect surface.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full parameter burden, and it does: path is the absolute folder path, app_name is shown in the report, confirm_upload is only true after user consent to upload to appledger.net, save_to_dashboard=false excludes the check from the dashboard. Each parameter gets meaning beyond its bare name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ("Scan an app folder with independent security scanners") and states the secondary value (plain-language explanation of findings). It is clearly distinct from siblings like preview_upload or get_fix_prompt, which are narrower steps in the same workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit procedural rule: the first check returns needs_confirmation, show the preview and ask, then call again with confirm_upload=true; later checks don't ask. Also says to offer save_link once, in one line. It never names the sibling tools directly as alternatives, so a 5 isn't warranted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_dashboardA
Idempotent

Save a connection key so future checks from this computer appear in the user's AppLedger dashboard.

The user creates the key (it starts with al_) at https://appledger.net/app/ under "Connect a computer". The key is stored in ~/.appledger/key. Only call this with a key the user gave you.

Args: key: the connection key, starting with al_.

NameRequiredDescriptionDefault
keyYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read-only, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuinely new behavioral context: what the write accomplishes downstream (subsequent checks get attributed to the dashboard), where the credential is persisted (~/.appledger/key), and a trust constraint on provenance. It still doesn't say what the call returns on success or failure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then acquisition instructions, then an Args block — well structured and short. Minor redundancy: the al_ prefix is stated twice (body and Args), which is the only real waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

One required param, no output schema, annotations covering idempotency and side-effect class — the description supplies everything an agent needs to decide to call it and how to source the argument. Only the return value/success signal is unaddressed, which is a small gap given no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the schema only says "key: string" — so the description carries the burden and does so well: it gives the prefix format (al_), where the user obtains the key, and a hard provenance rule. It stops short of validation details (length, malformed-key behavior), so not a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ("Save a connection key") and states the concrete effect: future checks from this computer appear in the user's AppLedger dashboard. It doesn't reference any sibling by name, but the purpose is unmistakable and doesn't overlap with preview_upload, check_app, or scanner_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Only call this with a key the user gave you" is an explicit when-not/constraint, and the preamble implies the triggering context (the user wants their checks visible in the dashboard). It doesn't spell out a full when-to-use scenario or name alternatives, but the exclusion is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_fix_promptA
Read-only

Return the fix request written by the last check_app run for this app folder.

The fix request lists every problem in order, where it is, and the expected fix, plus rules such as never putting keys in code and never removing features to silence a warning.

Args: path: absolute path to the app's folder (the same path given to check_app).

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful content about what the returned text contains (ordered problems, locations, expected fixes, plus guardrail rules), but says nothing about behavior when no prior run exists or how results are scoped beyond the folder.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core return value, then a short elaboration of contents, then a compact Args block. The clause about never putting keys in code and never removing features is illustrative rather than essential, but it is short enough to earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety and an output schema covering the return shape, the description only needs to establish the dependency on check_app and the path contract, which it does. The one gap is the no-prior-run scenario, which an agent would want to know before calling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the load — it explains the single parameter is an absolute path to the app's folder and must match the path used with check_app. That is meaningful semantics beyond the bare 'string' schema, though the absolute-path requirement is repeated rather than expanded with examples.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — returns the fix request written by the last check_app run for a given app folder — and names the sibling that produces it. An agent can immediately distinguish this from check_app, scanner_status, or preview_upload.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies it is used after check_app and enforces the linkage by requiring 'the same path given to check_app.' It does not explicitly say what to do if no check_app run has happened, nor exclude any cases, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_uploadA
Read-only

List the files a hosted check of this folder would send to appledger.net, and what stays behind.

Nothing is sent. In a git repository only files git tracks or would commit count; elsewhere the folder's .gitignore files decide. Secrets files, media, files over 1 MB, dependencies and build output are always left out. Also lists secrets files git would commit, which the check reports as problems.

Args: path: absolute path to the app's folder.

NameRequiredDescriptionDefault
pathYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnly/destructive/openWorld hints; the description goes well beyond by stating nothing is transmitted, explaining git-tracked vs .gitignore-driven selection, enumerating the always-excluded categories (secrets, media, >1 MB, dependencies, build output), and noting that committable secrets files surface as problems. This is exactly the safety-adjacent context an agent needs before a check.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by the dry-run caveat, the inclusion/exclusion rules, and a compact Args block. The exclusion list is dense but each item earns its place; nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one parameter, no output schema, and read-only annotations, the description covers what is listed, what is omitted, and the secrets-problem reporting. It stops short of describing the shape of the returned lists, but the semantic content is otherwise complete for a preview tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the lone parameter, and it does: 'path: absolute path to the app's folder' specifies both the format (absolute) and the target (the app's folder), beyond the bare 'string' type in the schema. Modest but sufficient compensation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

A specific verb ('List') plus a precisely scoped resource ('the files a hosted check of this folder would send to appledger.net, and what stays behind'), and 'Nothing is sent' clarifies the dry-run nature. The contrast with the actual hosted check is implied but the sibling check_app is never named, so differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The first sentence establishes clear context for when to call it: to preview what a hosted check would upload. There are no explicit exclusions or a named alternative ('use this instead of check_app when...'), which keeps it below a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scanner_statusA
Read-only

Show whether the AppLedger scanning service is reachable (or, in local mode, which scanners are installed on this computer), and how to fix anything that is missing.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), so the bar is lower, and the description still adds real context: the tool behaves differently in local mode (enumerates installed scanners) versus remote mode (probes service reachability), and it returns remediation guidance. It stops short of saying how the mode is determined or what the response looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence that front-loads the primary outcome and parenthesizes the mode-specific variant. No filler, nothing redundant with the annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-param tool with no output schema, the description carries the burden of describing returns and it does: reachability status, enumerated local scanners, and fix guidance for anything missing. Enough for an agent to know what signals to expect and how to act on them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so there is nothing to disambiguate; the baseline for a no-arg tool applies. The description correctly describes a parameterless probe rather than implying hidden configuration options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb ("Show") and a concrete resource (reachability of the AppLedger scanning service, or installed scanners in local mode). The dual-mode framing is clear, but the description never distinguishes this tool from siblings like check_app or get_fix_prompt, so an agent can't route on the text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage as a diagnostic/preflight step ("how to fix anything that is missing") but no explicit when-to-use, no exclusions, and no mention of when a caller should prefer check_app or get_fix_prompt. The agent must infer placement in the workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.2.5
    • First observedcheck_app
    • First observedconnect_dashboard
    • First observedget_fix_prompt
    • First observedpreview_upload
    • First observedscanner_status

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct action: preview, scan, retrieve fix request, connect dashboard, and check service status. The only real overlap is between preview_upload and check_app, which itself returns an upload_preview on first run; the descriptions explain the difference, but an agent may still wonder which to call first.

Naming Consistency4/5

All names are snake_case and mostly follow a verb_noun pattern (preview_upload, get_fix_prompt, connect_dashboard, check_app). scanner_status is noun-first rather than a verb, a minor deviation but still clear.

Tool Count5/5

Five tools is well-scoped for a security-check service: scan, preview, retrieve fix guidance, connect, and status. Nothing feels redundant or missing from the count perspective.

Completeness4/5

The scan lifecycle is covered: preview what's sent, run the check, get the fix prompt, verify the scanner, and connect to the dashboard. Minor gaps exist — no way to disconnect/revoke a saved key or list prior check results beyond the on-disk files.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Automatically detects security vulnerabilities in AI-generated code, scanning for hardcoded secrets, injection flaws, XSS, weak cryptography, authentication issues, path traversal, and vulnerable dependencies across JavaScript, Python, Java, and Go.
    14 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Predeploy security scanner for AI-generated code. 80+ vulnerability patterns across secrets, auth, injection, config, Supabase, and logging. Runs locally, code never leaves your machine. Optional x402 witnessed attestation.
    94 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    AI-powered security scanner for Python projects and GitHub repositories. Detects vulnerabilities, secrets, and provides AI risk assessment.
    11
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Local-first security check for AI coding agents — finds hardcoded secrets, exposed .env files, git-history leaks and vulnerable dependencies (OSV), entirely on your machine. Ask your agent "is this safe to ship?" and get a Launch Readiness score with a fix for every finding.
    MIT