Skip to content

fix(tools): cut repeated text from 27 tool definitions and lower the size cap - #636

Open
aliasunder wants to merge 21 commits into
mainfrom
fix/tool-definitions-batch-2
Open

aliasunder wants to merge 21 commits into
mainfrom
fix/tool-definitions-batch-2

Conversation

@aliasunder

@aliasunder aliasunder commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

What does this PR do?

Tightens the MCP definitions of the 27 tools that score below 5.0 on Glama's Tool Definition Quality Score, and lowers the size cap to hold the saving. The default tool list drops from 133,810 to 123,723 chars (−10,087, about 8%), which every claude.ai and Claude Desktop conversation loads. The Errors: sections were also checked against what a client can actually receive.

Each edit answers the grader's written reason for that tool. The most common reason was that the description repeats what the input schema already says, so each repeated fact now has one home:

  • A parameter's plain meaning (what it is, its format, its default) stays in the schema.
  • Interactions, consequences and non-obvious behaviour stay in the description.
  • A fact only one side stated stays where it was.

The six tools at 5.0 are not touched: vault_get_backlinks, vault_list_notes, vault_list_property_keys, vault_list_property_values, vault_recent_notes, vault_search_by_property. No runtime behaviour changes.

Changes per tool

Tool Score, lower dimensions Change
vault_insert_at_anchor 4.1: Behavior 3, Parameters 3, Conciseness 4, Completeness 4 position and first_match bullets cut (the schema states both); the verbatim and trailing-newline rule stays in the description and leaves the schema
vault_search_by_tag 4.5: Behavior 3, Conciseness 4 Example loses its restatement of the prefix rule; When to use no longer echoes the opening sentence
vault_write_note 4.6: Behavior 4, Conciseness 4, Parameters 4 The full-write warning is stated once; says that overwriting without properties keeps the existing property values; lists the refusal for a path a folder occupies; merge rule leaves the schema
vault_list_memory_files 4.7: Conciseness 3 The heading structure and leading_callout are each defined once, in Returns
vault_search_by_folder 4.7: Behavior 4, Conciseness 4 Returns field list compressed
vault_update_task 4.9: Conciseness 4 Sixteen parameter bullets that restated the schema cut; status behaviour on Kanban boards, recurring tasks and delete-on-completion tasks kept; examples cut from twelve to seven; position interaction rules leave the schema
vault_create_task 4.8: Conciseness 4, Parameters 4 Parameter bullets cut to what the schema lacks; examples cut from six to four; position interaction rules leave the schema
vault_list_tasks 4.8: Conciseness 4, Parameters 4 Seven restating parameter bullets cut; folder semantics, the date-filter rule and the status-expansion example kept
vault_search 4.8: Conciseness 4, Parameters 4 tags, type and related filter bullets cut; the two date-filter bullets become one
vault_read_file 4.8: Conciseness 4, Parameters 4 The two raw: true examples cut; the per-type raw sentences become one bullet; lists the failure for an image that cannot be decoded
vault_read_note 4.9: Conciseness 4 The outline shape is given once, on the outline parameter; the description keeps the bytes and empty-heading facts
vault_move_note 4.9: Conciseness 4 The two partial-failure bullets tightened, each keeping its state and recovery step
vault_patch_note 4.8: Conciseness 4, Parameters 4 Two sentences that the schema and Errors already carry cut; the child-headings fact moves into the section-boundaries sentence
vault_replace_in_note 4.8: Conciseness 4, Parameters 4 Body-only, empty-deletes and default restatements cut
vault_update_properties 4.8: Conciseness 4, Parameters 4 Merge rule leaves the schema; it stays in the opening sentence
vault_delete_memory 4.8: Conciseness 4, Parameters 4 The append-only rationale is stated once; lists "memory file not found"
vault_delete_note 4.8: Conciseness 4, Parameters 4 The unreadable-config bullet names the real risk: a guessed setting could let the retention sweep remove a note set to be kept forever
vault_get_daily_note 4.8: Conciseness 4, Parameters 4 Format and today-default restatements cut
vault_get_outgoing_links 4.8: Conciseness 4, Parameters 4 bytes clause tightened
vault_update_memory 4.8: Conciseness 4, Parameters 4 Near-duplicate-section sentence tightened
vault_delete_span 4.9: Conciseness 4 Path-error bullet shortened; the blank-line bullet says every run in the body collapses, as vault_replace_span's does
vault_find_orphans 4.9: Conciseness 4 The inline default list cut from the parameter bullet (the schema and the example show it)
vault_get_memory 4.9: Conciseness 4 The on_or_after paragraph tightened
vault_memory_recall 4.9: Parameters 4 Says that file is applied before limit; truncation rule leaves the schema
vault_replace_span 4.9: Parameters 4 Bullets cut to what the schema lacks; says blank-line collapsing also applies inside content
vault_list_files 4.9: Conciseness 4 Parameter bullets cut; the filesystem and full-set facts move to a Behavior: line
vault_list_tags 4.9: Parameters 4 The empty-result sentence moves under Errors:, like the other listing tools

