# Changelog

## [0.4.3](https://github.com/joshrotenberg/snodo/compare/v0.4.2...v0.4.3) (2026-10-26)


### Features

* advertise subscription capabilities per protocol dialect on mixed-era runtimes ([#388](https://github.com/joshrotenberg/snodo/issues/388)) ([ec455cf](https://github.com/joshrotenberg/snodo/commit/ec455cfb42e198d3c162517567c1ff919c64765b))
* **client:** renegotiate the protocol version once on -32022 ([#381](https://github.com/joshrotenberg/snodo/issues/381)) ([b624a4e](https://github.com/joshrotenberg/snodo/commit/b624a4e2fb15da6b53cdee8961fd7303794b35e5))
* declare metadata-only extensions and read a client's extension settings (closes [#289](https://github.com/joshrotenberg/snodo/issues/289)) ([#334](https://github.com/joshrotenberg/snodo/issues/334)) ([bf74c36](https://github.com/joshrotenberg/snodo/commit/bf74c367dc0cfc96ca04ec9a53f10f2bf1ff9801))
* forward backend log messages through snodo_proxy ([#338](https://github.com/joshrotenberg/snodo/issues/338)) ([80b2707](https://github.com/joshrotenberg/snodo/commit/80b270768ae920521a65867b36a5eecfa993b5a0))
* include the component name in dispatch instrumentation ([#374](https://github.com/joshrotenberg/snodo/issues/374)) ([b384338](https://github.com/joshrotenberg/snodo/commit/b38433810d838700630cf88ffc8e260ea0b22604))
* **oauth:** emit instrumentation events for bearer verification outcomes ([#377](https://github.com/joshrotenberg/snodo/issues/377)) ([5858055](https://github.com/joshrotenberg/snodo/commit/5858055dd8f449272d4a496b7c2bea078f6cce01))
* **otp:** add snodo_otp, GenServer calls and casts over MCP (refs [#371](https://github.com/joshrotenberg/snodo/issues/371)) ([#372](https://github.com/joshrotenberg/snodo/issues/372)) ([5979756](https://github.com/joshrotenberg/snodo/commit/59797563da8c09a8671a9937ee19b53a64025f3b))
* pass the request context to Snodo.Tool.GenServer's message builder ([#365](https://github.com/joshrotenberg/snodo/issues/365)) ([6a110c6](https://github.com/joshrotenberg/snodo/commit/6a110c6be3188c2d1d4a20371631593835691584))
* server logging through notifications/message (closes [#311](https://github.com/joshrotenberg/snodo/issues/311)) ([5e93394](https://github.com/joshrotenberg/snodo/commit/5e933945ceadeb6c63dd4c69f9169302e1f7169b))
* **stdio:** public API for application-owned server notifications ([#390](https://github.com/joshrotenberg/snodo/issues/390)) ([9c784fe](https://github.com/joshrotenberg/snodo/commit/9c784fe82982d018b5a1231d272b7fa3bf258d3d))
* **transport:** keep connections alive on the native HTTP listener ([#389](https://github.com/joshrotenberg/snodo/issues/389)) ([74e0119](https://github.com/joshrotenberg/snodo/commit/74e01197a416945fd8505d94fbf84c4ad6d8e013))


### Bug Fixes

* align Snodo.Schema.Validator.Basic with JSON Schema for integers, patterns, and lengths (closes [#280](https://github.com/joshrotenberg/snodo/issues/280)) ([#368](https://github.com/joshrotenberg/snodo/issues/368)) ([2f388a4](https://github.com/joshrotenberg/snodo/commit/2f388a41f0ea5cfb7de1fb3b4cb197ff8026498f))
* **client:** send notifications/cancelled when an initialize-era HTTP request times out (closes [#281](https://github.com/joshrotenberg/snodo/issues/281)) ([#346](https://github.com/joshrotenberg/snodo/issues/346)) ([0f758ad](https://github.com/joshrotenberg/snodo/commit/0f758adc3cb8db257014feacd0570127608acf93))
* export GenServer tool macros in formatter config ([#356](https://github.com/joshrotenberg/snodo/issues/356)) ([28625bb](https://github.com/joshrotenberg/snodo/commit/28625bb152ed707d4260c3f93dafabf81091f80b))
* list unsupported profile rules in the contract report ([#350](https://github.com/joshrotenberg/snodo/issues/350)) ([879a4b6](https://github.com/joshrotenberg/snodo/commit/879a4b6709b924a55a2dd932f073810213b02f6c))
* load the protocol module before checking its subscription shaping callbacks ([#369](https://github.com/joshrotenberg/snodo/issues/369)) ([62ec70b](https://github.com/joshrotenberg/snodo/commit/62ec70b820450c96f3a97012095c2212c77705b2))
* name enabled versions when initialize reaches a 2026-only server ([#373](https://github.com/joshrotenberg/snodo/issues/373)) ([2edd463](https://github.com/joshrotenberg/snodo/commit/2edd4637abbae1a1517ac086bdd1dae414e51bf0))
* **oauth:** keep the loopback listener running after a callback with the wrong state ([#366](https://github.com/joshrotenberg/snodo/issues/366)) ([e418672](https://github.com/joshrotenberg/snodo/commit/e41867229b7508635e158025990e06961f9730e1))
* **plug:** document and test that Bandit 1.14 bounds HTTP/2 body reads ([#380](https://github.com/joshrotenberg/snodo/issues/380)) ([cdb541b](https://github.com/joshrotenberg/snodo/commit/cdb541be6d8cffbf2c201f6c3017e69185864dcf))
* **plug:** end subscription streams promptly on server shutdown ([#375](https://github.com/joshrotenberg/snodo/issues/375)) ([c792040](https://github.com/joshrotenberg/snodo/commit/c792040a0ca9206ef4e6109124ef231ebef1ea6c))
* **plug:** explain the error when a body parser consumed the request body ([#378](https://github.com/joshrotenberg/snodo/issues/378)) ([b7af8a8](https://github.com/joshrotenberg/snodo/commit/b7af8a8de9f650a9863c1679448074abcce7c4ee))
* **proxy:** check Mcp-Param-* headers against the merged catalog's tool schemas (closes [#333](https://github.com/joshrotenberg/snodo/issues/333)) ([#347](https://github.com/joshrotenberg/snodo/issues/347)) ([823d642](https://github.com/joshrotenberg/snodo/commit/823d642496546ba54f3729c95ca6509bc9d44c5f))
* state that genserver_call and genserver_cast take literal options ([#387](https://github.com/joshrotenberg/snodo/issues/387)) ([34d7a51](https://github.com/joshrotenberg/snodo/commit/34d7a51190b8354aef3be1656d8a17f1eb646ac5))
* **tasks:** cancel the max_runtime timer when a job finishes ([#367](https://github.com/joshrotenberg/snodo/issues/367)) ([5191c8f](https://github.com/joshrotenberg/snodo/commit/5191c8f5d94fe74451382975436cd550666215b5))
* treat a 10-byte =?base64?= header value as malformed (closes [#278](https://github.com/joshrotenberg/snodo/issues/278)) ([#343](https://github.com/joshrotenberg/snodo/issues/343)) ([2f46075](https://github.com/joshrotenberg/snodo/commit/2f46075e60c1d19b49d174e573c4f554f03a408f))
* version header errors and initialize negotiation (closes [#277](https://github.com/joshrotenberg/snodo/issues/277)) ([#345](https://github.com/joshrotenberg/snodo/issues/345)) ([9e4cbe1](https://github.com/joshrotenberg/snodo/commit/9e4cbe19b0e7694b4399bfbd108e940837e939e0))

## [0.4.2](https://github.com/joshrotenberg/snodo/compare/v0.4.1...v0.4.2) (2026-10-22)


### Bug Fixes

* **client:** cancel a stdio request when its caller exits (closes [#273](https://github.com/joshrotenberg/snodo/issues/273)) ([#322](https://github.com/joshrotenberg/snodo/issues/322)) ([8a95efe](https://github.com/joshrotenberg/snodo/commit/8a95efea3d3b2ffd2ab5b76aaabce1d444363239))
* **conformance:** keep the patched transitive versions in the runner lockfile ([2a03dd2](https://github.com/joshrotenberg/snodo/commit/2a03dd2564b8b6476034a423de732328f86a454c))
* do not cache complete results reached through input round trips (closes [#284](https://github.com/joshrotenberg/snodo/issues/284)) ([#326](https://github.com/joshrotenberg/snodo/issues/326)) ([1e17626](https://github.com/joshrotenberg/snodo/commit/1e176262fffd003fc64d62934acdf0d2286a457a))
* keep progress reporting working inside the Timeout component wrapper (closes [#272](https://github.com/joshrotenberg/snodo/issues/272)) ([#325](https://github.com/joshrotenberg/snodo/issues/325)) ([b3b6613](https://github.com/joshrotenberg/snodo/commit/b3b66138a6abf155a73788c7f299b015ad2b7cdb))
* keep the native HTTP listener accepting after emfile (closes [#268](https://github.com/joshrotenberg/snodo/issues/268)) ([#316](https://github.com/joshrotenberg/snodo/issues/316)) ([b8f2b6d](https://github.com/joshrotenberg/snodo/commit/b8f2b6d71b513bc504d938dcecdb9c694a432cef))
* keep x-mcp-header mirror checks from revealing concealed tools (closes [#276](https://github.com/joshrotenberg/snodo/issues/276)) ([#318](https://github.com/joshrotenberg/snodo/issues/318)) ([493cc51](https://github.com/joshrotenberg/snodo/commit/493cc512079101e412f0a0145949e89caa9fb19c))
* **oauth:** keep the refresh token when the token endpoint fails transiently (closes [#270](https://github.com/joshrotenberg/snodo/issues/270)) ([#320](https://github.com/joshrotenberg/snodo/issues/320)) ([38ef518](https://github.com/joshrotenberg/snodo/commit/38ef518478513a4f8cfd96848337fb8260b5029a))
* **oauth:** remember the protected resource metadata URL from WWW-Authenticate (closes [#271](https://github.com/joshrotenberg/snodo/issues/271)) ([#321](https://github.com/joshrotenberg/snodo/issues/321)) ([a80590c](https://github.com/joshrotenberg/snodo/commit/a80590cba54eaf40e06516c9d9b3351655b47ed6))
* **plug:** keep the Plug instance stable across init/1 and document Phoenix forward (closes [#283](https://github.com/joshrotenberg/snodo/issues/283)) ([#313](https://github.com/joshrotenberg/snodo/issues/313)) ([1bb360e](https://github.com/joshrotenberg/snodo/commit/1bb360e0f1993c8b96395d7ca27d952e00165616))
* **plug:** open a listen stream on a response the disconnect probe already started (closes [#269](https://github.com/joshrotenberg/snodo/issues/269)) ([#317](https://github.com/joshrotenberg/snodo/issues/317)) ([b1dcf70](https://github.com/joshrotenberg/snodo/commit/b1dcf705343adc92623fe49f880e570c9cf32f63))
* **protocol:** retain experimental capabilities in legacy initialize ([#252](https://github.com/joshrotenberg/snodo/issues/252)) ([7d6f28a](https://github.com/joshrotenberg/snodo/commit/7d6f28a81f7491dbfcb28728850f825d610f5e6e)), closes [#250](https://github.com/joshrotenberg/snodo/issues/250)
* **proxy:** accept backends that list resources with the same name (closes [#275](https://github.com/joshrotenberg/snodo/issues/275)) ([#323](https://github.com/joshrotenberg/snodo/issues/323)) ([c54b2a4](https://github.com/joshrotenberg/snodo/commit/c54b2a4a1e6907f62b9d01fc9bc3e1a2eb831ff9))
* **proxy:** forward caller capabilities and complete 2026-07-28 result fields (closes [#266](https://github.com/joshrotenberg/snodo/issues/266), closes [#267](https://github.com/joshrotenberg/snodo/issues/267)) ([#312](https://github.com/joshrotenberg/snodo/issues/312)) ([3f4d94c](https://github.com/joshrotenberg/snodo/commit/3f4d94caac16ce91d167f123b52e557484794c5c))
* **proxy:** keep the manager responsive while backends connect or refresh (closes [#274](https://github.com/joshrotenberg/snodo/issues/274)) ([#324](https://github.com/joshrotenberg/snodo/issues/324)) ([b22b196](https://github.com/joshrotenberg/snodo/commit/b22b196bf1eb12dfa90d8512638615c316044155))


### Reverts

* undo the alpha.12 runner pin pushed to main by mistake ([#264](https://github.com/joshrotenberg/snodo/issues/264)) ([0f30b79](https://github.com/joshrotenberg/snodo/commit/0f30b792156f37a0970a683c603cce9c261286dd))

## [0.4.1](https://github.com/joshrotenberg/snodo/compare/v0.4.0...v0.4.1) (2026-10-02)


### Features

* add aggregating proxy package ([#243](https://github.com/joshrotenberg/snodo/issues/243)) ([6a3f69c](https://github.com/joshrotenberg/snodo/commit/6a3f69c7e301460d62f76d24fa8b2462cc648f04))
* add per-component middleware ([#242](https://github.com/joshrotenberg/snodo/issues/242)) ([5b36942](https://github.com/joshrotenberg/snodo/commit/5b36942acc33413cbb11eebdb0efc80d6c716538))
* cache Snodo.Client responses from server hints ([#240](https://github.com/joshrotenberg/snodo/issues/240)) ([15ebbf6](https://github.com/joshrotenberg/snodo/commit/15ebbf6b715de2293843eba63d656741d8da5b07))
* experiment with generated GenServer tools ([#241](https://github.com/joshrotenberg/snodo/issues/241)) ([2ece745](https://github.com/joshrotenberg/snodo/commit/2ece74576822dd5633217c8fa8c0935e0b482cb1))
* expose requested URI to resource-template policies ([#225](https://github.com/joshrotenberg/snodo/issues/225)) ([fd71e57](https://github.com/joshrotenberg/snodo/commit/fd71e57ea8d76181c95f474bc13e2688d3d0f0c1))
* expose W3C trace context to handlers and instrumentation ([#233](https://github.com/joshrotenberg/snodo/issues/233)) ([9d52692](https://github.com/joshrotenberg/snodo/commit/9d52692381aac1a29e29850ddad9b2739d9726ed))
* optionally conceal authorization refusals ([#231](https://github.com/joshrotenberg/snodo/issues/231)) ([2991c45](https://github.com/joshrotenberg/snodo/commit/2991c456e7ecfcd184632286b6be6b9c73ff7bff))
* render MCP catalogs as Markdown ([#235](https://github.com/joshrotenberg/snodo/issues/235)) ([326f6e0](https://github.com/joshrotenberg/snodo/commit/326f6e06671566018110d4e7ecba529b54b81811))
* send extension routing headers from the HTTP client ([#214](https://github.com/joshrotenberg/snodo/issues/214)) ([50be287](https://github.com/joshrotenberg/snodo/commit/50be287c5f410c396c60177ee7c479a9c262df24))
* support OAuth on the native HTTP listener ([#222](https://github.com/joshrotenberg/snodo/issues/222)) ([90fc323](https://github.com/joshrotenberg/snodo/commit/90fc3233faff4f3cce32f4dbcb617ecd6d23842e))


### Bug Fixes

* bound method in dispatch instrumentation ([#226](https://github.com/joshrotenberg/snodo/issues/226)) ([67c5876](https://github.com/joshrotenberg/snodo/commit/67c58766d3d6905c89d7275784049624c0b77e94))
* close Plug streams when their executor exits ([#228](https://github.com/joshrotenberg/snodo/issues/228)) ([3377fc3](https://github.com/joshrotenberg/snodo/commit/3377fc3ad67f33c4a1980d49d3d95e0720408cdf))
* close subscription sources across handoff races ([#232](https://github.com/joshrotenberg/snodo/issues/232)) ([bc4b943](https://github.com/joshrotenberg/snodo/commit/bc4b943a4e34d5bc534228a0d06ee8481ebc06bd))
* count only HTTP headers against the header limit ([#212](https://github.com/joshrotenberg/snodo/issues/212)) ([306d719](https://github.com/joshrotenberg/snodo/commit/306d7196c1fce3a26a4c034656ed76ec032cf571))
* reject duplicate keys in JSON objects ([#224](https://github.com/joshrotenberg/snodo/issues/224)) ([0c0d1b8](https://github.com/joshrotenberg/snodo/commit/0c0d1b8708dd15b069c4f07b48914575a84a2dc9))
* release request-only data from open subscriptions ([#230](https://github.com/joshrotenberg/snodo/issues/230)) ([2e9a08e](https://github.com/joshrotenberg/snodo/commit/2e9a08eac1ca4bc35e26dd48237fe3b94963d525))
* warn on public native HTTP binds ([#223](https://github.com/joshrotenberg/snodo/issues/223)) ([7035549](https://github.com/joshrotenberg/snodo/commit/70355499015b81fe9b378c3edff33ff705d13cca))


### Performance Improvements

* reuse compiled validation schemas ([#238](https://github.com/joshrotenberg/snodo/issues/238)) ([70e5e4f](https://github.com/joshrotenberg/snodo/commit/70e5e4fbe54b2e176deae49034a7fa0505042eab))
* reuse HTTP connections in Snodo.Client ([#239](https://github.com/joshrotenberg/snodo/issues/239)) ([11b0b9f](https://github.com/joshrotenberg/snodo/commit/11b0b9f028d9b3dbe57f53cebd506a1d1b640edd))

## [0.4.0](https://github.com/joshrotenberg/snodo/compare/v0.3.2...v0.4.0) (2026-10-01)


### ⚠ BREAKING CHANGES

* Snodo.Resource.Template.compile/1 returns {:error, reason} naming the unsupported shape instead of :unsupported, and the struct has new fields. Three kinds of template that compiled and matched URIs before are now refused at compile time: a variable name with a leading dot ({.ext}, {..}), which is RFC 6570 label expansion and before was read as a variable named ".ext"; templates longer than 1,024 bytes; and templates with more than 32 variables. A resource module whose :uri_template is outside the supported shapes and that does not define matches?/1 is now a compile error naming the shape; before, it compiled and matched no URI. A module that defines its own matches?/1 for such a template compiles as before, with or without @impl.

### Features

* RFC 6570 resource templates ([#204](https://github.com/joshrotenberg/snodo/issues/204)) ([5c10d2f](https://github.com/joshrotenberg/snodo/commit/5c10d2f9a4e06590453b60d14aefe985c9e86b8e))
* Tasks client API ([#205](https://github.com/joshrotenberg/snodo/issues/205)) ([7e8fca2](https://github.com/joshrotenberg/snodo/commit/7e8fca22403bd666d477f0683c767ef2fd1f8ed3))


### Bug Fixes

* client follow-ups from the [#184](https://github.com/joshrotenberg/snodo/issues/184) and [#187](https://github.com/joshrotenberg/snodo/issues/187) reviews ([#202](https://github.com/joshrotenberg/snodo/issues/202)) ([5e007b2](https://github.com/joshrotenberg/snodo/commit/5e007b263b3e86b6f1c33ee8da74ed83f440d283))
* grant the SQLite write slot to store writers in arrival order ([#199](https://github.com/joshrotenberg/snodo/issues/199)) ([7d7ed35](https://github.com/joshrotenberg/snodo/commit/7d7ed35a9b1306c9dc85d337a6b02316b628bd70))

## [0.3.2](https://github.com/joshrotenberg/snodo/compare/v0.3.1...v0.3.2) (2026-09-30)


### Features

* add snodo_oauth resource server package ([#181](https://github.com/joshrotenberg/snodo/issues/181)) ([5d44db2](https://github.com/joshrotenberg/snodo/commit/5d44db23519c93e07b539b787c8165652fb56624))
* answer input requests automatically in Snodo.Client ([#179](https://github.com/joshrotenberg/snodo/issues/179)) ([6d758d1](https://github.com/joshrotenberg/snodo/commit/6d758d15226adc551502b9fdcff355be07eba639))
* drain the native HTTP listener on shutdown ([#190](https://github.com/joshrotenberg/snodo/issues/190)) ([e25800c](https://github.com/joshrotenberg/snodo/commit/e25800c592be5106df5cc0811d11e4be6e004505))
* ExUnit assertions for testing servers ([#191](https://github.com/joshrotenberg/snodo/issues/191)) ([6452f1e](https://github.com/joshrotenberg/snodo/commit/6452f1e0b06d39bcc8facd84f148e4b54870f624))
* forward instrumentation events to :telemetry ([#182](https://github.com/joshrotenberg/snodo/issues/182)) ([0e783ad](https://github.com/joshrotenberg/snodo/commit/0e783ad4530fb121daf4d1f11cc5db6bb14b7f60))
* key identifiers for sealed MRTR request state ([#192](https://github.com/joshrotenberg/snodo/issues/192)) ([ecd5e14](https://github.com/joshrotenberg/snodo/commit/ecd5e142da4841ede611a3f726782fabc8ccf28d))
* nested arguments and output schemas in the tool DSL ([#193](https://github.com/joshrotenberg/snodo/issues/193)) ([24f890a](https://github.com/joshrotenberg/snodo/commit/24f890a5efa676bbe0b3c8f13a43bda9bcabcd8b))
* OAuth client support for Snodo.Client ([#186](https://github.com/joshrotenberg/snodo/issues/186)) ([af79ddb](https://github.com/joshrotenberg/snodo/commit/af79ddbd47c2f6c931702afc3ded662f54004104))
* open subscriptions/listen streams in Snodo.Client ([#184](https://github.com/joshrotenberg/snodo/issues/184)) ([fa10710](https://github.com/joshrotenberg/snodo/commit/fa1071038bfbda9defef9ad5f6b55195c89e2762))
* sampling and roots as MRTR input requests ([#180](https://github.com/joshrotenberg/snodo/issues/180)) ([1cf6cf1](https://github.com/joshrotenberg/snodo/commit/1cf6cf14bf0020408d50452f434d253aa7a0c8a3))
* sampling and roots handler kinds in Snodo.Client ([#185](https://github.com/joshrotenberg/snodo/issues/185)) ([451165a](https://github.com/joshrotenberg/snodo/commit/451165ab48c32f0f484e207d8d559a52a57f0a9d))
* Snodo.Client speaks the initialize-era protocol versions ([#187](https://github.com/joshrotenberg/snodo/issues/187)) ([ebc3504](https://github.com/joshrotenberg/snodo/commit/ebc35042213064126ccf6614a4a648e443cf5a25))

## [0.3.1](https://github.com/joshrotenberg/snodo/compare/v0.3.0...v0.3.1) (2026-09-29)


### Features

* add reusable Tasks store contract tests ([#172](https://github.com/joshrotenberg/snodo/issues/172)) ([6b03f90](https://github.com/joshrotenberg/snodo/commit/6b03f904d17cb4e39879b93b82a4a09c67bc379b))
* add title, icons, and metadata to tool definitions ([#169](https://github.com/joshrotenberg/snodo/issues/169)) ([6e04d22](https://github.com/joshrotenberg/snodo/commit/6e04d2205116c019cd94da8454d693763e81df47))
* attest release tarballs ([#175](https://github.com/joshrotenberg/snodo/issues/175)) ([550acf1](https://github.com/joshrotenberg/snodo/commit/550acf1275716df0d1f5e3d38f884ca4e0f03756))
* deliver progress notifications in Snodo.Client ([#177](https://github.com/joshrotenberg/snodo/issues/177)) ([361595b](https://github.com/joshrotenberg/snodo/commit/361595b874c3984b9d4bc4cc23752ea1486b3a9a))


### Bug Fixes

* exclude repository Mix tasks from sibling packages ([#168](https://github.com/joshrotenberg/snodo/issues/168)) ([d785636](https://github.com/joshrotenberg/snodo/commit/d785636a8d34f4fb21566fcdf3ce6ab338ad1e73))


### Performance Improvements

* index Hub resource subscriptions by URI ([#173](https://github.com/joshrotenberg/snodo/issues/173)) ([1238f05](https://github.com/joshrotenberg/snodo/commit/1238f05f1f74b5f1341f0996dfe079eeb4671550))

## [0.3.0](https://github.com/joshrotenberg/snodo/compare/v0.2.1...v0.3.0) (2026-09-27)


### ⚠ BREAKING CHANGES

* snodo_plug answers 411 to a request that declares Transfer-Encoding, without reading its body. Send request bodies with Content-Length, as the native listener already requires.
* a Tasks store started without :scope fails to start. Pass a scope function, or scope: :shared for the previous behavior.

### Bug Fixes

* apply the authorization policy to resource subscriptions and cache hints ([#117](https://github.com/joshrotenberg/snodo/issues/117)) ([27aaeeb](https://github.com/joshrotenberg/snodo/commit/27aaeeb0d84bfcc2ca5cd1e5ce5426198a84102d))
* authorize and validate task work before storing it ([#115](https://github.com/joshrotenberg/snodo/issues/115)) ([aad5c04](https://github.com/joshrotenberg/snodo/commit/aad5c044308a81c154923e8e1269aa90612c9790))
* bound HTTP connections and subscription streams ([#114](https://github.com/joshrotenberg/snodo/issues/114)) ([13b9352](https://github.com/joshrotenberg/snodo/commit/13b9352db01f87b855e8bae1af85d420acb7d4c8))
* bound integer literals in Snodo.Client HTTP responses ([#130](https://github.com/joshrotenberg/snodo/issues/130)) ([dd0cb23](https://github.com/joshrotenberg/snodo/commit/dd0cb234e82ab6ff521e66435a0b2a24d08256d8))
* bound integer literals, request ids, and progress tokens ([#118](https://github.com/joshrotenberg/snodo/issues/118)) ([a71e499](https://github.com/joshrotenberg/snodo/commit/a71e499bac14bf8a1f68a99d2fa9f95ecf7dd094))
* bound memory for an unterminated stdio line ([#125](https://github.com/joshrotenberg/snodo/issues/125)) ([e22a878](https://github.com/joshrotenberg/snodo/commit/e22a878c0a02f85b20b1c99f143581527e241bfa))
* bound Snodo.Client response sizes and page counts ([#119](https://github.com/joshrotenberg/snodo/issues/119)) ([6e1f785](https://github.com/joshrotenberg/snodo/commit/6e1f7857be988950be5b219ecf85ab9df14fe0fd)), closes [#88](https://github.com/joshrotenberg/snodo/issues/88)
* bound Tasks workers, task counts, lifetimes, and inputs ([#123](https://github.com/joshrotenberg/snodo/issues/123)) ([098b478](https://github.com/joshrotenberg/snodo/commit/098b47830e15319e519f5af5e8162cdcb5902f8b))
* bound the whole request body in snodo_plug ([#138](https://github.com/joshrotenberg/snodo/issues/138)) ([10789ba](https://github.com/joshrotenberg/snodo/commit/10789bae21e21e15ce06bd5cc19f9a8b9aa57df1))
* count only digits in the JSON integer literal limit ([#134](https://github.com/joshrotenberg/snodo/issues/134)) ([b2f049d](https://github.com/joshrotenberg/snodo/commit/b2f049db3a394ea37c8c2d4161244963de6b590a))
* make subscription filter checks linear and cap resource URIs ([#113](https://github.com/joshrotenberg/snodo/issues/113)) ([f125936](https://github.com/joshrotenberg/snodo/commit/f125936517f967b3a18a8ff17ff8ee942950f381))
* require an explicit scope in every Tasks store ([#121](https://github.com/joshrotenberg/snodo/issues/121)) ([bbc258f](https://github.com/joshrotenberg/snodo/commit/bbc258fe0d9d26e7720aefdb75ff1756a60034df))
* stop orphaned subscription workers and bound request bodies ([#135](https://github.com/joshrotenberg/snodo/issues/135)) ([0f1c8bf](https://github.com/joshrotenberg/snodo/commit/0f1c8bfbd77f38ae89e88a9e5bd0a3d65c7cf975)), closes [#127](https://github.com/joshrotenberg/snodo/issues/127)

## [0.2.1](https://github.com/joshrotenberg/snodo/compare/v0.2.0...v0.2.1) (2026-09-27)


### Features

* serve initialize-era clients over stdio ([#75](https://github.com/joshrotenberg/snodo/issues/75)) ([2a4d68c](https://github.com/joshrotenberg/snodo/commit/2a4d68c3cdfb35984748b5c73f623a00cdac4a4f))

## [0.2.0](https://github.com/joshrotenberg/snodo/compare/v0.1.0...v0.2.0) (2026-09-26)


### ⚠ BREAKING CHANGES

* tool content results carry kind :content instead of :resource.
* Snodo.Result has no error field, and Result.error/2 no longer takes an :error option.

### Features

* add Result.content/2 and deprecate Result.resource/2 (closes [#59](https://github.com/joshrotenberg/snodo/issues/59)) ([#72](https://github.com/joshrotenberg/snodo/issues/72)) ([68c9340](https://github.com/joshrotenberg/snodo/commit/68c9340e9ca4934283bea72c54fc386bf2ba9116))


### Bug Fixes

* accept a bare authorization module in Router.dispatch/5 (closes [#56](https://github.com/joshrotenberg/snodo/issues/56)) ([#65](https://github.com/joshrotenberg/snodo/issues/65)) ([456c816](https://github.com/joshrotenberg/snodo/commit/456c8160a05391b99eba1284131da2d9f5125d55))
* build the compliance report from the retained conformance run (closes [#62](https://github.com/joshrotenberg/snodo/issues/62)) ([#73](https://github.com/joshrotenberg/snodo/issues/73)) ([04e4685](https://github.com/joshrotenberg/snodo/commit/04e468514f73305b44130928311a6bf75426f0ec))
* deprecate Cancellation.cancel/2, whose reason is discarded (closes [#57](https://github.com/joshrotenberg/snodo/issues/57)) ([#70](https://github.com/joshrotenberg/snodo/issues/70)) ([3d9e1cd](https://github.com/joshrotenberg/snodo/commit/3d9e1cdc3d1a6f246bd2f36f683342fcf2fb7312))
* explain a disabled protocol in Snodo.Test.dispatch/2 (closes [#60](https://github.com/joshrotenberg/snodo/issues/60)) ([#66](https://github.com/joshrotenberg/snodo/issues/66)) ([3361a3d](https://github.com/joshrotenberg/snodo/commit/3361a3d8b962ce1b8ff6a56585c9c133655e9de0))
* validate the Snodo.Tool description at compile time (closes [#61](https://github.com/joshrotenberg/snodo/issues/61)) ([#67](https://github.com/joshrotenberg/snodo/issues/67)) ([45b0531](https://github.com/joshrotenberg/snodo/commit/45b0531a2d12c3b69d8975fd3f0adaaab48fbabb))


### Code Refactoring

* remove the unread error field from Snodo.Result (closes [#58](https://github.com/joshrotenberg/snodo/issues/58)) ([#71](https://github.com/joshrotenberg/snodo/issues/71)) ([30aad07](https://github.com/joshrotenberg/snodo/commit/30aad070566a08a206e6036a840c87b880f48534))

## 0.1.0 (2026-09-26)


### ⚠ BREAKING CHANGES

* rename mcp_ex to snodo ([#11](https://github.com/joshrotenberg/snodo/issues/11))

### Features

* add application authorization across discovery and dispatch ([#6](https://github.com/joshrotenberg/snodo/issues/6)) ([6e35765](https://github.com/joshrotenberg/snodo/commit/6e357655210f7f146c967f702e46be7f724866d5))
* add inline components and Simple resources and prompts ([#10](https://github.com/joshrotenberg/snodo/issues/10)) ([927d73d](https://github.com/joshrotenberg/snodo/commit/927d73d584031ce09e3c925f5b9408fd72681797))
* add MCP.Client for in-process dispatch ([#8](https://github.com/joshrotenberg/snodo/issues/8)) ([466fb8c](https://github.com/joshrotenberg/snodo/commit/466fb8cbd51f5b26b304441175230a72aaf387c8))
* add ordinary MRTR and elicitation workflows ([4914e1b](https://github.com/joshrotenberg/snodo/commit/4914e1b5097728cd4862749626750679d804d95e))
* add stdio and HTTP transports to MCP.Client ([#9](https://github.com/joshrotenberg/snodo/issues/9)) ([8d1d81e](https://github.com/joshrotenberg/snodo/commit/8d1d81e85c5bd3e4e6b1eceeb4d9360d3a4133ec))
* application stack, progress notifications, and conformance regression gate ([#1](https://github.com/joshrotenberg/snodo/issues/1)) ([d3b3041](https://github.com/joshrotenberg/snodo/commit/d3b3041e4164e8a3f4f4ad5e8912ad5f7edd4bf5))
* close the four target-application findings ([69f44a7](https://github.com/joshrotenberg/snodo/commit/69f44a7e0fad0299e852fb411671d5e308815cdb))
* mirror and validate Mcp-Param headers for x-mcp-header arguments (closes [#25](https://github.com/joshrotenberg/snodo/issues/25)) ([#40](https://github.com/joshrotenberg/snodo/issues/40)) ([ffa35c3](https://github.com/joshrotenberg/snodo/commit/ffa35c3b3369b55d4a9c48fb145b0396e40ff260))
* send clientInfo in request _meta from Snodo.Client (closes [#37](https://github.com/joshrotenberg/snodo/issues/37)) ([#47](https://github.com/joshrotenberg/snodo/issues/47)) ([3afe710](https://github.com/joshrotenberg/snodo/commit/3afe7107859e37ad9287de9c842a989987bf37f8))
* support initialize-era HTTP clients alongside 2026 (closes [#3](https://github.com/joshrotenberg/snodo/issues/3)) ([#4](https://github.com/joshrotenberg/snodo/issues/4)) ([bb43399](https://github.com/joshrotenberg/snodo/commit/bb433998ddaccb9ff0159b6ef149a994b6674e1b))


### Bug Fixes

* add Host validation and tighten Origin checks on HTTP transports (closes [#23](https://github.com/joshrotenberg/snodo/issues/23)) ([#33](https://github.com/joshrotenberg/snodo/issues/33)) ([638c26e](https://github.com/joshrotenberg/snodo/commit/638c26ea6cdeec49b05a62844f4f5aa5b629f860))
* bound stdio frame size and strip a leading BOM (closes [#21](https://github.com/joshrotenberg/snodo/issues/21)) ([#32](https://github.com/joshrotenberg/snodo/issues/32)) ([37ae8a5](https://github.com/joshrotenberg/snodo/commit/37ae8a5a65220ab0c85aed0cb9a4b13e7ce7ba44))
* do not answer JSON-RPC responses or malformed notifications (closes [#18](https://github.com/joshrotenberg/snodo/issues/18)) ([#28](https://github.com/joshrotenberg/snodo/issues/28)) ([3f92dd1](https://github.com/joshrotenberg/snodo/commit/3f92dd1d10c2ce2c61c506a5804cc804318f9a1c))
* harden URI template matching boundaries ([8d802fa](https://github.com/joshrotenberg/snodo/commit/8d802fa9044871e86bbada1b91ed79f94c6bab6d))
* keep initialize-era tools/list available when a tool has a non-object schema (closes [#24](https://github.com/joshrotenberg/snodo/issues/24)) ([#39](https://github.com/joshrotenberg/snodo/issues/39)) ([d093711](https://github.com/joshrotenberg/snodo/commit/d093711061d3f430c92ad487ce3d5f22cf241940))
* keep non-ASCII text intact over stdio ([#26](https://github.com/joshrotenberg/snodo/issues/26)) ([6f46a63](https://github.com/joshrotenberg/snodo/commit/6f46a63b655b6ea31b31378c1100d038700bf0a0))
* restore green CI on main ([#7](https://github.com/joshrotenberg/snodo/issues/7)) ([892788e](https://github.com/joshrotenberg/snodo/commit/892788e1b559f60d09e91d318239d460f20e16b5))
* restore the executor's :mcp_execution message tag ([#31](https://github.com/joshrotenberg/snodo/issues/31)) ([aa96bed](https://github.com/joshrotenberg/snodo/commit/aa96bede586a2012f25144829ec05af6e907449c))
* return tool input validation failures as isError results (closes [#13](https://github.com/joshrotenberg/snodo/issues/13)) ([#30](https://github.com/joshrotenberg/snodo/issues/30)) ([c48d6ea](https://github.com/joshrotenberg/snodo/commit/c48d6ea53632059ab4c4e66428e3550aff5eb828))
* treat client disconnect as cancellation in the Plug adapter (closes [#19](https://github.com/joshrotenberg/snodo/issues/19)) ([#34](https://github.com/joshrotenberg/snodo/issues/34)) ([740c1cb](https://github.com/joshrotenberg/snodo/commit/740c1cb2cb47c1b5efd340832ace1dfa0e1b00cc))
* use HTTP 200 for JSON-RPC errors on initialize-era dialects (closes [#14](https://github.com/joshrotenberg/snodo/issues/14)) ([#29](https://github.com/joshrotenberg/snodo/issues/29)) ([dbb3b5f](https://github.com/joshrotenberg/snodo/commit/dbb3b5f71218f2360765178d19815c11583d2b70))
* widen the sibling packages' dependency requirements ([#50](https://github.com/joshrotenberg/snodo/issues/50)) ([0413261](https://github.com/joshrotenberg/snodo/commit/04132617d849cd17a782a31e9843c4ecbd323782))


### Code Refactoring

* rename mcp_ex to snodo ([#11](https://github.com/joshrotenberg/snodo/issues/11)) ([84bf194](https://github.com/joshrotenberg/snodo/commit/84bf19430a89c1345f3daab41c2bd8ffc82e86fa))
