Skip to main content
Glama
chiz0me

express-recon-mcp

by chiz0me

express-recon

For GitHub App authentication, portable application workspaces, offline validation, and Git-friendly rendering, see the Git inventory workflow.

Fast, offline-first route scanner, authentication auditor, and OpenAPI generator for Express, Fastify, and NestJS.

It statically inspects supported JavaScript and TypeScript route patterns, authentication middleware, and schema evidence to generate an OpenAPI (Swagger) inventory — without executing your code or running your server (with optional worker execution available for runtime Express inspection). Unresolved paths and incomplete route graphs remain visible for review instead of being presented as confirmed coverage.

💡 In Simple Words:

  • Route Inventory: Recovers supported endpoints (GET /users, POST /login, etc.) and attached middleware, while reporting analysis gaps explicitly.

  • public: Means no recognized authentication middleware was found by your audit configuration on this route. (This is relative to your configuration and does not prove the endpoint is reachable from the public internet).

  • proven: Means a recognized authentication guard or middleware configured in your allowlist was located on the route (it does not prove the internal logic inside that guard is bug-free).

  • unknown: Means the route has an inline function or custom logic that needs a quick manual review by a developer.

  • OpenAPI / Swagger: Automatically generates or updates an OpenAPI 3.1 contract from your actual routes and validation schemas.


Why express-recon?

  • 🔒 Safe Static-First Analysis: Static mode analyzes code using Abstract Syntax Tree (AST) parsing without booting your application, connecting to databases, or executing code. For advanced Express inspection, optional runtime and hybrid modes execute trusted code in an isolated worker process.

  • 🌐 Local-First and Private by Default: Runs entirely on your local machine or CI runner without external cloud dependencies. No source code, routes, or tokens are sent externally unless you explicitly invoke remote features (such as scanning remote Git repositories or sending webhook notifications).

  • ⚡ Multi-Framework Support: Works seamlessly across Express 4 & 5, Fastify 4 & 5, and NestJS 10 & 11 (including TypeScript DTOs and decorators).

  • đŸ›Ąī¸ CI/CD Quality Gates: Can block pull requests on configured route, documentation, completeness, or policy findings.

  • 🤖 AI-Ready with MCP: Comes with a built-in Model Context Protocol (MCP) server so AI coding assistants (like Cursor, Claude Desktop, or Gemini CLI) can understand your backend architecture safely.


Related MCP server: MCPSentry

Start here

System Requirements: Node.js ^20.19.0 or >=22.12.0.

Install express-recon in your project as a development dependency so your whole team and your CI pipeline use the locked version:

npm install --save-dev express-recon
npx --no-install express-recon --help

The package installs two binaries: express-recon for CLI workflows and express-recon-mcp for the static local MCP server.

â„šī¸ Good to know: Local commands like discover, inventory, audit, docs, refresh, and middleware review do not use the network, do not install packages, and do not import application code. Installing the npm package is the only step that uses the network.


Five-minute quick start tutorial

Follow these four simple steps to scan your project, find all API endpoints, and check your security guards.

Step 1: Discover your repository structure

Run discover to find all applications, frameworks, entry files, and existing Swagger/OpenAPI files in your project:

npx --no-install express-recon discover --src . --out .express-recon