The path-error bullet in each edited tool becomes "absolute path blocked" / "path traversal blocked" / "hidden path blocked" — use a vault-relative path with no hidden (dot-prefixed) file or folder in it. The three messages name their own causes.

vault_update_memory and vault_delete_memory also fix a grammar slip in their opening sentence ("a About Me/ memory file").

Added facts, checked against the code

Tool Added Where the code does it
vault_write_note Overwriting without properties keeps the existing property values serializeNote, vault-filesystem.ts:260
vault_write_note "cannot write note …: that path is not a file" vault-filesystem.ts:431
vault_delete_memory "memory file not found" readMemoryFile, memory-store.ts:588, called by deleteMemory
vault_read_file An image that cannot be decoded fails with the decoder's message fitImageToByteBudget, fit-image-to-byte-budget.ts:99
vault_memory_recall file is applied before limit memoryRecall, search-queries.ts:587–601, then buildMemoryRecallResult
vault_replace_span Blank-line collapsing applies inside content too vault-patcher.ts:514
vault_delete_span Blank-line collapsing applies to every run in the body, not only the runs the deletion leaves vault-patcher.ts:456
vault_delete_note Why an unreadable trash config blocks the delete trash-config.ts:57
vault_list_files An empty extensions array returns an empty listing buildAssetListing, asset-operations.ts:388

Errors sections match what the client receives

Every message quoted in an Errors: section of the 33 tools was traced to a throw that a schema-valid call can reach. That found entries in both directions.

Listed, but the client could never receive them (the input schema rejects the input first, so the client gets an input validation error). Removed:

Tool Removed entry
vault_replace_in_note "oldText cannot be empty"
vault_create_task, vault_update_task "dependsOn cannot be empty"
vault_update_task "addSubtasks cannot be empty"

Quoted text that was not the text the server sends. Corrected:

Tool Was Now
vault_update_memory "entry/section contains a control character" "entry contains a control character" / "section contains a control character"
vault_create_task, vault_update_task "checkbox '[c]' is a NON_TASK status" "checkbox "[c]" is a NON_TASK status"

Returned by the tool, but not listed. Added:

Tool Added entry
vault_write_note "cannot write note …: that path is not a file"
vault_delete_memory "memory file not found"
vault_get_memory, vault_update_memory, vault_delete_memory "memory file must be a bare name without path separators"
vault_read_note "heading_level requires a heading", "heading cannot be empty"
vault_patch_note "heading cannot be empty"
vault_move_note "source and destination are the same path"
vault_create_task, vault_update_task "absolute path blocked" / "path traversal blocked" / "hidden path blocked"
vault_read_file "invalid .canvas JSON", and the decoder's message for an image that cannot be decoded

