Repository navigation
Release v2.3.0: merge v2/main into main - #5430
Conversation
The hdiutil create, attach and detach calls can pass vitest's 5 s default on a loaded machine, failing the gate on timing alone. Size the timeout for them (30 s) rather than retrying. Closes #5314 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Nothing in src/filesystem imports glob; pattern matching goes through minimatch. Drop it from the workspace's dependencies and refresh the lockfile, which also drops glob's own lru-cache, minipass and path-scurry entries that nothing else needed. Closes #5186 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…tion hints Adds a registration-level check over every tool-registering path, on both eras (registerTools, registerLegacyTools, registerConditionalTools with every capability declared, registerModernTools): each registered tool sets readOnlyHint, destructiveHint, idempotentHint and openWorldHint as booleans. The tool set is read from what each path registers, and each path is pinned to its known capability-gated and task tools so an empty path cannot pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
create_entities, create_relations and add_observations already skip what is stored, so repeating a call with the same arguments has no additional effect on the graph. Declare idempotentHint: true, as the delete tools do, update the annotations fixture, and add a protocol-level test that a repeat of each call leaves the graph unchanged. Closes #5153 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Prompt arguments carry no JSON Schema, only a description, so a client had no way to learn that resourceType accepts only "Text" or "Blob", or that resourceId must be a positive integer, before the prompt rejected the call. Both descriptions now say so, built from the RESOURCE_TYPE_* constants, and a protocol-level test reads them back from prompts/list in both eras, along with a check that every prompt argument is described. Closes #3985 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
The server never imports yargs, so drop it and @types/yargs from the workspace manifest and refresh the lockfile; the lockfile change is only the removal of yargs and its now-orphaned transitive packages. Closes #5206 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…only tools The ten read-only tools set only readOnlyHint and openWorldHint, so a client reading idempotentHint or destructiveHint fell back to the spec's defaults (not idempotent, destructive). Set both explicitly (true, false), pin them in the tools/list table test, and add protocol-level invariants every tool must keep: all four hints present, a read-only tool idempotent and not destructive, none open-world. The README's annotation table now shows them, and lists read_file. Closes #3402 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…nfig git_commit already takes the author and committer from GIT_AUTHOR_* and GIT_COMMITTER_* in the server's environment, then from user.name/user.email in Git config (GitPython's Actor). Document both routes in a new Commit identity section, add -e lines to the Docker examples, and pin each route with protocol-level tests. Closes #619 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
The README called the tool sequential_thinking, but index.ts registers it as sequentialthinking. Correct the four mentions; the tool is not renamed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
normalizePath trims whitespace and strips a leading or trailing quote, which suits a typed request but not a directory name the file system returned. resolveAllowedDirectories (both forms of a command-line directory) and parseRootUri (a Root's realpath) used it, so an allowed directory named `project ` was allowed as `project`, its sibling. Use normalizePathFormat, which formats without trimming, for all of them. The command-line form is not trimmed either: trimming after path.resolve could only ever drop a trailing character, which is exactly the sibling case, never a leading quote left over from shell quoting. Closes #5320 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…ll once addObservations filtered the incoming contents against what the entity already held, but not against each other, so contents: ["x", "x"] stored "x" twice and reported it twice in addedObservations. De-duplicate the contents first, keeping the first occurrence's order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
read_text_file tested head and tail for truthiness, so a count of 0 fell through to reading the whole file, and head: 0 with tail: 0 was not rejected. Compare against undefined instead, make tailFile return empty text for 0 lines (slice(-0) returned every line), and accept only non-negative integers for both counts. Closes #5184 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
list_directory_with_sizes substituted a size of 0 (and an epoch mtime, never shown) for an entry it could not stat, so an unreadable entry, a dangling symlink or a symlink leaving the allowed directories was listed as an empty file and counted in the combined size. Show such an entry's size as "unknown", sort it last by size, leave it out of the combined size, and say how many files the total excludes. Closes #5190 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
The fetch prompt passed its url argument straight to httpx, so a malformed
URL raised httpx.InvalidURL, which is not an HTTPError: it escaped the
prompt's error handling and the SDK answered with JSON-RPC code 0 ("Error
rendering prompt fetch"). Validate the url with the same AnyUrl type the
tool's parameter uses and answer a bad one with INVALID_PARAMS and the
validation reason. A valid URL is fetched normalized, as the tool does.
Closes #4914
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Models read "search for files and directories matching a pattern" as a content search and called search_files to grep, getting "No matches found" for text that was in the files. The description now opens with "by NAME, not by content", says the glob is matched case-sensitively against each entry's path relative to 'path' (it said the working directory), and gives '**/name' as the any-depth form. The README entry says the same. A new test pins the wording and each matching rule it states. Closes #896 Closes #3419 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
With --read-only the server registers only the tools annotated readOnlyHint: true. Every other tool is removed before any client connects, so it is absent from tools/list and cannot be called, on both protocol eras. Keying on the annotation fails closed: a new write tool is withheld with no change to the mode. `--` ends the options. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
git_diff validated target with rev_parse, which resolves one revision, so main..feature and main...feature were refused although git diff accepts them. A target that does not resolve whole is now split at its first '..' or '...', and each endpoint gets the single-target checks: no leading '-', and it must resolve. An empty endpoint means HEAD. Closes #5194 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
When an edit_file oldText matches nowhere, the error now names the edit that failed (edit k of n), states the matching rules, says nothing was written, and quotes the closest run of file lines with line numbers, plus the first differing line JSON-quoted so whitespace differences are visible. The tool description and README now state the matching rules. What matches is unchanged: the report never edits a near match. Closes #2034 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…g parent When a requested path is, or passes through, a symlink whose target does not exist, the realpath of that entry in resolveUnicodeEquivalentPath failed with ENOENT, and validatePath reported "Parent directory does not exist" for a directory that does exist. The entry is known to exist at that point (lstat found it), so an ENOENT from its realpath means its target is missing: say so, naming the symlink. The request is still refused; any other realpath failure is reported as it is. Closes #5191 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
formatThought padded the whole thought as one string, so a thought with line breaks drew its earlier lines outside the frame, put the right border after the last line only, and sized the box from the whole string. Each line (split on \r\n, \n or a lone \r) is now a padded row of its own, and the box is as wide as the longest line or the header. Closes #5205 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Under npx or an npm install the default memory.jsonl sits inside a node_modules tree, where a reinstall, an update or a cleared npx cache can delete it. The server now prints a warning on stderr at startup when the memory file it resolves is inside node_modules, and the README recommends setting MEMORY_FILE_PATH to an absolute path the user owns, says why, and states the atomic-save and lock guarantees that already exist. The default path is unchanged (#4117). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Merges a branch, tag or commit into the current branch. Fast-forward only by default; fast_forward_only=false allows a merge commit. Refuses a detached HEAD, a dirty working tree and a merge already in progress, and aborts a merge that stops on conflicts (naming the files) or fails to commit, so a failed call leaves the repository as it was. Keeps the flag-injection guard and repository confinement of the other tools. Closes #659 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
get_current_time's timezone and convert_time's source_timezone and target_timezone may now be omitted. Each defaults to the server's local timezone (detected, or set with --local-timezone), which the input schema carries as the argument's default and the description names. time stays required, and an explicitly empty timezone is still rejected as missing. Closes #2853 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
One resources/read of demo://resource/collection/summer-specials, or of
the demo://resource/collection/by-category/{category} template, returns
several contents, each under its item's own
demo://resource/collection/item/{itemId} URI, which reads back on its own.
Both templates complete their variable; a category or item not in the
catalog is not found (-32602). Served to both protocol eras, with no state.
Closes #3130
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
convert_time attached the source zone to today's date and the given HH:MM, which always resolves to fold=0: on a DST fall-back day a repeated wall time (01:30 in America/New_York on 2024-11-03) has two instants, and the tool silently answered with the first. TimeConversionResult gains an optional later_occurrence (a LaterOccurrence: a note, and the source, target and time_difference at the second instant), set only when the source time's fold=1 reading has a different UTC offset. source and target keep the first occurrence, so an unambiguous conversion is unchanged apart from later_occurrence: null. Closes #5196 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
expandHome recognized only `~` and `~/`, so a Windows user's `~\projects` (a command-line directory, a request path or a plain-path client Root) resolved to a literal `~` directory under the working directory. Expand `~\` as well, on win32 only: on POSIX a backslash is a filename character and `~\notes` names a file. parseRootUri carried its own copy of the `~/` check; it now calls expandHome, so a Root and a command-line directory agree. Closes #5180 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…with a Streamable HTTP mode The Dockerfile copied src/everything alone and ran a lockfile-less npm install, so the image ignored the root package-lock.json and the overrides that pin transitive dependencies, and `--omit-dev` was not an npm flag. Its CMD also took the whole command, so `docker run mcp/everything streamableHttp` failed with "Cannot find module '/app/streamableHttp'". Build from the repository root with npm ci against the workspace lockfile, keep the context to what the build reads with a Dockerfile.dockerignore, run as the node user, expose PORT 3001, stop on SIGINT, and split ENTRYPOINT from a `stdio` CMD so the transport name is the run argument. Document building and running both modes in the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Files inside the allowed directories can now be read with resources/read
through a `file://{+path}` resource template, returned as text or as a
base64 blob with their MIME type. Reads go through the same validatePath,
roots barrier and 2026-07-28 no-directories error as the tools, and the
template has no list callback, so resources/list never enumerates the disk.
The template lives in file-resources.ts and is registered from
createServer() with one call.
Closes #297
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
copy_file copies one regular file to a new location, so a model can duplicate a file without reading it into the conversation and writing it back. It is registered right after move_file and, like move_file, never overwrites: an existing destination fails it. It reuses the copy half of the cross-device move (#5188): the source is opened relative to its pinned directory and must be a regular file, and the destination is created exclusively relative to its own, then takes the source's permissions and times. Directories are refused. The stdio tests no longer pin the tool count, so a new tool does not break them; server-tools.test.ts still pins the full list. Closes #519 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
search_nodes rejects a query longer than SEARCH_QUERY_MAX_LENGTH (2048 characters); the README listed the input only as a string. Closes #5200 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…stem-minimatch-11 fix(filesystem): move minimatch to ^11.0.4 for GHSA-g3hv-75wg-m249
…ase-audit fix(deps): v2.3.0 release audit, raise the qs override to >=6.16.1
…v2/main chore: version packages
…on-calver-2026.11.4 chore: stamp Python CalVer versions for 2026.11.4
|
|
| Tools | Prompts | Resources | Resource templates | |
|---|---|---|---|---|
| Base | 22 | 4 | 7 | 3 |
| Head | 22 | 4 | 8 | 5 |
initialize
--- base/initialize.json
+++ target/initialize.json
- _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.2.1"
+ _meta.io.modelcontextprotocol/serverInfo.icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...tools
--- base/tools.json
+++ target/tools.json
- _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.2.1"
+ _meta.io.modelcontextprotocol/serverInfo.icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[echo].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-annotated-message].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-env].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-header-params].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-resource-links].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-resource-reference].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-roots-list].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-structured-content].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-sum].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[get-tiny-image].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[gzip-file-as-resource].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[simulate-research-query].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-elicitation-request].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-elicitation-request-async].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-list-changed].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-log-messages].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-long-running-operation].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-multi-step-elicitation].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-resource-update].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-sampling-request].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-sampling-request-async].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ tools[trigger-url-elicitation].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...prompts
--- base/prompts.json
+++ target/prompts.json
- _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.2.1"
+ _meta.io.modelcontextprotocol/serverInfo.icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ prompts[args-prompt].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ prompts[completable-prompt].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
- prompts[resource-prompt].arguments[resourceId].description: "ID of the text resource to fetch"
+ prompts[resource-prompt].arguments[resourceId].description: "ID of the resource to fetch. Must be a positive integer (1 or greater)."
- prompts[resource-prompt].arguments[resourceType].description: "Type of resource to fetch"
+ prompts[resource-prompt].arguments[resourceType].description: "Type of resource to fetch. Must be \"Text\" or \"Blob\"."
+ prompts[resource-prompt].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ prompts[simple-prompt].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...resources
--- base/resources.json
+++ target/resources.json
- _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.2.1"
+ _meta.io.modelcontextprotocol/serverInfo.icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[summer-specials]: {"description":"A resource collection: one read returns every item in the catalog as a separate content, each under its own demo://resource/collection/item/{itemId} URI.","icons":[{"mimeType":"image/s...
+ resources[architecture.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[extension.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[features.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[how-it-works.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[instructions.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[startup.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resources[structure.md].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...resource_templates
--- base/resource_templates.json
+++ target/resource_templates.json
- _meta.io.modelcontextprotocol/serverInfo.version: "2.1.0"
+ _meta.io.modelcontextprotocol/serverInfo.version: "2.2.1"
+ _meta.io.modelcontextprotocol/serverInfo.icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resourceTemplates[collection-by-category]: {"description":"A resource collection filtered by the {category} variable (accessories, footwear, skincare): one read returns each item in that category as a separate content, under its own URI.","ico...
+ resourceTemplates[collection-item]: {"description":"One item of the resource collections, selected by the {itemId} variable (1 to 5). The collections return their items under these URIs.","icons":[{"mimeType":"image/svg+xml","sizes":["a...
+ resourceTemplates[Dynamic Blob Resource].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resourceTemplates[Dynamic Text Resource].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...
+ resourceTemplates[Minted Resource].icons: [{"mimeType":"image/svg+xml","sizes":["any"],"src":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub2...Updated by this run for 281b1671ed304431f23be2e5b9c3b2d81df01628.
There was a problem hiding this comment.
🟡 Changes recommended
Diagnostic formatting can exhaust memory through quadratic output growth, and generated resources still omit required icons from legacy listings and modern resource links.
2 open issues
What changed in this PR
Merges the v2.3.0 milestone from v2/main into main as part of #5425, bringing accumulated improvements across the seven reference servers and release tooling.
Changes:
- Adds protocol demonstrations, filesystem controls, fetch configuration, and improved memory, time, and Git behavior.
- Expands regression coverage and updates package versions, changelogs, and user documentation.
- Refreshes Docker packaging and release procedures, increases GitHub response buffers, and removes the Claude workflow.
| File | Description |
|---|---|
| src/time/uv.lock | Updates locked package version. |
| src/time/tests/test_eras.py | Expects get_time_ago in both eras. |
| src/time/tests/test_entrypoints.py | Checks the expanded stdio tool list. |
| src/time/README.md | Documents timezone defaults, past times, and ambiguity. |
| src/time/pyproject.toml | Updates release version. |
| src/sequentialthinking/README.md | Corrects tool name and documents history limits. |
| src/sequentialthinking/package.json | Bumps version and removes unused dependencies. |
| src/sequentialthinking/lib.ts | Bounds history and formats multiline thoughts. |
| src/sequentialthinking/index.ts | Shortens the tool description. |
| src/sequentialthinking/CHANGELOG.md | Records release changes. |
| src/sequentialthinking/__tests__/tools-list.test.ts | Checks description limits and parameter documentation. |
| src/sequentialthinking/__tests__/thought-logging.test.ts | Covers multiline logging. |
| src/memory/README.md | Documents lightweight reads and storage safety. |
| src/memory/package.json | Updates release version. |
| src/memory/CHANGELOG.md | Records release changes. |
| src/memory/__tests__/knowledge-graph.test.ts | Covers repeated-observation deduplication. |
| src/memory/__tests__/file-path.test.ts | Tests unsafe storage-location warnings. |
| src/memory/__tests__/entry-point.test.ts | Checks startup storage warnings. |
| src/git/uv.lock | Updates locked package version. |
| src/git/tests/test_server.py | Covers revision-range edge cases. |
| src/git/tests/test_protocol.py | Checks expanded tools and diff ranges. |
| src/git/tests/test_identity.py | Tests commit identity configuration. |
| src/git/tests/snapshots/list_tools.json | Updates diff, merge, and remote tool metadata. |
| src/git/pyproject.toml | Updates release version. |
| src/filesystem/roots-utils.ts | Preserves exact paths and shares home expansion. |
| src/filesystem/pinned-directory.ts | Adds guarded append and copy operations. |
| src/filesystem/path-utils.ts | Supports Windows home-relative backslash paths. |
| src/filesystem/package.json | Bumps version and refreshes dependencies. |
| src/filesystem/index.ts | Parses access controls and logs allowed directories. |
| src/filesystem/allowed-directories.ts | Implements Roots confinement and access summaries. |
| src/filesystem/__tests__/win32.test.ts | Covers Windows home expansion and Roots. |
| src/filesystem/__tests__/tool-annotations.test.ts | Checks tool annotation invariants. |
| src/filesystem/__tests__/stdio.test.ts | Covers exact directory names over stdio. |
| src/filesystem/__tests__/server-paths.test.ts | Checks broken-symlink diagnostics. |
| src/filesystem/__tests__/search-files-description.test.ts | Checks documented filename-search behavior. |
| src/filesystem/__tests__/roots-utils.test.ts | Covers untrimmed resolved Roots. |
| src/filesystem/__tests__/pinned-directory.test.ts | Allows more time for disk-image operations. |
| src/filesystem/__tests__/path-utils.test.ts | Preserves literal POSIX backslashes. |
| src/filesystem/__tests__/lib.test.ts | Checks propagation of realpath failures. |
| src/fetch/uv.lock | Updates locked package version. |
| src/fetch/tests/test_readability_js_opt_out.py | Checks opt-out against the new extractor runner. |
| src/fetch/tests/test_protocol.py | Updates timeout schema and URL-validation coverage. |
| src/fetch/tests/test_prompt_url.py | Tests prompt URL validation and normalization. |
| src/fetch/tests/test_markdown_negotiation.py | Covers native Markdown negotiation. |
| src/fetch/tests/test_hidden_ssr.py | Tracks both HTML extraction paths. |
| src/fetch/tests/test_entrypoints.py | Updates expected startup arguments. |
| src/fetch/tests/test_empty_tree.py | Uses Python extraction for crash reproduction. |
| src/fetch/tests/harness.py | Adapts fixtures to the server-owned runner. |
| src/fetch/src/mcp_server_fetch/title.py | Preserves page titles in simplified Markdown. |
| src/fetch/src/mcp_server_fetch/timeout.py | Defines configurable timeout parsing and bounds. |
| src/fetch/src/mcp_server_fetch/allowlist.py | Validates allowed hosts and rejects unlisted requests. |
| src/fetch/src/mcp_server_fetch/__init__.py | Adds host allowlist and timeout flags. |
| src/fetch/pyproject.toml | Updates release version. |
| src/everything/tools/trigger-url-elicitation.ts | Adds themed tool icons. |
| src/everything/tools/trigger-sampling-request.ts | Adds themed tool icons. |
| src/everything/tools/trigger-sampling-request-async.ts | Adds themed tool icons. |
| src/everything/tools/trigger-resource-update.ts | Adds themed tool icons. |
| src/everything/tools/trigger-multi-step-elicitation.ts | Adds themed tool icons. |
| src/everything/tools/trigger-long-running-operation.ts | Adds cancellation-aware waits and icons. |
| src/everything/tools/trigger-log-messages.ts | Adds themed tool icons. |
| src/everything/tools/trigger-list-changed.ts | Adds themed tool icons. |
| src/everything/tools/trigger-elicitation-request.ts | Adds themed tool icons. |
| src/everything/tools/trigger-elicitation-request-async.ts | Adds themed tool icons. |
| src/everything/tools/toggle-subscriber-updates.ts | Adds themed tool icons. |
| src/everything/tools/toggle-simulated-logging.ts | Adds themed tool icons. |
| src/everything/tools/simulate-research-query.ts | Adds themed tool icons. |
| src/everything/tools/gzip-file-as-resource.ts | Adds themed tool icons. |
| src/everything/tools/get-tiny-image.ts | Adds themed tool icons. |
| src/everything/tools/get-sum.ts | Adds themed tool icons. |
| src/everything/tools/get-structured-content.ts | Adds themed tool icons. |
| src/everything/tools/get-roots-list.ts | Adds themed tool icons. |
| src/everything/tools/get-resource-reference.ts | Adds themed tool icons. |
| src/everything/tools/get-resource-links.ts | Adds themed tool icons. |
| src/everything/tools/get-header-params.ts | Adds themed tool icons. |
| src/everything/tools/get-env.ts | Adds themed tool icons. |
| src/everything/tools/get-annotated-message.ts | Adds themed tool icons. |
| src/everything/tools/echo.ts | Adds themed tool icons. |
| src/everything/server/index.ts | Advertises server icons. |
| src/everything/server/icons.ts | Defines shared light and dark icon sets. |
| src/everything/resources/templates.ts | Clarifies prompt arguments and adds template icons. |
| src/everything/resources/minted.ts | Adds minted-resource template icons. |
| src/everything/resources/index.ts | Registers resource collections. |
| src/everything/resources/files.ts | Adds static-resource icons. |
| src/everything/resources/collections.ts | Demonstrates multi-content resource reads. |
| src/everything/README.md | Documents collections, icons, and Docker usage. |
| src/everything/prompts/simple.ts | Adds themed prompt icons. |
| src/everything/prompts/resource.ts | Adds themed prompt icons. |
| src/everything/prompts/completions.ts | Adds themed prompt icons. |
| src/everything/prompts/args.ts | Adds themed prompt icons. |
| src/everything/package.json | Updates release version. |
| src/everything/docs/structure.md | Documents collection and icon modules. |
| src/everything/docs/features.md | Describes collections, icons, and cancellation. |
| src/everything/Dockerfile.dockerignore | Limits the Docker build context. |
| src/everything/Dockerfile | Uses locked workspace installs and non-root execution. |
| src/everything/CHANGELOG.md | Records release changes. |
| src/everything/__tests__/surface.test.ts | Updates protocol snapshots for new metadata and resources. |
| src/everything/__tests__/static-files.test.ts | Separates static documents from collection resources. |
| src/everything/__tests__/registrations.test.ts | Checks annotation presence across registration paths. |
| src/everything/__tests__/prompts.test.ts | Checks advertised prompt argument descriptions. |
| src/everything/__tests__/long-running-cancel.test.ts | Tests cancellation in both protocol eras. |
| src/everything/__tests__/icons.test.ts | Checks themed icons on protocol surfaces. |
| src/everything/__tests__/harness.ts | Omits icons from unrelated snapshots. |
| src/everything/__tests__/collections.test.ts | Tests collection reads and completions. |
| scripts/verify-action-pins.mjs | Updates credentialed-job examples in comments. |
| scripts/release-notes.test.mjs | Covers large replies and spawn errors. |
| scripts/release-notes.mjs | Increases subprocess buffers and clarifies advisory credits. |
| scripts/lib/sweep.test.mjs | Covers large GitHub replies and spawn errors. |
| scripts/lib/sweep.mjs | Increases GitHub subprocess buffer limits. |
| scripts/claude-workflow.test.mjs | Removes tests for the deleted workflow. |
| RELEASING.md | Clarifies Python release PR issue linking. |
| package.json | Raises the qs override minimum. |
| docs/ai-software-factory.md | Updates advisory tracking documentation. |
| .github/workflows/sdk-watch.yml | Removes a stale workflow reference from a comment. |
| .github/workflows/python.yml | Exercises first-use JavaScript dependency installation. |
| .github/workflows/claude.yml | Removes the Claude Code workflow. |
| .claude/skills/board-ops/SKILL.md | Updates advisory-card conversion timing. |
Review effort: Balanced
#5205 padded every row of the box to the thought's longest line, so one long line and many short ones logged their product: a 60 KB thought wrote 400 million characters. The box is now at most MAX_BOX_TEXT_WIDTH (100) wide, wrapping longer lines and a longer header without splitting a surrogate pair, and at most MAX_BOX_ROWS (1000) rows, ending with a row that counts the lines left out. The box tops out near 107 KB; the stored thought and the tool result are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…cons #3131 put a light/dark icon pair on every primitive, and the docs say every resources/list entry carries one, but the resource the gzip tool creates had none: the 2025-era session resource (its list entry and link) and the 2026-07-28 minted link. Both now carry RESOURCE_ICONS, and the icon tests cover the generated resource in both eras. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
A truncated thought of short lines had a summary row wider than the box (33 characters against a 20-character border). The row texts are now collected first and the box is sized to include the summary; widening cannot change the wrapping, since below the cap no line wrapped and at the cap the summary fits. The very-many-lines test checks every row's width. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…hing-generated-resource-icons fix(everything): give gzip-file-as-resource's resource the resource icons
The row cap counts thought-text rows only (a long branchId's header rows are not capped), so there is no absolute size guarantee; and the tool result never carries the thought text, which the server keeps whole in its history. README, changeset and the MAX_BOX_ROWS comment now say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…tialthinking-linear-thought-box fix(sequentialthinking): bound the stderr thought box
…v2/main chore: version packages
There was a problem hiding this comment.
🔵 Needs a closer look
Release-critical Docker build and stdio/HTTP/shutdown validation could not be independently verified in this environment, and the linked release ledger evidence was unavailable.
No open issues 🎉
2 resolved since last review
Review effort: Balanced
Release evidence for
|
| Check | Result |
|---|---|
npm run local:gate |
EXIT 0. Server tests: everything 461, filesystem 663 (6 skipped), memory 229, sequential-thinking 138, fetch 460, git 301, time 171. Per-file coverage gates pass. Smoke booted 9/9 server/transport pairs. Interface diff: no changes. |
npm run pack:verify |
EXIT 0. 7/7 publish artifacts installed into an empty directory and booted. everything 2.2.1 booted over stdio, SSE and Streamable HTTP. |
| What publishes | All 7 versions are new to their registry: everything 2.2.1, filesystem 2.2.0, memory 2.1.0, sequential-thinking 2.1.1, and fetch, git and time 2026.11.4. |
| CI on this PR | 42 pass, 9 skipped. This includes all seven Windows legs and Source is v2/main. |
Docker (#3309)
The image was built with docker build -f src/everything/Dockerfile from a clean git archive 281b1671 (Docker 28.5.1), under a unique tag that was removed afterwards.
config: user=node entrypoint=["node","dist/index.js"] cmd=["stdio"] exposes 3001/tcp stopsignal=SIGINT 68 MB
inside: everything 2.2.1 · qs 6.17.1 · runs as node
stdio (docker run -i) legacy: exit 0 "Echo: docker-stdio"
modern: exit 0 "Echo: docker-stdio", serverInfo mcp-servers/everything 2.2.1
stdio gzip-file-as-resource link icons [light, dark] in both eras (the #5434 fix is in the image)
http (streamableHttp, -p 127.0.0.1:3932:3001)
legacy: exit 0 "Echo: docker-http"
modern: exit 0 "Echo: docker-http", serverInfo mcp-servers/everything 2.2.1
docker stop: 0.2 s
Shutdown and cancellation (#4846, #1124)
An SDK client over stdio started trigger-long-running-operation, cancelled it after its first progress notification, called echo, and then closed stdin.
legacy: call rejected · progress after cancel 0 · echo "Echo: after cancel" · exited 11 ms after stdin closed
modern: call rejected · progress after cancel 0 · echo "Echo: after cancel" · exited 9 ms after stdin closed
2.1.0 (published), first head: exited 9,005 / 9,002 ms after stdin closed
Milestone issues
All 71 closed issues in the milestone were exercised in both protocol eras, not just read. That includes #5433 and #5434, the two findings from the first review on this PR. 69 pass, and 2 are Windows-only fixes (#5180, #5313): they were probed on macOS and are covered by the Windows CI legs above. The ledger has one row per issue, with the command or client action and its output.
🤖 Generated with Claude Code

Part of #5425
Milestone merge for v2.3.0:
v2/main→main. No commits of its own;the merged tree is
origin/v2/main's (5dc9bf16).Fast-forwarded from
cc602786to281b1671after the review on this PR: it adds #5436 (#5434, everything resource icons), #5435 (#5433, sequential-thinking thought box) and #5437 (Version Packages: everything 2.2.1, sequential-thinking 2.1.1).Release ledger: Servers v2.3.0 Release Ledger
🤖 Generated with Claude Code