---
summary: Linter `describe-on-fields` recurses into nested objects, array elements, and union variants and now covers resource outputs; `maintenance` skill adds Phase C to sync framework scripts from package to consumer
breaking: false
---

# 0.6.16 — 2026-04-23

Deepens the `describe-on-fields` linter from top-level-only to a full recursive walk, extends it to resource outputs, and closes a silent-drift gap between the package's `scripts/` and consumer projects via a new `maintenance` skill phase.

## Changed

- **`src/linter/rules/schema-rules.ts`** — `checkFieldDescriptions` now recurses into nested `z.object` shapes, array element types (skipping primitive elements, where the array-level describe is sufficient), and `z.union` / `z.discriminatedUnion` variants. Diagnostic path syntax: `.key` for object properties, `[]` for array elements, `|<i>` for union variant at index `i`. Each nesting level is evaluated independently — a described container does **not** suppress checks on its children, because MCP clients read the flattened JSON Schema. Optional/nullable/default/readonly/nonoptional wrappers are transparently unwrapped when walking.
- **`src/linter/rules/resource-rules.ts`** — resource `output` schemas now run through `checkFieldDescriptions` in addition to the existing structural + serializability checks. Previously the rule only applied to tool `input` / `output` and resource `params`, so resources could ship JSON fields without descriptions and pass the linter.
- **`skills/maintenance/`** — section 5 expanded from "Sync project skills" to "Sync project skills **and scripts**", with a new **Phase C**: compare `node_modules/@cyanheads/mcp-ts-core/scripts/<fixed-list>` against project `scripts/` by content hash and overwrite on mismatch (`build-changelog`, `build`, `check-docs-sync`, `check-skills-sync`, `clean`, `devcheck`, `lint-mcp`, `tree`). Project-specific scripts outside the list are left untouched. Checklist at section-end now requires running the sync and reviewing `git diff scripts/` before committing.
- **`skills/add-tool/`** + **`skills/design-mcp-server/`** — added **"seed orientation context"** guidance: when a tool's call position makes the agent's next moves predictable (session open/close, state-changing verbs post-confirmation, new-scope entry points), piggyback a compact snapshot of relevant state — recent activity, tracked state, a couple of reference items — alongside the primary result. Cuts a predictable follow-up call *and* primes the LLM on project conventions (recent commits teach commit-message style; recent tags teach versioning format). Gather sub-operations with `Promise.allSettled` so a single sub-failure degrades to a warning on the outer call.
- **`skills/setup/`** + **`skills/polish-docs-meta/`** — added explicit guardrails against editing `skills/*/SKILL.md` or `skills/*/references/*`. These are synced from `@cyanheads/mcp-ts-core` and overwritten on the next `maintenance` refresh — project-specific agent context belongs in `CLAUDE.md` / `AGENTS.md`.
- **`examples/mcp-server/tools/definitions/template-data-explorer.app-tool.ts`** — added `.describe()` to the `SaleRowSchema` container so the bundled example stays lint-clean under the new recursive check; without this, consumers scaffolding from the template would see a spurious `describe-on-fields` warning on startup.
- **`@cloudflare/workers-types`** — `^4.20260423.1` → `^4.20260424.1` (devDependency patch bump).

## Added

- **`tests/unit/linter/validate.test.ts`** — five new cases covering the expanded `describe-on-fields` rule: nested object fields, array element fields, primitive array elements (asserts **no** recursion), `z.discriminatedUnion` variant fields (with path `|<i>` assertion), and resource output schemas.