The memory shrink-guard entry on vault_update_memory and vault_delete_memory now says what triggers the refusal and what resolves it (a manual edit), because re-reading and retrying returns the same refusal.

Each added or corrected entry has a test over real HTTP: the error entries in server-error-contracts.test.ts, and the empty extensions result in server-integration.test.ts. The other added facts are pinned where the code does them: the file-before-limit rule in memory-recall.test.ts, and blank-line collapsing in vault-patcher.test.ts (inside the replacement content for vault_replace_span, and elsewhere in the body for both span tools).

Size

Configuration Before After
default (33 tools) 133,810 123,723
embedding-off (33 tools) 132,536 122,507

The three task tools account for most of the saving. A few tools grow slightly because they gained Errors: entries (vault_update_memory, vault_delete_memory, vault_read_file).

CHARS_PER_TOOL_ALLOWANCE drops from 4055 to 3821: the default average when the allowance was set (3,745 chars per tool) plus 2%. The default average is now 3,749. The cap assertion was checked by adding one char more than the remaining headroom, which fails it.

Checks on the text

  • No unintended change: the six untouched tools are byte-identical in all 17 configuration snapshots, and the server instructions and prompts are unchanged.
  • No dropped fact: for each of the 27 tools, every fact in the old description and schema was listed first and then located in the new text. The embedding-off renderings of vault_search and vault_memory_recall were checked as well. The pass found three drops, all restored in this PR: what a hidden path is, and two vault_list_files facts.

The README's daily-notes note now lists the unsupported format tokens w, Q and Z/ZZ, which the server already rejected and vault_get_daily_note now names.

AGENTS.md gains one rule under "MCP tool definitions": edit only the tools a change is meant for, because a grader re-scores every definition whose text changes.

One existing test changed: the guard that pinned the outline shape in vault_read_note's description now pins it on the outline parameter, where the shape lives.

Type of change

  • New MCP tool
  • Bug fix
  • Refactoring
  • Documentation
  • CI / workflow change
  • Infrastructure (SST, Docker)
  • Other:

Checklist

  • npm test passes
  • npm run lint passes
  • npm run prettier:check passes
  • npm run build succeeds
  • New MCP tools follow the naming and description conventions in AGENTS.md (no new tool; the edited descriptions keep the required sections)
  • README or ARCHITECTURE.md updated (docs changed in this PR: AGENTS.md, one rule)

🤖 Generated with Claude Code

aliasunder and others added 9 commits October 3, 2026 14:39
vault_insert_at_anchor, vault_search_by_tag, vault_write_note,
vault_list_memory_files and vault_search_by_folder each said some facts
twice, in the description and again in the input schema or in a second
section. Each fact now has one home.

vault_write_note also states that overwriting without properties keeps
the existing property values, and lists the refusal for a path a folder
occupies, with an error-contract test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vault_list_tasks, vault_create_task and vault_update_task described most
parameters twice, once in the description and once in the input schema.
The description now keeps only what the schema does not say: parameter
interactions, consequences, and the status behaviour on Kanban boards,
recurring tasks and delete-on-completion tasks. The position parameter's
interaction rules live in the description only. Example sets are cut to
one per pattern.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…o one side

A review of the first five edits found the shortened path-error bullet no
longer said that hidden means dot-prefixed. The bullet says it again.
vault_insert_at_anchor keeps its verbatim and trailing-newline rule in the
description and vault_write_note its merge rule, with the schema text cut
to the plain meaning. vault_search_by_tag's When to use names the main use.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…itions

Each tool loses the text its input schema or another section already
carried: restated parameter bullets, duplicate examples, and the long
cause clause of the path-error bullet. Facts that only one side stated
stay where they were.

Three Errors sections gain a failure the tool can return, each with an
error-contract test: vault_delete_memory on a missing memory file,
vault_read_file on an image that cannot be decoded, and (already added)
vault_write_note on a path a folder occupies. vault_list_tags states its
empty result under Errors like the other listing tools.

