---
summary: "mcpTest fixture-based Vitest subpath; platform-native utils sweep under Node≥24/Bun≥1.3 (AbortSignal.any, Uint8Array base64, Symbol.dispose, performance.now); workerd R2/D1 storage suites; typecheck project with @ts-expect-error negative cases; R2 list cap fix"
breaking: false
security: false
agent-notes: |
  MirrorStore now extends AsyncDisposable — custom backend implementations must add [Symbol.asyncDispose]. SpeechToTextOptions.audio and TextToSpeechResult.audio changed from Buffer to Uint8Array. initHighResTimer and loadPerfHooks are now no-ops (kept as deprecated exports to avoid breaking callers). New ./testing/vitest subpath requires vitest >=4.0.0 as an optional peer when used.
---

# 0.10.5 — 2026-06-11

## Added

- **`./testing/vitest` subpath** — exports `mcpTest` (`test.extend`-based Vitest fixture) and `McpTestFixtures`, providing per-test `ctx` (fresh `createMockContext()`) and `storage` (fresh `createInMemoryStorage()`) without manual setup. Re-exports `createMockContext` and `createInMemoryStorage` for fixture-override patterns. ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))
- **`vitest >=4.0.0`** added as an optional peer dependency. ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))
- **`test:typecheck` script** — runs the new `typecheck` Vitest project over `tests/types/**/*.test-d.ts` via `tsc` checker with `ignoreSourceErrors`. ([#229](https://github.com/cyanheads/mcp-ts-core/issues/229))
- **`tests/types/` typecheck suite** — three `.test-d.ts` files covering `ReasonOf`, `TypedFail`, `TypedRecoveryFor`, `createFail`, `createRecoveryFor`, `HandlerContext`, and tool-builder output inference with `@ts-expect-error` negative cases. ([#229](https://github.com/cyanheads/mcp-ts-core/issues/229))
- **`RateLimiter[Symbol.dispose]`** — enables `using limiter = new RateLimiter(...)` (ES2022 explicit resource management). ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`sqliteMirrorStore[Symbol.asyncDispose]`** — enables `await using store = sqliteMirrorStore(spec)`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`CanvasRegistry[Symbol.asyncDispose]`** — enables `await using registry = new CanvasRegistry(...)`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **Workerd R2 storage suite** (`tests/worker/storage-r2.worker.test.ts`) — set/get/delete/list/TTL exercised through the worker handler via miniflare `r2Buckets` binding. ([#228](https://github.com/cyanheads/mcp-ts-core/issues/228))
- **Workerd D1 storage suite** (`tests/worker/storage-d1.worker.test.ts`) — set/get/delete/list/TTL exercised through the worker handler via miniflare `d1Databases` binding. ([#228](https://github.com/cyanheads/mcp-ts-core/issues/228))
- **Encoding worker tests** (`tests/worker/encoding.worker.test.ts`) — `arrayBufferToBase64` / `base64ToString` verified in the workerd runtime. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`skills/api-workers` `v1.5`** — documents the `r2Buckets` / `d1Databases` miniflare binding pattern for workerd storage tests. ([#228](https://github.com/cyanheads/mcp-ts-core/issues/228))
- **`skills/api-testing` `v1.5`** — documents `mcpTest`, `McpTestFixtures`, and the `./testing/vitest` subpath. ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))

## Changed

- **`fetchWithTimeout`** — `externalSignal` forwarding replaced with `AbortSignal.any([controller.signal, externalSignal])`; available on Node ≥24, Bun ≥1.3, and workerd. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`retry` sleep** — cancellation signal now forwarded to the retry-sleep timer via `AbortSignal.any`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`performance.ts`** — `nowMs()` delegates directly to `globalThis.performance.now()`; `initHighResTimer` and `loadPerfHooks` are now no-ops (deprecated, kept to avoid breaking callers). `initHighResTimer()` call removed from `createApp()` and `createWorkerHandler()`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`arrayBufferToBase64` / `base64ToString`** — Worker/browser branch now uses `Uint8Array.prototype.toBase64()` / `Uint8Array.fromBase64()` (V8 25+ / workerd); Buffer fast-path stays primary on Node/Bun. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`MirrorStore`** — interface now extends `AsyncDisposable`; custom backend implementations must add `[Symbol.asyncDispose]`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`TextToSpeechResult.audio`** / **`SpeechToTextOptions.audio`** — type changed from `Buffer | string` to `Uint8Array | string`. ([#216](https://github.com/cyanheads/mcp-ts-core/issues/216))
- **`templates/tests/tools/echo.tool.test.ts`** — updated to use `mcpTest` from `@cyanheads/mcp-ts-core/testing/vitest`. ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))
- **`export-map` allowlist test** — updated to include the `./testing/vitest` subpath. ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))
- **`optional-peer-deps` test** — adds an integration-entrypoint exemption for `./testing/vitest` (its `vitest` peer is expected). ([#227](https://github.com/cyanheads/mcp-ts-core/issues/227))
- **`worker-runtime.fixture`** — adds `storage_set` / `storage_get` / `storage_delete` / `storage_list` probe tools backing the workerd storage suites; the miniflare `r2Buckets` / `d1Databases` bindings live in `vitest.worker.ts`. ([#228](https://github.com/cyanheads/mcp-ts-core/issues/228))

## Fixed

- **R2 `list()` cap** — `limit + 1` page-probe clamped to `R2_MAX_LIST_LIMIT = 1000`; R2 rejects requests above this cap. At the limit, pagination falls back to `listed.truncated` for has-more detection. ([#228](https://github.com/cyanheads/mcp-ts-core/issues/228))
- **`lintCappedListTruncation` allowlist check** — truthiness guard replaced with `Array.isArray()` before calling `.includes()` (lint conformance; behavior unchanged).

## Deprecated

- **`initHighResTimer()`** — no-op; remove calls from consumer startup. Will be removed in a future major release.
- **`loadPerfHooks()`** — no-op; `globalThis.performance` is ambient on all supported engine floors. Will be removed in a future major release.

## Dependency bumps (dev)

- `@cloudflare/vitest-pool-workers` ^0.16.14 → ^0.16.15
- `@cloudflare/workers-types` 4.20260610.1 → 4.20260611.1
- `@opentelemetry/exporter-metrics-otlp-http` ^0.218.0 → ^0.219.0
- `@opentelemetry/exporter-trace-otlp-http` ^0.218.0 → ^0.219.0
- `@opentelemetry/instrumentation-http` ^0.218.0 → ^0.219.0
- `@opentelemetry/instrumentation-pino` ^0.64.0 → ^0.65.0
- `@opentelemetry/resources` ^2.7.1 → ^2.8.0
- `@opentelemetry/sdk-metrics` ^2.7.1 → ^2.8.0
- `@opentelemetry/sdk-node` ^0.218.0 → ^0.219.0
- `@opentelemetry/sdk-trace-node` ^2.7.1 → ^2.8.0
