Skip to main content
Glama

APSA

Evidence-first security audits for Android and iOS.

English · 한국어

This English README is the source of truth. The Korean README follows it.

APSA 1.6 analysis extensions. This version adds bounded native cross-file flow and input-bound path guards, JS/TS/Dart candidates, recorded Gradle variant selection, OSV batching and transmission exclusions, authenticated runtime evidence, AAB scalar resources, detached CMS consistency and paired verification. See scope, options and remaining limits and the new labeled synthetic results. The remaining follow-up adds explicit .apks device selection, IPA sparse-page/resource seals and supplied-anchor chain checks, and a typed runtime recorder exercised with fresh synthetic app models. The synthetic bundletool selection checks pass; installed split merging, Apple signer identity and physical-device validation remain outside verified scope. Fresh comparator samples remain partial and do not establish accuracy rankings. iOS OS URL delivery is still under validation; callback dispatch alone is not proof of app acquisition or backend revocation. The five validation gates record new compiler, signature-mutation and installed iOS simulator evidence, along with the separate package, comparator, bundletool and backend measurement scopes. See 1.6 release validation for the current candidate gates and upgrade effects, including the changed MCP tool manifest.

APSA 1.6 large-input follow-up. Rule version: 2026.10.15.apsa.160. Input staging and AST analysis share code priorities and round-robin scheduling within inferred module groups. Lock inventories follow app code; ambiguous *Tests/ and plain Frameworks/ directories retain production priority. Reports record module omissions, comparisons expose input completeness, and the Action summary shows staging omissions. Partial fingerprints remain SBOM metadata instead of application hashes. See scope and validation.

APSA 1.6 review fixes. Bounded device-spec metadata, per-file partial reasons, text/compiled hybrid coverage, explicit signature binding scope, portable source comparisons and exact package-content checks are documented in strengthening scope and evidence limits. Synthetic acquisition adapters are source-test helpers and are excluded from the installed wheel.

APSA helps developers and security teams audit their own mobile apps. It inspects source code and APK/AAB/IPA builds, correlates public vulnerability information, and keeps evidence, coverage, and report history together. Use the CLI, terminal UI, or the same audit engine through MCP and reusable skills.

Pronounced “ap-sah”; Korean name 앱사. The name connects “app + audit” with App Security Audit. APSA combines the earlier Quaygate lint engine and Mobile Audit workflows in one package.

APSA 1.1 adds bounded model report pages, portable approved baselines, exported policy decisions, and explicit source module/configuration selection. See model and team workflows for the contract and release sequence for later analysis milestones.

Mixed unsupported source languages and truncated pattern results are incomplete. Declared Gradle versions remain candidates until resolved-build evidence is supplied. OS-CVE correlation reports a bounded recent window, so feed freshness alone cannot satisfy historical coverage.

APSA 1.2 adds AAB base-manifest/module DEX analysis, embedded IPA Mach-O metadata, bounded Objective-C .m candidates and parser OS isolation that is on by default where it can start. Every AAB audit stays partial, and embedded IPA metadata does not authenticate signatures. See analysis scope and limits and the independent holdout.

Upgrading from 1.1. With the default APSA_PARSER_SANDBOX=auto, the parser runs under macOS Seatbelt or Linux bubblewrap after an input-free activation probe succeeds. Without a backend, the report records parser_isolation.state: unavailable and parses with resource limits only. If the backend is present but cannot start (for example inside another sandbox or with blocked user namespaces), the report also records the attempted backend and probe reason and adds an inventory warning. required refuses such audits; off skips the backend. A parser failure after isolation has started aborts the audit without an unsandboxed retry. Dependencies declared only in a Gradle version catalog no longer receive CVE matches until build usage or resolved versions are supplied. New rules (AST-CRYPTO-ECB, AST-CRYPTO-WEAK-HASH, AST-SQL-CONCAT, OBJC-CRYPTO-WEAK-HASH, OBJC-WEBVIEW-UNTRUSTED-REQUEST) can add findings relative to existing 1.1 baselines.

APSA 1.3 links Gradle version-catalog aliases to the shipped dependency configurations that use them and reads application-module gradle.lockfile coordinates as resolved versions. It also decodes AAB feature-module manifests, recomputes Mach-O CodeDirectory page and entitlement hashes without authenticating the signature, adapts more Swift and Objective-C syntax, and can backfill an explicit range of Android security bulletins with SoC vendor and vendor patch-level context. See the dependency evidence results, the independent source pairs and analysis scope and limits.

Upgrading from 1.2.

  • Catalog aliases referenced from shipped configurations become declared candidates and can receive CVE matches again; unreferenced, test-only and build-tooling aliases stay unresolved. Application-module lockfile coordinates are exact, so their matches are version-affected, and the default policy fails on high and critical ones; other modules' lockfile coordinates stay declared candidates. A declared candidate that every shipping application resolved is superseded and leaves CVE correlation. Partial inputs keep every candidate, and with unparsed project references only an application's own declarations can be superseded.

  • Lockfile assumptions: APSA does not check that dependency locking is enabled or that the lockfile is current, and it merges the release runtime classpaths of every application module (flavors and wear, TV or automotive apps). --source-module scans only that module's directory, so a root version catalog and library-module declarations outside it are not read.

  • Baselines and waivers: a lockfile-resolved finding has a new location (gradle.lockfile) and status, so only_new treats it as new and waivers for the old finding ID no longer match. Re-approve baselines after upgrading.

  • --online sends dependency names and versions to OSV, including shipped catalog aliases, transitive lockfile coordinates and private group IDs unless excluded. The default auto mode uses legacy queries for at most 100 eligible unique package-version coordinates and batch queries for larger inventories. Default online budgets are 1000 packages, 100 packages per batch and 2000 OSV requests, including pagination and vulnerability-record lookups. scan --online --osv-query-mode legacy retains the 100-package limit; --osv-query-mode batch explicitly selects batching with the default budgets. Use scan's --osv-exclude-ecosystem, --osv-exclude-name or --osv-exclude-coordinate for local transmission exclusions. Excluded dependencies are never sent or marked checked, even with a prior cached result. Unchecked, unresolved, unsupported or excluded dependencies keep online coverage incomplete; a fresh result for one package does not complete the rest.

  • IPA reports gain BINARY-IOS-CODE-INTEGRITY. Consistent hashes do not prove authenticity, because a modified binary that was re-signed is consistent. A mismatch adds a warning, not a finding; App Store encrypted and unsigned executables stay not-run.

  • intel sync refreshes only the recent Android bulletin window; use intel backfill for older months. Records cached by 1.2 derive their vendor scope from the component name; entries outside chipset and kernel sections use the platform patch level only. AAB feature-module installation stays unknown.

  • Adapted Swift and Objective-C files stay partial, and an Objective-C function overlapping a normalized preprocessor conditional is skipped as uncertain. Unmodified 1.2 skills upgrade with apsa skill install.

APSA 1.4 is easier to put in front of developers and coding agents. A GitHub Action uploads SARIF to code scanning with stable fingerprints, security severity, MASWE tags and evidence status; every report carries an OWASP MASWE v1.0 coverage matrix that names the weaknesses APSA did not assess; and the MCP server is packaged for the MCP Registry and as a Claude Code plugin, with a documented MCP security model.

Upgrading from 1.3.

  • SARIF exports now list a descriptor for every rule with results (help, security-severity, precision, MASVS/MASWE tags), add partialFingerprints from the finding identity, and report not-run and partial coverage as tool execution notifications. Candidate findings are warning rather than error and their rules are tagged candidate. --sarif-root makes locations repository-relative; URIs are percent-encoded, and APK/AAB/IPA members and files outside the target appear as logical locations on the target. Code scanning may therefore show re-keyed alerts once.

  • New source checks (exported components, backup, targetSdk, privacy manifests, ATS exceptions, hard-coded secrets, insecure randomness, trust-all TLS, external storage, Java deserialization, more SQL sinks, mutable PendingIntent) add findings and coverage entries. A policy with required_rules or a severity gate can fail where 1.3 passed; review the first 1.4 report before tightening gates.

  • Rule metadata gains MASWE v1.0 identifiers; model context and capabilities gain a maswe section, and Markdown reports a MASWE coverage table. Reports derived by reports ingest add external_inputs and findings with origin: external; existing fields keep their meaning.

  • The MCP server adds verify_finding, specs_validate, reports_ingest_sarif, reports_checklist and reports_history. tool_manifest_sha256 now covers a normalized APSA-owned surface, so its value changes; update any pinned hash. Unmodified 1.3 skills upgrade with apsa skill install.

APSA 1.5 widens what a source scan looks for. New checks cover the OWASP MASWE weaknesses behind most MASTG demo misses: broken ciphers and implicit ECB, key material and IVs built from constants, short (512–1536-bit) RSA, DSA and DH key sizes and CryptoKit Insecure digests; biometric results not bound to a key, device-credential fallback and keys that survive new enrollment; TLS below 1.2, iOS connections outside App Transport Security, and user CAs or cleartext in the network security configuration; unverified App Links, intent redirection and implicit internal Intents; path traversal and keyed unarchiving without secure coding; and Safe Browsing turned off, UIWebView and WKWebView file access. On a blind holdout of 24 public vulnerable/fixed pairs labeled by MASWE weakness, APSA 1.5.0 found 7 of the 21 scored in-scope pairs at the labeled lines (Wilson 95% 17–55%). Two of the seven come from rules new in 1.5 and five from rules 1.4 already had; the fixed-side FP upper bound is 4 of 21, and a 22nd in-scope pair failed to scan. See the blind pair results and analysis scope and limits.

