Packages

Transport-agnostic MCP (Model Context Protocol) server library with a Streamable HTTP Plug integration.

Current section

Files

Jump to
mcp42 CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to mcp42 are documented in this file.
## [Unreleased]
## [0.1.2] - 2026-09-07
### Fixed
- **Sessions were linked to the HTTP request process** (critical): the plug
started each `Mcp42.Session` with `start_link/1` inside the request process.
Under Bandit/Cowboy the request process finishes as soon as the response is
sent, killing the session — every follow-up request (tools/list, tools/call)
then 404s. Sessions are now started detached via `Task.start/1`, and DELETE
kills by session id instead of killing the request's own linked child.
- **`Dispatcher.server_info/1` returned placeholder info for not-yet-loaded
server modules**: `function_exported?/3` answers `false` until BEAM has
loaded the module, so the first `initialize` after boot returned
`"Rproxy.Mcp" / "0.0.0"` instead of the server's real name. The dispatcher
now calls `Code.ensure_loaded/1` first.
- `Mcp42.SessionRegistry` fallback start (`ensure_registry/0`) was linked to
the request process; the registry is now started detached (new
`SessionRegistry.start/1`) so its ETS table survives request processes.
## [0.1.1] - 2026-09-07
### Fixed
- `Mcp42.Plug` — Phoenix compatibility: when the host mounts `Plug.Parsers`
(any Phoenix endpoint), `conn.body_params` is already the decoded map and
the raw body has been consumed, which made every POST fail with a JSON-RPC
parse error. The plug now re-encodes a populated `body_params` map with
`Jason.encode!/1`; `%Plug.Conn.Unfetched{}` (bare Plug) still reads the
raw body.
## [0.1.0] - 2026-09-06
### Added
- `Mcp42.Protocol` — pure JSON-RPC 2.0 codec (encode/decode, standard error
codes, no batching per MCP 2025-06-18).
- `Mcp42.Server` behaviour (`use Mcp42.Server`) — tools/0 + handle_tool/3,
optional server_info/0 override. The ONLY integration surface; app logic
never enters the library.
- `Mcp42.Dispatcher` — pure MCP method dispatch: initialize (protocol
negotiation 2025-06-18 / 2024-11-05 / 2024-10-07), ping, tools/list,
tools/call, notifications. Tool errors are RESULTS (isError: true), host
crashes are contained as JSON-RPC internal errors.
- `Mcp42.Session` — per-connection session process (UUID v4 id, negotiated
protocol version, bounded 100-message inbox with fail-fast backpressure).
- `Mcp42.SessionRegistry` — ETS-backed id->pid registry, public reads,
GenServer-owned writes with automatic :DOWN cleanup.
- `Mcp42.Plug` — Streamable HTTP transport (spec 2025-06-18): POST
(JSON-RPC, lazy session on initialize, Mcp-Session-Id echo), GET (SSE
stream), DELETE (terminate, 204), origin validation (403 cross-origin,
localhost allowed by default), content-type guard (415), parse-error
mapping (400 + JSON-RPC error body).