vault_delete_note's unreadable-config bullet names the real risk: a
guessed setting could let the retention sweep remove a note set to be
kept forever.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…us 2%

The default configuration's tool list fell from 133,810 to 124,145 chars
(3,762 per tool), so the allowance drops from 4055 to 3838 to hold the
saving. AGENTS.md gains the rule to edit only the tools a change is meant
for.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vault_read_note's description no longer repeats the outline shape that
the outline parameter's schema text already gives, so the drift guard
reads the schema text and asserts it whole.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The nested-folder example moves to the folder parameter's schema text,
and Returns says again that only supported types are readable.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The default configuration's average is 3,764 chars per tool after the
vault_list_files fix, so the 2% allowance is 3840.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds three failures to the Errors sections of the tools that return them:
a memory file name with a path separator (vault_get_memory,
vault_update_memory, vault_delete_memory), heading_level without heading
(vault_read_note), and a move onto the same path (vault_move_note).

Removes four listed messages the client never sees because the input
schema rejects the input first: "oldText cannot be empty"
(vault_replace_in_note), "dependsOn cannot be empty" (vault_create_task,
vault_update_task) and "addSubtasks cannot be empty" (vault_update_task).

Each added entry, and the entries that stay in the edited bullets, has an
error-contract test over real HTTP.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/tools/task-tools.ts
@umm-actually

umm-actually Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

umm-actually re-reviewed at e7e6f1e

No new findings (16 tracked finding(s) across all runs).

Context notes
  • Priority docs already in context: README.md
  • 17 changed file(s) excluded from review: src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/default.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/disabled-tools.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/file-tools-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/file-tools-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/memory-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/memory-off+file-tools-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/memory-off+file-tools-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/memory-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+file-tools-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+file-tools-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+memory-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+memory-off+file-tools-off+embedding-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+memory-off+file-tools-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly+memory-off.json (diff_exclude_paths input), src/vault-mcp/mcp-core/__tests__/__snapshots__/tool-surface/readonly.json (diff_exclude_paths input)

umm-actually · z-ai/glm-5.3-flash

aliasunder and others added 2 commits October 3, 2026 15:44
vault_update_memory quoted "entry/section contains a control character",
a string the client never receives; it now quotes the two real messages.
Its shrink-guard entry and vault_delete_memory's say what triggers the
refusal and what to do, since re-reading alone does not clear it.