Upgrading from 1.4.

  • New rules add findings and coverage entries: AST-CRYPTO-WEAK-CIPHER, IOS-CRYPTO-WEAK-CIPHER, AST-CRYPTO-HARDCODED-KEY, AST-CRYPTO-STATIC-IV, SOURCE-WEAK-KEY-SIZE, SOURCE-BIOMETRIC-EVENT-BOUND, SOURCE-BIOMETRIC-FALLBACK, SOURCE-BIOMETRIC-ENROLLMENT, SOURCE-WEAK-TLS-VERSION, IOS-ATS-BYPASS-API, ANDROID-NSC-USER-CA, ANDROID-DEEPLINK-AUTOVERIFY, AST-INTENT-REDIRECTION, AST-IMPLICIT-INTENT, IOS-WEBVIEW-FILE-ACCESS, WEBVIEW-SAFE-BROWSING-OFF, IOS-UIWEBVIEW, AST-PATH-TRAVERSAL and IOS-INSECURE-UNARCHIVE. Candidates are not gated by default. The new configuration-confirmed findings (ANDROID-NSC-USER-CA, and ANDROID-CLEARTEXT from the network security configuration) count under the default allowed_statuses, but medium and low thresholds are off by default. Policies that gate candidates or medium/low findings, and only_new baselines, will see them.

  • The MASWE matrix changes: MASWE-0003, 0013, 0020, 0021 and 0022 leave not-assessed (they are not-run for APK and IPA, which these source checks do not read), and ANDROID-NSC-CONFIG adds coverage to MASWE-0026 and 0027.

  • Existing rules find more: AST-CRYPTO-ECB also reports a bare "AES" transformation (its title is now "AES in ECB mode is selected"; fingerprints are unchanged), AST-CRYPTO-WEAK-HASH reports CryptoKit Insecure.MD5 and Insecure.SHA1, AST-SQL-CONCAT reads SQLiteQueryBuilder.query, the groupBy/having/orderBy/limit arguments and nested exported providers, and SOURCE-INSECURE-RANDOM runs on Swift and Objective-C (its coverage on iOS-only trees changes from not-applicable to checked).

  • The AST engine now follows Kotlin let, also, use, apply, run and with lambdas, so every structural rule can report code inside them. A ?.let lambda, or one with return@, merges like a branch that may not run; a reassignment inside a lambda that always runs can now also remove a 1.4 finding. Other lambdas and Swift closures are still not analyzed.

  • ANDROID-CLEARTEXT also comes from the referenced network security configuration (configuration-confirmed, so code scanning rates it). The manifest's usesCleartextTraffic candidate is dropped when that configuration was parsed, minSdk is 24 or higher, and the configuration states cleartextTrafficPermitted or targetSdk is 28 or higher. Findings from a configuration that several source sets define are candidates.

  • New coverage states can make an audit incomplete: ANDROID-NSC-USER-CA and ANDROID-NSC-CONFIG are partial when a referenced configuration cannot be parsed, is missing from the scanned sources or is a build placeholder, and checks that stop at their match budget report partial. With the default fail_on_partial, such a scan fails the gate and cannot be exported as a baseline. Compiled AAB configurations are not-run.

  • Text rules no longer count binary XML from packages as checked, so WEBVIEW-SAFE-BROWSING-OFF is not-run on APKs. The rules resource may carry case_sensitive and once_per_file; inventory gains deep_links[].browsable and network_security_parsed. Unmodified 1.4 skills upgrade with apsa skill install; the MCP tool manifest hash is unchanged.

