Skip to content

Release v2.2.0: merge v2/main into main - #5338

Merged
cliffhall merged 120 commits into
mainfrom
v2/chore/5330-release-v2.2.0
Oct 28, 2026
Merged

cliffhall merged 120 commits into
mainfrom
v2/chore/5330-release-v2.2.0

Conversation

@cliffhall

@cliffhall cliffhall commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Part of #5330

Milestone merge for v2.2.0: v2/main → main. No commits of its own;
the merged tree is origin/v2/main's (e1a083ef), head 8be205bb.

Release ledger: https://claude.ai/artifact/4QBpF136w3oXcAMVDRJtbe

⚠️ Merge with Create a merge commit. Do not click Update branch.

🤖 Generated with Claude Code

cliffhall and others added 30 commits October 25, 2026 00:11
A newcomer running `uvx mcp-server-git` sees it open no port and appear
to hang, and the README never says why. Add a Transports section after
the install commands: what each transport is, that every server here
serves stdio and only everything also serves Streamable HTTP, how to
try either with the Inspector, and where the MCP docs cover transports.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…-transports

docs: explain stdio vs Streamable HTTP in the root README
Replace the archived server-postgres entry with mcp-server-fetch, and
make the Windows note name the one remaining npx-based entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
typescript.yml and python.yml posted their `(dispatched)` pending status
without checking for a newer dispatched run on the commit, so a re-run
(which keeps its run ID) or a late-starting older run reset the newer
run's result to pending, and its own result job then stayed silent and
left it there. Both pending jobs now run the result job's newer-run
check, as dco.yml and everything-mcp-diff.yml already do (#5222), and
the stub-gh test covers all four workflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ease:notes

The generator built the Thanks section only from the authors of issues the
listed PRs close, so advisory reporters and outside contributors credited on
an issue were pasted in by hand, and v2.0.0 published without them.

- --advisory GHSA-… (repeatable) reads each advisory's credits_detailed,
  draft or published; declined credits, bots and maintainers are dropped, a
  pending credit is listed and flagged on stderr. The lead-in reads issues,
  vulnerabilities, or both.
- --thank "@login (#ref), <what>" (repeatable) writes the prototype
  paragraph after the reporter list.
- The preview lists every maintainer credit note on the milestone's closed
  issues that names a non-maintainer, marking which have a --thank.
- release skill 5a collects both before the preview and drops the by-hand
  step; RELEASING.md mentions the new credits.

Closes #5250

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
The claude job holds a shell, ANTHROPIC_API_KEY and id-token: write, and
any GitHub user could start it by writing @claude in a comment, review or
issue. Each event's condition now also requires the author of the text that
carries the mention to be OWNER, MEMBER or COLLABORATOR.

scripts/claude-workflow.test.mjs evaluates the job's if: against a payload
for every event the workflow listens to, so a disjunct that loses its check,
or checks the wrong author, fails the script tests. AGENTS.md records the
rule under Credentialed workflow jobs.

Closes #4795

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…llow-up write-ups on the card

GitHub refuses to publish an advisory while its private fork has an open
PR, and publishing deletes the fork. The security-advisory skill now
closes the fork's PR once its head is on v2/main, adds both checks to the
pre-publish list, and keeps a follow-up card's write-up on the card so
step 6 can still read it after publication.

Closes #5251

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…atch-pending-supersede

fix(ci): a superseded dispatched run posts no pending status (typescript.yml, python.yml)
…e-client-example

docs(readme): use only active servers in the client config example
… same target

While the registry target stays put, a server can upgrade on its own, be
added, or move between SDK groups, and the open issue kept its original
rows and server-<name> labels. The sweep now re-renders an OPEN issue for
the current target and edits it when the body differs (a ticked checklist
box alone is not a difference). Scope labels move only by the delta
between the old body's rows and the new ones, so labels triage or a
maintainer applied or removed are kept. A closed issue is left alone.

The sweep writer's edit gains --add-label / --remove-label, applied one by
one so it never replaces the label set.

Closes #5067

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
An open Dependabot alert whose advisory lists no first_patched_version
was skipped, so a newly disclosed vulnerability with no fix yet filed no
issue. It now stays in its (package, manifest) group:

- When no applying advisory has a fix, the issue asks for a decision
  (mitigate, pin away, drop, accept) instead of a bump; the marker
  records fixed=none.
- When others do, the bump issue carries a "No patched release" section
  for the unpatched advisories whose range still covers the target.
- A patched release published later rewrites the same issue into a bump
  in place, since the marker is keyed on package and manifest.

An advisory that loses its patched version now rewrites its issue to ask
for a decision rather than leaving it as is; it still never stands the
issue down.

Closes #5066

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Encode every "/" in an npm package name with replaceAll, and skip the
one-line HTML comment marker with startsWith/endsWith instead of a regex
tag filter. No behavior change for this repo's package names or for
GitHub's generated release notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…de-workflow-trusted-actors

fix(ci): start the Claude workflow only for trusted authors
…e card-body rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
The login check backtracked to @my in @my-scope/pkg, so a value that
credits nobody passed. Copilot round 1 on #5283.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Copilot on #5285: a group whose last outdated copy reached the target, or
that no manifest declares any more, was dropped before the refresh ran,
so its open issue kept stale **yes** rows and scope labels. Such a group
is now kept as settled: it files nothing and queues no analysis, but an
open issue for its target is rewritten to say nothing is behind, and the
scope labels its rows had called for are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…he target

Copilot round 1 on #5286. `undecided()` counted an unpatched advisory as
cleared whenever the bump's target fell outside its range. That missed
two cases: a target pickTarget had rejected (older than an affected
copy), and a range that reaches above the target (`>= 3.0.0`,
`< 1 || > 3`), where a raised floor can later resolve.

Now a rejected target clears nothing, and a verified one clears only a
range wholly below it: every `||` alternative carries an upper-bound
clause the target fails (`rangeBelow`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Copilot on #5285: a scope label a maintainer had applied before its
server fell behind was taken as the sweep's once the rows called for it,
so a later refresh removed it when the server caught up. The body now
records the scope labels the sweep applied on its last line, and a
refresh removes a label only if that record names it. A body without the
record (filed before it existed) falls back to its rows, which is what
the sweep applied at filing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Copilot round 2 on #5286.

- `rangeBelow` asked whether the target fails an upper-bound clause,
  but both ecosystems leave prereleases out of a range, so
  `2.0.0-rc.1` fails `< 3.0.0` while sitting below it. The bound is now
  compared by ordering, and an unreadable bound throws (treated as
  needing a decision).
- The new-advisory comment named only newly added unpatched advisories,
  so an unpatched one the issue already tracked read as cleared "along
  with the rest". It now names every advisory the bump leaves open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ase-notes-thanks

release:notes: credit advisory reporters and by-hand contributors in the Thanks section
…ory-close-fork-pr

docs(skills): close the advisory fork's PR before publishing; keep follow-up write-ups on the card
…unknown install

Copilot on #5285, round 3:

- The record of sweep-applied scopes kept a scope whose label a
  maintainer had removed, since an absent label never entered
  removeLabels. If they reapplied it, a later catch-up removed their
  label. Ownership now lapses whenever the rows stop calling for a scope.
- A copy with no installed version is not behind, so a group whose
  lockfile stopped resolving a copy was treated as settled and its issue
  rewritten as done. A group now settles only when every copy has a
  known installed version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ql-release-scripts

chore(scripts): clear the four CodeQL alerts in the release scripts
Copilot round 3 on #5286. With an unpatched advisory the bump cannot
clear, the dry run after the fix refreshes the issue to that advisory
rather than reporting the exposure cleared; the Fix section now says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ts-no-patched-release

feat(ci): alert sweep tracks advisories with no patched release
cliffhall and others added 19 commits October 27, 2026 08:35
…stem-head-crlf

fix(filesystem): head returns CRLF lines normalized to LF, like tail
…s its realpath

parseRootUri kept only the realpath of each client Root, so a request that
used the Root's own spelling (a symlinked directory, /tmp on macOS) was
refused. It now returns both forms and getValidRootDirectories admits both,
deduplicated, as resolveAllowedDirectories does for command-line
directories. validatePath still realpaths every request, so a symlink
inside a Root that points outside it stays refused.

Closes #5183

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
normalizePath trims whitespace and quotes, which are legal POSIX filename
characters, so a Root advertised as 'alias ' would have allowed an
unrelated sibling 'alias'. Format the advertised form with
normalizePathFormat instead, and pin it with a regression test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…creating under it

A Root's advertised form can be a symlink, which can be retargeted after the
Roots load. resolveUnicodeEquivalentPath started its walk for a missing path
from the allowed directory's realpath without checking it, so write_file or
create_directory under a retargeted alias landed outside every allowed
directory. Check that starting realpath like each component below it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…stem-root-advertised-form

fix(filesystem): allow a client Root in its advertised form as well as its realpath
rename() cannot cross a device boundary, so move_file failed with EXDEV
between allowed directories on different mounts. On EXDEV, moveFile now
falls back to moveFileAcrossDevices, which opens the source and creates
the destination relative to their anchored directories (O_EXCL, no
symlinks followed), copies the content, mode and times, then removes the
source only while it is still the file copied. A failed step removes the
copy and leaves the source in place. A directory or symlink is refused
with a clear error rather than copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
A symlink source is resolved by validatePath before the move, so its
target is what moves, on one device or across two; the copy refuses a
symlink only when one is swapped in after validation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ss the copy is in place

Review round 1 on #5322:
- the copy is created 0600 and takes the source's mode only once it is
  complete (openInDirectory gains an optional creation mode, default
  unchanged), so a private file is never readable at the destination
- before removing the source, the copy must still be at the destination
  (anchored lstat identity); if it was removed or replaced, the source
  stays and the move fails
- a failure closing the source after a complete copy now removes the
  copy too, so a retry is not blocked by a leftover destination

Rebased onto #5325 (#5154): the cross-device move's identity checks take
BigInt stats in isSameEntry's (pathStat, handleStat) order, and the
copy's identity is read again from its descriptor after the write, since
isSameEntry's Windows dev-0 fallback compares size and mtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…ice move

Review round 3 on #5322: the source's device and inode still match after
another writer edits it in place, so the move would delete the edited
source while the destination held the content read before the edit.
Before the source is removed, its size, mtime and ctime (ns) must also
match the stat taken when it was opened; otherwise the copy is removed
and the source kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Review round 4 on #5322: futimes was given the source's Date times,
which keep only milliseconds. Pass seconds derived from atimeNs and
mtimeNs instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Review round 5 on #5322: fs.futimes takes a negative number to mean
"now", so the seconds passed since round 4 lost any time before 1970.
Pass them as a numeric string, which it parses as given.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…stem-move-exdev

fix(filesystem): move a file across filesystems by copying it on EXDEV
The bounded-walk cap tests walk MAX_WALK_ENTRIES + 1 mocked entries on
purpose, so their cost scales with the runner. On a loaded Windows
runner the search_files one crossed vitest's 5 s default and turned
v2/main red. Give the three cap tests a 30 s timeout, with the reason
beside it; no retry, and the real bound is still the one tested.

Fixes #5328. Approach also proposed by FelixFangX in that issue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…d-walk-test-timeout

test(filesystem): explicit timeout on the 100000-entry walk tests
…on-calver-2026.10.28

chore: stamp Python CalVer versions for 2026.10.28
@cliffhall cliffhall added the v2 label Oct 28, 2026
Copilot AI balanced review requested due to automatic review settings October 28, 2026 18:59
@changeset-bot

changeset-bot Bot commented Oct 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8be205b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

everything: MCP interface diff

Base: ef9808f71090 (Merge pull request #5249 from modelcontextprotocol/v2/chore/5243-release-v2.1.0)
Head: the build in this checkout, at f0e6549420af (Merge 8be205b into ef9808f)

⚠️ Interface changes detected in 6 part(s) of the interface. Review them below to confirm they are intended.

Tools Prompts Resources Resource templates
Base 22 4 7 3
Head 22 4 7 3

initialize

--- base/initialize.json
+++ target/initialize.json

- _meta.io.modelcontextprotocol/serverInfo.version: "2.0.1"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
- instructions: "# Everything Server – Server Instructions\n\nAudience: These instructions are written for an LLM or au..."
+ instructions: "# Everything Server – Server Instructions\n\nAudience: These instructions are written for an LLM or au..."

instructions

--- base/instructions
+++ target/instructions
- # Everything Server – Server Instructions

Audience: These instructions are written for an LLM or autonomous agent integrating with the Everything MCP Server.
Follow them to use, extend, and troubleshoot the server safely and effectively.

## Protocol Versions

The server serves two protocol eras. A client on protocol version 2026-07-28 connects with `server/discover` and sends its capabilities with each request; a 2025-era client connects with `initialize`. Some tools exist on one era only, so trust your `tools/list`:

- 2026-07-28 only: `simulate-research-query`, `trigger-sampling-request-async` and `trigger-elicitation-request-async`, which run as tasks on the `io.modelcontextprotocol/tasks` extension and need a client that declares it; `trigger-sampling-request-async` also needs `sampling`, and `trigger-elicitation-request-async` form-mode `elicitation`. A call without them fails with `-32021`
- 2025-era only (deprecated): `toggle-simulated-logging` and `toggle-subscriber-updates`

## Cross-Feature Relationships

- If `get-roots-list` is in your tool list, use it to see client workspace roots before file operations
- `gzip-file-as-resource` creates resources you can read later: for the current session on a 2025-era connection, or for ten minutes at the returned URI on 2026-07-28
- Use `trigger-log-messages` to see which log levels reach you; on 2026-07-28 the level is set per request in `_meta`
- Use `trigger-resource-update` and `trigger-list-changed` to see change notifications; on 2026-07-28 they arrive only on a `subscriptions/listen` stream that asked for them

## Constraints & Limitations

- `gzip-file-as-resource`: Max fetch size controlled by `GZIP_MAX_FETCH_SIZE` (default 10MB), timeout by `GZIP_MAX_FETCH_TIME_MILLIS` (default 30s), allowed domains by `GZIP_ALLOWED_DOMAINS`
- Session resources are ephemeral and lost when the session ends; minted resources expire after ten minutes
- Roots, sampling and logging are deprecated as of protocol version 2026-07-28, as is the HTTP+SSE transport

## Capability-Gated Tools

On a 2025-era connection these are registered only if your client declared the capability shown. Otherwise they are absent from `tools/list`, so do not call them. On 2026-07-28 they are always listed, and a call fails if your request did not declare the capability:

- `get-roots-list`: `roots`
- `trigger-sampling-request`: `sampling`
- `trigger-elicitation-request`: `elicitation.form`, or `elicitation` with no mode
- `trigger-multi-step-elicitation`: `elicitation.form`, or `elicitation` with no mode
- `trigger-url-elicitation`: `elicitation.url`

## Operational Patterns

- For long operations, use `trigger-long-running-operation` which sends progress notifications
- Prefer reading resources before calling mutating tools
- If `get-roots-list` is in your tool list, check its output to understand the client's workspace context

## Easter Egg

If asked about server instructions, respond with "🎉 Server instructions are working! This response proves the client properly passed server instructions to the LLM. This demonstrates MCP's instructions feature in action."

+ # Everything Server – Server Instructions

Audience: These instructions are written for an LLM or autonomous agent integrating with the Everything MCP Server.
Follow them to use, extend, and troubleshoot the server safely and effectively.

## Protocol Versions

The server serves two protocol eras. A client on protocol version 2026-07-28 connects with `server/discover` and sends its capabilities with each request; a 2025-era client connects with `initialize`. Some tools exist on one era only, so trust your `tools/list`:

- 2026-07-28 only: `simulate-research-query`, `trigger-sampling-request-async` and `trigger-elicitation-request-async`, which run as tasks on the `io.modelcontextprotocol/tasks` extension and need a client that declares it; `trigger-sampling-request-async` also needs `sampling`, and `trigger-elicitation-request-async` form-mode `elicitation`. A call without them fails with `-32021`
- 2025-era only (deprecated): `toggle-simulated-logging` and `toggle-subscriber-updates`

## Cross-Feature Relationships

- If `get-roots-list` is in your tool list, use it to see client workspace roots before file operations
- `gzip-file-as-resource` creates resources you can read later: for the current session on a 2025-era connection, or for ten minutes at the returned URI on 2026-07-28
- Use `trigger-log-messages` to see which log levels reach you; on 2026-07-28 the level is set per request in `_meta`
- Use `trigger-resource-update` and `trigger-list-changed` to see change notifications; on 2026-07-28 they arrive only on a `subscriptions/listen` stream that asked for them

## Constraints & Limitations

- `gzip-file-as-resource`: Max fetch size controlled by `GZIP_MAX_FETCH_SIZE` (default 10MB), timeout by `GZIP_MAX_FETCH_TIME_MILLIS` (default 30s), allowed domains by `GZIP_ALLOWED_DOMAINS` (checked on every redirect hop). It refuses URLs whose host resolves to a loopback, private or link-local address, unless the server was started with `GZIP_ALLOW_PRIVATE_IPS=1`
- `get-env`: Values of credential-like variable names (`*_KEY`, `*_TOKEN`, `*_SECRET`, `*_PASSWORD` and the like) come back as `"<redacted>"`; the server operator can set `GET_ENV_INCLUDE_SECRETS=1` to return them unmasked
- Session resources are ephemeral and lost when the session ends; minted resources expire after ten minutes
- Roots, sampling and logging are deprecated as of protocol version 2026-07-28, as is the HTTP+SSE transport

## Capability-Gated Tools

On a 2025-era connection these are registered only if your client declared the capability shown. Otherwise they are absent from `tools/list`, so do not call them. On 2026-07-28 they are always listed, and a call fails if your request did not declare the capability:

- `get-roots-list`: `roots`
- `trigger-sampling-request`: `sampling`
- `trigger-elicitation-request`: `elicitation.form`, or `elicitation` with no mode
- `trigger-multi-step-elicitation`: `elicitation.form`, or `elicitation` with no mode
- `trigger-url-elicitation`: `elicitation.url`

## Operational Patterns

- For long operations, use `trigger-long-running-operation` which sends progress notifications
- Prefer reading resources before calling mutating tools
- If `get-roots-list` is in your tool list, check its output to understand the client's workspace context

## Easter Egg

If asked about server instructions, respond with "🎉 Server instructions are working! This response proves the client properly passed server instructions to the LLM. This demonstrates MCP's instructions feature in action."

tools

--- base/tools.json
+++ target/tools.json

- _meta.io.modelcontextprotocol/serverInfo.version: "2.0.1"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
- tools[get-env].description: "Returns all environment variables, helpful for debugging MCP server configuration"
+ tools[get-env].description: "Returns all environment variables, helpful for debugging MCP server configuration. Values of credent..."

prompts

--- base/prompts.json
+++ target/prompts.json

- _meta.io.modelcontextprotocol/serverInfo.version: "2.0.1"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"

resources

--- base/resources.json
+++ target/resources.json

- _meta.io.modelcontextprotocol/serverInfo.version: "2.0.1"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"

resource_templates

--- base/resource_templates.json
+++ target/resource_templates.json

- _meta.io.modelcontextprotocol/serverInfo.version: "2.0.1"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"

Updated by this run for 8be205bb3d77ba71f78f1f83fa8233afb8ee4aed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Replacing the configured root’s .git after startup can bypass repository confinement, while concurrent memory migration can incorrectly terminate a client after another client completes the migration.

2 open issues
What changed in this PR

This milestone merge brings the v2.2.0 release changes from v2/main into main, covering reference-server fixes, security improvements, and release tooling for #5330.

Changes:

  • Improves filesystem operations, memory persistence, Git confinement, and container timezone handling.
  • Strengthens fetch behavior and Everything server defaults, with expanded regression coverage.
  • Updates package versions, documentation, CI safeguards, and release procedures.
File Description
src/​time/​uv.lock Updates the locked release version.
src/​time/​README.md Documents container timezone overrides.
src/​time/​pyproject.toml Sets the Python release version.
src/​time/​Dockerfile Expands timezone configuration at startup.
src/​memory/​README.md Documents migration failure handling.
src/​memory/​package.json Bumps Memory to 2.0.1.
src/​memory/​index.ts Preserves extra fields and reports migration failures.
src/​memory/​CHANGELOG.md Records persistence fixes.
src/​memory/​__tests__/​file-path.test.ts Covers migration failures.
src/​memory/​__tests__/​extra-fields.test.ts Covers preservation of unmodelled fields.
src/​git/​uv.lock Updates the locked release version.
src/​git/​tests/​test_server.py Tests Unicode output and commit-based branching.
src/​git/​tests/​test_protocol.py Tests confinement, encoding, and branch behavior.
src/​git/​tests/​snapshots/​list_tools.json Updates branch-tool documentation snapshots.
src/​git/​src/​mcp_server_git/​server.py Adds directory validation and improves Git output and branching.
src/​git/​README.md Explains confinement and branch bases.
src/​git/​pyproject.toml Sets the Python release version.
src/​filesystem/​server.ts Bounds tree traversal and describes hard-link metadata.
src/​filesystem/​roots-utils.ts Keeps advertised and resolved Root paths.
src/​filesystem/​README.md Documents filesystem behavior and limits.
src/​filesystem/​path-utils.ts Retries initial directory resolution.
src/​filesystem/​package.json Bumps Filesystem to 2.1.0.
src/​filesystem/​index.ts Uses retrying startup resolution.
src/​filesystem/​CHANGELOG.md Records filesystem improvements.
src/​filesystem/​__tests__/​stdio.test.ts Tests startup resolution retries.
src/​filesystem/​__tests__/​server-tools.test.ts Tests line endings, cross-device moves, and hard links.
src/​filesystem/​__tests__/​server-roots.test.ts Tests Root aliases and escape rejection.
src/​filesystem/​__tests__/​server-paths.test.ts Tests case-sensitive path admission.
src/​filesystem/​__tests__/​roots-utils.test.ts Covers Root resolution retries.
src/​filesystem/​__tests__/​path-utils.test.ts Covers retry helper behavior.
src/​filesystem/​__tests__/​lib.test.ts Tests path identity, metadata, and move fallback.
src/​fetch/​uv.lock Updates release and extraction dependencies.
src/​fetch/​tests/​test_translated_addresses.py Tests IPv4-embedded IPv6 address checks.
src/​fetch/​tests/​test_robots_status.py Tests refusal on robots.txt server errors.
src/​fetch/​tests/​test_readability_js_opt_out.py Tests extraction without Node.js.
src/​fetch/​tests/​test_raw_prefix_and_deps.py Tests raw-content labels and dependency declarations.
src/​fetch/​tests/​test_protocol.py Removes obsolete robots.txt expectations.
src/​fetch/​tests/​test_non_cp1252_pages.py Covers Unicode extraction on Windows.
src/​fetch/​tests/​test_missing_content_type.py Tests headerless content detection.
src/​fetch/​tests/​test_html_charset.py Tests HTML charset decoding.
src/​fetch/​tests/​test_hidden_ssr.py Tests recovery of hidden server-rendered content.
src/​fetch/​tests/​test_entrypoints.py Updates CLI argument expectations.
src/​fetch/​tests/​test_empty_tree.py Covers empty extraction trees.
src/​fetch/​src/​mcp_server_fetch/​__init__.py Adds the Readability.js opt-out flag.
src/​fetch/​README.md Documents extraction and request restrictions.
src/​fetch/​pyproject.toml Updates release version and dependencies.
src/​everything/​tools/​trigger-long-running-operation.ts Corrects the tool name in JSDoc only.
src/​everything/​tools/​get-resource-links.ts Clarifies naming without changing behavior.
src/​everything/​tools/​get-env.ts Masks credential-like environment values by default.
src/​everything/​README.md Documents masking and gzip fetch controls.
src/​everything/​package.json Bumps Everything to 2.1.0.
src/​everything/​docs/​structure.md Updates tool configuration descriptions.
src/​everything/​docs/​instructions.md Describes masking and fetch restrictions.
src/​everything/​docs/​features.md Clarifies environment output and resource types.
src/​everything/​CHANGELOG.md Records tool fixes and safer defaults.
src/​everything/​__tests__/​tools.test.ts Tests masking and PNG integrity.
src/​everything/​__tests__/​sampling-elicitation.test.ts Tests summaries against actual form fields.
src/​everything/​__tests__/​private-ips-opted-in.ts Enables private addresses for local fixtures.
src/​everything/​__tests__/​gzip-private-addresses.test.ts Tests default private-address rejection.
src/​everything/​__tests__/​gzip-limits.test.ts Tests redirect restrictions and limits.
src/​everything/​__tests__/​gzip-file-as-resource.test.ts Covers HTTP failures and local fixture opt-in.
scripts/​version-pr-ci.test.mjs Checks superseded pending-status jobs.
scripts/​npm-publish-guard.mjs Encodes every slash in registry paths.
scripts/​lib/​sweep.test.mjs Tests targeted label edits.
scripts/​lib/​sweep.mjs Adds individual label additions and removals.
scripts/​claude-workflow.test.mjs Tests trusted-author workflow conditions.
RELEASING.md Documents advisory and prototype credits.
README.md Refreshes client examples and explains transports.
package-lock.json Synchronizes workspace release versions.
AGENTS.md Updates workflow security and maintenance guidance.
.github/​workflows/​typescript.yml Avoids pending updates from superseded runs.
.github/​workflows/​python.yml Prepares extraction dependencies and guards pending statuses.
.github/​workflows/​claude.yml Restricts triggering mentions to trusted authors.
.claude/​skills/​security-advisory/​SKILL.md Updates private-fork closure and follow-up preservation procedures.
.claude/​skills/​release/​SKILL.md Adds advisory and prototype credit procedures.

Review effort: Balanced

Comment on lines +466 to +469
with git.Repo(allowed) as allowed_repo:
own = {
Path(allowed_repo.git_dir).resolve(),
Path(allowed_repo.common_dir).resolve(),
Comment thread src/memory/index.ts
);
return newMemoryPath;
await fs.rename(oldMemoryPath, newMemoryPath);
} catch (error) {
@cliffhall
cliffhall merged commit 60200eb into main Oct 28, 2026
86 checks passed
@cliffhall
cliffhall deleted the v2/chore/5330-release-v2.2.0 branch October 28, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants