0.4.1 (2026-10-02)
Features
- add aggregating proxy package (#243) (6a3f69c)
- add per-component middleware (#242) (5b36942)
- cache Snodo.Client responses from server hints (#240) (15ebbf6)
- experiment with generated GenServer tools (#241) (2ece745)
- expose requested URI to resource-template policies (#225) (fd71e57)
- expose W3C trace context to handlers and instrumentation (#233) (9d52692)
- optionally conceal authorization refusals (#231) (2991c45)
- render MCP catalogs as Markdown (#235) (326f6e0)
- send extension routing headers from the HTTP client (#214) (50be287)
- support OAuth on the native HTTP listener (#222) (90fc323)
Bug Fixes
- bound method in dispatch instrumentation (#226) (67c5876)
- close Plug streams when their executor exits (#228) (3377fc3)
- close subscription sources across handoff races (#232) (bc4b943)
- count only HTTP headers against the header limit (#212) (306d719)
- reject duplicate keys in JSON objects (#224) (0c0d1b8)
- release request-only data from open subscriptions (#230) (2e9a08e)
- warn on public native HTTP binds (#223) (7035549)
Performance Improvements
- reuse compiled validation schemas (#238) (70e5e4f)
- reuse HTTP connections in Snodo.Client (#239) (11b0b9f)
0.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
Bug Fixes
- client follow-ups from the #184 and #187 reviews (#202) (5e007b2)
- grant the SQLite write slot to store writers in arrival order (#199) (7d7ed35)
0.3.2 (2026-09-30)
Features
- add snodo_oauth resource server package (#181) (5d44db2)
- answer input requests automatically in Snodo.Client (#179) (6d758d1)
- drain the native HTTP listener on shutdown (#190) (e25800c)
- ExUnit assertions for testing servers (#191) (6452f1e)
- forward instrumentation events to :telemetry (#182) (0e783ad)
- key identifiers for sealed MRTR request state (#192) (ecd5e14)
- nested arguments and output schemas in the tool DSL (#193) (24f890a)
- OAuth client support for Snodo.Client (#186) (af79ddb)
- open subscriptions/listen streams in Snodo.Client (#184) (fa10710)
- sampling and roots as MRTR input requests (#180) (1cf6cf1)
- sampling and roots handler kinds in Snodo.Client (#185) (451165a)
- Snodo.Client speaks the initialize-era protocol versions (#187) (ebc3504)
0.3.1 (2026-09-29)
Features
- add reusable Tasks store contract tests (#172) (6b03f90)
- add title, icons, and metadata to tool definitions (#169) (6e04d22)
- attest release tarballs (#175) (550acf1)
- deliver progress notifications in Snodo.Client (#177) (361595b)
Bug Fixes
Performance Improvements
0.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) (27aaeeb)
- authorize and validate task work before storing it (#115) (aad5c04)
- bound HTTP connections and subscription streams (#114) (13b9352)
- bound integer literals in Snodo.Client HTTP responses (#130) (dd0cb23)
- bound integer literals, request ids, and progress tokens (#118) (a71e499)
- bound memory for an unterminated stdio line (#125) (e22a878)
- bound Snodo.Client response sizes and page counts (#119) (6e1f785), closes #88
- bound Tasks workers, task counts, lifetimes, and inputs (#123) (098b478)
- bound the whole request body in snodo_plug (#138) (10789ba)
- count only digits in the JSON integer literal limit (#134) (b2f049d)
- make subscription filter checks linear and cap resource URIs (#113) (f125936)
- require an explicit scope in every Tasks store (#121) (bbc258f)
- stop orphaned subscription workers and bound request bodies (#135) (0f1c8bf), closes #127
0.2.1 (2026-09-27)
Features
0.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
Bug Fixes
- accept a bare authorization module in Router.dispatch/5 (closes #56) (#65) (456c816)
- build the compliance report from the retained conformance run (closes #62) (#73) (04e4685)
- deprecate Cancellation.cancel/2, whose reason is discarded (closes #57) (#70) (3d9e1cd)
- explain a disabled protocol in Snodo.Test.dispatch/2 (closes #60) (#66) (3361a3d)
- validate the Snodo.Tool description at compile time (closes #61) (#67) (45b0531)
Code Refactoring
0.1.0 (2026-09-26)
⚠ BREAKING CHANGES
- rename mcp_ex to snodo (#11)
Features
- add application authorization across discovery and dispatch (#6) (6e35765)
- add inline components and Simple resources and prompts (#10) (927d73d)
- add MCP.Client for in-process dispatch (#8) (466fb8c)
- add ordinary MRTR and elicitation workflows (4914e1b)
- add stdio and HTTP transports to MCP.Client (#9) (8d1d81e)
- application stack, progress notifications, and conformance regression gate (#1) (d3b3041)
- close the four target-application findings (69f44a7)
- mirror and validate Mcp-Param headers for x-mcp-header arguments (closes #25) (#40) (ffa35c3)
- send clientInfo in request _meta from Snodo.Client (closes #37) (#47) (3afe710)
- support initialize-era HTTP clients alongside 2026 (closes #3) (#4) (bb43399)
Bug Fixes
- add Host validation and tighten Origin checks on HTTP transports (closes #23) (#33) (638c26e)
- bound stdio frame size and strip a leading BOM (closes #21) (#32) (37ae8a5)
- do not answer JSON-RPC responses or malformed notifications (closes #18) (#28) (3f92dd1)
- harden URI template matching boundaries (8d802fa)
- keep initialize-era tools/list available when a tool has a non-object schema (closes #24) (#39) (d093711)
- keep non-ASCII text intact over stdio (#26) (6f46a63)
- restore green CI on main (#7) (892788e)
- restore the executor's :mcp_execution message tag (#31) (aa96bed)
- return tool input validation failures as isError results (closes #13) (#30) (c48d6ea)
- treat client disconnect as cancellation in the Plug adapter (closes #19) (#34) (740c1cb)
- use HTTP 200 for JSON-RPC errors on initialize-era dialects (closes #14) (#29) (dbb3b5f)
- widen the sibling packages' dependency requirements (#50) (0413261)