Upgrading from 1.5.0. 1.5.1 audits large source trees partially instead of refusing them and fixes a slowdown on Android translations.

  • A source tree over the text staging budgets (64 MiB, 12,000 files) no longer fails with an input-budget error (exit 1). Files are staged by kind: app code and configuration, other shipped text, localized or qualified Android res/values-* files, then tests. inventory.input_snapshot.omitted counts what was left out, and the audit is incomplete (exit 3). With the default fail_on_partial the gate still fails, and a partial report cannot become a baseline. The 100,000-entry and 64-level budgets also stop reading instead of refusing.

  • If app code, configuration or other shipped text is left out (app_scope_complete: false), not-applicable coverage becomes partial too and DEPENDENCY-CVE gains a partial entry (unless --sbom supplies the dependencies), so required rules cannot pass even with fail_on_partial = false.

  • SARIF from such an audit carries a warning notification and run.properties.inputSnapshot. A workflow with fail-on-incomplete: "false" now passes with a warning and uploads partial results where 1.5.0 failed; code scanning sees no results for omitted files. Scan a narrower path (one module per job, with its own category) for complete results. MCP report context gains input.input_snapshot.

  • In 1.5.0, strings.xml files with many escaped apostrophes (\'), common in French and Italian translations, made WEBVIEW-SAFE-BROWSING-OFF slow enough to hit the parser timeout (about 150 s for a 694 KiB file). XML files are now cleaned of <!-- --> comments only, so // in XML text no longer hides a match. Comment cleaning also stays linear on unterminated strings and comments; a /* with no closing */ after it is read as text.

  • Unmodified 1.5.0 skills upgrade with apsa skill install; the MCP tool manifest hash is unchanged.

What it checks

Area

Available checks

Source code

Java/Kotlin/Swift AST analysis; bounded Objective-C .m candidates; WebView and deep-link patterns; Manifest, Info.plist, storage, and dependency inspection, including Gradle catalog usage and application lockfiles; exported components, backup and targetSdk; Apple required-reason APIs against privacy manifests; known credential formats (masked); weak random for security values; mutable implicit PendingIntents; trust-all TrustManagers and hostname verifiers, unevaluated iOS server trust and weakened ATS exception domains; external storage writes; Java deserialization; (1.5) broken ciphers, constant keys and IVs, short RSA keys, biometric binding and fallback, TLS versions, iOS APIs outside ATS, network security configuration, App Links, intent redirection and implicit Intents, path traversal, keyed unarchiving, Safe Browsing, UIWebView and WKWebView file access

Android builds

DEX calls and constant flow; AAB base and feature-module manifests and module DEX (always partial); resources and network configuration; exported components/providers; signing-block and v1 certificate evidence; ELF hardening

iOS builds

Mach-O headers, including embedded framework/extension metadata; CodeDirectory page and entitlement hash integrity (not signature authentication); limited entitlement/configuration checks (embedded XML entitlements, ATS exceptions, provisioning indicators); PIE, canary, and string evidence

Public intelligence

Apple/Android advisories with bounded Android bulletin backfill, CVE, CISA KEV, OWASP guidance, and OSV dependency correlation

Reports and CI

SQLite history, comparison and reassessment, JSON/Markdown/SARIF export, coverage requirements, and expiring waivers

Runtime

Prepared scenarios for owned Android test apps and iOS simulator apps; physical iOS devices are unsupported

Model integration

stdio MCP tools/resources and packaged skills, without a required model provider or LLM API key

Findings distinguish candidate, configuration-confirmed, version-affected, and runtime-confirmed evidence. coverage and warnings show what actually ran. A signing block does not prove signature authenticity, and an affected dependency version does not prove exploitability. A scan with no findings does not establish that the whole app is secure.

OWASP mappings describe relevant checks; APSA does not certify MASVS compliance or implement every MASTG test. Public advisories cannot reveal undisclosed zero-days. App files alone cannot establish a device's OS patch state. See OWASP coverage and the support matrix, both currently in Korean, for tested scope and limits.

Related MCP server: apk-docforge

Install and run

Install uv on macOS or Linux. APSA targets CPython 3.11 and 3.12; not every host/Python combination has been tested (see the support matrix). The examples select Python 3.12, which uv can download if needed. Initial installation can use the network; scans can then use local inputs and cached intelligence.

Install the published package from PyPI:

uv tool install --python 3.12 apsa==1.6.0
apsa --version
apsa doctor --json
apsa demo --out ./apsa-demo

The package provides apsa and the compatibility aliases quaygate and mobile-audit. If the command is not found, run uv tool update-shell and open a new terminal. GitHub Releases provides the wheel, source distribution, checksums, and a verified bundle with locked requirements, attribution, and the build manifest.

For development or installation with the repository's locked dependencies, use a checkout:

git clone https://github.com/ictechgy/apsa.git
cd apsa
uv sync --locked --python 3.12
uv run --locked apsa doctor --json
uv run --locked apsa demo --out ./apsa-demo

doctor checks parsers, optional device tools, and offline readiness. demo writes an intentionally vulnerable example and scans it; choose a new output directory.

To register the checkout's commands on your PATH:

uv tool install --editable . --force --python 3.12 --constraints requirements-release.txt
apsa --version

This registers apsa and the compatibility aliases quaygate and mobile-audit. --force replaces existing tools with those command names. An editable installation depends on this checkout; keep it in place. If the command is not found, run uv tool update-shell and open a new terminal. The examples below assume apsa is on PATH. Without a global installation, prefix them with uv run --locked from the checkout.

apsa scan /path/to/owned/mobile-project
apsa scan /path/to/owned/app.apk
apsa scan /path/to/owned/app.ipa --sbom /path/to/build.cdx.json
apsa tui

Use a CycloneDX JSON SBOM from the actual build to improve dependency correlation. tui, or apsa without arguments, opens the terminal interface. Run apsa COMMAND --help for options.

Public intelligence and network use

A default scan reads local files and cached intelligence without uploading source code or builds. Public-feed collection and OSV queries use the network:

Command

Network behavior

apsa scan TARGET

Uses local inputs and cached intelligence

apsa intel sync

Fetches public vulnerability sources

apsa intel watch

Polls public sources and reassesses saved inventories; does not reread app files or implicitly query OSV

apsa intel backfill --source android --since YYYY-MM

Fetches an explicit, bounded range of monthly Android security bulletins

apsa scan TARGET --online

Sends eligible dependency names and versions to OSV; default auto selects legacy for at most 100 eligible unique coordinates and batch above 100, with a 1000-package default budget. Scan accepts explicit mode and local exclusion flags below

apsa intel watch --online

Sends saved dependency names and versions using auto and the default budgets for each saved inventory on each poll; has no mode/exclusion flags and does not inherit scan exclusions

apsa intel sync
apsa intel status
apsa intel watch --interval 900
apsa scan /path/to/owned/app --online
apsa scan /path/to/owned/app --online --osv-query-mode legacy
apsa scan /path/to/owned/app --online --osv-exclude-coordinate 'Maven:com.private:*'

Scan supports repeatable --osv-exclude-ecosystem, --osv-exclude-name and --osv-exclude-coordinate flags. Patterns are case-sensitive shell globs; coordinates use ecosystem:name. MCP dependency_check accepts query_mode and the corresponding exclude_ecosystems, exclude_names, exclude_coordinates lists. Exclusions are applied locally before transmission and do not count as checked from old cache. Each MCP call uses only its supplied lists; a report's recorded scan exclusions are not inherited. Pass the required exclusions on every dependency_check call. SwiftURL name and coordinate exclusions match both the stored repository name and its canonical OSV transmission name (for example github.com/owner/repo). An unsupported repository identity stays untransmitted when such a policy is active. Use scan or MCP when an exclusion policy is required: intel watch --online neither accepts these controls nor carries over a scan's exclusions. No source code or builds are sent to OSV. The request budget counts OSV operations, including pagination and record lookups, rather than individual HTTP redirect hops.

Watch polls every 900 seconds by default, with a 60-second minimum; it is not a push stream. It runs until interrupted unless --cycles sets a finite number of polls. Reassessment saves a new snapshot when findings, coverage, or intelligence state changes. Inspect feed freshness, failures, and pending CVE processing with intel status. Fetching a CVE document and completing its processing are separate states. The default pending-item policy allows no backlog; use intel_max_pending to set an explicit allowance.

apsa reports reassess latest
apsa reports compare audit_BEFORE audit_AFTER
apsa reports export latest --format sarif --out audit.sarif
apsa reports verify

Reassessment applies current intelligence to a saved inventory; run scan again for changed files or new static checks. If connected to an AI client, that client may send report metadata to its model provider. APSA's MCP context excludes source excerpts, full source files, and screenshot bytes; client-side data handling still depends on the client.

CI and background jobs

apsa policy init --out apsa.toml
apsa scan /path/to/owned/app --policy apsa.toml --out audit.json
apsa scan /path/to/owned/app --fail-on high --include-candidates
apsa scan /path/to/owned/app --background --json
apsa jobs status JOB_ID --json

Severity gates exclude candidate findings by default. Opt in with --include-candidates or the policy's allowed_statuses. Required rules accept only checked or not-applicable coverage; partial execution and missing required checks do not pass. Waivers need a finding ID, a reason, and an expiry date. A background job being completed means it finished; check its audit_incomplete flag and report before treating the audit as complete.

Unreadable source directories and files leave warnings and incomplete coverage; a source tree with no readable supported files fails explicitly. A source tree over the text staging budgets (64 MiB, 12,000 files) is audited partially rather than refused. Files are staged by kind in this order: app code and configuration (configuration first, then the app's code, then headers and vendored code such as .build/ or vendor/), other shipped text (base resources, JSON, YAML), localized or qualified Android res/values-* files, then tests. inventory.input_snapshot.omitted counts the files and bytes left out by kind (code_and_config, other_text, localized_values, tests), including files over the 8 MiB file limit and files that could not be read or staged. Unreadable directories, and directories past the tree-wide budgets of 100,000 entries (read in name order) or 64 levels, are reported as warnings instead. When app code, configuration or other shipped text is left out, app_scope_complete is false and not-applicable coverage also becomes partial. For a complete audit, scan a narrower folder such as the app module. Storage capture failures remain not-run and cannot establish that a canary was deleted.

Exit code

Meaning for the unified CLI

0

Command completed or policy passed

1

Execution error

2

Invalid arguments

3

Incomplete audit or policy, failed report verification, or failed or partial intelligence synchronization

4

Findings exceeded the configured CI threshold

130

Interrupted

--json emits an envelope containing ok, data or error, and exit_code; watch emits one JSON envelope per cycle (NDJSON). ok is true for codes 0 and 4; code 4 means evaluation succeeded but the CI threshold was exceeded. CI must check exit_code and the policy result. Reports may still be produced for codes 3 and 4.

GitHub code scanning

permissions:
  contents: read
  security-events: write
  actions: read            # private repositories: lets the upload read the workflow run
steps:
  - uses: actions/checkout@v7
    with:
      persist-credentials: false
  - uses: ictechgy/apsa@<commit-sha> # v1.6.0; pin the full commit SHA
    with:
      path: android            # source folder, or a built APK/AAB/IPA in the workspace
      fail-on-incomplete: "true"

The action installs apsa from PyPI at the matching version with the release's hash-locked dependencies, runs scan with --format sarif --sarif-root, writes a job summary, uploads the SARIF file to code scanning and then applies the result. A policy failure or a fail-on threshold fails the job even when the audit is also incomplete (exit code 3 can hide a threshold failure, so the action reads the report rather than the exit code alone). With a policy, every unmet policy condition (required rules, required intelligence, expired waivers, baseline checks) fails the job; only a partial audit is left to fail-on-incomplete, which fails on exit 3 unless set to "false". Use policy (with baseline-file and baseline-sha256) for team gates, or fail-on for a severity threshold that excludes candidates.

By default the action is offline: it does no CVE or dependency-advisory correlation, and dependency findings need intel-sync (fetch public advisories first; a partial sync is a warning) and online (send dependency names and versions to OSV, see network use). Private repositories need GitHub Code Security to upload SARIF; set upload-sarif: "false" to keep only the file. Pull requests from forks and every Dependabot-triggered run get a read-only token, so the action skips the upload there and still writes the file and summary.

Each alert's fingerprint is APSA's finding identity: the rule plus the evidence location (file, line, function or archive member). Editing the flagged line or moving the file can therefore close one alert and open another. Candidate findings are uploaded at warning level and tagged candidate, and a rule whose results are all candidates carries no security-severity, so it does not trip code scanning's default check for High or Critical alerts. A rule with confirmed results takes its security-severity from those, and its candidate alerts share that rating. Code scanning tracks alerts per category (default apsa); if you uploaded APSA SARIF before under another category, keep that value, because a new category starts new alerts and leaves the old category's alerts open until you delete its analyses. GitHub may offer Copilot Autofix suggestions on third-party alerts where your plan enables it; this has not been tested with APSA alerts, and APSA's evidence status stays in each alert's properties.

Without the action:

apsa scan android --format sarif --out apsa.sarif --sarif-root android
apsa reports export latest --format maswe --out maswe.json
apsa reports export latest --format cyclonedx --out apsa.cdx.json

reports ingest REPORT --sarif FILE --tool NAME (MCP reports_ingest_sarif) imports another tool's SARIF 2.1.0 results, such as Android Lint, CodeQL or Semgrep, into a new report. Imported results stay candidates with origin: external, add no APSA coverage, and are cross-linked with APSA findings of a related weakness at the same location. Their text is sanitized and treated as untrusted.

--format checklist --checklist masvs-v2 (or a TOML file mapping your own inspection items to MASWE identifiers and APSA rules) lists, per item, the related checks' states and findings; statuses never claim an item passed. reports history TARGET lists when each finding was first and last observed and when a later report stopped observing it, as inspection and remediation records. See using APSA with Korean inspection standards (Korean).

--format cyclonedx writes a CycloneDX 1.6 SBOM of the dependencies APSA discovered, with package URLs and the evidence behind each version, and embeds APSA's dependency matches as VEX entries. Each entry carries the evidence status, the CISA KEV flag and when APSA first observed it for that target, which helps run vulnerability-handling clocks such as the EU Cyber Resilience Act's. Every analysis state is in_triage: APSA never marks a vulnerability not_affected; record that decision yourself with a justification. The SBOM is not a complete build inventory and does not make an app compliant with any regulation.

See the CI example and operations guide (Korean) for policies, backup, limits, and troubleshooting.

MCP and skills

apsa integrations --root /absolute/path/to/owned-apps
apsa mcp --root /absolute/path/to/owned-apps
apsa skill install
apsa context --report latest --section findings --limit 20 --json

Use integrations to generate a configuration with the installed executable path, or a python -m apsa fallback when no apsa executable is found. The shape below is illustrative; replace both absolute paths:

{
  "mcpServers": {
    "apsa": {
      "command": "/absolute/path/to/apsa",
      "args": ["mcp", "--root", "/absolute/path/to/owned-apps"]
    }
  }
}

Install for agents

Client

Install

Claude Code

/plugin marketplace add ictechgy/apsa, then /plugin install apsa@apsa. The plugin runs uvx --python 3.12 apsa@VERSION mcp --root <current project> and adds the skill.

Any MCP client

Use the configuration from apsa integrations, or the MCP Registry entry io.github.ictechgy/apsa (PyPI package, uvx, required --root).

Codex and other skill runtimes

apsa skill install, plus the integrations configuration.

During 1.4 development, Claude Code 2.1.295 (the plugin loaded from the checkout with --plugin-dir, root ${CLAUDE_PROJECT_DIR}) and Codex CLI 0.162.0 were each verified calling capabilities and audit_scan against that historical local build on a freshly generated synthetic project. These are not 1.6 client checks. Marketplace and MCP Registry installs are checked after the package is published. Other clients are not yet verified.

MCP uses stdio and requires an explicit --root; repeat it for multiple roots. integrations defaults to the current directory when no root is supplied. Roots restrict audited targets and access to their reports and jobs. --allow-any-root explicitly removes that restriction. APSA does not change model-client configuration automatically; client authentication belongs to the client.

Purpose

MCP tools

Audits

capabilities, audit_scan, audit_start, audit_reassess, verify_finding, specs_validate

Jobs

jobs_list, jobs_status, jobs_cancel

Reports

reports_list, reports_get, reports_compare, reports_export_baseline, reports_ingest_sarif, reports_checklist, reports_history

Intelligence

intelligence_sync, intelligence_search, intelligence_get, dependency_check

Policy

policy_evaluate

Runtime planning

runtime_plan, runtime_devices

verify_finding (CLI apsa verify) cross-checks a finding claimed by another tool or AI reviewer against APSA's evidence and never refutes it. Project taint specifications name project-specific sources and sinks, such as a deep-link parser or an in-app browser wrapper, for APSA to follow deterministically; see project specifications.

capabilities reports tool_manifest_sha256, a hash of the APSA-owned tool surface (names, descriptions, annotation hints and parameter shapes); the tool set never changes within a process. Compare a hash computed from tools/list with the published values rather than trusting the server's own report. Read-only tools are annotated read-only and idempotent, network tools open-world. App content and advisory text are treated as untrusted data and model context omits source excerpts; see the MCP security model.

Resources include apsa://rules and apsa://reports/{report_id}. The previous quaygate:// and mobile-audit:// resource schemes remain compatible.

Report context defaults to 20 records and 64 KiB. Resolve latest once, then page with the returned immutable report ID and page.next_cursor, keeping section/filters fixed. partial_response describes the page; audit_incomplete describes execution. Oversized records are explicitly omitted and remain available in local exports. Portable baselines require explicit approval provenance and a SHA-256 pinned in reviewed CI configuration. See workflow examples.

The default server exposes runtime planning. runtime_execute and runtime_start are registered only with --allow-runtime at server startup. Both preview a scenario by default; execute=true runs it. runtime_start starts a cancellable background device job. Runtime tests need an authorized, prepared test app; the default audit does not boot devices or install apps. See the operations guide (Korean) before running a scenario.

skill install copies the packaged APSA skill to ~/.codex/skills/apsa. To install directly into another model runtime's skill directory:

apsa skill install --name apsa --dest /path/to/runtime/skills/apsa

Use --name quaygate or --name mobile-audit to update a skill installed under an older default name; custom edits are preserved unless --force is supplied. integrations reports skill status. For clients without MCP, context provides report context that excludes source excerpts, full source files, and screenshot bytes.

Compatibility and stored data

quaygate and mobile-audit invoke the same unified CLI. Python entry points python -m apsa, python -m quaygate, and python -m mobile_audit remain available. Existing reports and QG-* rule IDs retain their identity.

Data is stored by default in ~/.local/share/mobile-audit. Path precedence is --home → APSA_HOME → QUAYGATE_HOME → MOBILE_AUDIT_HOME → that default. Renaming does not copy the database or move history. Existing MCP configurations must include an authorized --root.

The legacy apk, ipa, and device subcommands retain quick lint output and exit codes 0/1/2; they do not save unified audit history or correlate vulnerability intelligence. Use scan for the full workflow. Older cached OSV records without severity need a fresh scan --online or intel watch --online; reassessment alone cannot recover missing scores.

Development, validation, and licensing

uv sync --locked --extra dev --python 3.12
make test benchmark
make export-release
make release RELEASE_OUT=dist/apsa-local-release

Choose a new or empty release directory. Release verification requires uv 0.12.1 and builds wheel/sdist twice, compares their hashes, and checks a clean installation outside the checkout with offline source/APK scans, MCP, and skill installation. It writes hashes, an SBOM, dependency notices, and a release manifest without publishing. Initial dependency preparation can use the network. The same-host repeat check does not claim byte-identical builds across platforms.

Tagged releases use GitHub Actions to publish the verified distributions to PyPI after the supported CI matrix passes. See release publishing for the workflow and download contents.

Recorded product validation is in RELEASE_READINESS.md. The curated benchmark is a regression corpus, not a measure of production detection rates. Integration boundaries and the threat model are currently in Korean. Historical reviews remain tied to their original snapshots.

A reproducible APSA/MobSF comparison and its recorded results use freshly generated synthetic source projects and APKs. They measure development candidates recorded before APSA 1.2.0, not the published package; these results are not production accuracy estimates. A rerun on the APSA 1.3.0 release runtime with newly generated inputs reproduced the candidate figures (see RELEASE_READINESS.md).

A separate public-source and CVE evaluation records initial results on six pinned app source snapshots, selected dependency/CVE units and OS advisory fixtures. It preserves extraction gaps, scanner failures and incomplete coverage; it does not measure whole-app security or general production accuracy.

The subsequent hardening rerun completes all six source scans and closes four measured integration gaps. It reuses observed labels and reports remaining incomplete coverage; it is a development check.

The coverage extension records narrow Swift/Kotlin compatibility, recognized function counts and Apple-evidenced iOS/iPadOS branch decisions. Adapted source remains partial; the selected fixtures do not establish general CVE accuracy.

The additional analysis and independent holdout covers AAB/IPA metadata, Objective-C, parser isolation and two independently labeled public sources. It records selected CVE boundary agreement, unresolved catalog usage and remaining parser gaps separately.

The dependency evidence evaluation compares APSA's Gradle catalog usage and lockfile coordinates with Gradle's own resolution on three frozen holdouts of public apps, keeping first blind results separate from reruns after the truth was seen. The independent source pairs score vulnerable and fixed commits of public projects against truth frozen before scanning. The blind MASWE-labeled pairs measure 1.5 on a new holdout labeled by weakness, and the OWASP MASTG demos are a development benchmark. All are narrow samples, not general accuracy estimates.

The source is publicly available on GitHub. LICENSE preserves the original Quaygate MIT notice. This publication does not declare an additional license for the combined product.

Available Tools

23 tools
audit_reassessB

Re-evaluate a saved inventory against current cached intelligence and save a new report.

ParametersJSON Schema
NameRequiredDescriptionDefault
report_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=false), and the description's 'save a new report' is consistent, adding the useful detail that a new artifact is produced rather than an in-place update. It does not disclose whether prior reports are overwritten, permission requirements, or how cached intelligence is refreshed.

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 front-loaded sentence that states the action, inputs, and outcome with zero filler. Every clause earns its place.

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

Completeness3/5

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

An output schema exists, so return values needn't be explained, and the operation is simple with one parameter. However, the description omits prerequisite/permission context and any routing advice relative to the many sibling tools, leaving the definition only minimally complete.

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

Parameters2/5

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

Schema description coverage is 0% for the single report_id parameter, so the description must carry the burden. It refers to 'a saved inventory' and 'a new report' but never clarifies what report_id identifies or its required format, leaving the parameter's semantics under-specified.

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 states a specific verb and scope: re-evaluate a *saved* inventory against *current cached intelligence* and save a new report. The word 're-evaluate' plus 'saved inventory' distinguishes it from siblings like audit_scan or audit_start, which imply fresh scans, without naming them explicitly.

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

Usage Guidelines2/5

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

There is no explicit when-to-use, when-not-to-use, or alternative routing. The phrase 'saved inventory' weakly implies an existing report is prerequisite, but the agent receives no guidance on choosing this over reports_compare, audit_scan, or intelligence_sync.

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

audit_scanA

Inspect local source/APK/AAB/APKS/IPA using cached intelligence. APKS requires apk_set_device with sdkVersion, supportedAbis, screenDensity and supportedLocales; selected APKs are inspected individually without installation or manifest/resource merging. ipa_trust_policy supplies explicit digest-bound DER anchors for cryptographic chain checks only, without Apple signer identity, revocation or app authenticity verification. Configuration selects a relative manifest or .plist without build-system merge. dependency_module and runtime_configuration select recorded Gradle lock resolution, with optional relative dependency_evidence paths; freshness and installed-build correspondence remain unverified. specs declares project sources/sinks; findings stay candidates. No network or device mutation.

ParametersJSON Schema
NameRequiredDescriptionDefault
sbomNo
specsNo
targetYes
device_infoNo
configurationNo
source_moduleNo
apk_set_deviceNo
ipa_trust_policyNo
dependency_moduleNo
dependency_evidenceNo
runtime_configurationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

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

The description discloses real behavioral limits beyond the annotations: findings stay candidates, freshness and installed-build correspondence remain unverified, ipa_trust_policy does not verify Apple signer identity or revocation, and there is "No network or device mutation." This is strong for a non-read-only tool, though it never explains what state the readOnlyHint=false operation actually writes.

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 and each sentence conveys parameter-scoping or verification-limit information with little filler. It is dense to the point of being hard to parse in one read, which keeps it from a 5.

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?

An output schema exists, so return values need no explanation. Combined with the extensive caveat coverage the description gives an agent enough to call the tool correctly for the main artifact types, with only a few parameters left unaddressed.

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?

With 0% schema description coverage and 11 parameters, the description carries the full burden and does compensate for most of it: apk_set_device, ipa_trust_policy, configuration, dependency_module, runtime_configuration, dependency_evidence, and specs all get usage context. sbom, source_module, device_info, and target remain undocumented, so it is not a clean 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 opening clause states a specific verb and resource set: "Inspect local source/APK/AAB/APKS/IPA using cached intelligence." An agent immediately knows the artifact classes covered. It does not, however, differentiate itself from siblings like audit_start or audit_reassess, so it stops short of a 5.

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?

Some conditional usage is given (APKS requires apk_set_device with sdkVersion, supportedAbis, screenDensity, supportedLocales), which is genuinely useful. But there is no guidance on when to choose audit_scan over audit_start, audit_reassess, or dependency_check; usage is implied rather than stated.

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

audit_startA

Start a persistent offline audit. APKS requires apk_set_device with sdkVersion, supportedAbis, screenDensity and supportedLocales; selected APKs are inspected individually without installation or manifest/resource merging. ipa_trust_policy supplies explicit digest-bound DER anchors for cryptographic chain checks only, without Apple signer identity, revocation or app authenticity verification. Configuration selects a relative manifest or .plist without build-system merge. dependency_module and runtime_configuration select recorded Gradle lock resolution; optional dependency_evidence paths narrow it, without verifying freshness or installation. specs declares project sources/sinks. Use jobs_status for progress and jobs_cancel to stop it.

ParametersJSON Schema
NameRequiredDescriptionDefault
sbomNo
specsNo
targetYes
device_infoNo
configurationNo
source_moduleNo
apk_set_deviceNo
ipa_trust_policyNo
dependency_moduleNo
dependency_evidenceNo
runtime_configurationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

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

Annotations only declare readOnlyHint=false, destructiveHint=false, openWorldHint=false. The description adds substantial behavioral context beyond that: APKs are inspected individually without installation or manifest/resource merging, ipa_trust_policy anchors are for cryptographic chain checks only (no signer identity, revocation, or authenticity verification), and configuration does not undergo build-system merge. These 'what it deliberately does not do' statements are exactly the kind of disclosure annotations cannot carry.

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

Conciseness3/5

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

The purpose is front-loaded, which is good, but the parameter explanation is one dense run-on block of semicolon-separated clauses with no structure. Every clause carries information, yet the lack of segmentation makes it hard to scan for a specific parameter.

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

Completeness3/5

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

An output schema exists, so return values need not be covered, and the description handles most of the 11 parameters plus follow-up tools. However, for an 11-parameter tool with 0% schema coverage, the unexplained 'target' (the only required parameter), 'sbom', 'device_info', and 'source_module' leave a real gap.

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 must compensate and largely does: it explains apk_set_device's required sub-fields (sdkVersion, supportedAbis, screenDensity, supportedLocales), the semantics of ipa_trust_policy, configuration, dependency_module, runtime_configuration, dependency_evidence, and specs. It leaves sbom, target, device_info, and source_module unexplained, so compensation is incomplete.

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 opening sentence gives a specific verb and resource ('Start a persistent offline audit') and the 'persistent/offline' qualifier is meaningful scoping. It does not explicitly differentiate itself from the sibling audit_scan, so an agent must infer the distinction rather than being told.

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?

It names follow-up tools ('Use jobs_status for progress and jobs_cancel to stop it'), which is useful routing, but never states when to choose audit_start over audit_scan, specs_validate, or dependency_check. Usage is implied by the parameter descriptions rather than stated.

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

capabilitiesB
Read-onlyIdempotent

Discover input types, evidence states, runtime requirements and available interfaces.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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

Annotations declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered by structured data. The description does not contradict these but also adds no behavioral context beyond listing what is discoverable. No information about response format, caching, or auth requirements beyond what annotations provide.

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?

A single tight sentence with no filler. It is front-loaded with the verb and enumerates the discovery scope compactly. However, the enumeration of four categories in one sentence is dense without structuring, and there is no elaboration on any of them.

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

Completeness3/5

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

There is an output schema, so the description need not explain return values, and with zero parameters the schema burden is minimal. Still, for a capability-discovery tool the description could clarify what an agent should do with the results or when it is worthwhile to call it. It is minimally viable but leaves usage context to the agent's inference.

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?

The tool takes zero parameters, so per calibration the baseline is 4. There are no parameter semantics to misrepresent, and the description appropriately does not invent any.

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

Purpose3/5

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

The description names what is being discovered (input types, evidence states, runtime requirements, interfaces), but the verb is essentially 'Discover' and the tool is a metadata/capability introspection endpoint. It does not clearly distinguish itself from siblings like specs_validate or runtime_devices, which also touch on runtime and specs concerns. The purpose is inferable but vague.

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

Usage Guidelines2/5

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

No guidance on when to call this tool versus any of the 23 siblings. An agent has no indication whether this should be called at startup, before audits, or only in certain contexts. The description gives no when/when-not/alternatives information.

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

dependency_checkA

Query OSV for inventoried package versions and save a reassessed report. query_mode is auto, legacy or batch; auto batches above 100 packages. Exclusion lists are case-sensitive globs for ecosystems, package names or ecosystem:name coordinates. Excluded packages are never transmitted or marked checked from cache. Batched queries preserve per-package pagination and partial failures.

ParametersJSON Schema
NameRequiredDescriptionDefault
report_idNolatest
query_modeNoauto
exclude_namesNo
exclude_ecosystemsNo
exclude_coordinatesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false and openWorldHint=true, so the external-write profile is partly covered. The description adds genuinely non-inferable behavior: excluded packages are never transmitted or marked checked from cache, and batched queries preserve per-package pagination and partial failures. It still omits what happens to the existing report being overwritten and any auth or rate-limit constraints.

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?

Four sentences, no filler, purpose front-loaded before the parameter and behavior details. Each sentence conveys a distinct actionable fact (mode semantics, exclusion glob syntax, exclusion side effects, batching behavior).

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

Completeness3/5

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

An output schema exists, so return values need not be explained. Still, for a five-parameter tool with zero schema documentation the description leaves gaps: report_id is unexplained, the relationship to audit_reassess/reports_checklist is unstated, and whether the saved report overwrites or appends is unclear.

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 full burden and largely succeeds: it enumerates the query_mode values (auto/legacy/batch), the auto threshold, and the case-sensitive glob semantics for the three exclude_* lists. The report_id parameter is never mentioned at all despite having a 'latest' default, leaving one of five params undocumented.

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?

States a specific verb and resource pair ('Query OSV for inventoried package versions') plus a second effect ('save a reassessed report'), which is more than a restatement of the name. However it never distinguishes itself from closely related siblings such as audit_reassess or reports_checklist, so the agent must infer the boundary.

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?

The description gives conditional guidance for the query_mode parameter ('auto batches above 100 packages'), which implicitly tells the agent which mode to pick. It never states when to call dependency_check instead of a sibling like audit_reassess, and no prerequisites (e.g. an existing report or inventory) are named.

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

intelligence_getA

Read an exact CVE; refresh=true fetches its official CNA record into cache.

ParametersJSON Schema
NameRequiredDescriptionDefault
cve_idYes
refreshNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

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

The description usefully discloses that refresh=true mutates state by fetching the official CNA record into a cache, which explains the otherwise surprising readOnlyHint=false on a tool whose description starts with "Read". It does not cover error behavior for unknown CVE IDs or rate limits, so it falls short of 5.

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 front-loaded sentence with the primary action first and the optional flag's effect second. No filler, no redundancy, instantly scannable.

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?

An output schema exists, so return values need not be described, and the non-obvious cache side effect of refresh is covered. The remaining gap is the accepted format/validation of cve_id, which an agent should not have to guess.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must carry parameter meaning. It explains refresh (fetches the CNA record into cache) but says nothing about cve_id format (e.g. CVE-YYYY-NNNN) or whether an unknown ID is an error, leaving one of two parameters undocumented.

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?

States a specific verb+resource ("Read an exact CVE") and the word "exact" implicitly distinguishes it from the lookup-by-query sibling intelligence_search. It is clear what the tool does, but it never names the sibling it differs from, 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 Guidelines3/5

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

Usage is only implied: "exact CVE" suggests this is the direct-ID path versus intelligence_search, and refresh=true is given a condition, but there is no explicit "use this when / use X instead" guidance and no statement of when to set refresh.

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

intelligence_syncC

Fetch official public mobile advisories and update local cache. Returns per-source failures and scope.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sourcesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=false, openWorldHint=true and destructiveHint=false, so the agent knows this reaches external sources and mutates local state without being destructive. The description usefully adds that it updates a local cache and reports per-source failures plus scope, but omits whether the sync is blocking, whether it overwrites existing cached advisories, and any auth or rate-limit constraints.

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?

Two short sentences with no filler, and the primary action is front-loaded ahead of the return-value note. It is efficient, though 'scope' is left unexplained and reads as an afterthought.

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

Completeness2/5

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

An output schema exists, so return values need not be restated, and the description does gesture at per-source failures. However, for a non-read-only tool with an open-world dependency and two completely undocumented parameters, the definition leaves too much unstated to call it complete.

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

Parameters2/5

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

Schema description coverage is 0% and neither of the two parameters is described in the schema. The description never mentions 'limit' or 'sources', so an agent gets no help understanding what limit bounds or what source identifiers are valid — a real gap for a tool whose only inputs are these two fields.

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?

States a specific verb pair (fetch + update local cache) and a concrete resource (official public mobile advisories), which separates it from read-only siblings like intelligence_get and intelligence_search. It stops short of explicitly naming those siblings as the non-sync alternatives, so it is clear but not fully differentiated.

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

Usage Guidelines2/5

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

No guidance on when to run a sync versus calling intelligence_search or intelligence_get directly, no mention of prerequisites, freshness needs, or how often it should be invoked. The agent must infer the trigger condition entirely from the name.

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

jobs_cancelA

Request cancellation of an authorized job; poll jobs_status until terminal.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations declare readOnlyHint=false and destructiveHint=false but say nothing about timing. The description adds that this is a *request* (not synchronous) and that the job reaches a terminal state observable via jobs_status — genuinely useful context beyond the annotations. It stops short of noting reversibility or permission requirements.

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?

One sentence, front-loaded with the action and followed by the essential next step. No wasted words.

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?

Output schema exists, so return values need not be explained, and the async workflow is conveyed. For a mutation tool with no explicit permission or reversibility notes, a small gap remains.

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

Parameters3/5

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

Schema coverage is 0% for the single job_id parameter, so the schema gives no semantic help. The description only implies through 'authorized job' that the id must belong to a job the caller is permitted to cancel, adding minimal meaning.

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?

States a specific verb and resource ('Request cancellation of an authorized job') and implicitly contrasts with the polling tool it names, jobs_status. It doesn't distinguish itself from other job-related siblings like jobs_list, but the action is unambiguous.

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?

Provides clear follow-up guidance: 'poll jobs_status until terminal,' which tells the agent this is asynchronous and how to complete the workflow. It does not state when cancellation is inappropriate (e.g., already-terminal jobs) or name any exclusion.

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

jobs_listC

List background jobs visible inside this server's configured roots.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior1/5

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

The description presents a pure enumeration operation ('List background jobs'), while the annotations declare readOnlyHint=false, meaning the tool is not guaranteed to be side-effect free. The description offers no explanation of what non-read-only behavior occurs, and no pagination or ordering behavior is disclosed.

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?

One short, front-loaded sentence with no filler, so it reads cleanly. It is terse to the point of under-specification, but there is no wasted or redundant text to penalize.

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

Completeness3/5

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

With an output schema present, return values need not be explained, and the tool's complexity is low (one optional parameter). However, the limit/pagination semantics and the tension with the non-read-only annotation leave real gaps for correct invocation.

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

Parameters2/5

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

Schema description coverage is 0% and the single 'limit' parameter (default 20) is never mentioned in the description, so its meaning, range, and pagination implications are undocumented anywhere. The description does not compensate for the coverage gap.

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?

States a specific verb (List) and resource (background jobs) plus a scoping qualifier ('visible inside this server's configured roots'), which is more than a tautology. It does not explicitly distinguish itself from siblings jobs_status and jobs_cancel, but the verb choice makes the read/enumerate role inferable.

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?

The phrase 'inside this server's configured roots' implies the context in which listing makes sense, but there is no explicit when-to-use guidance and no mention of the sibling alternatives jobs_status or jobs_cancel for inspecting or cancelling a specific job.

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

jobs_statusC

Read durable job state and progress. An interrupted worker never becomes a successful audit.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior1/5

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

The description asserts a pure read operation ("Read durable job state and progress"), but the annotations declare readOnlyHint=false, meaning the tool may modify state. That is a direct contradiction of the behavioral claim in the text. The remaining sentence adds no concrete behavior such as polling cadence, terminal state semantics, or error conditions.

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

Conciseness3/5

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

Two short sentences, front-loaded with the action, which is good. The second sentence is atmospheric and ambiguous rather than informative, so it does not clearly earn its place in a definition this terse.

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

Completeness2/5

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

An output schema exists, so return values need not be explained, but for a job-polling tool the description omits the essential context: how the job_id is obtained, how to interpret completion vs. failure, and how this differs from jobs_list. Combined with the annotation contradiction, this leaves the agent under-informed.

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

Parameters2/5

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

Schema description coverage is 0% for the single job_id parameter, and the description says nothing about its format, or where the id comes from (presumably audit_start or jobs_list). The name is largely self-explanatory, which prevents a 1, but the description does nothing to compensate for the missing schema documentation.

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?

"Read durable job state and progress" states a specific verb (Read) and resource (job state/progress), so the core purpose is unambiguous. It does not, however, distinguish itself from sibling job tools such as jobs_list or jobs_cancel, leaving the agent to infer the boundary from the name alone.

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

Usage Guidelines2/5

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

There is no explicit when-to-use, when-not-to-use, or alternative guidance. The agent must infer that this is called after audit_start to poll a job, and the cryptic line "an interrupted worker never becomes a successful audit" reads as an aphorism rather than a usage rule. None of jobs_list, jobs_cancel, or audit_scan are referenced as alternatives.

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

policy_evaluateC
Read-onlyIdempotent

Evaluate team thresholds, explicit coverage requirements and expiring waivers without changing reports.

ParametersJSON Schema
NameRequiredDescriptionDefault
report_idNolatest
baseline_idNo
policy_pathYes
baseline_pathNo
baseline_sha256No

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the 'without changing reports' clause largely restates structured data. What the description does add is the scope of evaluation (thresholds, coverage requirements, waivers), which is genuine behavioral context the annotations do not carry. It omits what happens on an invalid policy file or what a failed evaluation 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.

Conciseness4/5

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

One compact sentence with the subject matter front-loaded and no filler. Minor deduction because the trailing 'without changing reports' clause repeats what the annotations already assert, spending words on redundant information.

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

Completeness2/5

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

An output schema exists, so return values need not be documented, but for a five-parameter tool with 0% schema coverage and no routing guidance the description is materially incomplete. An agent cannot determine how baseline selection works or when this tool should be chosen over its many validation-adjacent siblings.

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

Parameters1/5

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

Schema description coverage is 0% across five parameters, and the description addresses none of them. The baseline_id / baseline_path / baseline_sha256 trio is genuinely ambiguous (identifier vs. file vs. integrity hash) and the required policy_path is never explained, so the description fails to compensate for the coverage gap.

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 gives a specific verb (evaluate) plus the concrete subject matter being evaluated: team thresholds, explicit coverage requirements, and expiring waivers. That is far more informative than a name restatement. It does not, however, distinguish this from plausible siblings such as specs_validate, verify_finding, or audit_scan, so it stops short of a 5.

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

Usage Guidelines2/5

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

There is no statement of when to reach for policy_evaluate versus specs_validate, verify_finding, or audit_scan, and no preconditions or exclusions are given. The only usage-flavored clause ('without changing reports') is a safety property, not routing guidance.

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

reports_checklistB
Read-onlyIdempotent

Map a report onto a checklist: masvs-v2 (built in) or a checklist TOML inside an MCP root that maps items to MASWE identifiers and APSA rules. Statuses are findings, partial, no-findings-in-checked-scope, not-run, not-applicable or not-assessed; none is a pass.

ParametersJSON Schema
NameRequiredDescriptionDefault
checklistNomasvs-v2
report_idNolatest

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already declare this as a safe, idempotent, closed-world read. The description adds genuinely new behavioral context: the set of possible statuses and the crucial semantic caveat that 'none is a pass', which prevents the agent from misreading the output. It stops short of describing scoping or pagination, but the output schema covers return shape.

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 action, then the checklist options, then the status taxonomy. Dense but essentially waste-free; the status clause is long but carries real semantic payload.

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

Completeness3/5

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

The output schema means return values need not be explained, and checklist sources plus statuses are covered. However, for a tool sitting among eleven reports_* siblings, the absence of selection guidance and of report_id semantics leaves notable gaps.

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

Parameters3/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 extra weight. It does explain the 'checklist' parameter's accepted values (masvs-v2 or a TOML path) and what those checklists contain, but says nothing about 'report_id' or how the 'latest' default resolves, leaving one of two parameters semantically unexplained.

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?

States a specific verb+resource ('Map a report onto a checklist') and enumerates the checklist sources (built-in masvs-v2 or a TOML file under an MCP root). That is clear enough to act on, but it does not contrast itself against siblings like reports_get or reports_compare, which also consume a report.

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

Usage Guidelines2/5

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

There is no when-to-use or when-not-to-use guidance. The agent is not told when checklist mapping is preferable to reports_get, reports_compare, or reports_history, so selection among the many reports_* siblings must be inferred from the name alone.

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

reports_compareA
Read-onlyIdempotent

Compare exact report IDs, retaining coverage differences and unproven remediation states. verification=true adds source traces and scope/build/assertion pairing; portable_inputs=true requires verification and only normalizes absolute targets for identical, complete canonical SHA256 source inputs with unchanged analysis scope. Binary and runtime bindings remain strict; disappearance never proves remediation.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterYes
beforeYes
verificationNo
portable_inputsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already cover read-only, idempotent, non-destructive semantics, yet the description adds substantive behavior: coverage differences are retained, remediation states are only reported as proven/unproven, disappearance of a finding never proves remediation, and binary/runtime bindings stay strict. That is meaningful disclosure beyond the annotations, though terms like "scope/build/assertion pairing" remain opaque.

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

Conciseness3/5

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

The purpose is front-loaded in the first clause, and little is pure filler, but the middle sentence is a dense run-on of jargon ("scope/build/assertion pairing," "identical, complete canonical SHA256 source inputs") that is hard to parse on first read. Length is justified by tool complexity, but structure could be cleaner.

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

Completeness3/5

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

An output schema exists and annotations cover safety, so return values and side effects need not be spelled out. However, for a comparison tool with conditional verification modes, terms like "unproven remediation states" and the scope-matching rule are left under-defined, and nothing says what happens on mismatched or invalid report IDs.

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 load, and it does: before/after are identified as "exact report IDs," and both booleans are explained along with their dependency (portable_inputs requires verification) and the narrow condition under which absolute targets are normalized. It stops short of describing ID format or provenance, leaving a small gap.

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?

States a specific verb and resource ("Compare exact report IDs") and pins the scope to exact IDs, which implicitly separates it from fuzzy or historical lookups like reports_history or reports_get. It is clear what the tool does, though it never names a sibling or contrasts behavior directly.

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?

Gives conditional guidance for the two flags ("verification=true adds source traces", "portable_inputs=true requires verification"), which helps pick a mode. It never says when to use this tool versus reports_get/reports_history, nor states prerequisites such as how to obtain valid report IDs, so usage is only implied.

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

reports_export_baselineB

Export an explicitly approved baseline inside configured roots. Do not invent approval; pin the returned artifact hash in reviewed CI configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault
report_idYes
approved_byYes
output_pathYes
approval_referenceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false and destructiveHint=false, so safety profile is partly covered. The description adds meaningful context beyond that: approval must be genuine and pre-existing, output is confined to configured roots, and the return includes an artifact hash meant to be pinned in reviewed CI — implying integrity/auth requirements not captured by annotations.

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?

Two compact sentences with the core purpose front-loaded and the guardrail second. Nothing is wasted, though the terseness leaves gaps rather than trimming redundancy.

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

Completeness3/5

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

An output schema exists so return values needn't be described, and the description covers the key approval/integrity concerns. But with 0% param coverage on a 4-required-param mutation tool and no differentiation from siblings, it is only partially complete for the task.

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

Parameters2/5

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

Schema description coverage is 0% with 4 required params, so the description carries the full burden. 'Inside configured roots' hints that output_path is constrained and 'Do not invent approval' loosely gestures at approved_by/approval_reference, but no format, origin, or expected value for report_id or the approval fields is given, leaving most parameter semantics undocumented.

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?

States a specific verb (Export) and resource (an explicitly approved baseline), with an added scoping condition (inside configured roots). It is clear what the tool does, but it never distinguishes itself from the many reports_* siblings (reports_get, reports_list, reports_compare), so an agent must infer the difference.

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?

Gives actionable constraint guidance ('Do not invent approval', 'pin the returned artifact hash in reviewed CI configuration'), which implies the intended workflow. However, it offers no explicit when-to-use/when-not or naming of alternative tools among the many reports_* siblings.

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

reports_getC
Read-onlyIdempotent

Read bounded context pages. Continue using the returned immutable report_id; finding_id pages its evidence. Oversized records remain in local exports.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
statusNo
sectionNofindings
severityNo
max_bytesNo
report_idNolatest
finding_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

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

Annotations already cover read-only, idempotent, non-destructive, and closed-world behavior. The description adds some useful behavior beyond that: immutable report_id continuation, finding_id evidence paging, and that oversized records remain in local exports rather than being returned.

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?

Three short sentences with no filler, and the pagination continuation is stated up front after the opening purpose sentence. The terseness and jargon ('bounded context pages') slightly hurt immediate clarity, but the structure is efficient.

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

Completeness2/5

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

This is an 8-parameter tool with 0% schema description coverage and no annotations explaining parameter roles. Although an output schema exists, the description does not explain the pagination/filter parameters or when to use it over sibling report tools, so it is incomplete for the tool's complexity.

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

Parameters2/5

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

Schema description coverage is 0% for all 8 parameters, so the description must compensate but does not. It gives only partial meaning for report_id and finding_id and leaves limit, cursor, status, section, severity, and max_bytes unexplained.

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

Purpose3/5

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

The description gives a verb, 'Read,' and a vague object, 'bounded context pages,' then later names report_id and finding_id/evidence. It never plainly states that it retrieves report or finding data, and it does not distinguish itself from siblings such as reports_list or reports_history.

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?

It implies pagination continuation by saying to keep using the returned immutable report_id and that finding_id pages its evidence. However, it provides no explicit when-to-use alternatives or when-not-to-use guidance relative to the many reports_* siblings.

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

reports_historyA
Read-onlyIdempotent

First and last observation of each finding across saved reports of one target, for inspection and remediation records. A finding no longer observed is not proof of remediation unless the same checks completed.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds genuine semantic context beyond that: the caveat that an unobserved finding is not proof of remediation unless the same checks completed, which steers interpretation of the result.

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?

Two sentences: the first front-loads what is returned, the second delivers a decisive interpretation caveat. No filler, and the most important constraint is not buried.

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

Completeness3/5

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

An output schema exists, so return shape need not be explained. However, for a tool in a dense reports_* family, the description omits how it differs from reports_compare/reports_get and leaves the 'target' identifier ambiguous, so an agent still lacks enough to call it confidently.

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

Parameters3/5

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

Schema description coverage is 0% for the single 'target' parameter, so the schema does not help. The description only implies scope via 'one target' and adds no format or identifier guidance (ID, name, URL?). Marginally informative but not compensating for the coverage gap.

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?

States a specific resource and scope: first/last observation of each finding across saved reports of one target. This is a clear verb-resource statement, but it never distinguishes itself from siblings like reports_compare or reports_get, which an agent must disambiguate before choosing.

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?

The phrase 'for inspection and remediation records' implies intended usage, but there is no explicit when-to-use, when-not-to-use, or named alternative tool. Given four sibling reports_* tools, the routing guidance is thin.

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

reports_ingest_sarifA

Import another tool's SARIF 2.1.0 results (for example Android Lint, CodeQL or Semgrep) into a new report derived from report_id. Imported results stay candidates with origin external, add no APSA coverage, and are linked to APSA findings of a related weakness at the same location. Result text is untrusted data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
toolYes
report_idYes
sarif_rootNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior5/5

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

Annotations only cover the safety profile (write, non-destructive, closed-world). The description goes well beyond them: imported results stay candidates with origin external, add no APSA coverage, are linked to APSA findings of a related weakness at the same location, and that result text is untrusted data. This is rich, non-obvious behavioral context.

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?

A single front-loaded paragraph that begins with the action and then adds constraints. Dense but earns its sentences; could benefit from slight separation of the security note but is not padded.

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

Completeness3/5

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

An output schema exists, so return values need not be described, and the behavioral effects are well covered. However, for a write tool with 0% parameter coverage, the meaning and format of path, tool, and sarif_root are left entirely unexplained.

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

Parameters2/5

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

Schema description coverage is 0% across 4 parameters. The description only implicitly references report_id as the source for the new report and says nothing about path, tool, or the sarif_root default, leaving most parameters undocumented in both schema and description.

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: import SARIF 2.1.0 results into a new report derived from report_id. Names concrete source tool examples (Android Lint, CodeQL, Semgrep) and clearly distinguishes this ingestion action from sibling read/list/compare tools.

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?

The context of when this applies (importing an external tool's SARIF output) is implied and the examples aid recognition, but there is no explicit when-to-use guidance relative to siblings like reports_get or reports_history, and no stated prerequisites or exclusions.

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

reports_listB
Read-onlyIdempotent

List saved audit IDs for exact follow-up reads.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already cover the safety profile completely (readOnlyHint, idempotentHint, destructiveHint=false, openWorldHint=false), so the bar is low. The description adds the content type of the result ('saved audit IDs'), but says nothing about pagination or ordering despite the presence of a limit parameter with default 20.

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?

A single short sentence with the action front-loaded and no filler. It is efficient, though its brevity shades into under-specification rather than tightness.

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

Completeness3/5

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

With an output schema present, return-value shape needn't be explained, and annotations cover safety. However, for a listing tool whose entire purpose is paging through IDs, the missing explanation of the limit parameter and pagination behavior leaves a real gap.

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

Parameters2/5

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

There is one parameter (limit) with 0% schema description coverage, so the description must carry the burden and does not mention it at all. It gives no hint about paging, default page size, or how many IDs are returned per call.

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?

States a specific verb (List) and a specific resource (saved audit IDs), so an agent immediately knows this is a discovery/enumeration tool. It implicitly distinguishes itself from reports_get and reports_history by framing its output as IDs 'for exact follow-up reads,' though it never names those siblings explicitly.

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?

The phrase 'for exact follow-up reads' implies the workflow (list first, then fetch precisely), but there is no explicit when-to-use versus reports_history / reports_get / reports_export_baseline, and no stated preconditions. Usage is inferable rather than directed.

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

runtime_devicesA
Read-onlyIdempotent

List adb devices and available iOS simulators without changing app state.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, covering the safety profile. The description's 'without changing app state' largely restates readOnlyHint rather than adding new behavioral context like environment prerequisites or discovery scope.

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 front-loaded sentence that states the action and its resources with no filler. Every clause earns 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?

An output schema exists, so return values need not be explained, and the annotations carry the safety profile. For a zero-parameter discovery tool the description is sufficient, with only minor room to note environment or prerequisite context.

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?

The tool takes zero parameters, so there is nothing for the description to disambiguate. The baseline of 4 applies for a parameterless tool.

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 names a specific verb (List) and two concrete resources (adb devices, iOS simulators). It is unambiguous about what the tool returns, though it does not explicitly contrast itself with its sibling runtime_plan.

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

Usage Guidelines2/5

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

There is no explicit statement of when to use this tool versus alternatives such as runtime_plan. The phrase 'without changing app state' hints at a safe-discovery context but is not framed as guidance.

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

runtime_planB
Read-onlyIdempotent

Generate an editable test scenario. Does not run it or log out the app automatically.

ParametersJSON Schema
NameRequiredDescriptionDefault
packageNo
platformNo
report_idNolatest

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds genuine value by clarifying that generation does not execute the scenario or log out the app, but it omits permissions required, what the generated plan contains, and whether the report_id source affects the output.

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?

Two short sentences with no filler, and the core action is front-loaded ahead of the negative constraint. It is efficient, though the second sentence is a caveat rather than a positive usage signal.

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

Completeness3/5

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

The presence of an output schema means return values need not be explained, which lowers the burden. Still, with three fully undocumented parameters and only an abstract artifact noun, an agent lacks enough to call this correctly or to select it confidently over execution-oriented siblings.

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

Parameters2/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 full burden for package, platform, and report_id — and it supplies none of them. The only implicit hint is the report_id default of "latest"; what package or platform accept, and how they shape the generated scenario, is entirely undocumented.

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?

States a specific verb and artifact ("Generate an editable test scenario"), which distinguishes it from execution-oriented siblings like audit_start or runtime_devices. However, "test scenario" remains somewhat abstract and the description never names an alternative tool, so the differentiation is implicit rather than explicit.

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?

"Does not run it or log out the app automatically" implies this is a planning/authoring step rather than an execution step, which gives the agent a usable context cue. But it names no alternatives and states no when-to-use condition relative to siblings like audit_start or runtime_devices, so guidance is only implied.

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

specs_validateA
Read-onlyIdempotent

Validate a project taint specification (TOML/JSON, version = 1) before audit_scan uses it. Sources name exact functions returning untrusted url/text; sinks name exact functions (kind webview-load or sql, argument index). Proposed specifications need human review before their findings enter a baseline.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare this is a read-only, idempotent, non-destructive, closed-world operation, so the safety profile is covered. The description adds real behavioral context beyond that: it explains the source/sink content model and, importantly, that proposed specs require human review before findings are baselined.

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?

Three sentences, front-loaded with the core action and scoped tightly to format, semantics, and the review gate. Dense and mostly waste-free, though the middle sentence about sources/sinks is somewhat compressed and the final governance sentence could arguably be split or trimmed.

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?

An output schema exists, so return/validation-result structure need not be explained here. The description covers purpose, accepted format and version, the source/sink model, and the downstream review workflow; the remaining gap is the ambiguity of the path parameter.

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

Parameters3/5

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

There is a single required parameter (path) with 0% schema description coverage, so the description carries the burden. The description implies the path targets a project taint specification, but never states whether it is a file path, directory, or project root, nor acceptable extensions, leaving the parameter under-specified.

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?

The description states a specific verb and resource (validate a project taint specification), pins the accepted formats and version (TOML/JSON, version = 1), and ties the tool to the sibling it feeds (audit_scan), so an agent can place it precisely without opening the schema.

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?

It gives a clear use context: validate before audit_scan consumes the spec, and proposed specifications must pass human review before their findings enter a baseline. It stops short of naming explicit alternatives or when-not-to-use conditions, so it is strong context rather than full routing guidance.

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

verify_findingA

Cross-check a mobile finding claimed elsewhere (for example by an AI code reviewer) against APSA evidence for target. Give a MASWE-NNNN or CWE-N weakness or an APSA rule ID, optionally with a file path and line. Uses the latest report for target unless report_id is given; rescan=true scans first and saves a report. Verdicts: corroborated, same-file-other-location, path-unmatched (see candidate_paths), file-not-analyzed, not-observed, partial, not-run, not-assessed. APSA never refutes a claim.

ParametersJSON Schema
NameRequiredDescriptionDefault
lineNo
pathNo
ruleNo
rescanNo
targetYes
weaknessNo
report_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Adds real behavior beyond the annotations: the default-to-latest-report rule, the fact that rescan writes a new saved report (consistent with readOnlyHint=false), the full enumerated verdict set, and the crucial semantic 'APSA never refutes a claim.' No permission/rate-limit context is given, so it is not a full 5.

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 purpose, then inputs, then report behavior, then verdict values. Dense but each clause carries information; the long verdict enumeration is the only mildly costly element.

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 7-parameter verification tool with an output schema already covering return values, the description supplies everything else an agent needs: accepted identifier forms, report/report_id/rescan interaction, and the meaning of every possible verdict outcome.

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% across 7 parameters, so the description must carry semantics and largely does: it maps rule/weakness to accepted ID formats, describes path plus line as an optional locator, and explains report_id and rescan. Target formatting and the exact difference between rule and weakness inputs remain slightly under-specified.

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 (cross-check) and resource (a mobile finding claimed elsewhere) against a named evidence source for a named target. The parenthetical example of an AI code reviewer makes the scenario concrete, and no sibling tool (reports_*, audit_*, intelligence_*) does this, so an agent can differentiate it without opening any schema.

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?

Explains the input contract (MASWE-NNNN or CWE-N weakness or APSA rule ID, optionally path/line) and the report-selection rule (latest report unless report_id is given; rescan=true scans first and saves). It does not name an alternative tool or state when not to use this one, so it stops short of explicit routing.

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. 4 tool updatesv1.6.0
    • Changedaudit_scan5 fields changed
      • addedInput schema / properties / apk_set_device
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Apk Set Device"
        +}
      • addedInput schema / properties / dependency_evidence
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Dependency Evidence"
        +}
      • addedInput schema / properties / dependency_module
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Dependency Module"
        +}
      • addedInput schema / properties / ipa_trust_policy
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ipa Trust Policy"
        +}
      • addedInput schema / properties / runtime_configuration
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Runtime Configuration"
        +}
    • Changedaudit_start5 fields changed
      • addedInput schema / properties / apk_set_device
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Apk Set Device"
        +}
      • addedInput schema / properties / dependency_evidence
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Dependency Evidence"
        +}
      • addedInput schema / properties / dependency_module
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Dependency Module"
        +}
      • addedInput schema / properties / ipa_trust_policy
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ipa Trust Policy"
        +}
      • addedInput schema / properties / runtime_configuration
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Runtime Configuration"
        +}
    • Changeddependency_check4 fields changed
      • addedInput schema / properties / exclude_coordinates
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Exclude Coordinates"
        +}
      • addedInput schema / properties / exclude_ecosystems
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Exclude Ecosystems"
        +}
      • addedInput schema / properties / exclude_names
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Exclude Names"
        +}
      • addedInput schema / properties / query_mode
        Added value: +{
        +  "default": "auto",
        +  "title": "Query Mode",
        +  "type": "string"
        +}
    • Changedreports_compare2 fields changed
      • addedInput schema / properties / portable_inputs
        Added value: +{
        +  "default": false,
        +  "title": "Portable Inputs",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / verification
        Added value: +{
        +  "default": false,
        +  "title": "Verification",
        +  "type": "boolean"
        +}
  2. 10 tool updatesv1.5.1
    • Changedaudit_scan3 fields changed
      • addedInput schema / properties / configuration
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Configuration"
        +}
      • addedInput schema / properties / source_module
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Source Module"
        +}
      • addedInput schema / properties / specs
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Specs"
        +}
    • Changedaudit_start3 fields changed
      • addedInput schema / properties / configuration
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Configuration"
        +}
      • addedInput schema / properties / source_module
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Source Module"
        +}
      • addedInput schema / properties / specs
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Specs"
        +}
    • Changedpolicy_evaluate2 fields changed
      • addedInput schema / properties / baseline_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Baseline Path"
        +}
      • addedInput schema / properties / baseline_sha256
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Baseline Sha256"
        +}
    • Addedreports_checklist
    • Addedreports_export_baseline
    • Changedreports_get6 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "default": 0,
        +  "title": "Cursor",
        +  "type": "integer"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 20,
        +  "title": "Limit",
        +  "type": "integer"
        +}
      • addedInput schema / properties / max_bytes
        Added value: +{
        +  "default": 65536,
        +  "title": "Max Bytes",
        +  "type": "integer"
        +}
      • addedInput schema / properties / section
        Added value: +{
        +  "default": "findings",
        +  "title": "Section",
        +  "type": "string"
        +}
      • addedInput schema / properties / severity
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Severity"
        +}
      • addedInput schema / properties / status
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Status"
        +}
    • Addedreports_history
    • Addedreports_ingest_sarif
    • Addedspecs_validate
    • Addedverify_finding
  3. 17 tool updatesv1.0.3
    • First observedaudit_reassess
    • First observedaudit_scan
    • First observedaudit_start
    • First observedcapabilities
    • First observeddependency_check
    • First observedintelligence_get
    • First observedintelligence_search
    • First observedintelligence_sync
    • First observedjobs_cancel
    • First observedjobs_list
    • First observedjobs_status
    • First observedpolicy_evaluate
    • First observedreports_compare
    • First observedreports_get
    • First observedreports_list
    • First observedruntime_devices
    • First observedruntime_plan