Entries that share a remedy share a bullet (the memory file-name errors,
vault_get_memory's two "requires a file" errors). vault_get_outgoing_links
quotes its extension error. vault_get_daily_note lists the remaining
unsupported format tokens. Three repeated facts are cut from one side.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…al allowance

vault_create_task and vault_update_task list the three path-guard errors
their path parameter can raise. vault_read_file lists "invalid .canvas
JSON". vault_read_note and vault_patch_note list "heading cannot be
empty" for a whitespace-only heading. The NON_TASK entry on both task
tools quotes the message as the server sends it. Each has an
error-contract test.

The size allowance is 3875: the final default average (3,798 chars per
tool) plus 2%.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@aliasunder
aliasunder marked this pull request as ready for review October 3, 2026 19:48
Comment thread src/vault-mcp/mcp-core/tools/vault-crud-tools.ts
@umm-actually

umm-actually Bot commented Oct 3, 2026

Copy link
Copy Markdown

Add the newly listed unsupported daily-note tokens to the README note
Low severity · conventions · medium confidence

README.md:1 — beyond the diff's line ranges, in code the changes touch or depend on.

This PR expands vault_get_daily_note's unsupported-token list in the tool description to include w, Q, and Z/ZZ, but README's Daily-notes note still enumerates only ordinals, dd, d, e, k/kk and the L-family — the user-facing doc now under-reports which formats error out.

Failure scenario: A user with a daily-note filename format using w or Z reads the README, sees those tokens not listed as unsupported, keeps the format, and vault_get_daily_note rejects every call while the docs said nothing about it.

Suggested fix
Extend the README note's token list with the weekday/quarter/zone tokens (w, Q, Z/ZZ) the tool description now names.

umm-actually · z-ai/glm-5.3-flash

aliasunder and others added 2 commits October 3, 2026 16:22
Fix 16 readability pauses from the fresh-eyes stranger read: resolve
ambiguous antecedents (pause 3), replace jargon (pause 2 "rendition",
pause 7 "tokens"), fix broken grammar (pause 10 NON_TASK sentence),
separate packed sub-cases (pauses 5, 14, 15), define opaque terms
(pause 13 "trailing section content"), break dense clauses (pauses 6,
9, 12), clarify compact notation (pauses 1, 4, 8), add missing cascade
order (pause 11), and make the AGENTS.md "one home per kind" heading
concrete (pause 16). Tighten both Obsidian syntax paragraphs (create
and update) for the same pattern. Net size change is a small shrink;
six frozen tools untouched.

Ship-Check: code-quality · claude-opus-4-6

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reviews of the edited definitions listed about thirty places where the
description and a parameter's schema text still said the same thing, or
where a small fact was missing or misleading. Each repeat is cut from one
side: plain meaning stays in the schema, interactions and consequences in
the description.

Restores three facts and one spelled-out abbreviation that the previous
readability commit dropped: the Dataview form and the adjacent-field
effect in the task tools' Obsidian syntax note, and what a daily-note
forward reference points to.

Also: vault_memory_recall's second example no longer uses the query form
its own text calls poorly ranking, vault_list_files says what an
extensionless file reports, and the sort cascade names its real order.

The size allowance is 3821: the default average (3,745 chars per tool)
plus 2%.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/__tests__/tool-surface-snapshot.test.ts
aliasunder and others added 2 commits October 3, 2026 16:48
The sort_by .describe() text said "done and cancelled do not cascade"
but "cancelled" is not in the sort_by enum — an agent reading this
would think it is a valid sort key. Only "done" lacks a cascade.

Ship-Check: bug-check · claude-opus-4-6

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…README

The daily-notes note named ordinals, dd, d, e, k/kk and the localized
formats. The server also rejects w, Q and Z/ZZ, which the tool
description now lists, so the README names them too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@aliasunder

Copy link
Copy Markdown
Owner Author

Reply to issue comment 5972944109 ("Add the newly listed unsupported daily-note tokens to the README note"): valid, fixed in 17f3208.

The README daily-notes note now lists w (week number), Q (quarter) and Z/ZZ (UTC offset) alongside the tokens it named before. The list matches UNSUPPORTED_PATTERNS in moment-format.ts.

Sweep for the token list: README.md is the one doc that carries it. DOCKERHUB.md is regenerated from the README and does not include that note. The vault_get_daily_note description lists the same tokens.


🔍 ship-check · pr-monitor · claude-fable-5-1

Comment thread src/vault-mcp/mcp-core/tools/memory-tools.ts Outdated
Comment thread src/vault-mcp/mcp-core/tools/search-tools.ts
@umm-actually

umm-actually Bot commented Oct 3, 2026

Copy link
Copy Markdown

Mark additional_properties conditional in recent_notes and search_by_property
Low severity · subtle bugs · medium confidence

src/vault-mcp/mcp-core/tools/search-tools.ts:251 — beyond the diff's line ranges, in code the changes touch or depend on.

Pre-existing: vault_recent_notes and vault_search_by_property list additional_properties as an unconditional Returns field, but this PR's own edits mark it conditional (additional_properties?) in vault_search_by_tag and vault_find_orphans and reword vault_search_by_folder to 'when present'. All five tools map results through the same formatNoteMetadata helper, so presence semantics are identical and the two unconditional listings misstate the response shape.

Failure scenario: A script consuming vault_recent_notes builds on the documented shape and reads additional_properties from every entry; a note whose frontmatter holds only promoted keys (title, tags, type, created, related) comes back without the field, and the consumer throws on the missing key or reports a malformed response.

Suggested fix
Change both Returns lists to "additional_properties?" (or add a "when present" clause, as vault_search_by_folder now does) so all five metadata listings agree with formatNoteMetadata's actual behavior. If the new "Edit only the tools a change is meant for" rule is read as blocking these two, land the two-word fix in a follow-up rather than leaving the definitions contradicting each other.

umm-actually · z-ai/glm-5.3-flash

…at resolves

The bullet ended with "inspect the file before retrying", but the guard refuses the same append again until the content a rewrite cannot keep is gone. It now says a retry returns the same refusal until a manual edit removes that content, and that reading the note finds it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/tools/asset-tools.ts
Comment thread src/vault-mcp/mcp-core/tools/search-tools.ts
@aliasunder

Copy link
Copy Markdown
Owner Author

Reply to issue comment 5973542886 ("Mark additional_properties conditional in recent_notes and search_by_property"): valid, and the maintainer approved fixing it in a follow-up change.

  • Behaviour: formatNoteMetadata (tool-helpers.ts) adds additional_properties only when a note has at least one unpromoted property.
  • Already say so: vault_search_by_tag, vault_find_orphans, vault_search_by_folder.
  • Still list it without the ?: vault_recent_notes, vault_search_by_property.
  • Fix: that one character in each of the two Returns lines, plus the regenerated snapshots.

🔍 ship-check · pr-monitor · claude-fable-5-1

…st_files

The tool description says an empty extensions array returns an empty listing, and no test made that call. The fixture vault holds files, so the empty result can only come from the filter.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/tools/memory-tools.ts
Comment thread src/vault-mcp/mcp-core/tools/task-tools.ts Outdated
Comment thread src/vault-mcp/mcp-core/tools/vault-crud-tools.ts
… that tool is disabled

The parent_block_id / parent_line bullet named vault_update_task without the availability check its two sibling references use. The clause now goes through whenToolEnabledText, so the text is unchanged while vault_update_task is served and absent when it is not.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Errors:
- A visible folder containing no files — or one that doesn't exist — returns an empty listing, not an error.
- A visible folder containing no files — or one that doesn't exist — returns an empty listing, not an error. So does an empty extensions array.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reject an empty extensions array instead of documenting an empty listing
Low severity · conventions · medium confidence

vault_list_files' new Errors bullet promises that an empty extensions array returns an empty listing, turning an accidental artifact ([] is truthy, so the filter is applied with an empty allow-list) into a documented contract. An empty filter list can never select anything, so per the conventions' input-boundary rule it is invalid input and should be rejected by the schema's .min(1) floor — as the sibling array params (depends_on, subtasks, heading) already do — rather than silently producing a result the caller likely reads as "this folder has no files".

Failure scenario: An agent computes the extensions list from its own intent (e.g. "images" for a folder that turns out to hold none) and sends vault_list_files({ extensions: [] }) expecting an unfiltered listing; the server returns { files: [], extension_counts: {}, total: 0, truncated: false }, and the agent reports the vault/folder as containing no files.

Suggested fix
In `asset-tools.ts`, change the filter schema to reject the empty list (and drop the Errors clause): `extensions: z.array(z.string().min(1)).min(1).optional().describe(...)`. If the empty list is intentionally kept as a valid input, say so in the schema `.describe()` too, since that is where a caller reads the parameter's plain meaning.

umm-actually · deepseek/deepseek-v4.1-flash

Comment thread src/vault-mcp/mcp-core/tools/memory-tools.ts
…fore limit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/tools/vault-crud-tools.ts
…un in the body

vault_delete_span's bullet said only runs left by the deletion collapse, but
deleteSpan collapses every run in the note's body, as vault_replace_span's
bullet already says. Pin both tools' claims: runs elsewhere in the body
collapse on delete and replace, and a run inside replacement content
collapses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/vault-mcp/mcp-core/tools/vault-crud-tools.ts Outdated
…adings

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant