关于 semver-checks
semver-checks 分析 TypeScript 声明文件的变化,建议语义化版本升级幅度并识别 API 破坏性变更。它面向 TypeScript 包维护者,可通过命令行、GitHub Action 和 MCP 验证发布。
主要功能
- 01比较 TypeScript 声明文件
- 02检测 API 类型破坏性变更
- 03建议 SemVer 升级幅度
- 04比较 npm 规格、引用或路径
- 05生成适用于 CI 和 PR 的报告
适用场景
- 01发布前检查包的变更
- 02在 PR 中拦截已确认的破坏
- 03核验声明的版本升级幅度
- 04审查不同版本间的 API 变化
MCP 相关
MCP 服务提供 `semver_compare` 工具用于比较版本。该工具要求显式提供 `old` 输入;命令行的默认比较方式不适用于 MCP。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
2收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| new | string | 否 | 新版本:文件系统路径、git ref 或 npm spec。默认为当前目录。 |
| old | string | 是 | 旧版本:文件系统路径、git ref(标签、分支、commit SHA)或 npm spec。若 "name@version" 不是现有路径,则按 npm 规格读取(例如 "[email protected]"、"lodash@latest");加上前缀 "npm:" 可明确指定。 |
| entry | any | 否 | 相对于项目根目录的入口文件(例如 "src/index.ts")。对于包含多个入口点的包,请传入数组或逗号分隔的字符串。若省略,则从 package.json 自动检测。 |
| newAs | enum | 否 | 强制将 "new" 解析为文件系统路径、git ref 或 npm spec。"ref" 是 "git" 的有效别名。path | git | ref | npm |
| oldAs | enum | 否 | 强制将 "old" 解析为文件系统路径、git ref 或 npm spec。"ref" 是 "git" 的有效别名。仅当自动检测会将输入解析为错误类型时才需要,例如形如 "[email protected]" 的 monorepo 标签。path | git | ref | npm |
| declared | enum | 否 | 此发布版本声明的升级类型;也可设为 "auto",从 .changeset/*.md 中读取,之后再读取两个 package.json 版本。报告中会增加 "declaration" 判定:当已确认的破坏性变更级别高于声明时为 "mismatch";当变更表明需要高于已声明的升级级别时为 "review";其他情况为 "ok"。如果 "auto" 找不到可读取的内容,则报错,而不是报告通过。major | minor | patch | none | auto |
| maxChanges | integer | 否 | 要包含的变更数量(默认 50)。变更按已确认的重大破坏、新增内容、仅供审查的内容依次排列,因此达到上限时会舍弃最不具操作性的末尾内容。`summary` 始终统计所有变更,`omitted` 字段会报告省略了哪些内容,以及要传入多少才能获取全部内容。 |
| installDeps | boolean | 否 | 分析前安装依赖(没有 `node_modules` 时,处理本地路径需要此选项) |
详细介绍
semver-checks
pino 10.4.0(一个次要版本)在其 pino 命名空间中添加了 export { pino as default, pino }。这会关闭该命名空间中 9 个成员的隐式导出,因此 const t: pino.TimeFn = () => '' 在针对 10.3.1 编译时可以通过,而针对 10.4.0 编译时会因 TS2694 失败,报错为“命名空间 'pino' 没有导出的成员 'TimeFn'”。
npx semver-checks compare [email protected] [email protected]
在可发布的包目录中不带任何参数运行 npx semver-checks,会将 <name>@latest 与 . 进行比较。此默认行为仅适用于 CLI:GitHub Action 和 MCP semver_compare 工具需要显式指定 old。
semver-checks — Recommended bump: MAJOR
major: 20 (confident: 11, review: 9) minor: 88 patch: 0
Breaking Changes — confident (MAJOR)
✗ Export 'TimeFn' was removed
was: type-alias
✗ Export 'MixinFn' was removed
was: type-alias
✗ Export 'MixinMergeStrategyFn' was removed
was: type-alias
...
输出经过精简,仅显示升级计数和 9 个被移除导出中的 3 个(... 表示省略部分,stderr 警告未显示);完整运行还会列出另外 6 个导出、为 MultiStreamRes 添加的 2 个必需属性、仅供审查的发现以及新增内容。
semver-checks 会比较两侧的 TypeScript 声明,并根据类型变更所要求的版本升级幅度给出建议,因此结论来自 API,而非提交消息。两侧都不需要检出:每侧都可以是 npm 规格、git 引用或工作树。
npx semver-checks compare your-package@latest .
同一项检查也可以作为拉取请求门禁使用:它会标注变更行,并在确认存在破坏性变更时失败:
# .github/workflows/semver-check.yml
on: pull_request
jobs:
semver-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm ci
- uses: kyungseopk1m/[email protected]
with:
old: "your-package@latest"
strict: "true"
所有输入方式,以及用于评估已声明升级幅度并以评论形式发布结论的发布拉取请求变体,都在 GitHub Action 中介绍。
为什么选择 semver-checks?
版本升级幅度意味着对某个版本如何影响其公共 API 的判断,而这通常是在工作结束时凭记忆手动写下的。对编写者而言,移除必需导出的重构看起来只是补丁;对所有下游用户而言,它却会导致构建失败。
发布工具只能根据获得的证据采取行动。semantic-release 根据提交约定推导发布类型,而 changesets 会记录作者撰写的发布说明,并在其 frontmatter 中声明升级幅度。二者都会继承作者当时的判断。
semver-checks 使用 ts-morph直接读取公共 API,并根据类型签名的变化决定升级幅度。
上面的示例并非杜撰。在真实发布版本中运行此工具,就能发现以次要版本和补丁版本发布的破坏性类型变更。它在结构性变更方面最可靠,也就是移除或重命名导出、收窄签名,以及新增必需参数和属性。保持等价的类型重写是已知的薄弱环节,工具可能对此过度报告;docs/accuracy.md 明确说明了哪些情况可以信任它,哪些情况不应信任。
// 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;
// Developer writes: "fix: findUser can come up empty"
// Published as minor — but no existing consumer is written to handle null:
export function findUser(id: string): User | null;
// ^^^^^^^^^^^ return-type-changed (MAJOR)
这种变更的反向操作不会造成破坏:将 User | null 收窄为 User,会让每个消费者都获得一个原本就已做好准备接收的值,而 semver-checks 会将其报告为 return-type-narrowed,并建议 MINOR。
semver-checks 可以与现有发布工作流配合使用。将其作为发布前的验证步骤——它会告诉你预期的升级幅度是否安全,或你是否即将意外发布破坏性变更。
快速入门
npm install --save-dev semver-checks
比较一个 git 标签与最新提交:
npx semver-checks compare v1.0.0 HEAD
将已发布的 npm 版本与当前工作树进行比较——无需 git 标签,即可回答“我当前的更改是否属于破坏性发布?”:
npx semver-checks compare your-package@latest
<package>@<version> 参数会从 npm 注册表获取(通过 npm pack),并用作旧版本。具体版本、范围和常见的 dist-tag 会自动识别([email protected]、your-package@^1、your-package@next)。对于不常见的 dist-tag,请使用 npm: 前缀或 --old-as npm(npm:your-package@my-custom-tag)明确意图,以免被误认为 git 引用。
比较两个本地目录:
npx semver-checks compare ./old ./new
不带 ./ 前缀的现有相对路径也会被视为本地目录:
npx semver-checks compare packages/core packages/core-next
如果 git 引用与现有路径名冲突,请明确指定按引用解释:
npx semver-checks compare main HEAD --old-as ref
以 JSON、Markdown(用于 PR 评论)或 GitHub Actions 注释格式输出:
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
如果检测到破坏性更改,则在 CI 中失败(exit 1):
npx semver-checks compare v1.0.0 HEAD --strict
检查当前版本或过去版本的 API 表面:
npx semver-checks snapshot
npx semver-checks snapshot --ref v1.0.0
npx semver-checks snapshot --npm [email protected]
所有标志都列在 docs/cli.md 中。
多个入口点
当 package.json 声明了包含多个子路径的 "exports" 映射时,会提取并独立比较每个声明了 .d.ts 入口的子路径。添加子路径属于 MINOR 更改,移除子路径属于 MAJOR 更改;子路径内部的更改会使用 # 分隔符报告(例如 ./utils#helper)。无需任何标志——系统会自动检测该映射。
对于没有 "exports" 映射的项目,可重复使用 --entry 或以逗号分隔,显式传入多个入口:
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
输出示例
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)
? Call signatures of interface 'Middleware' changed
before: (req: string) => void
after: (request: string, next?: (() => void) | undefined) => void
New Features (MINOR)
+ Export 'createConfig' was added
第二条发现是一项参数重命名和一个可选参数的新增,两者都不会强制任何调用方进行更改——但由于工具将调用签名作为打印出的文本进行比较,因此无法证明这一点;它会如实说明,而不是猜测。--strict 只会在确认存在破坏性更改时以状态码 1 退出;仅供审查的项目不会导致门禁失败,除非你启用 --strict-review。
CI 集成
GitHub Action
semver-checks 提供了一个可复用的复合操作。最便捷的配置是将已发布的 latest 版本与 PR 的工作树进行比较,因此无需 git 标签,并会在差异中添加行内注释:
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: "22"
- run: npm ci
- uses: kyungseopk1m/[email protected]
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
| 输入 | 说明 | 默认值 |
|---|---|---|
old | 旧版本 — npm 规格(pkg@latest)、git 引用或路径 | (必填) |
new | 新版本 — git 引用或路径 | . |
entry | 入口文件(省略时会从 package.json 自动检测) | (自动) |
old-as | 强制将 old 作为 path、git 或 npm 读取。单体仓库标签(如 [email protected])需要此设置,因为自动检测会将这种格式识别为 npm 规格 | (自动检测) |
new-as | 强制将 new 作为 path、git 或 npm 读取 | (自动检测) |
install-deps | 分析前在两侧安装依赖,不论其来源类型。本地路径需要此设置;git 引用会自行安装 | false |
format | text、json、markdown 或 github | github |
strict | 遇到**有把握(已证实)**的破坏性变更时,使此步骤失败(退出码为 1) | false |
strict-review | 遇到任何破坏性变更时使此步骤失败(退出码为 1),包括仅供审查的(启发式)变更 | false |
declared | 此版本声明的升级类型:major、minor、patch、none 或 auto。声明的升级类型低于已证实的破坏性变更时,此步骤会失败,并取代 strict | (关闭) |
comment | 将报告作为评论发布到 PR,并在后续推送时更新(强制使用 format: markdown) | false |
token | 用于发布评论的令牌。复合操作无法读取 secrets 上下文,因此必须传入令牌 | ${{ github.token }} |
version | 通过 npx 运行的 semver-checks 版本 | (与操作引用匹配) |
完整示例见 examples/github-actions.yml。
在版本发布 PR 中
此版本声明的升级类型是否涵盖了其 API 表面的变化?@clerk/break-check 和 semvet 也会根据两个 package.json 版本评估声明的升级类型;从 .changeset 文件读取升级类型则是此处特有的功能。declared: auto 会从 .changeset/*.md 读取升级类型,并在无法读取时回退到两个 package.json 版本;comment: true 会将判定结果发布到 PR,而不是只留在日志中。
permissions:
contents: read
pull-requests: write # required for `comment`
jobs:
semver-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm ci
- uses: kyungseopk1m/[email protected]
with:
old: "your-package@latest"
declared: "auto"
comment: "true"
声明的升级类型低于已证实的破坏性变更时,此步骤会失败;如果只是低估了新增内容,则会通过并附带说明。token 默认为 github.token;如果你的配置需要使用其他令牌,请显式传入。从 fork 发起的 PR 会获得只读令牌,因此此时会跳过评论并发出警告,而不会使此步骤失败。
评论通过 gh pr comment --edit-last --create-if-none 发布,该命令会更新令牌所有者在此 PR 中最近发布的评论。它不会查找自身的标记,因此,如果同一令牌还会在其他工作流中发布评论,请为此工作流使用专用令牌,或关闭 comment。
不使用此操作
直接运行 CLI — 例如,将已发布版本与工作树进行比较:
- name: Check for breaking changes
run: npx semver-checks compare your-package@latest --format github --strict
或者与 git 标签进行比较:
- name: Check for breaking changes
run: npx semver-checks compare v$(node -p "require('./package.json').version") HEAD --strict
准确性
每项重大变更都有一个置信度。proven 表示该变更本身就是证据,或分析器解析出类型关系并确认两者确实无关;--strict 只会在这些情况下失败。heuristic 表示保守判定的 MAJOR,无法证明其结论,因此会提示你进行审查,但默认门槛不会拦截;除非你启用 --strict-review。
评分卡以 tsc 为判定依据,而不是作者发布的版本升级,因为这个工具存在的前提就是作者可能会把版本升级判断错。在 24 个包中选取了 111 对相邻的 minor/patch 版本,并针对每对版本都编译了一个使用者程序:
| 标志 | 失败条件 | 在 111 对版本中的结果(43 个真实破坏性变更) | 能保证的契约 |
|---|---|---|---|
--strict | 仅 proven MAJOR | 对 37 对版本报错,其中 36 对确实存在破坏性变更:精确率 97.3%,召回率 83.7% | 失败是强烈信号。通过并不代表完全没有问题 |
--strict-review | 每个 MAJOR | 对全部 43 个真实破坏性变更报错,也对 10 对没有破坏性变更的版本报错:召回率 100%,精确率 81.1% | 结果为绿色表示分析没有报告任何破坏性变更 |
在同一语料库中,不进行类型解析、仅基于名称和参数个数的基线方案得分为 87.5% / 32.6%。每次推送都启用 --strict,并在发布前由人员查看输出的场景中运行 --strict-review。
docs/accuracy.md 介绍了其余内容:语料库的构建方式、--strict 不会报错的 7 对版本及其原因、剩下的唯一一个误报、方差探测拒绝回答的问题,以及已知的十项限制。
程序化 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 on both sides before analyzing
declared?: DeclaredBump | "auto"; // Optional: grade the bump this release declares
}
type DeclaredBump = "major" | "minor" | "patch" | "none";
type SourceRef =
| { type: "path"; path: string }
| { type: "git"; ref: string; cwd?: string }
| { type: "npm"; spec: string }; // e.g. { type: 'npm', spec: '[email protected]' }
interface SemverReport {
recommended: "major" | "minor" | "patch";
changes: ApiChange[];
summary: {
major: number;
minor: number;
patch: number;
majorProven: number;
majorReview: number;
};
// Present only when a declared bump was supplied or detected.
declaration?: BumpDeclaration;
}
interface BumpDeclaration {
declared: DeclaredBump;
source: string; // where it was read from: a changeset path, or the two versions
required: "major" | "minor" | "patch"; // what the proven breaks require
suggested: "major" | "minor" | "patch"; // what the whole change set argues for
verdict: "ok" | "review" | "mismatch";
}
interface ApiChange {
kind: ChangeKind;
severity: "major" | "minor" | "patch";
symbolPath: string;
message: string;
oldValue?: string;
newValue?: string;
confidence?: "proven" | "heuristic";
}
你也可以单独提取快照:
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
参考文档
| 文档 | 内容 |
|---|---|
| docs/cli.md | compare 和 snapshot 的所有标志、退出码、输出格式,以及 --declared 判定表 |
| docs/change-rules.md | 所有 ChangeKind 值、MAJOR 和 MINOR |
| docs/mcp.md | MCP 服务设置和两种工具的架构 |
| docs/accuracy.md | 语料库、置信度等级和已知限制 |
MCP 服务
semver-checks 以 Model Context Protocol 服务的形式提供,因此 Agent 可以将其作为工具调用:
claude mcp add semver-checks -- npx -y semver-checks --mcp
提供两种工具:semver_compare 和 semver_snapshot。其他客户端的设置方法及完整参数架构请参阅 docs/mcp.md。
与其他工具的比较
| semver-checks | semantic-release | changesets | npm-check-updates | |
|---|---|---|---|---|
| 输入 | TypeScript API | 提交消息 | 作者编写的变更集 | package.json |
| 检测方式 | 类型化 API 规则 | 关键词匹配 | 开发者声明 | 仅检查版本范围 |
| 版本升级建议 | 自动 | 根据消息格式 | 每项变更手动指定 | 仅更新依赖 |
semver-checks 是一个验证层,而非发布工具。可将其与 semantic-release 或 changesets 配合使用,以检查声明的版本升级是否与 API 变更相符。
差异
ts-semver-checks、@clerk/break-check 和 semvet 都会将本地构建与基线进行比较。ts-semver-checks 和 semvet 使用编译器可赋值性;ts-semver-checks 通过 --expect 接受你预期的版本升级类型,且没有 Action 或 MCP 服务,而 semvet 会根据 package.json 中声明的升级类型进行评分。@clerk/break-check 会对比 API Extractor 快照,增加一轮 LLM 审查,根据 package.json 中声明的升级类型进行评分,并支持多包单体仓库。
semver-checks 可以直接比较两个已发布的 npm 版本(compare pkg@x pkg@y),从 .changeset 文件读取声明的升级类型,提供 MCP 服务,并在 docs/accuracy.md 中公布准确性数据。
工作原理
- 提取:使用 ts-morph 解析新旧 TypeScript 源文件,构建带类型的 API 快照(函数、接口、枚举、类、类型别名、变量、命名空间)
- 对比:逐个符号比较两个快照,检测新增、移除和签名变更
- 分类:为每项差异指定
major、minor或patch严重级别 - 报告:返回结构化的
SemverReport,包含建议的升级类型和每项变更的详细信息
对于 git 引用比较,系统会通过 git archive 将引用提取到临时目录,在其中安装依赖,然后清理该目录。对于 npm 规格,系统会使用 npm pack 下载已发布的 tarball 并将其提取到临时目录,不安装依赖,因为 tarball 已包含构建产物。本地路径比较默认不会安装任何内容。--install-deps(或 installDeps: true)可覆盖此设置,无论源类型是什么,都会在两侧运行安装命令;此选项是为本地路径场景提供的,因为只有该场景需要安装依赖。
常见问题
semver-checks 能捕获所有 semver 违规吗?
不能。它可以捕获通过 TypeScript 静态类型系统机械检测到的 API 表面变更:导出项移除、签名变更、类型变更、可选性变更,以及类似的结构性变更。它无法检测行为变更、文档变更,或隐藏在条件编译后的变更。当软件包针对同一入口点发布不同的 ESM 和 CJS 声明文件时(例如,import.types 和 require.types 不同),系统只会分析其中一个表面,因此可能漏掉仅影响另一个表面的破坏性变更。请参阅 docs/accuracy.md。
它会产生误报吗?
会。它倾向于多报 MAJOR,而不是漏报破坏性变更,但默认的 CI 门禁只会因已被 proven 证实的破坏性变更而失败。参数和返回类型变更会经过结构化可赋值性检查,因此参数类型放宽、返回类型收窄,以及 readonly T[] 与 ReadonlyArray<T> 这类等价改写,都不会导致误报为 MAJOR。类型别名和变量仍存在保守判断的情况,因为系统会先将它们规范化为序列化文本进行比较,并且仅在可行时才通过探测将比较升级为已解析关系。具体模式列于 已知限制 中。
它支持默认导出吗?
支持。默认导出会以符号名 default 提取,并像对应的函数、类或值声明一样进行比较。
我可以与已发布的 npm 版本进行比较吗?
可以。传入 <package>@<version> 规格,semver-checks 会使用 npm pack 从注册表下载该版本,解压 tarball,并分析其中打包的 .d.ts 声明:
npx semver-checks compare your-package@latest # published latest vs working tree
npx semver-checks compare [email protected] [email protected] # two published releases
已发布的 tarball 中包含编译后的 .d.ts 文件,而工作树中包含 .ts 源文件,因此两侧的类型_表示形式_可能略有不同(TypeScript 会在声明文件中显式生成某些推断类型)。删除、添加和签名更改都能可靠检测;少数等效但表述不同的类型可能会导致差异输出显得嘈杂。比较两个已发布版本(.d.ts 与 .d.ts)可以避免这种不对称。
没有 tsconfig.json 时可以使用吗?
本地路径或 git 引用输入不可以:这些输入会作为 TypeScript 项目打开,需要在项目根目录,或从 package.json 的 exports 字段推断出的根目录中有一个 tsconfig.json。已发布的 npm 输入则不同——如果 tarball 中没有附带配置文件,程序会生成一个宽松的配置。
如果分析的项目存在 TypeScript 错误,会怎样?
semver-checks 会向 stderr 输出警告,列出最多 5 个错误,然后继续运行。如果类型错误影响了 API 表面,结果可能不完整。设置 SEMVER_CHECKS_VERBOSE=1 可查看完整诊断信息。
如何确定入口点?
semver-checks 按以下顺序查找入口文件:
- 如果提供了
--entry标志,则使用该标志 package.json中exports['.']下的声明文件——会遍历每种条件(types、require/import/node/browser/module/default、嵌套条件和回退数组),并接受.d.ts/.d.mts/.d.cts。裸字符串"exports": "./index.js"或扁平条件对象"exports": { "types": "./index.d.ts", "default": "./index.js" }(没有.子路径键)会被视为.入口,因此会读取其中的types条件;对于已发布的软件包,还会检查.js目标是否有同名的配套声明文件。没有.键的纯子路径映射不会设置根入口(不会虚构根入口)package.json顶层的types或typings字段- 依次尝试
src/index.ts、index.ts,然后将惯用的根目录index.d.ts/.d.mts/.d.cts作为回退
如果以上方法都无法解析,请显式传入 --entry。
如果项目附带包含多个子路径的 "exports" 映射,每个子路径都会单独解析和比较(参见多个入口点)。
支持 monorepo 吗?
支持。将 --entry 指向软件包的入口文件,或从该软件包的目录运行 CLI。形如 [email protected] 的 monorepo 标签会被自动检测为 npm 规格,因此对于这些标签,请传入 --old-as ref。
要求
- Node.js
^20.0.0 || >=22.0.0(由于传递依赖的限制,不支持 Node 21,且该版本已结束生命周期) - 对于本地路径 / git 引用输入:被分析的项目中需要有
tsconfig.json和 TypeScript 源文件(.ts/.tsx) - 对于 npm 规格:无需额外条件——会分析 tarball 中打包的
.d.ts声明;如果没有tsconfig.json,则会生成一个
双模块支持
semver-checks 同时提供 CommonJS 和 ES 模块构建版本:
// ESM
import { compare } from "semver-checks";
// CJS
const { compare } = require("semver-checks");
贡献
欢迎贡献。提交拉取请求前,请阅读 CONTRIBUTING.md。
许可证
MIT。参见 LICENSE。
作者
Kyungseop Kim — @kyungseopk1m
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。