From 1235bda1d79380ad2e6f559d1e4865b6261b503d Mon Sep 17 00:00:00 2001 From: olaservo Date: Sat, 1 Aug 2026 18:52:12 -0700 Subject: [PATCH 1/7] chore: reset TypeScript servers to 1.0.0 One-time semver reset ahead of changesets adoption (#4472). None of the four servers has ever carried a true semver value: the CalVer era was date-stamping, and everything's staged 2.0.0 was never published. 1.0.0 is unpublished on npm for all four. Hardcoded MCP serverInfo versions are aligned to match. Co-Authored-By: Claude Fable 5 --- src/everything/package.json | 2 +- src/everything/server/index.ts | 2 +- src/filesystem/index.ts | 2 +- src/filesystem/package.json | 2 +- src/memory/index.ts | 2 +- src/memory/package.json | 4 ++-- src/sequentialthinking/index.ts | 2 +- src/sequentialthinking/package.json | 4 ++-- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/everything/package.json b/src/everything/package.json index 745d1b10bb..2f6ad48125 100644 --- a/src/everything/package.json +++ b/src/everything/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server-everything", - "version": "2.0.0", + "version": "1.0.0", "description": "MCP server that exercises all the features of the MCP protocol", "license": "SEE LICENSE IN LICENSE", "mcpName": "io.github.modelcontextprotocol/server-everything", diff --git a/src/everything/server/index.ts b/src/everything/server/index.ts index f1459cc812..327a47cae6 100644 --- a/src/everything/server/index.ts +++ b/src/everything/server/index.ts @@ -47,7 +47,7 @@ export const createServer: () => ServerFactoryResponse = () => { { name: "mcp-servers/everything", title: "Everything Reference Server", - version: "2.0.0", + version: "1.0.0", }, { capabilities: { diff --git a/src/filesystem/index.ts b/src/filesystem/index.ts index 234605bb13..cddb712c1b 100644 --- a/src/filesystem/index.ts +++ b/src/filesystem/index.ts @@ -163,7 +163,7 @@ const GetFileInfoArgsSchema = z.object({ const server = new McpServer( { name: "secure-filesystem-server", - version: "0.2.0", + version: "1.0.0", } ); diff --git a/src/filesystem/package.json b/src/filesystem/package.json index 139c4f00b4..a0fdc8807e 100644 --- a/src/filesystem/package.json +++ b/src/filesystem/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server-filesystem", - "version": "0.6.3", + "version": "1.0.0", "description": "MCP server for filesystem access", "license": "SEE LICENSE IN LICENSE", "mcpName": "io.github.modelcontextprotocol/server-filesystem", diff --git a/src/memory/index.ts b/src/memory/index.ts index 9865c5318e..4de0fd5ed8 100644 --- a/src/memory/index.ts +++ b/src/memory/index.ts @@ -256,7 +256,7 @@ const RelationSchema = z.object({ // The server instance and tools exposed to Claude const server = new McpServer({ name: "memory-server", - version: "0.6.3", + version: "1.0.0", }); const RESOURCE_URI = "memory://knowledge-graph"; diff --git a/src/memory/package.json b/src/memory/package.json index 4fdcd3f9a4..39d9a6ee10 100644 --- a/src/memory/package.json +++ b/src/memory/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server-memory", - "version": "0.6.3", + "version": "1.0.0", "description": "MCP server for enabling memory for Claude through a knowledge graph", "license": "SEE LICENSE IN LICENSE", "mcpName": "io.github.modelcontextprotocol/server-memory", @@ -34,4 +34,4 @@ "typescript": "^5.6.2", "vitest": "^4.1.8" } -} \ No newline at end of file +} diff --git a/src/sequentialthinking/index.ts b/src/sequentialthinking/index.ts index 217845bb3d..98e3a34208 100644 --- a/src/sequentialthinking/index.ts +++ b/src/sequentialthinking/index.ts @@ -17,7 +17,7 @@ const coercedBoolean = z.preprocess((val) => { const server = new McpServer({ name: "sequential-thinking-server", - version: "0.2.0", + version: "1.0.0", }); const thinkingServer = new SequentialThinkingServer(); diff --git a/src/sequentialthinking/package.json b/src/sequentialthinking/package.json index 03fbb2b361..e53f95508e 100644 --- a/src/sequentialthinking/package.json +++ b/src/sequentialthinking/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server-sequential-thinking", - "version": "0.6.2", + "version": "1.0.0", "description": "MCP server for sequential thinking and problem solving", "license": "SEE LICENSE IN LICENSE", "mcpName": "io.github.modelcontextprotocol/server-sequential-thinking", @@ -37,4 +37,4 @@ "typescript": "^5.3.3", "vitest": "^4.1.8" } -} \ No newline at end of file +} From bfbe4cc48574ea4fe313efe70096cf44f5615967 Mon Sep 17 00:00:00 2001 From: olaservo Date: Sat, 1 Aug 2026 18:52:24 -0700 Subject: [PATCH 2/7] feat: adopt changesets for the TypeScript workspaces Adds @changesets/cli with GitHub-flavored changelogs, a Version Packages workflow that maintains the rolling version-bump PR on every push to main, and contributor docs covering when a changeset is needed and the semver policy (#4472). Co-Authored-By: Claude Fable 5 --- .changeset/README.md | 19 + .changeset/config.json | 14 + .github/workflows/version-packages.yml | 39 + CONTRIBUTING.md | 12 + package-lock.json | 1043 ++++++++++++++++++++++-- package.json | 8 +- 6 files changed, 1079 insertions(+), 56 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/version-packages.yml diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..49096342b7 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,19 @@ +# Changesets + +The TypeScript packages in this repo are versioned with [changesets](https://github.com/changesets/changesets). If your PR changes a TypeScript server in `src/` in a way users will notice, add a changeset: + +```bash +npm run changeset +``` + +Pick the affected package(s), choose a bump type, and write a one-line summary — that line becomes the CHANGELOG entry. Commit the generated file in `.changeset/` with your PR. + +Bump types: + +- **patch** — bug fixes +- **minor** — new tools, prompts, resources, or options +- **major** — breaking changes (tool removed or renamed, schema change that breaks clients, protocol or Node floor bump) + +Docs-only, CI-only, and Python-only changes don't need a changeset. The Python servers (`fetch`, `git`, `time`) use CalVer and are not managed by changesets — see [RELEASING.md](../RELEASING.md). + +Merged changesets accumulate in a rolling **"Version Packages" PR**; merging that PR applies the version bumps and CHANGELOG updates. Publishing happens when a maintainer creates a GitHub Release. diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..33c415fa4e --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": [ + "@changesets/changelog-github", + { "repo": "modelcontextprotocol/servers" } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/version-packages.yml b/.github/workflows/version-packages.yml new file mode 100644 index 0000000000..a662fa5215 --- /dev/null +++ b/.github/workflows/version-packages.yml @@ -0,0 +1,39 @@ +name: Version Packages + +# Maintains the rolling changesets "Version Packages" PR: every push to main +# re-runs `changeset version` against the accumulated changesets and creates or +# updates the PR that applies the version bumps and CHANGELOG entries. +# Publishing is separate — see release.yml (triggered by GitHub Releases). + +on: + push: + branches: [main] + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + version: + if: github.repository_owner == 'modelcontextprotocol' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Create or update the Version Packages PR + uses: changesets/action@v1 + with: + title: "chore: version packages" + commit: "chore: version packages" + env: + # Also used by @changesets/changelog-github to link PRs in CHANGELOGs + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ce9a21dd6..ec190f1985 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,18 @@ We're more selective about: We don't accept: - **New server implementations** — We encourage you to publish them to the [MCP Server Registry](https://github.com/modelcontextprotocol/registry) instead. +## Changesets (TypeScript versioning) + +The TypeScript servers (`everything`, `filesystem`, `memory`, `sequentialthinking`) are versioned with [changesets](https://github.com/changesets/changesets). If your PR changes one of them in a way users will notice, include a changeset: + +```bash +npm run changeset +``` + +Pick the affected package(s), choose a bump type (**patch** = bug fixes; **minor** = new tools, prompts, resources, or options; **major** = breaking changes), and write a one-line summary — it becomes the CHANGELOG entry. Commit the generated `.changeset/*.md` file with your PR. + +Docs-only, CI-only, and Python-only changes don't need a changeset. The Python servers use CalVer and are released separately — see [RELEASING.md](RELEASING.md). + ## Testing When adding or configuring tests for servers implemented in TypeScript, use **vitest** as the test framework. Vitest provides better ESM support, faster test execution, and a more modern testing experience. diff --git a/package-lock.json b/package-lock.json index 1845571736..1a3c729ae8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,10 @@ "@modelcontextprotocol/server-filesystem": "*", "@modelcontextprotocol/server-memory": "*", "@modelcontextprotocol/server-sequential-thinking": "*" + }, + "devDependencies": { + "@changesets/changelog-github": "^0.5.1", + "@changesets/cli": "^2.29.5" } }, "node_modules/@babel/helper-string-parser": { @@ -54,6 +58,16 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", @@ -78,6 +92,271 @@ "node": ">=18" } }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz", + "integrity": "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^3.1.4", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz", + "integrity": "sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", + "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0" + } + }, + "node_modules/@changesets/changelog-github": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz", + "integrity": "sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/get-github-info": "^0.7.0", + "@changesets/types": "^6.1.0", + "dotenv": "^8.1.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.31.1", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.31.1.tgz", + "integrity": "sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.1.1", + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/changelog-git": "^0.2.1", + "@changesets/config": "^3.1.4", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/get-release-plan": "^4.0.16", + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@changesets/write": "^0.4.0", + "@inquirer/external-editor": "^1.0.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "enquirer": "^2.4.1", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz", + "integrity": "sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/logger": "^0.1.1", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz", + "integrity": "sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-github-info": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz", + "integrity": "sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dataloader": "^1.4.0", + "node-fetch": "^2.5.0" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz", + "integrity": "sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/config": "^3.1.4", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", + "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz", + "integrity": "sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "js-yaml": "^4.1.1" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", + "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz", + "integrity": "sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.3", + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", + "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", + "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz", + "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "human-id": "^4.1.1", + "prettier": "^2.7.1" + } + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -124,6 +403,28 @@ "hono": "^4" } }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -152,6 +453,78 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", @@ -911,6 +1284,42 @@ } } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -942,6 +1351,19 @@ "node": "18 || 20 || >=22" } }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/body-parser": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", @@ -1064,6 +1486,13 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", + "dev": true, + "license": "MIT" + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1078,15 +1507,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1122,18 +1542,6 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -1253,6 +1661,13 @@ "node": ">= 8" } }, + "node_modules/dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1279,6 +1694,16 @@ "node": ">= 0.8" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -1298,6 +1723,29 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -1337,6 +1785,20 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -1389,6 +1851,20 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1592,6 +2068,13 @@ "express": ">= 4.11" } }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1693,6 +2176,20 @@ "url": "https://opencollective.com/express" } }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1711,6 +2208,21 @@ "node": ">= 0.8" } }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1824,6 +2336,27 @@ "node": ">= 6" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1836,6 +2369,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1906,6 +2446,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/human-id": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.0.tgz", + "integrity": "sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } + }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", @@ -1922,6 +2472,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", @@ -2036,6 +2596,29 @@ "node": ">=0.10.0" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2092,17 +2675,40 @@ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "dev": true, - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -2115,6 +2721,16 @@ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "license": "BSD-2-Clause" }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -2397,6 +3013,26 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "11.5.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", @@ -2570,6 +3206,16 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2611,6 +3257,27 @@ "dev": true, "license": "MIT" }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -2690,6 +3357,26 @@ "wrappy": "1" } }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -2700,6 +3387,65 @@ "node": ">=4" } }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -2715,6 +3461,16 @@ "node": ">= 0.8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2757,6 +3513,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -2784,6 +3550,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pkce-challenge": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", @@ -2883,6 +3659,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2928,6 +3721,46 @@ "node": ">= 0.10" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -2995,6 +3828,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -3305,6 +4148,16 @@ "dev": true, "license": "ISC" }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -3315,6 +4168,37 @@ "node": ">=0.10.0" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, + "node_modules/spawndamnit/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3347,6 +4231,28 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -3383,6 +4289,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -3449,6 +4368,13 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -3509,6 +4435,16 @@ "dev": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -3701,6 +4637,24 @@ } } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3775,15 +4729,6 @@ "node": ">=12" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3804,18 +4749,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/zod": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", @@ -3836,7 +4769,7 @@ }, "src/everything": { "name": "@modelcontextprotocol/server-everything", - "version": "2.0.0", + "version": "1.0.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", @@ -3860,7 +4793,7 @@ }, "src/filesystem": { "name": "@modelcontextprotocol/server-filesystem", - "version": "0.6.3", + "version": "1.0.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", @@ -3883,7 +4816,7 @@ }, "src/memory": { "name": "@modelcontextprotocol/server-memory", - "version": "0.6.3", + "version": "1.0.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0" @@ -3901,7 +4834,7 @@ }, "src/sequentialthinking": { "name": "@modelcontextprotocol/server-sequential-thinking", - "version": "0.6.2", + "version": "1.0.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", diff --git a/package.json b/package.json index ab0b8c8800..4abea40d44 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,13 @@ "build": "npm run build --workspaces", "watch": "npm run watch --workspaces", "publish-all": "npm publish --workspaces --access public", - "link-all": "npm link --workspaces" + "link-all": "npm link --workspaces", + "changeset": "changeset", + "version-packages": "changeset version" + }, + "devDependencies": { + "@changesets/cli": "^2.29.5", + "@changesets/changelog-github": "^0.5.1" }, "dependencies": { "@modelcontextprotocol/server-everything": "*", From 8aed891f2157c54ba1a323acea6c3679fa12b66c Mon Sep 17 00:00:00 2001 From: olaservo Date: Sat, 1 Aug 2026 18:52:25 -0700 Subject: [PATCH 3/7] feat: publish releases from manually-created GitHub Releases Reworks release.yml from workflow_dispatch to release:[published]. No job computes, stamps, or tags a version anymore: every package runs as an independent matrix job and publishes only if its manifest version is missing from the registry. The npm guard skips (not fails) an existing version and treats a never-published package (E404) as publish it; PyPI keeps skip-existing. Test gates stay as defense in depth, and the release environment binding for OIDC trusted publishing is unchanged (#4472). Co-Authored-By: Claude Fable 5 --- .github/workflows/release.yml | 278 +++++++++++++--------------------- 1 file changed, 103 insertions(+), 175 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd05addc73..a7c728dfa3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,124 +1,135 @@ name: Release +# Publishing is triggered by a maintainer creating a GitHub Release (see +# RELEASING.md). No job here computes, stamps, or tags a version: the versions +# in package.json / pyproject.toml on the released ref are the source of truth, +# and every package publishes if (and only if) its version is not already on +# the registry. A package whose publish failed or was skipped simply publishes +# on the next release — the registry-diff guard picks it up. +# +# Authentication is OIDC trusted publishing on both registries. The npm and +# PyPI trusted publishers are bound to this workflow filename (release.yml) +# and the `release` environment — the publish jobs must stay in this file. + on: - workflow_dispatch: + release: + types: [published] jobs: - create-metadata: + detect-packages: runs-on: ubuntu-latest if: github.repository_owner == 'modelcontextprotocol' outputs: - hash: ${{ steps.last-release.outputs.hash }} - version: ${{ steps.create-version.outputs.version}} - npm_packages: ${{ steps.create-npm-packages.outputs.npm_packages}} - pypi_packages: ${{ steps.create-pypi-packages.outputs.pypi_packages}} + npm_packages: ${{ steps.find-packages.outputs.npm_packages }} + pypi_packages: ${{ steps.find-packages.outputs.pypi_packages }} steps: + # Defaults to the release tag — the exact ref the maintainer released - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Get last release hash - id: last-release - run: | - HASH=$(git rev-list --tags --max-count=1 || echo "HEAD~1") - echo "hash=${HASH}" >> $GITHUB_OUTPUT - echo "Using last release hash: ${HASH}" - - name: Install uv - uses: astral-sh/setup-uv@v7 - - - name: Create version name - id: create-version + - name: Find all packages + id: find-packages + working-directory: src run: | - VERSION=$(uv run --script scripts/release.py generate-version) - echo "version $VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + NPM=$(find . -name package.json -not -path "*/node_modules/*" -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]') + PYPI=$(find . -name pyproject.toml -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]') + echo "npm_packages=$NPM" >> "$GITHUB_OUTPUT" + echo "pypi_packages=$PYPI" >> "$GITHUB_OUTPUT" - - name: Create notes - run: | - HASH="${{ steps.last-release.outputs.hash }}" - uv run --script scripts/release.py generate-notes --directory src/ $HASH > RELEASE_NOTES.md - cat RELEASE_NOTES.md - - - name: Release notes - uses: actions/upload-artifact@v7 - with: - name: release-notes - path: RELEASE_NOTES.md - - - name: Create python matrix - id: create-pypi-packages - run: | - HASH="${{ steps.last-release.outputs.hash }}" - PYPI=$(uv run --script scripts/release.py generate-matrix --pypi --directory src $HASH) - echo "pypi_packages $PYPI" - echo "pypi_packages=$PYPI" >> $GITHUB_OUTPUT - - - name: Create npm matrix - id: create-npm-packages - run: | - HASH="${{ steps.last-release.outputs.hash }}" - NPM=$(uv run --script scripts/release.py generate-matrix --npm --directory src $HASH) - echo "npm_packages $NPM" - echo "npm_packages=$NPM" >> $GITHUB_OUTPUT - - update-packages: - needs: [create-metadata] - if: ${{ needs.create-metadata.outputs.npm_packages != '[]' || needs.create-metadata.outputs.pypi_packages != '[]' }} - runs-on: ubuntu-latest + publish-npm: + needs: [detect-packages] + if: ${{ needs.detect-packages.outputs.npm_packages != '[]' }} + strategy: + fail-fast: false + matrix: + package: ${{ fromJson(needs.detect-packages.outputs.npm_packages) }} + name: Publish ${{ matrix.package }} (npm) environment: release permissions: - contents: write - outputs: - changes_made: ${{ steps.commit.outputs.changes_made }} + contents: read + id-token: write # Required for npm trusted publishing (OIDC) + runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Install uv - uses: astral-sh/setup-uv@v7 - - name: Update packages - run: | - HASH="${{ needs.create-metadata.outputs.hash }}" - uv run --script scripts/release.py update-packages --directory src/ $HASH + - uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + registry-url: "https://registry.npmjs.org" - - name: Configure git - run: | - git config --global user.name "GitHub Actions" - git config --global user.email "actions@github.com" + # OIDC trusted publishing requires npm >=11.5.1; Node 22's bundled npm is 10.x. + - name: Ensure npm CLI supports OIDC trusted publishing + run: npm install -g npm@^11.5.1 - - name: Commit changes - id: commit + # Registry-diff guard: skip (not fail) when the version is already + # published, and treat a never-published package (E404) as "publish it" + - name: Check whether this version is already on npm + id: guard + working-directory: src/${{ matrix.package }} run: | - VERSION="${{ needs.create-metadata.outputs.version }}" - git add -u - if git diff-index --quiet HEAD; then - echo "changes_made=false" >> $GITHUB_OUTPUT + NAME=$(jq -r .name package.json) + VERSION=$(jq -r .version package.json) + set +e + PUBLISHED=$(npm view "$NAME" versions --json 2>&1) + EXIT_CODE=$? + set -e + if [ $EXIT_CODE -ne 0 ]; then + if echo "$PUBLISHED" | grep -q "E404"; then + echo "$NAME has never been published — proceeding with first publish" + echo "skip=false" >> "$GITHUB_OUTPUT" + else + echo "npm view failed for $NAME:" + echo "$PUBLISHED" + exit 1 + fi + elif echo "$PUBLISHED" | jq -e --arg v "$VERSION" '(if type == "array" then . else [.] end) | index($v) != null' > /dev/null; then + echo "$NAME@$VERSION is already on npm — skipping" + echo "skip=true" >> "$GITHUB_OUTPUT" else - git commit -m 'Automatic update of packages' - git tag -a "$VERSION" -m "Release $VERSION" - git push origin "$VERSION" - echo "changes_made=true" >> $GITHUB_OUTPUT + echo "$NAME@$VERSION is new — proceeding with publish" + echo "skip=false" >> "$GITHUB_OUTPUT" fi + - name: Install dependencies + if: steps.guard.outputs.skip != 'true' + working-directory: src/${{ matrix.package }} + run: npm ci + + # Defense in depth: CI already validated main, but this tests the exact + # ref being published (covers manual tags and any future trigger path) + - name: Run tests + if: steps.guard.outputs.skip != 'true' + working-directory: src/${{ matrix.package }} + run: npm test --if-present + + - name: Build package + if: steps.guard.outputs.skip != 'true' + working-directory: src/${{ matrix.package }} + run: npm run build + + # Authenticates via OIDC trusted publishing (no token) — each package's + # npm trusted publisher is bound to this workflow + the release environment + - name: Publish package + if: steps.guard.outputs.skip != 'true' + working-directory: src/${{ matrix.package }} + run: npm publish --access public + env: + NPM_CONFIG_PROVENANCE: "true" + publish-pypi: - needs: [update-packages, create-metadata] - if: ${{ needs.create-metadata.outputs.pypi_packages != '[]' && needs.create-metadata.outputs.pypi_packages != '' }} + needs: [detect-packages] + if: ${{ needs.detect-packages.outputs.pypi_packages != '[]' }} strategy: fail-fast: false matrix: - package: ${{ fromJson(needs.create-metadata.outputs.pypi_packages) }} - name: Build ${{ matrix.package }} + package: ${{ fromJson(needs.detect-packages.outputs.pypi_packages) }} + name: Publish ${{ matrix.package }} (PyPI) environment: release permissions: id-token: write # Required for trusted publishing runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - ref: ${{ needs.create-metadata.outputs.version }} - name: Install uv uses: astral-sh/setup-uv@v7 @@ -136,6 +147,8 @@ jobs: working-directory: src/${{ matrix.package }} run: uv run --frozen pyright + # Defense in depth: CI already validated main, but this tests the exact + # ref being published (covers manual tags and any future trigger path) - name: Run tests working-directory: src/${{ matrix.package }} run: | @@ -149,95 +162,10 @@ jobs: working-directory: src/${{ matrix.package }} run: uv build + # skip-existing is the PyPI equivalent of the npm registry-diff guard: + # an already-published version is skipped, not failed - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: src/${{ matrix.package }}/dist - skip-existing: true # re-runs tolerate already-uploaded files - - publish-npm: - needs: [update-packages, create-metadata] - if: ${{ needs.create-metadata.outputs.npm_packages != '[]' && needs.create-metadata.outputs.npm_packages != '' }} - strategy: - fail-fast: false - matrix: - package: ${{ fromJson(needs.create-metadata.outputs.npm_packages) }} - name: Build ${{ matrix.package }} - environment: release - permissions: - contents: read - id-token: write # Required for npm trusted publishing (OIDC) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.create-metadata.outputs.version }} - - - uses: actions/setup-node@v7 - with: - node-version: 22 - cache: npm - registry-url: 'https://registry.npmjs.org' - - # OIDC trusted publishing requires npm >=11.5.1; Node 22's bundled npm is 10.x. - - name: Ensure npm CLI supports OIDC trusted publishing - run: npm install -g npm@^11.5.1 - - - name: Install dependencies - working-directory: src/${{ matrix.package }} - run: npm ci - - - name: Check if version exists on npm - working-directory: src/${{ matrix.package }} - run: | - VERSION=$(jq -r .version package.json) - if npm view --json | jq -e --arg version "$VERSION" '[.[]][0].versions | contains([$version])'; then - echo "Version $VERSION already exists on npm" - exit 1 - fi - echo "Version $VERSION is new, proceeding with publish" - - - name: Run tests - working-directory: src/${{ matrix.package }} - run: npm test --if-present - - - name: Build package - working-directory: src/${{ matrix.package }} - run: npm run build - - # Authenticates via OIDC trusted publishing (no token) — each package's - # npm trusted publisher is bound to this workflow + the release environment - - name: Publish package - working-directory: src/${{ matrix.package }} - run: | - npm publish --access public - env: - NPM_CONFIG_PROVENANCE: "true" - - create-release: - needs: [update-packages, create-metadata, publish-pypi, publish-npm] - if: | - always() && - needs.update-packages.outputs.changes_made == 'true' && - (needs.publish-pypi.result == 'success' || needs.publish-npm.result == 'success') - runs-on: ubuntu-latest - environment: release - permissions: - contents: write - steps: - - uses: actions/checkout@v6 - - - name: Download release notes - uses: actions/download-artifact@v8 - with: - name: release-notes - - - name: Create release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN}} - run: | - VERSION="${{ needs.create-metadata.outputs.version }}" - gh release create "$VERSION" \ - --title "Release $VERSION" \ - --notes-file RELEASE_NOTES.md - + skip-existing: true From bd22331806d011637c7db803b81cc16bea2cec64 Mon Sep 17 00:00:00 2001 From: olaservo Date: Sat, 1 Aug 2026 18:52:35 -0700 Subject: [PATCH 4/7] feat: add prepare-release dispatch for Python CalVer stamping Replaces scripts/release.py with a focused script that stamps today's CalVer date onto Python packages changed since their last version bump (refreshing uv.lock), and a workflow_dispatch workflow that opens the resulting PR. The rest of release.py (version computation, matrix and notes generation) retires with the old release flow (#4472). Co-Authored-By: Claude Fable 5 --- .github/workflows/prepare-release.yml | 69 +++++++++ scripts/prepare_python_release.py | 104 +++++++++++++ scripts/release.py | 215 -------------------------- 3 files changed, 173 insertions(+), 215 deletions(-) create mode 100644 .github/workflows/prepare-release.yml create mode 100644 scripts/prepare_python_release.py delete mode 100755 scripts/release.py diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000000..7cea5dd843 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,69 @@ +name: Prepare Python Release + +# Stamps today's CalVer date (e.g. 2026.8.1) onto Python packages that changed +# since their last version bump, and opens a normal PR with the result. The +# TypeScript packages are versioned by changesets (see version-packages.yml). +# Publishing happens separately, when a maintainer creates a GitHub Release. + +on: + workflow_dispatch: + +jobs: + prepare: + if: github.repository_owner == 'modelcontextprotocol' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Stamp CalVer versions + run: uv run --script scripts/prepare_python_release.py --directory src > stamped.txt + + - name: Check for changes + id: changes + run: | + if git diff --quiet; then + echo "No Python packages need a version stamp" + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create pull request + if: steps.changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + DATE=$(date +%Y.%-m.%-d) + BRANCH="release/python-$DATE" + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git add -u + git commit -m "chore: stamp Python CalVer versions for $DATE" + git push --force origin "$BRANCH" + { + echo "Stamps today's CalVer date onto the Python packages that changed since their last version bump:" + echo + sed 's/^/- /' stamped.txt + echo + echo "Generated by the **Prepare Python Release** workflow. After merging, create a GitHub Release to publish." + echo + echo "> [!NOTE]" + echo "> PRs opened with the workflow token don't trigger CI — close and reopen this PR to run it." + } > pr-body.md + if gh pr list --head "$BRANCH" --state open --json number --jq length | grep -qv '^0$'; then + echo "PR for $BRANCH already open — branch updated" + else + gh pr create \ + --head "$BRANCH" \ + --title "chore: stamp Python CalVer versions for $DATE" \ + --body-file pr-body.md + fi diff --git a/scripts/prepare_python_release.py b/scripts/prepare_python_release.py new file mode 100644 index 0000000000..67eb2b5df8 --- /dev/null +++ b/scripts/prepare_python_release.py @@ -0,0 +1,104 @@ +#!/usr/bin/env uv run --script +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "tomlkit>=0.13.2" +# ] +# /// +"""Stamp today's CalVer date onto Python packages that changed since their last version bump. + +Used by the prepare-release workflow (see RELEASING.md). The TypeScript packages +are versioned by changesets and are not touched by this script. + +For each src/*/pyproject.toml: + 1. Find the last commit that changed the `version` field. + 2. If any .py, .md, or pyproject.toml file in the package changed since then, + set the version to today's date (CalVer, e.g. 2026.8.1) and refresh uv.lock. + +Publishing stays safe regardless: release.yml only publishes versions that are +not already on the registry. +""" + +import argparse +import datetime +import subprocess +import sys +from pathlib import Path + +import tomlkit + +RELEVANT_SUFFIXES = {".py", ".md"} # .md counts: READMEs ship in the sdist + + +def git(args: list[str], cwd: Path) -> str: + return subprocess.run( + ["git", *args], cwd=cwd, check=True, capture_output=True, text=True + ).stdout.strip() + + +def last_version_bump_commit(package_dir: Path) -> str | None: + """The most recent commit that changed the version line in pyproject.toml.""" + output = git( + ["log", "-1", "--format=%H", "-G", r"^version\s*=", "--", "pyproject.toml"], + cwd=package_dir, + ) + return output or None + + +def has_relevant_changes(package_dir: Path, since_commit: str) -> bool: + output = git(["diff", "--name-only", since_commit, "--", "."], cwd=package_dir) + for line in output.splitlines(): + path = Path(line) + if path.suffix in RELEVANT_SUFFIXES or path.name == "pyproject.toml": + return True + return False + + +def stamp_version(package_dir: Path, version: str) -> None: + pyproject = package_dir / "pyproject.toml" + data = tomlkit.parse(pyproject.read_text()) + data["project"]["version"] = version # type: ignore[index] + pyproject.write_text(tomlkit.dumps(data)) + # Refresh uv.lock to match the updated pyproject.toml + subprocess.run(["uv", "lock"], cwd=package_dir, check=True) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--directory", type=Path, default=Path("src")) + args = parser.parse_args() + + directory = args.directory.resolve(strict=True) + today = datetime.date.today() + version = f"{today.year}.{today.month}.{today.day}" + + stamped = [] + for pyproject in sorted(directory.glob("*/pyproject.toml")): + package_dir = pyproject.parent + data = tomlkit.parse(pyproject.read_text()) + name = str(data["project"]["name"]) # type: ignore[index] + current = str(data["project"]["version"]) # type: ignore[index] + + if current == version: + print(f"{name}: already at {version}, skipping", file=sys.stderr) + continue + + since = last_version_bump_commit(package_dir) + # No version-bump commit found (shouldn't happen with full history): + # stamp anyway — release.yml's registry guard makes over-stamping harmless. + if since is not None and not has_relevant_changes(package_dir, since): + print(f"{name}: no changes since {current}, skipping", file=sys.stderr) + continue + + stamp_version(package_dir, version) + stamped.append(f"{name}: {current} -> {version}") + print(f"{name}: {current} -> {version}", file=sys.stderr) + + # stdout is the machine-readable summary (used as the PR body) + for line in stamped: + print(line) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/release.py b/scripts/release.py deleted file mode 100755 index b3dcf0c1e2..0000000000 --- a/scripts/release.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env uv run --script -# /// script -# requires-python = ">=3.12" -# dependencies = [ -# "click>=8.1.8", -# "tomlkit>=0.13.2" -# ] -# /// -import sys -import re -import click -from pathlib import Path -import json -import tomlkit -import datetime -import subprocess -from dataclasses import dataclass -from typing import Any, Iterator, NewType, Protocol - - -Version = NewType("Version", str) -GitHash = NewType("GitHash", str) - - -class GitHashParamType(click.ParamType): - name = "git_hash" - - def convert( - self, value: Any, param: click.Parameter | None, ctx: click.Context | None - ) -> GitHash | None: - if value is None: - return None - - if not (8 <= len(value) <= 40): - self.fail(f"Git hash must be between 8 and 40 characters, got {len(value)}") - - if not re.match(r"^[0-9a-fA-F]+$", value): - self.fail("Git hash must contain only hex digits (0-9, a-f)") - - try: - # Verify hash exists in repo - subprocess.run( - ["git", "rev-parse", "--verify", value], check=True, capture_output=True - ) - except subprocess.CalledProcessError: - self.fail(f"Git hash {value} not found in repository") - - return GitHash(value.lower()) - - -GIT_HASH = GitHashParamType() - - -class Package(Protocol): - path: Path - - def package_name(self) -> str: ... - - def update_version(self, version: Version) -> None: ... - - -@dataclass -class NpmPackage: - path: Path - - def package_name(self) -> str: - with open(self.path / "package.json", "r") as f: - return json.load(f)["name"] - - def update_version(self, version: Version): - with open(self.path / "package.json", "r+") as f: - data = json.load(f) - data["version"] = version - f.seek(0) - json.dump(data, f, indent=2) - f.truncate() - - -@dataclass -class PyPiPackage: - path: Path - - def package_name(self) -> str: - with open(self.path / "pyproject.toml") as f: - toml_data = tomlkit.parse(f.read()) - name = toml_data.get("project", {}).get("name") - if not name: - raise Exception("No name in pyproject.toml project section") - return str(name) - - def update_version(self, version: Version): - # Update version in pyproject.toml - with open(self.path / "pyproject.toml") as f: - data = tomlkit.parse(f.read()) - data["project"]["version"] = version - - with open(self.path / "pyproject.toml", "w") as f: - f.write(tomlkit.dumps(data)) - - # Regenerate uv.lock to match the updated pyproject.toml - subprocess.run(["uv", "lock"], cwd=self.path, check=True) - - -def has_changes(path: Path, git_hash: GitHash) -> bool: - """Check if any files changed between current state and git hash""" - try: - output = subprocess.run( - ["git", "diff", "--name-only", git_hash, "--", "."], - cwd=path, - check=True, - capture_output=True, - text=True, - ) - - changed_files = [Path(f) for f in output.stdout.splitlines()] - # .md counts as a change: READMEs ship inside the published package - # (npm tarball / PyPI long_description) - relevant_files = [f for f in changed_files if f.suffix in [".py", ".ts", ".md"]] - return len(relevant_files) >= 1 - except subprocess.CalledProcessError: - return False - - -def gen_version() -> Version: - """Generate version based on current date""" - now = datetime.datetime.now() - return Version(f"{now.year}.{now.month}.{now.day}") - - -def find_changed_packages(directory: Path, git_hash: GitHash) -> Iterator[Package]: - for path in directory.glob("*/package.json"): - if has_changes(path.parent, git_hash): - yield NpmPackage(path.parent) - for path in directory.glob("*/pyproject.toml"): - if has_changes(path.parent, git_hash): - yield PyPiPackage(path.parent) - - -@click.group() -def cli(): - pass - - -@cli.command("update-packages") -@click.option( - "--directory", type=click.Path(exists=True, path_type=Path), default=Path.cwd() -) -@click.argument("git_hash", type=GIT_HASH) -def update_packages(directory: Path, git_hash: GitHash) -> int: - # Detect package type - path = directory.resolve(strict=True) - version = gen_version() - - for package in find_changed_packages(path, git_hash): - name = package.package_name() - package.update_version(version) - - click.echo(f"{name}@{version}") - - return 0 - - -@cli.command("generate-notes") -@click.option( - "--directory", type=click.Path(exists=True, path_type=Path), default=Path.cwd() -) -@click.argument("git_hash", type=GIT_HASH) -def generate_notes(directory: Path, git_hash: GitHash) -> int: - # Detect package type - path = directory.resolve(strict=True) - version = gen_version() - - click.echo(f"# Release : v{version}") - click.echo("") - click.echo("## Updated packages") - for package in find_changed_packages(path, git_hash): - name = package.package_name() - click.echo(f"- {name}@{version}") - - return 0 - - -@cli.command("generate-version") -def generate_version() -> int: - # Detect package type - click.echo(gen_version()) - return 0 - - -@cli.command("generate-matrix") -@click.option( - "--directory", type=click.Path(exists=True, path_type=Path), default=Path.cwd() -) -@click.option("--npm", is_flag=True, default=False) -@click.option("--pypi", is_flag=True, default=False) -@click.argument("git_hash", type=GIT_HASH) -def generate_matrix(directory: Path, git_hash: GitHash, pypi: bool, npm: bool) -> int: - # Detect package type - path = directory.resolve(strict=True) - version = gen_version() - - changes = [] - for package in find_changed_packages(path, git_hash): - pkg = package.path.relative_to(path) - if npm and isinstance(package, NpmPackage): - changes.append(str(pkg)) - if pypi and isinstance(package, PyPiPackage): - changes.append(str(pkg)) - - click.echo(json.dumps(changes)) - return 0 - - -if __name__ == "__main__": - sys.exit(cli()) From 6d193ed39dec695283d213fce10f7b730e5f9d61 Mon Sep 17 00:00:00 2001 From: olaservo Date: Sat, 1 Aug 2026 18:52:36 -0700 Subject: [PATCH 5/7] docs: describe the release-triggered publishing flow in RELEASING.md Documents the merged state of the Phase 2 pipeline: changesets/semver for TypeScript, CalVer prepare-release for Python, publishing triggered by manually-created GitHub Releases, and the registry-diff self-healing behavior (#4472). Co-Authored-By: Claude Fable 5 --- RELEASING.md | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index fc7056c4d8..af9343c0b7 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,22 +1,38 @@ # Releasing -How the packages in this repository are published, and what to do when a publish fails. +How the packages in this repository are versioned and published, and what to do when a publish fails. + +## How versioning works + +**No workflow ever computes or stamps a version at release time.** The version in each package's manifest on `main` is the source of truth, and versions only change through reviewed PRs: + +- **TypeScript servers** (`everything`, `filesystem`, `memory`, `sequentialthinking`) use **semver, managed by [changesets](https://github.com/changesets/changesets)**. Feature PRs include a changeset file (see [CONTRIBUTING.md](CONTRIBUTING.md)); merged changesets accumulate in a rolling **"Version Packages" PR** (maintained by [`version-packages.yml`](.github/workflows/version-packages.yml) on every push to `main`), which applies version bumps and CHANGELOG entries when merged. Semver policy: **patch** = bug fixes; **minor** = new tools, prompts, resources, or options; **major** = breaking changes (tool removed or renamed, schema change that breaks clients, protocol or Node floor bump). +- **Python servers** (`fetch`, `git`, `time`) use **CalVer** (e.g. `2026.8.1`). A maintainer dispatches the **Prepare Python Release** workflow ([`prepare-release.yml`](.github/workflows/prepare-release.yml)), which stamps today's date onto each Python package that changed since its last version bump and opens a normal PR. + +> [!NOTE] +> PRs opened by these workflows use the workflow token, which doesn't trigger CI. Close and reopen the PR to run CI before merging. ## How publishing works -All packages publish exclusively from the [`release.yml`](.github/workflows/release.yml) GitHub Actions workflow, gated by the `release` environment (a required reviewer must approve each deployment). Releases are triggered deliberately by a maintainer via **workflow_dispatch** (Actions → Release → Run workflow, or `gh workflow run release.yml`) — there is no scheduled/automatic release. +Publishing is triggered by a maintainer **creating a GitHub Release** (Releases → Draft a new release → choose or create a tag on `main` → auto-generate notes → publish). The release tag is just a label — it carries no version semantics. + +The [`release.yml`](.github/workflows/release.yml) workflow runs on `release: published`, gated by the `release` environment (a required reviewer must approve each deployment). It runs every package as an independent matrix job (`fail-fast: false` — one package's failure never blocks another). Each job: checkout at the release tag → registry-diff guard → install → **run the package's tests** (plus `pyright` for Python) → build → publish. + +The **registry-diff guard** makes releases idempotent and self-healing: a package whose version already exists on the registry is **skipped, not failed** (npm: an explicit version check, where a never-published package counts as "publish it"; PyPI: `skip-existing` on the upload action). A package whose publish failed or was skipped simply publishes on the next release. **Authentication is OIDC trusted publishing on both registries — there are no registry tokens.** -- **npm** (TypeScript servers): each `@modelcontextprotocol/*` package is registered on npmjs.com with a [trusted publisher](https://docs.npmjs.com/trusted-publishers) bound to this repository, workflow filename `release.yml`, and environment `release` (the binding is case-sensitive). Packages publish with [provenance attestations](https://docs.npmjs.com/generating-provenance-statements). -- **PyPI** (Python servers): published via [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) using `pypa/gh-action-pypi-publish`. +- **npm**: each `@modelcontextprotocol/*` package is registered on npmjs.com with a [trusted publisher](https://docs.npmjs.com/trusted-publishers) bound to this repository, workflow filename `release.yml`, and environment `release` (the binding is case-sensitive). Packages publish with [provenance attestations](https://docs.npmjs.com/generating-provenance-statements). +- **PyPI**: published via [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) using `pypa/gh-action-pypi-publish`, with the same `release.yml` + `release` environment binding. + +Because of those bindings, the publish jobs must stay in `release.yml` and keep the `release` environment. -A release run: +## Cutting a release -1. **Detects changed packages** since the last release tag — a package counts as changed if any `.py`, `.ts`, or `.md` file in its directory changed (READMEs ship inside the published artifacts). -2. **Stamps versions and pushes the release tag** — versions are date-based (CalVer, e.g. `2026.7.4`). -3. **Publishes each changed package as an independent matrix job** (`fail-fast: false` — one package's failure never blocks another). Each job: checkout at the release tag → install → double-publish guard → **run the package's tests** (plus `pyright` for Python) → build → publish. The guard differs by registry: the npm job aborts before tests if the version already exists; for PyPI the skip happens at the publish step itself (`skip-existing` on the upload action). -4. **Creates the GitHub release** with generated notes. +1. Make sure the version bumps you want to ship are on `main`: merge the **Version Packages** PR (TypeScript) and/or the **Prepare Python Release** PR (Python). CI validates these like any other PR. +2. Create a GitHub Release on the releases page with auto-generated notes. Any tag name works (it's a label, not a version); dating them (e.g. `release-2026-08-01`) keeps the list readable. +3. Approve the `release` environment deployments when prompted. +4. Each package publishes if its version isn't on the registry yet; already-published packages skip cleanly. ## When a publish fails @@ -29,21 +45,17 @@ gh run rerun --failed --repo modelcontextprotocol/servers ``` - A re-run is still a `release.yml` run in the `release` environment, so it satisfies the trusted-publisher binding. -- It re-runs only the failed legs, checked out at the original release tag — it publishes exactly the tagged code, and the double-publish guard keeps already-published packages safe. +- It re-runs only the failed legs, checked out at the original release tag — it publishes exactly the released code, and the registry-diff guard keeps already-published packages safe. - It needs a fresh `release` environment approval, and the run must be complete first (approve or reject any pending deployments). - GitHub's re-run window is ~30 days from the original run, and re-runs execute the *original* workflow snapshot — workflow fixes on `main` don't apply to a re-run. -**Otherwise: let the next release pick it up.** If the re-run window has closed (or the fix required a workflow change), the failed version simply never exists on that registry — that's benign; npm and PyPI version histories don't need to match. The package publishes at the next version, provided it has a qualifying change (`.py`, `.ts`, or `.md`) since the last release tag. +**Otherwise: just cut the next release.** The registry-diff guard picks up any version that never made it to the registry — no stranded versions, no artificial file touches. **Never:** - Publish manually with an npm token or from a laptop — there are no registry tokens, and manual publishes would break the provenance/trust chain. -- Dispatch a fresh `release.yml` run expecting it to retry a failed version — versions are date-granular, so a same-day dispatch collides with the existing tag, and a later dispatch mints a *new* version. Neither retries the failed one. +- Edit versions directly on `main` to force a publish — versions change only through the Version Packages and Prepare Python Release PRs. ## Environment approvals The `release` environment's required-reviewer list is configured in the repository settings (Settings → Environments → `release`). Reviewer rights come only from that list — repository admin does not confer deployment approval. - ---- - -Planned changes to this process — semver via changesets for the TypeScript packages, publishing triggered by manually-created GitHub Releases — are tracked in [#4463](https://github.com/modelcontextprotocol/servers/issues/4463). This document will be updated when that work merges. From 9677b08c011ecd7dfe9c0155610b5c4a04a078b5 Mon Sep 17 00:00:00 2001 From: olaservo Date: Sun, 2 Aug 2026 18:08:02 -0700 Subject: [PATCH 6/7] fix: keep npm guard payload stderr-free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With --json, npm writes errors as JSON to stdout, so capturing stderr into the payload (2>&1) was unnecessary and risked stray npm warnings corrupting the JSON that jq parses — which would misread an already-published version as new. Capture stdout only. Co-Authored-By: Claude Fable 5 --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a7c728dfa3..fe1bfc4400 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,8 +69,10 @@ jobs: run: | NAME=$(jq -r .name package.json) VERSION=$(jq -r .version package.json) + # stdout only: with --json, npm writes errors as JSON to stdout, and + # stray stderr warnings must not corrupt the payload we parse set +e - PUBLISHED=$(npm view "$NAME" versions --json 2>&1) + PUBLISHED=$(npm view "$NAME" versions --json 2>/dev/null) EXIT_CODE=$? set -e if [ $EXIT_CODE -ne 0 ]; then From de849c410ddf5e60694856357e57b80527822410 Mon Sep 17 00:00:00 2001 From: olaservo Date: Mon, 3 Aug 2026 11:36:18 -0700 Subject: [PATCH 7/7] chore: rename prepare-release.yml to prepare-python-release.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The workflow is Python-specific (TypeScript versioning goes through version-packages.yml), so the filename should say so — matching its display name and the script it runs. Suggested in review. Co-Authored-By: Claude Fable 5 --- .../{prepare-release.yml => prepare-python-release.yml} | 0 RELEASING.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{prepare-release.yml => prepare-python-release.yml} (100%) diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-python-release.yml similarity index 100% rename from .github/workflows/prepare-release.yml rename to .github/workflows/prepare-python-release.yml diff --git a/RELEASING.md b/RELEASING.md index af9343c0b7..eb7d1d399b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,7 +7,7 @@ How the packages in this repository are versioned and published, and what to do **No workflow ever computes or stamps a version at release time.** The version in each package's manifest on `main` is the source of truth, and versions only change through reviewed PRs: - **TypeScript servers** (`everything`, `filesystem`, `memory`, `sequentialthinking`) use **semver, managed by [changesets](https://github.com/changesets/changesets)**. Feature PRs include a changeset file (see [CONTRIBUTING.md](CONTRIBUTING.md)); merged changesets accumulate in a rolling **"Version Packages" PR** (maintained by [`version-packages.yml`](.github/workflows/version-packages.yml) on every push to `main`), which applies version bumps and CHANGELOG entries when merged. Semver policy: **patch** = bug fixes; **minor** = new tools, prompts, resources, or options; **major** = breaking changes (tool removed or renamed, schema change that breaks clients, protocol or Node floor bump). -- **Python servers** (`fetch`, `git`, `time`) use **CalVer** (e.g. `2026.8.1`). A maintainer dispatches the **Prepare Python Release** workflow ([`prepare-release.yml`](.github/workflows/prepare-release.yml)), which stamps today's date onto each Python package that changed since its last version bump and opens a normal PR. +- **Python servers** (`fetch`, `git`, `time`) use **CalVer** (e.g. `2026.8.1`). A maintainer dispatches the **Prepare Python Release** workflow ([`prepare-python-release.yml`](.github/workflows/prepare-python-release.yml)), which stamps today's date onto each Python package that changed since its last version bump and opens a normal PR. > [!NOTE] > PRs opened by these workflows use the workflow token, which doesn't trigger CI. Close and reopen the PR to run CI before merging.