What happens? This creates .express-recon/discovery.json. It inspects your project and identifies:

  • Which frameworks are in use (Express, Fastify, or NestJS).

  • Each distinct application and its unique ID (for example, app:src/app.js#app).

  • Where your main server file is located.

  • Any existing OpenAPI specifications or JSDoc comments.

Step 2: Build a complete route inventory

Run inventory to get a list of every API route without any security judgment:

npx --no-install express-recon inventory --src . --format json,md --out .express-recon

What happens? This writes two files:

  1. routes.json: A machine-readable catalog of every endpoint, method, and middleware.

  2. routes.md: A clean, readable Markdown table showing all your routes.

💡 Ignoring files: If you have files you want to skip (such as build outputs, tests, or legacy code), create an .express-reconignore file in your project root. It uses standard glob patterns (like client/** or dist/**).

Important: Add .express-recon/ to your .gitignore so generated reports are not accidentally committed, unless you intentionally want to save a baseline.

Step 3: Identify authentication guards

Run suggest-auth to automatically detect functions in your code that look like authentication middleware:

npx --no-install express-recon suggest-auth --src . > .express-recon/auth-candidates.json

What happens? The tool looks for common auth naming patterns (such as requireAuth, authenticate, verifyToken, jwtGuard, requireAdmin) and ranks them for you.

Check these candidates, then create a simple configuration file named recon.config.yaml in your project root:

# 1. Tell express-recon which middleware protect your APIs:
authMiddleware:
  requireAuth: authenticated
  requireAdmin:
    tags: [admin]
    roles: [administrator]

# 2. List routes that are intentionally public (so audit will not flag them):
acceptedPublic:
  - applicationId: app:src/app.js#app
    method: GET
    path: /health
  - "POST /login"
  - "POST /register"

💡 Tip: In single-app repositories, simple strings like "POST /login" work great. For multi-app monorepos, use the structured form with applicationId to target the specific app.

Step 4: Audit routes and enforce security in CI/CD

Now, run audit to check every route against your configuration and fail if any unauthenticated endpoint is exposed:

npx --no-install express-recon audit --src . --config recon.config.yaml \
  --format json,md --out .express-recon \
  --fail-on public,unknown,incomplete

Understanding Exit Codes:

  • Exit code 0: All checks passed! Every route is either authenticated (proven) or explicitly listed in acceptedPublic.

  • Exit code 2: Security rule matched! One or more routes are unprotected (public), need review (unknown), or have incomplete static coverage. In CI/CD pipelines (like GitHub Actions), this will intentionally fail the build to stop vulnerable code from being deployed.

  • Exit code 1: General operational error (such as a missing file or invalid CLI flag).

Choose the right workflow

Here is a quick cheat sheet to help you pick the right command for your task:

What do you want to do?

Command to run

Does code run?

Uses network?

Primary output

Understand an unfamiliar repo

discover

No

No

Apps, packages, entry points, and existing docs

List all routes without security checks

inventory

No (in static mode)

No

Complete route registry in JSON & Markdown

Check auth and enforce security rules

audit

No (in static mode)

No

Security findings, audit summary, and policy checks

Combine OpenAPI, JSDoc, and code routes

docs

No

No

Reconciled OpenAPI 3.1 specification & drift report

Keep an AI-enriched OpenAPI spec up to date

refresh

No

No

Updated OpenAPI spec preserving manual descriptions

Review complex middleware with an AI agent

review-middleware

No (in static mode)

No

Bounded evidence bundle for human or AI review

Validate and import review suggestions

import-review

No

No

Validated advisory configuration suggestions

Scan a single remote Git repository

scan-repo

No

Yes (Git fetch)

Provenance plus complete static inventory/audit

Scan every repository in a GitHub Org

scan-org

No

Yes (GitHub API)

Multi-repo inventory with progress and HTML sites

View saved reports in a browser (Swagger UI)

render

No

No

Clean, self-contained offline HTML website

Send route change alerts to Slack/Webhook

notify

No

Yes (Webhook POST)

Signed, secure notification events

Inspect complex dynamic Express routing

inventory (hybrid)

Yes

App-dependent

Combined static and runtime route observations


Framework support at a glance

express-recon understands the unique routing and lifecycle patterns of each framework:

Framework

Static route discovery

Lifecycle & Middleware evidence

Runtime / Hybrid mode

Express (4 & 5)

Apps, routers, nested mounts, route chaining (app.route()), input schemas (Zod, Joi, express-validator)

app.use(), router middleware, and route-level guards

Fully supported for trusted local code

Fastify (4 & 5)

Root instances, plugins, prefixes, encapsulated scopes, direct registrars, and route schema options

Request hooks (onRequest, preHandler, etc.) and per-route hooks

Static-first (use --mode static)

NestJS (10 & 11)

Modules, controllers, global prefixes, route mappings, TypeScript DTOs, and class-validator

Guards (@UseGuards), interceptors, pipes, and filters

Static-first (use --mode static)

â„šī¸ How it handles unknown patterns: If Fastify or NestJS uses dynamic wiring (such as an unresolved object spread or dynamic module import), express-recon does not pretend everything is fine. It marks the affected route as unknown or adds an opaque route diagnostic, alerting you that manual review is needed.


Key concepts explained in simple words

express-recon follows a strict principle: separate facts from security decisions.

  1. inventory records facts: It lists routes, middleware names, source file line numbers, and request/response shapes. It never makes a security judgment on its own.

  2. audit applies your security decisions: It takes the inventory and checks it against your authMiddleware rules and acceptedPublic list.

  3. The Three Auth Statuses:

    • đŸŸĸ proven: The route has a confirmed guard that matched your authMiddleware configuration.

    • 🔴 public: No configured guard matched this route. This indicates that no recognized authentication middleware was found under your current configuration (it is configuration-relative and does not prove reachability or lack of network-level security).

    • 🟡 unknown: An inline closure or anonymous function is in the middleware chain. It might be checking auth, or it might not. You should inspect it manually.

  4. Stable Application IDs: In modern projects, a single repository might contain multiple services. express-recon gives each detected app a stable identifier (e.g. app:src/app.js#app, fastify:src/server.js#server, or nestjs:src/main.ts#app). Identical paths in separate apps are never accidentally mixed up.

Every JSON report is deterministic and versioned. Run npx --no-install express-recon schema to view its JSON Schema. For field-by-field details, see the CLI and report reference.

Common workflows

1. Working with Monorepos and Multi-App Repositories

If your repository contains multiple services (for example, a public API in apps/public and an admin API in apps/admin), run discover first to see their unique application IDs:

npx --no-install express-recon discover --src . --out .express-recon

Then, target a specific app using --app-id:

npx --no-install express-recon docs --src . \
  --app-id 'app:apps/public/src/app.js#app' \
  --out .express-recon/public-api

💡 Why use --app-id? In a monorepo, multiple packages might have an app.js or server.ts. Specifying --app-id ensures that express-recon audits only the intended application and does not accidentally mix routes from different services.

For trusted hybrid scans on an Express app, you can bind the runtime entry point to that exact app ID:

npx --no-install express-recon audit --mode hybrid --src . \
  --app ./apps/public/src/app.js \
  --app-id 'app:apps/public/src/app.js#app' \
  --config recon.config.yaml --format json

2. Merging Existing OpenAPI specs and swagger-jsdoc

If your project already has an OpenAPI specification or JSDoc comments (@openapi or @swagger), run docs to reconcile them with your actual code:

npx --no-install express-recon docs --src . --app-id 'app:src/app.js#app' \
  --out .express-recon/docs \
  --fail-on docs-conflict,docs-incomplete

How conflicts are resolved:

  1. Authored OpenAPI specification has the highest priority and is treated as truth.

  2. JSDoc comments fill in any missing parameter descriptions, summaries, and tags.

  3. Static code analysis fills in any remaining routes or parameter shapes found in your source code.

  4. Conflict detection: If code and docs disagree (for example, a route exists in code but is missing from docs, or vice versa), it is clearly flagged in docs-report.json.

📘 Learn more in the detailed OpenAPI guide.


3. Keeping AI-Enriched OpenAPI Documentation in Sync (refresh)

When documenting an API, you or an AI agent might write rich summaries and descriptions in openapi.json. When the backend code changes, you don't want those manual descriptions to be wiped out!

The refresh command creates a living documentation workspace:

# 1. Initialize or update the documentation workspace:
npx --no-install express-recon refresh --src . \
  --app-id 'app:src/app.js#app'

By default, this writes to .express-recon/api. On every run, it performs a fresh static inventory, compares routes with the previous run, and rebuilds an offline Swagger UI site under api-reference/.

How to safely enrich descriptions:

  1. You or an AI agent can edit summary, description, parameters, requestBody, responses, and components.schemas in .express-recon/api/openapi.json.

  2. Explicitly accept your changes:

    npx --no-install express-recon refresh --src . --accept-enrichment

Why this is helpful:

  • Your accepted descriptions are saved in openapi.enrichment.json.

  • When backend code changes, routes that stayed the same keep their descriptions automatically.

  • Only newly added or modified routes are flagged as unreviewed or stale in refresh-report.json.

  • If a description depends on delegated code beyond the detected route and handler files, add repository-relative paths to that operation's x-express-recon.enrichmentSources before acceptance.

  • In CI/CD, you can gate on --fail-on enrichment-stale,enrichment-unreviewed to ensure all API changes are properly documented.


4. Reviewing Complex Middleware with an AI Agent

If your project has complex custom middleware that the static scanner cannot automatically verify, you can bundle the evidence for review:

# 1. Create a review bundle of all uncertain middleware:
npx --no-install express-recon review-middleware --src . --out .express-recon/review

# 2. Provide middleware-review.json to a teammate or an AI model, then validate their response:
npx --no-install express-recon import-review \
  --review .express-recon/review/middleware-review.json \
  --assessment middleware-assessment.yaml \
  --out .express-recon/review

The review bundle extracts exact code snippets, callsites, and routes. The import-review command validates the assessment against a strict schema and provides advisory suggestions without granting automatic authority. See the AI agent guide.

5. Scanning Remote Git Repositories and GitHub Organizations

Scanning a single Git repository (scan-repo)

You can scan a remote repository directly without manually cloning it or running npm install:

npx --no-install express-recon scan-repo --repo owner/project --ref main \
  --out .express-recon/remote

How it works safely:

  • Performs a shallow Git fetch over HTTPS without checking out files, running hooks, installing dependencies, or executing code.

  • Generates repo-scan.json containing discovery, inventory/audit, documentation status, and commit provenance.

  • For private repositories, set the GH_TOKEN (recommended) or GITHUB_TOKEN environment variable. The token is used in-memory and never saved to disk.

  • See SECURITY.md for details on the security model.

Scanning an entire GitHub organization (scan-org)

To get a complete security inventory of every backend service across your company or GitHub organization:

# 1. Scan all repositories in an organization (skips forks and archived repos by default):
npx --no-install express-recon scan-org --org acme \
  --concurrency 2 --max-repos 500 \
  --fail-on incomplete

# 2. Resume an interrupted scan (picks up right where it left off!):
npx --no-install express-recon scan-org --org acme \
  --concurrency 4 --max-repos 500 \
  --fail-on incomplete --resume

# 3. Update an existing scan (only rescans repos that had new git commits):
npx --no-install express-recon scan-org --org acme \
  --max-repos 500 --concurrency 2 --update

# 4. Compare today's scan with last month's scan to see newly added or removed routes:
npx --no-install express-recon scan-org --org acme \
  --baseline .express-recon/acme-before \
  --out .express-recon/acme-current --concurrency 2 --max-repos 500 \
  --fail-on incomplete

Organization scans always use durable output: omitting --out derives .express-recon/<lowercase-organization> from the current directory.

Key features for organization scanning:

  • Framework Detection: Distinguishes Express, Fastify, and NestJS apps from packages that merely list the framework as a dependency.

  • Checkpoint & Resume (--resume): If your network disconnects or CI times out, running with --resume verifies SHA-256 digests and only scans incomplete or failed repositories.

  • Smart Updates (--update): Compares GitHub push commit markers and only scans repositories that have changed since the last inventory.

  • Delta Reports (--baseline): Compares two organization runs and generates organization-delta.json, detailing new routes, deleted routes, and auth regressions.

  • Token Efficiency for AI: Set EXPRESS_RECON_CONTEXT=agent so AI assistants inspect the compact aggregate index first without wasting context tokens on massive logs. See the AI agent guide.

Check out our production-ready scheduled organization inventory example for automated GitHub Actions workflows with Slack notifications.


6. Browsing Saved Reports as an Offline HTML Website (render)

Turn your JSON scan reports into a beautiful, static HTML website with an interactive Swagger UI:

# Render from the default .express-recon/ output directory:
npx --no-install express-recon render

# Render from an organization scan:
npx --no-install express-recon render \
  --input .express-recon/acme \
  --out .express-recon/acme-site

# Render a side-by-side comparison of changes between two scans:
npx --no-install express-recon render \
  --baseline .express-recon/acme-before \
  --input .express-recon/acme-current \
  --out .express-recon/acme-changes-site

# Render a single OpenAPI file with packaged Swagger UI:
npx --no-install express-recon render \
  --input .express-recon/docs/openapi.json \
  --out .express-recon/api-reference

With no paths, render looks only at the current directory, .express-recon/, and its immediate child directories. The default output is a sibling named <input>-html.

Organization pages show repositories with discovered routes in the main table, grouped as complete and incomplete. Repositories with zero discovered routes, including complete scans, are collapsed below under No routes discovered. Other statuses are grouped in a collapsed reference table. Each table has independent search, completion/status, and framework filters. Framework choices reflect the saved evidence; mixed-framework repositories match each included framework. When saved domain data includes hostnames, a separate Domain filter searches any part of a hostname, ignoring case, and combines with the other filters. Repository tables wrap long values on wide screens and use labelled rows on narrow screens so all columns remain visible without horizontal scrolling. The overview groups related totals into summary cards, with percentages alongside raw counts. Also in API docs shows how many discovered routes match authored OpenAPI, Swagger, or JSDoc evidence, and route details identify their documentation sources. Each route counts once, even if multiple specifications or path variants match. Missing evidence, uncertain paths, and ambiguous application ownership stay Not checked rather than implying zero overlap. Generated-only operations do not count as authored documentation. Invalid API specifications appear in a collapsed Show details section below the repository tables. Repository tables sort each completion group by route count from high to low by default. The Sort control can reverse that order, sort by app/module count, or sort repository names alphabetically without changing the active filters.

Optional saved gin-recon outputs are supported by the renderer only—no Gin scanner or changes to the scan architecture are required. Point --input at a fleet.json, its directory, or a bundle containing that directory. When an organization output also contains a matching Gin fleet (directly or one directory below), its routes, per-module OpenAPI references, middleware suggestions, and producer statistics are included automatically. Original JSON evidence is linked for download. Existing Express scans and Gin scans retain separate detail pages. See the render reference for limits and trust boundaries.

Deployment domains can be scanned independently and saved as domain-inventory.json beside organization-inventory.json. Plain express-recon render --input <scan-output> automatically reads this optional sidecar: it adds repository domain counts, domains.html, joined evidence in domain-merge.json, and safe OpenAPI server enrichment. The original route artifacts and domain catalog are not rewritten. scan-org --update, --resume and --overwrite leave this producer-owned sidecar (and optional domain-bindings.json) untouched. The separate domain-recon package can write it directly with scan --org <owner> --express-output <scan-output>. See the domain sidecar contract.

Other tools can export a versioned render-bundle.json with routes, OpenAPI, statistics, and JSON evidence. Matching bundles alongside an organization output are included automatically; arbitrary files are not guessed or executed. See the schemas and integration guide, synthetic example, and reusable express-recon-render-port skill.

Why the offline site is great:

  • 100% Offline: Embedded CSS and JavaScript. Open index.html directly in your browser (file://) without running a web server or needing an internet connection.

  • Direct-file compatible: Each page includes its viewing assets and branding, including Swagger UI on API pages. Keep the output folder together for links to other pages and evidence downloads.

  • Packaged Swagger UI: Easily browse and inspect API endpoint contracts without sending live network requests.

  • Privacy & Security: Built with a strict Content Security Policy (CSP). It disables external network calls, tracking, and remote analytics.


7. Enforcing Pull-Request Security Gates in CI/CD

Prevent developers from accidentally merging unauthenticated routes or breaking documentation:

# Step 1: Scan the base branch (e.g. main)
npx --no-install express-recon audit --src ./base --config recon.config.yaml \
  --format json --out ./base-results --fail-on incomplete

# Step 2: Scan the pull request and fail ONLY on newly introduced public routes or regressions:
npx --no-install express-recon audit --src ./current --config recon.config.yaml \
  --baseline ./base-results/routes.json \
  --format json,md --out ./current-results \
  --fail-on new,regression,incomplete
  • If a developer introduces a new route without auth, audit exits with code 2, blocking the PR.

  • Existing accepted routes from the baseline do not cause false alarms.

  • See our ready-to-copy GitHub Actions PR workflow with automated PR comments and annotations.

To send real-time alerts when new routes are merged:

  • Use our trusted Slack notifier example to post new endpoints directly to your team's Slack channel.

  • Or use our signed webhook example for custom webhook listeners. The notify command emits bounded events for added/removed/semantically changed routes, authentication regressions, and incomplete scans from either a repository or organization comparison. Delivery uses HMAC-SHA256 Standard Webhooks headers, an exact committed hostname allowlist, HTTPS-only/no-redirect requests, current plus previous secret rotation, bounded retry, and deterministic event IDs for receiver-side deduplication. Secrets are read only from named environment variables; --dry-run needs neither a URL nor a secret.

npx --no-install express-recon notify \
  --input current-results/routes.json \
  --events routes.added,routes.changed,auth.regressed,scan.incomplete \
  --dry-run

Runtime and hybrid trust boundary

Static mode is the default and is appropriate for untrusted source. Runtime and hybrid modes import the app inside a bounded child process. That process contains crashes, process.exit(), leaked timers, and serialized output, but it is not an OS sandbox: trusted target code retains filesystem, process, and network permissions.

# Explicit trusted entry:
npx --no-install express-recon inventory --mode hybrid --src . --app ./src/app.js

# Conservative auto-selection; fails unless discovery finds exactly one app and
# one high-confidence entry:
npx --no-install express-recon inventory --mode hybrid --src . \
  --app auto --allow-exec

The worker sets EXPRESS_RECON_DRY=1, starts with an isolated environment, and can stub common infrastructure clients. Native ESM dependency imports are not intercepted by the CommonJS stubbing layer. Full boot configuration and static resolution details are in the reference and security model.

MCP server for AI agents

The stdio MCP server exposes static local tools only. It cannot acquire remote repositories or execute target code.

{
  "mcpServers": {
    "express-recon": {
      "command": "npx",
      "args": ["--no-install", "express-recon-mcp"],
    },
  },
}

Core tools include discover_repository, inventory_routes, audit_routes, query_audit, explain_route, finding_by_fingerprint, suggest_auth, openapi_spec, reconcile_openapi, token-bounded refresh_openapi/query_refresh, review_middleware, import_middleware_review, validate_policies, and report_schema.

query_audit pages are byte-bounded and tied to a retained analysis snapshot, configuration, and filters. Pass the returned snapshotId to explain_route for the bounded registration and uncertainty evidence behind one route.

Useful requests are precise about the evidence boundary:

Inventory every supported app in this repository. Group results by framework and application ID, and report coverage and partial paths before conclusions.

Audit routes using requireAuth as the only confirmed authentication guard. List public and unknown separately; do not call either internet-reachable.

Reconcile the selected app's existing OpenAPI document and report code-only, docs-only, conflicting, duplicate, and incomplete operations.

See the AI agent guide for tool selection and a required evidence checklist.

The MCP server intentionally has no remote or organization-scanning tool. Run scan-org explicitly in the CLI, then give an agent the generated aggregate and per-repository reports.

Library

const {
  inventory,
  audit,
  discover,
  buildReport,
  compareOrganizationReports,
  reconcileDocumentation,
  createMiddlewareReview,
  applyMiddlewareAssessments,
  scanRepository,
  scanOrganization,
  renderHtmlSite,
  buildNotificationEvents,
  deliverWebhook,
  signWebhook,
  validateNotificationEvent,
  verifyWebhookSignature,
  executeRuntime,
  formatters,
} = require("express-recon");

const source = inventory({ mode: "static", src: "." });
const report = buildReport(source, {
  command: "inventory",
  mode: "static",
  sourceRoot: ".",
});

console.log(formatters.markdown.format(report));

async function observeOrganization() {
  return scanOrganization("acme", {
    concurrency: 2,
    onProgress(event) {
      process.stderr.write(`${JSON.stringify(event)}\n`);
    },
  });
}

renderHtmlSite(".express-recon/acme", ".express-recon/acme-site");

Static library inventory supports Express, Fastify, and NestJS repositories. Passing an already loaded Express app to inventory()/audit() executes it in the caller's process; runtime and hybrid modes are Express-only. Prefer executeRuntime() when a bounded worker result is needed. The library reference describes the shared behavior; the complete API reference documents every public export.

Documentation

npm run docs:coverage derives the supported CLI, configuration, library, and example surfaces from the repository and requires 100% documentation and public API JSDoc coverage.

Known boundaries

  • Static analysis cannot fully recover data-driven route registration, arbitrary dependency injection, computed mounts, or every TypeScript resolution pattern. It retains partial evidence and diagnostics instead of silently dropping it.

  • Documentation-only operations are split into verified and unverified drift when unresolved route graphs or opaque route providers prevent a sound stale- documentation conclusion.

  • Auth classification is only as sound as the reviewed middleware allowlist.

  • OpenAPI generation prefers statically resolved framework schemas, validators, DTOs, and returned literals over field-name placeholders. Unsupported computation and low/medium-confidence fragments remain explicitly unrefined; the bundled openapi-doc skill provides the deeper AI-assisted pass.

  • scan-repo is non-executing, but Git protocol parsing and network transfer still process untrusted remote data.

  • Organization scans are API-visible rather than proof of every repository that exists; token permissions define visibility.

  • Runtime/hybrid mode is Express-only and for trusted local code only.

Frequently asked questions (FAQ)

In static mode (the default), no. Static analysis parses your code's AST using oxc-parser, reading .js and .ts files as structured text without booting your server, connecting to databases, or executing any code. If you explicitly choose runtime or hybrid mode for advanced Express inspection, it executes trusted code in an isolated worker process.

Exit code 2 is an intentional policy gate signal, not an application crash. With --fail-on public,unknown, express-recon returns exit code 2 when a route has no configured guard match (public) or has middleware that still requires review (unknown). In CI/CD, this stops the job on those configured policy findings; it does not prove that a route is internet-reachable or that a recognized guard is effective at runtime.

Add it to the acceptedPublic list in your recon.config.yaml:

acceptedPublic:
  - "GET /health"
  - "POST /login"

Once listed, audit knows this route is intentionally open to the public and will not flag it as a violation.

Yes! express-recon parses TypeScript natively, resolves tsconfig.json path aliases (such as @/controllers/*), handles barrel exports (index.ts), and extracts TypeScript DTO validation schemas.


MIT licensed. Security issues should be reported privately as described in SECURITY.md.

Classify before organization scans

Use classify-org --org acme --out .express-recon/acme to build a persistent framework catalog and JavaScript/Gin scan plan without cloning every repository. Pass --classification-cache .express-recon/acme/repository-classification.json to scan-org to use it. Exact-commit classifications survive --overwrite fresh route scans; --reclassify forces fresh classification. Unknown repositories stay eligible, and mixed-framework repositories can run both scanners. See the classification reference.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Scan APIs for security vulnerabilities and get OWASP risk scores. Detects auth bypass, BOLA/IDOR, data exposure, prompt injection, and 12+ security categories.
    24 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    The MCP bridge that audits your routes before exposing them to LLMs and blocks prompt-injection at runtime.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP-compatible clients to inspect Next.js codebases, analyze App Router and Pages Router structure, discover API routes, and audit build performance through controlled tools.
    7 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely operate Express applications through a permission-scoped MCP server, with static analysis and audit logging.
    2 npm
    Apache 2.0