---
summary: "enrichmentTrailer per-field rendering, ctx.enrich.delta, three new enrichment lint rules, skill-sync prune for upstream-deleted skills, AGENTS.md shipped in npm package, safe format script"
breaking: false
security: false
agent-notes: |
  Skills synced in this release (version bumps — propagate to project skills/ and mirrors):
  - add-app-tool: 1.3 → 1.4
  - add-export: 1.0 → 1.1
  - add-service: 1.5 → 1.6
  - add-tool: 2.10 → 2.11 (enrichment trailer guidance + ctx.enrich.delta mutator pattern)
  - api-context: 1.4 → 1.5 (ctx.enrich.delta added; trailer rendering note)
  - api-linter: 1.4 → 1.5 (enrichment-trailer-render, enrichment-trailer-orphan, enrichment-trailer-unknown-field rule entries)
  - design-mcp-server: 2.13 → 2.14 (enrichmentTrailer per-tool note)
  - git-wrapup: 1.1 → 1.2 (commit-structure rewrite: group by concern, release commit on top)
  - maintenance: 2.4 → 2.5 (prune framework skills deleted upstream)
  - orchestrations/workflows/maintenance-release.md updated (commit structure aligned with git-wrapup)
  - polish-docs-meta: 2.4 → 2.5
  - setup: 1.7 → 1.8 (keep-both guidance replaces delete-one)

  The format script is now safe-by-default (biome --write, no --unsafe). Scaffolded servers should update their format script too (templates/package.json already updated — adoption on next maintenance pass).
---

# 0.9.15 — 2026-05-29

## Added

- **`enrichmentTrailer`** per-field `content[]` rendering config on `ToolDefinition`. Each declared enrichment field can supply a `render` (maps the validated value to markdown — stops structured fields from JSON-blobbing in the trailer) and/or a `label` (overrides the field-name shown in generic/delta rendering). `structuredContent` always keeps the full structured value, unaffected by trailer config. Resolves to `never` when no `enrichment` block is declared. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175))
- **`ctx.enrich.delta({ field, before, after })`** kind-tag helper for raw mutation before/after state. Writes `{ before, after }` to `structuredContent` and renders `**field:** before → after` in the `content[]` trailer. Declare the field in `enrichment` as `z.object({ before, after })` — the linter recognizes the delta shape and exempts it from the `enrichment-trailer-render` requirement. ([#176](https://github.com/cyanheads/mcp-ts-core/issues/176))
- **`enrichment-trailer-render`** lint rule (error): fires when a non-scalar (object/array) enrichment field has no `enrichmentTrailer.render`. The delta shape (`z.object({ before, after })`) is exempt. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175))
- **`enrichment-trailer-orphan`** lint rule (error): fires when `enrichmentTrailer` is declared without an `enrichment` block. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175))
- **`enrichment-trailer-unknown-field`** lint rule (error): fires when an `enrichmentTrailer` key doesn't match any declared enrichment field. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175))
- **`format:unsafe` script** added to root and `templates/package.json` — `biome check --write --unsafe .`. Unsafe autofixes now require a deliberate, reviewed step rather than running with the default `format`. ([#166](https://github.com/cyanheads/mcp-ts-core/issues/166))
- **`scripts/check-skills-sync.ts`** stale-framework-skill detection: a skill dir present only in a mirror that carries `metadata.audience: external` is flagged as stale (a framework skill removed upstream but never pruned from the mirror). User-authored skills (no marker) are left alone. ([#170](https://github.com/cyanheads/mcp-ts-core/issues/170))
- **`templates/_.mcpbignore`** now anchors `/skills/` and `/.agents/` — dev skills no longer surface in MCPB bundles published to the Claude Directory. ([#172](https://github.com/cyanheads/mcp-ts-core/issues/172))

## Changed

- **`format` script** changed from `biome check --write --unsafe .` to `biome check --write .` in root and `templates/package.json` — safe autofixes only by default, preventing silent behavior changes from unsafe rules like `noUselessConstructor`. ([#166](https://github.com/cyanheads/mcp-ts-core/issues/166))
- **`package.json` `files[]`** now ships `AGENTS.md` alongside `CLAUDE.md` — previously only `CLAUDE.md` was included in the published package. Every agent reading `node_modules/@cyanheads/mcp-ts-core/AGENTS.md` now resolves correctly. ([#171](https://github.com/cyanheads/mcp-ts-core/issues/171))
- **`skills/maintenance`** v2.5: Phase A skill-sync step now prunes framework skills deleted upstream — a skill carrying `metadata.audience: external` absent from the package is deleted from `skills/` and agent mirrors. User skills (no marker) are never touched. Phase B mirror sync updated accordingly. ([#170](https://github.com/cyanheads/mcp-ts-core/issues/170))
- **`skills/setup`** v1.8: keep-both guidance replaces delete-one. Both `CLAUDE.md` and `AGENTS.md` are now recommended to be kept; the delete-one instruction removed. ([#171](https://github.com/cyanheads/mcp-ts-core/issues/171))
- **`skills/git-wrapup`** v1.2: Step 7 rewritten — commit-structure model changed from "one atomic commit" to "group by concern, release artifacts on top." Work commits are per-concern, release commit (version bumps + changelog + tree) lands last. File is the atomic boundary. ([approved pre-existing edit])
- **`skills/orchestrations/workflows/maintenance-release.md`**: commit-structure section updated to align with `git-wrapup` v1.2. ([approved pre-existing edit])
- **`skills/add-tool`** v2.11, **`skills/api-context`** v1.5, **`skills/api-linter`** v1.5, **`skills/design-mcp-server`** v2.14: enrichment trailer rendering guidance added; `enrichment-trailer-*` rules documented. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175), [#176](https://github.com/cyanheads/mcp-ts-core/issues/176))
- **`skills/add-app-tool`** v1.4, **`skills/add-export`** v1.1, **`skills/add-service`** v1.6, **`skills/polish-docs-meta`** v2.5: `CLAUDE.md` references paired with `AGENTS.md` throughout. ([#171](https://github.com/cyanheads/mcp-ts-core/issues/171))
- **`changelog/template.md`** and **`templates/changelog/template.md`**: `AGENTS.md` reference paired with `CLAUDE.md`. ([#171](https://github.com/cyanheads/mcp-ts-core/issues/171))
- **`README.md`**: scaffold description updated to name both `CLAUDE.md`/`AGENTS.md`. ([#171](https://github.com/cyanheads/mcp-ts-core/issues/171))
- **`@cloudflare/workers-types`** `^4.20260529.1 → ^4.20260530.1`

## Fixed

- **`renderEnrichmentTrailer`** now skips keys stripped by the effective-output parse (enriched but not declared in the block), preventing ghost trailer lines. ([#175](https://github.com/cyanheads/mcp-ts-core/issues/175))