TDQS

B3.4/5.0

Scored across 23 tools

Disambiguation4/5

Most tools map to distinct resources and actions (jobs_*, intelligence_*, reports_*, runtime_*), but audit_scan and audit_start have nearly identical descriptions covering the same APKS/IPA/configuration semantics, making it hard to know which to choose initially. dependency_check vs intelligence_search also have mild boundary overlap around CVE lookups, but are distinguishable.

Naming Consistency5/5

Names follow a strict namespace_action snake_case pattern (audit_scan, reports_get, intelligence_sync, jobs_cancel, runtime_plan) with a clear domain prefix throughout. No camelCase mixing or divergent verb styles; the convention is fully predictable.

Tool Count4/5

23 tools is on the heavy end and sits just below the 'heavy' threshold, but the server spans several genuine sub-domains (scanning, reports, intelligence, jobs, runtime, policy) so most tools earn their place. A few report variants could potentially be consolidated.

Completeness4/5

The audit/report lifecycle is well covered (start, scan, reassess, list, get, compare, checklist, history, export, ingest, verify) plus intelligence, jobs, runtime, and policy. Minor gaps exist, such as no report deletion and specs_validate existing without a spec-creation tool, but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP clients to drive the complete mobile security toolkit—static/dynamic analysis, Frida hooks, runtime exploration, traffic interception, network setup, and IoT scans—through engine-exposed tools.
    1
    GPL 3.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to scan codebases, persist and prioritize security findings against SLAs, retrieve CVE details, propose fixes, and create tickets through its tools. It also supports agent-assisted remediation drafting while enforcing human approval and preventing auto-merge.
    1
    MIT