Skip to content

bug(linter): capped-list-no-truncation's max_ shape also matches value-bound filters #345

Description

@cyanheads

mcp-ts-core version

0.11.4

Runtime

Bun

Runtime version

Bun 1.3.14

Transport

N/A — build-time linter

OS

macOS

Description

Related: #278

capped-list-no-truncation treats every depth-0 max_* input as a result cap. It correctly covers maxResults and max_rows, but also classifies value-bound filters such as max_depth_km, maxLat, and max_upload_mbps. A top-level array without truncated or totalCount then produces a truncation warning even though the input does not cap result count.

Reproduction

const definition = {
  name: 'search',
  input: z.object({
    max_depth_km: z.number().describe('Maximum depth filter.'),
  }),
  output: z.object({
    nodes: z.array(z.string()).describe('Matching nodes.'),
  }),
};

Run bun run lint:mcp with the definition registered.

Actual behavior

The linter reports capped-list-no-truncation because max_depth_km matches the generic max_* arm.

Expected behavior

Value-bound filters should not trigger the rule. Count caps, including camelCase and snake_case forms, should still trigger when their normalized noun correlates with a top-level array output. For example, max_articles should match an articles array and max_result_count should match results.

Additional context

Keep the generic limit, *_limit, per_page, and page_size shapes. truncationAllowlist remains the escape hatch.

Acceptance criteria

  • Value-bound inputs such as max_depth_km, maxLat, max_date, and max_upload_mbps do not trigger the rule.
  • Conventional count caps, including camelCase and snake_case forms, still trigger when their normalized noun matches a top-level array and no truncation disclosure exists.
  • max_result_count and equivalent explicit count suffixes match a results array.
  • totalCount and truncated remain recognized in enrichment and top-level output.
  • Regression coverage covers matching and non-matching names.

Scope

  • Correlate the max_* arm with top-level array output names.
  • Keep the existing disclosure and allowlist behavior.

Out of scope

  • Matching bare count, size, n, rows, or records.
  • Changing array-output or disclosure conditions.
  • A general English pluralizer; normalization only needs the bounded count-noun shapes covered by tests.

Touchpoints

  • src/linter/rules/enrichment-rules.ts
  • tests/unit/linter/enrichment-rules.test.ts
  • tests/unit/linter/validate.test.ts
  • skills/api-linter/SKILL.md
  • skills/add-tool/SKILL.md
  • CLAUDE.md and the per-version release changelog entry

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions