Back to Browse

Semver Checks MCP Server

Developer ToolsLow Risk10.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

Detect breaking changes in your TypeScript library's public API and recommend the SemVer bump.

About

Detect breaking changes in your TypeScript library's public API and recommend the SemVer bump.

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (2 strong, 2 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry. Trust signals: 3 highly-trusted packages.

10 files analyzed · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

file_system

Check that this permission is expected for this type of plugin.

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-kyungseopk1m-semver-checks": {
      "args": [
        "-y",
        "semver-checks"
      ],
      "command": "npx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

npm version CI License: MIT Node.js Version

semver-checks

Catch the breaking changes your commit messages miss. semver-checks analyzes what actually changed in your TypeScript public API and recommends the correct semver bump.

npx semver-checks compare v1.0.0 HEAD

Why semver-checks?

Tools like semantic-release and changesets rely on developers writing correct commit messages. In practice, commit messages don't always reflect actual API impact — a "small refactor" that removes a required export gets published as a patch, and downstream consumers' builds break.

semver-checks analyzes your TypeScript public API directly using ts-morph and recommends the correct SemVer bump based on what actually changed in the type signatures — not what the commit message says.

This is not hypothetical. Run it across real releases and it flags breaking type changes that shipped as minors or patches — for example, p-limit 6.1.0 added a required property to its exported LimitFunction type and was published as a minor; semver-checks flags it MAJOR. It is most dependable on structural changes — removed or renamed exports, narrowed signatures, added required parameters and properties — which it detects reliably. Equivalence-preserving type rewrites are a known weak spot it can over-report; see Accuracy & Limitations for exactly where to trust it and where not to.

// v1.0.0
export interface Config {
  host: string;
  port: number;
}

// Developer writes: "fix: add missing timeout config"
// Published as patch — but this is a MAJOR change:
export interface Config {
  host: string;
  port: number;
  timeout: number;
}
//                                                    ^^^^^^^^^^^^^^^^ required-property-added
// v1.0.0
export function findUser(id: string): User | null;

// Developer writes: "refactor: simplify findUser return"
// Published as minor — but consumers checking `result === null` silently break at runtime:
export function findUser(id: string): User;
//                                    ^^^^ return-type-changed (MAJOR)

semver-checks is complementary to your existing release workflow. Use it as a verification step before publishing — it tells you whether your intended bump is safe, or whether you're about to ship a breaking change by accident.

Accuracy & Limitations

semver-checks grades every breaking change by confidence, so the CI gate stays trustworthy:

  • proven — the break follows from a structural fact (a member added/removed, an optionality/readonly/static transition, an enum or overload change) or from a resolved type relation the analyzer decided is genuinely unrelated. --strict exits 1 on these, and only these — safe to leave on in CI.
  • heuristic — a conservative MAJOR the analyzer could not prove (a type-text difference it couldn't resolve, or a one-directional change in an invariant position where a safe reading exists). These surface for human review but do not fail --strict; opt in with --strict-review if you want every MAJOR to gate.

This is the design's center of gravity: the equivalence-preserving rewrites and input-union widenings that make text-based type-semver tools cry wolf land in heuristic, off the default gate, while real under-bumps stay proven and on it. It is neither sound (zero false positives) nor complete (catches everything), so a proven MAJOR is a strong signal, not a theorem. That isolation only covers the over-reporting surfaces in Known limitations; the under-report and structural rows in the same table are a different axis, a silent patch or an outright failure, not a confidence question.

It is most reliable on conventional, single-entry packages with an explicitly-typed public surface: added / removed / renamed exports, function and method signature changes, added required parameters and properties, and removed members are detected dependably and reported as proven.

Measured. Across 44 adjacent real-world npm release pairs (.d.ts.d.ts, seven API shapes, the author's published bump as the oracle), 37 were analyzable. Of those, 19 matched the published bump exactly, 9 were stricter than the published bump, and 9 were looser. The graded gate splits the 9 stricter rows cleanly: --strict fires on 4 of them — real breaks the author shipped under-bumped: p-limit 6.1.0 and ky 1.14.0 each added a required property to an exported type yet released as a minor (tsc confirms a TS2741 for implementers), commander 12.1.0 removed a public method, and commander 14.0.2 turned the optional cb parameter of Command#outputHelp and Command#help into a required one in a patch — while the other 5 (the equivalence rewrites, input-union widenings, and return-only generics on the surfaces below) demote to review-only and pass the gate. Most of the looser results are releases bumped for runtime-only reasons with no public type change. Reproduce the scorecard with scripts/accuracy-probe.mjs (after npm run build), or spot-check your own dependencies:

npx semver-checks compare <pkg>@<previous> <pkg>@<latest>

Known limitations

Ten known gaps, grouped by direction: three over-report as review-only heuristic MAJORs that never fail --strict (equivalence-preserving type rewrites, input-position union widening, return-only generics); four under-report as a silent patch (shallow class reads, non-ambient class method overload reordering, skipped constructor comparison on generic/mixin subclasses, a handful of declaration-level distinctions); and three are structural rather than a grading question (multi-subpath double counting, memory limits on deeply recursive types, non-standard entry layouts). Full table below.

AreaWhat happensWhy
Equivalence-preserving refactorsReplacing a type with an equivalent one — an alias swap like Exclude<…>SetDifference<…>, or { [P in K]: T }Pick<T, K> — is reported as a type-alias-changed, but as a review-only (heuristic) MAJOR, off the --strict gate.Type aliases and variables are compared as normalized text, not by resolving both types and checking assignability; an unresolved comparison is graded heuristic.
Input-position widening in aliasesWidening a union used as an input (e.g. adding bigint to a parameter-only union) is reported MAJOR, though it accepts strictly more — graded heuristic (the relation is one-directional in an invariant position), so --strict does not gate on it.Variance is analyzed for function parameters and returns, but not inside a type alias body.
Type parameters added to functionsAdding a return-only type parameter (fn(): stringfn<T extends string>(): T) is reported MAJOR, though existing call sites still infer the same result — graded heuristic (a generic added to a callable), off the gate.The "required generic added" rule treats a callable-context addition as review-only; in a type/interface/class context, where the argument is always written explicitly, it stays proven.
Dual-format / multi-subpath double countingA package exposing the same symbols under several exports subpaths (. plus a JS wrapper like ./esm.mjs, or . plus ./lite) reports each change once per subpath.Each .-prefixed subpath is analyzed independently; identical changes across subpaths are not yet de-duplicated.
Deeply recursive conditional typesExtremely type-heavy libraries (e.g. type-fest) can exhaust memory during extraction. Raising the heap — NODE_OPTIONS=--max-old-space-size=8192 npx semver-checks … — gets some through; there is no in-process guard, so a hard OOM still aborts.Declaration extraction has no depth/size bound on deeply recursive conditional / mapped types.
Non-standard entry layoutsA few packages whose types live only beside a JS target — no types condition, no top-level types, no root index.d.ts — can't be auto-resolved; pass --entry.Sibling-.d.ts-of-JS-target resolution is not implemented.
Class declarations are read shallowlyChanging a class's extends base, making a class or one of its members abstract, or making a class method required (m?(): voidm(): void) is reported as no change at all — a patch. The interface equivalent of the last one is detected.Only the class's own members, their types, and their static/optional/readonly flags are extracted; heritage and abstract are not.
Class method overload reordering is undetectedIn a plain .ts source (not an ambient .d.ts/declare class), reordering a class method's overload signatures is reported as no change at all (a patch), even though TypeScript resolves an overloaded call against the first matching signature in declaration order, so the reorder is a real break. Disjoint overloads (where call resolution never actually changes) still break, too: ReturnType<typeof method> always resolves to the last signature, so reordering swaps what that utility type produces.getMethods() on a non-ambient class returns one implementation node per method, so overloads are merged into a single signature (e.g. bar(x: number): void; bar(x: string): void extracts as one x: number | string signature) before comparison, losing declaration order. Ambient declarations, which have no implementation node, extract each overload separately and detect the reorder.
Constructor comparison is skipped on generic/mixin subclassesA class with no explicit constructor of its own and an extends clause has its constructor comparison skipped entirely, rather than judged against the constructor it inherits, whatever shape the base takes (a plain class, a generic instantiation like extends Base<string>, a class expression, or a mixin factory).Declaration nodes alone can't instantiate a base's type arguments, so the inherited constructor can't be resolved reliably for generics, class expressions, or mixins. Rather than risk a wrong answer, the comparison is skipped whenever a class both lacks an explicit constructor and extends something; a class with no extends at all still defaults to an implicit public zero-arg constructor.
Some declaration-level distinctions are invisibleA value export narrowed to a type-only one (export declare class Cdeclare class C; export type { C }), an enum becoming a const enum, and a second interface declaration merged into the first are all reported as no change.Exports are resolved to their declarations without recording whether the export itself was type-only, and only the first declaration of a merged symbol is read.

When a type can't be resolved in isolation (imported types, bare generics, anything involving any), semver-checks falls back to the conservative MAJOR verdict by design — see Does it have false positives?.

Quick Start

npm install --save-dev semver-checks

Compare a git tag to the current working tree:

npx semver-checks compare v1.0.0 HEAD

Compare the published npm release against your working tree — answers "is my current change a breaking release?" without needing git tags:

npx semver-checks compare your-package@latest

A <package>@<version> argument is fetched from the npm registry (via npm pack) and used as the old version. Concrete versions, ranges, and common dist-tags are auto-detected (your-package@1.2.3, your-package@^1, your-package@next). For an uncommon dist-tag, make the intent explicit with the npm: prefix or --old-as npm (npm:your-package@my-custom-tag) so it isn't mistaken for a git ref.

Compare two local directories:

npx semver-checks compare ./old ./new

Existing relative paths without a ./ prefix are also treated as local directories:

npx semver-checks compare packages/core packages/core-next

If a git ref collides with an existing path name, force ref interpretation explicitly:

npx semver-checks compare main HEAD --old-as ref

Output as JSON, Markdown (for PR comments), or GitHub Actions annotations:

npx semver-checks compare v1.0.0 HEAD --format json
npx semver-checks compare v1.0.0 HEAD --format markdown
npx semver-checks compare v1.0.0 HEAD --format github

Fail in CI if breaking changes are detected (exit 1):

npx semver-checks compare v1.0.0 HEAD --strict

Inspect the API surface of the current or a past version:

npx semver-checks snapshot
npx semver-checks snapshot --ref v1.0.0
npx semver-checks snapshot --npm lodash@4.17.21

Multiple entry points

When package.json declares an "exports" map with several subpaths, every subpath with a declared .d.ts entry is extracted and compared independently. Adding a subpath is a MINOR change and removing one is MAJOR; a change inside a subpath is reported with a # separator (e.g. ./utils#helper). No flags are needed — the map is auto-detected.

For projects without an "exports" map, pass multiple entries explicitly by repeating --entry or comma-separating them:

npx semver-checks compare v1.0.0 HEAD --entry src/index.ts --entry src/utils.ts
npx semver-checks compare v1.0.0 HEAD --entry src/index.ts,src/utils.ts

Example output

semver-checks — Recommended bump: MAJOR
  major: 2 (confident: 1, review: 1)  minor: 1  patch: 0

  Breaking Changes — confident (MAJOR)
  ✗ Required property 'timeout' was added to interface 'Config'
      now: number

  Needs review — couldn't prove safe (MAJOR)
  ? Type alias 'UserId' changed
      before: string | number
      after:  string

  New Features (MINOR)
  + Export 'createConfig' was added

--strict exits 1 on the confident break only; the review-only item passes the gate unless you opt into --strict-review.

Programmatic API

import { compare, extract } from "semver-checks";

const report = await compare({
  oldSource: { type: "git", ref: "v1.0.0" },
  newSource: { type: "path", path: "." },
});

console.log(report.recommended); // 'major' | 'minor' | 'patch'
console.log(report.changes); // ApiChange[]
console.log(report.summary); // { major: 2, minor: 1, patch: 0 }
interface CompareOptions {
  oldSource: SourceRef;
  newSource: SourceRef;
  entry?: string | string[]; // Optional: specify one or more entry points
  installDeps?: boolean; // Optional: install deps before analyzing local path sources
}

type SourceRef =
  | { type: "path"; path: string }
  | { type: "git"; ref: string; cwd?: string }
  | { type: "npm"; spec: string }; // e.g. { type: 'npm', spec: 'lodash@4.17.21' }

interface SemverReport {
  recommended: "major" | "minor" | "patch";
  changes: ApiChange[];
  summary: {
    major: number;
    minor: number;
    patch: number;
    majorProven: number;
    majorReview: number;
  };
}

interface ApiChange {
  kind: ChangeKind;
  severity: "major" | "minor" | "patch";
  symbolPath: string;
  message: string;
  oldValue?: string;
  newValue?: string;
  confidence?: "proven" | "heuristic";
}

You can also extract a snapshot independently:

import { extract } from "semver-checks";

const snapshot = await extract({ projectPath: "." });
// Snapshots are keyed by export subpath ('.' is the root entry; additional
// subpaths come from the package.json "exports" map).
console.log(Object.keys(snapshot.entrypoints["."])); // root entry's symbol names

Change Rules

Breaking changes (MAJOR)

RuleDescription
export-removedA public export was removed
entrypoint-removedA public export subpath was removed
required-param-addedA required parameter was added to a function
param-removedA parameter was removed
param-type-changedA parameter's type changed
return-type-changedA function's return type changed
property-removedAn interface property was removed
required-property-addedA required property was added to an interface
property-type-changedAn interface property's type changed
interface-property-became-requiredAn optional interface property or method became required
interface-property-became-readonlyAn interface property changed from mutable to readonly
interface-method-removedAn interface method was removed
required-interface-method-addedA required interface method was added
interface-method-signature-changedAn interface method's signature changed
enum-member-removedAn enum member was removed
enum-member-value-changedAn enum member's value changed
class-constructor-changedA class constructor's signature changed
class-constructor-visibility-narrowedA class constructor's visibility was narrowed (e.g. publicprivate)
class-method-removedA public class method was removed
class-method-signature-changedA public class method's signature changed
class-method-became-staticA class method changed from instance to static
class-method-became-instanceA class method changed from static to instance
class-property-removedA public class property was removed
class-property-type-changedA public class property's type changed
class-property-became-staticA class property changed from instance to static
class-property-became-instanceA class property changed from static to instance
class-property-became-requiredAn optional class property became required
required-class-property-addedA required class property was added
class-property-became-readonlyA public class property changed from mutable to readonly
generic-param-requiredA required generic parameter was added
generic-param-removedA generic parameter was removed
generic-constraint-changedA generic parameter's constraint changed
generic-param-default-changedA generic parameter's default type changed or was removed
overload-removedA function overload was removed
interface-call-signature-changedAn interface's call signatures changed
interface-construct-signature-changedAn interface's construct signatures changed
index-signature-changedAn interface's index signatures changed
interface-heritage-changedAn interface's extends clause changed
type-alias-changedA type alias definition changed
variable-type-changedAn exported variable's type changed

New features (MINOR)

RuleDescription
export-addedA new public export was added
entrypoint-addedA new public export subpath was added
optional-param-addedAn optional parameter was added
optional-property-addedAn optional property was added to an interface
interface-method-addedAn optional interface method was added
interface-property-became-optionalA required interface property or method became optional
interface-property-became-mutableAn interface property changed from readonly to mutable
enum-member-addedAn enum member was added
overload-addedA function overload was added
class-constructor-visibility-widenedA class constructor's visibility was widened (e.g. privatepublic)
generic-param-with-defaultA generic parameter with a default was added
generic-param-default-addedA default was added to an existing generic parameter
class-method-addedA public class method was added
class-property-addedAn optional public class property was added
class-property-became-optionalA required class property became optional
class-property-became-mutableA public class property changed from readonly to mutable
param-type-widenedA parameter's type was widened — existing callers still type-check (contravariant)
return-type-narrowedA function's return type was narrowed — existing consumers still type-check (covariant)

CLI Reference

compare

semver-checks compare <old> [new] [options]
OptionShortDescriptionDefault
--entry <path>-eEntry file path (e.g., src/index.ts); repeat or comma-separate for multiple entriesAuto-detect
--format <type>-ftext, json, markdown, or githubtext
--strict-sExit 1 if a confident (proven) breaking change is found — safe to gate CI onfalse
--strict-reviewExit 1 if any breaking change is found, including review-only (heuristic) onesfalse
--install-depsInstall dependencies before analyzing local path inputsfalse
--old-as <kind>Force <old> to be interpreted as path, ref (or git), or npmAuto-detect
--new-as <kind>Force [new] to be interpreted as path, ref (or git), or npmAuto-detect

Arguments:

  • <old>: an npm spec (pkg@version), a git ref (tag, branch, commit SHA), or a local directory path for the old version
  • [new]: npm spec, git ref, or path for the new version; defaults to . (current directory)

Output formats:

  • text — colored human-readable summary (default)
  • json — the structured SemverReport
  • markdown — a Markdown summary suitable for a PR comment or $GITHUB_STEP_SUMMARY
  • githubGitHub Actions workflow commands (::error:: / ::warning::) that surface inline on the PR

If an argument matches an existing filesystem path, semver-checks treats it as a path source even without a ./ prefix. A <package>@<version> shape that is not an existing path is resolved from the npm registry. A plain ref (v1.2.3, main) has no @version and is resolved as a git ref. A git ref that happens to share the name@version shape (e.g. a lerna/monorepo tag like pkg@1.0.0) would be auto-detected as an npm spec — force git resolution with --old-as ref in that case. Use --old-as ref / --new-as ref (or --old-as npm) when auto-detection guesses wrong.

When using git refs, the command must run inside a git repository. The ref is resolved against the working directory's repo.

snapshot

semver-checks snapshot [path] [options]
OptionShortDescription
--ref <ref>-rUse a git ref instead of a local path
--npm <spec>Snapshot a published npm package (e.g. lodash@4.17.21)
--entry <path>-eEntry file path; repeat or comma-separate for multiple entries
--install-depsInstall dependencies before analyzing a local path

Arguments:

  • [path]: project path; defaults to . (current directory)

Global options

OptionDescription
--mcpStart semver-checks as an MCP server over stdio

Environment variables

VariableDescription
SEMVER_CHECKS_VERBOSE=1Print warnings for skipped symbols, type resolution failures, and dependency install issues

MCP Server

semver-checks ships as a Model Context Protocol (MCP) server, letting AI agents (Claude Code, Codex, Cursor, etc.) call it as a tool directly.

Setup

# Claude Code
claude mcp add semver-checks -- npx -y semver-checks --mcp

Use npx -y for global-on-demand installs so the MCP server does not block on an interactive "install this package?" prompt.

Or add it to your .claude/settings.json:

{
  "mcpServers": {
    "semver-checks": {
      "command": "npx",
      "args": ["-y", "semver-checks", "--mcp"]
    }
  }
}

For a locally installed version:

{
  "mcpServers": {
    "semver-checks": {
      "command": "/path/to/node_modules/.bin/semver-checks",
      "args": ["--mcp"]
    }
  }
}

Relative paths and git refs are resolved from the MCP server process's current working directory. For reliable results, launch the server from the repository you want to inspect, or pass absolute filesystem paths for local sources.

Available Tools

ToolDescription
semver_compareCompare two versions and get a SemVer recommendation + change list
semver_snapshotExtract the public API surface of a project as a JSON snapshot
semver_compare
ArgumentTypeRequiredDescription
oldstringYesFilesystem path or git ref (tag, branch, SHA)
newstringFilesystem path or git ref. Defaults to .
entrystringEntry file (e.g. src/index.ts). Auto-detected if omitted
oldAs"path" | "git"Force interpretation of old
newAs"path" | "git"Force interpretation of new
installDepsbooleanInstall dependencies before analysis

oldAs and newAs accept only "path" or "git" in MCP mode.

semver_snapshot
ArgumentTypeRequiredDescription
pathstringFilesystem path or git ref. Defaults to .
entrystringEntry file
asGitRefbooleanTreat path as a git ref
installDepsbooleanInstall dependencies before analysis

CI Integration

GitHub Action

semver-checks ships a reusable composite action. The most ergonomic setup compares the published latest release against the PR's working tree, so it needs no git tags and posts inline annotations on the diff:

name: SemVer Check

on:
  pull_request:
    branches: [main]

jobs:
  semver-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci

      - uses: kyungseopk1m/semver-checks@v0.9.0
        with:
          old: "your-package@latest" # the published version to compare against
          format: "github" # inline ::error:: / ::warning:: annotations
          strict: "true" # fail the PR on a confident (proven) breaking change
InputDescriptionDefault
oldOld version — an npm spec (pkg@latest), git ref, or path(required)
newNew version — git ref or path.
entryEntry file (auto-detected from package.json when omitted)(auto)
formattext, json, markdown, or githubgithub
strictFail the step (exit 1) on a confident (proven) breaking changefalse
strict-reviewFail the step (exit 1) on any breaking change, including review-only (heuristic) onesfalse
versionsemver-checks version to run via npx(matches the action ref)

A full example that also posts a Markdown summary as a sticky PR comment lives in examples/github-actions.yml.

Without the action

Run the CLI directly — for example, compare the published release to the working tree:

- name: Check for breaking changes
  run: npx semver-checks compare your-package@latest --format github --strict

Or compare against a git tag:

- name: Check for breaking changes
  run: npx semver-checks compare v$(node -p "require('./package.json').version") HEAD --strict

Comparison with Other Tools

semver-checkssemantic-releasechangesetsnpm-check-updates
InputTypeScript ASTCommit messagesManual YAMLpackage.json
DetectionTyped API rulesKeyword matchingDeveloper-declaredVersion range only
RecommendationAutomaticBased on message formatManual per changeDependency updates only

semver-checks is a verification layer, not a release tool. Use it alongside semantic-release or changesets to check whether the declared bump matches the API changes.

How It Works

  1. Extract: Parse old and new TypeScript source files using ts-morph, building a typed API snapshot (functions, interfaces, enums, classes, type aliases, variables, namespaces)
  2. Diff: Compare the two snapshots symbol by symbol — detect additions, removals, and signature changes
  3. Classify: Assign each diff a major, minor, or patch severity
  4. Report: Return a structured SemverReport with the recommended bump and per-change details

For git ref comparisons, the ref is extracted to a temporary directory via git archive, dependencies are installed there if needed, and the directory is cleaned up after extraction. For npm specs, the published tarball is downloaded with npm pack and extracted to a temporary directory (no dependency install — the tarball already bundles its build output), then cleaned up. Local path comparisons do not install dependencies unless you opt in with --install-deps or installDeps: true.

FAQ

Will semver-checks catch every semver violation?

No. It catches API surface changes that are mechanically detectable from TypeScript's static type system: removed exports, signature changes, type changes, optionality changes, and similar structural changes. It does not detect behavioral changes, documentation changes, or changes hidden behind conditional compilation. When a package ships distinct ESM and CJS declaration files for the same entry point (for example, divergent import.types and require.types), only one surface is analyzed, so a break confined to the other surface can be missed. See Accuracy & Limitations.

Does it have false positives?

Yes. It errs toward over-reporting MAJOR rather than missing a break, but the default CI gate only fails on proven breaks. Parameter and return type changes go through a structural assignability check, so widened parameters, narrowed returns, and equivalent rewrites such as readonly T[] vs ReadonlyArray<T> avoid false majors. Type aliases and variables still have conservative cases because they are compared as normalized serialized text, not fully resolved types. The concrete patterns are listed under Known limitations.

Does it support default exports?

Not currently. Only named exports are analyzed.

Can I compare against a published npm version?

Yes. Pass a <package>@<version> spec and semver-checks downloads that release from the registry with npm pack, extracts the tarball, and analyzes its bundled .d.ts declarations:

npx semver-checks compare your-package@latest          # published latest vs working tree
npx semver-checks compare your-package@1.0.0 your-package@2.0.0  # two published releases

Because a published tarball ships compiled .d.ts files while your working tree ships .ts source, type representation can differ slightly between the two sides (TypeScript materializes some inferred types in declarations). Removals, additions, and signature changes are detected reliably; a handful of equivalent-but-reworded types may show up as a noisy diff. Comparing two published releases (.d.ts vs .d.ts) avoids that asymmetry.

Can I use it without a tsconfig.json?

For local path and git-ref inputs, yes — tsconfig.json must exist at the project root (or at the path inferred from the exports field in package.json). For npm specs, a permissive tsconfig.json is synthesized automatically when the published package does not ship one.

What happens if the analyzed project has TypeScript errors?

semver-checks will print a warning to stderr listing up to 5 errors and continue. Results may be incomplete if type errors affect the API surface. Set SEMVER_CHECKS_VERBOSE=1 for full diagnostics.

How is the entry point determined?

semver-checks looks for the entry file in this order:

Documentation truncated — see the full README on GitHub.

Reviews

No reviews yet

Be the first to review this server!

Semver Checks MCP Server - Detect breaking changes in your TypeScript library's public | MCP Marketplace