Wymcp. Plugs. Dispatch
(Wymcp v0.1.1)
View Source
The method surface of both eras: routes a validated message to the module
that answers it. The last plug in Wymcp.Plugs.Pipeline.
Three branches, in clause order. A JSON-RPC response — a client's answer to a server-initiated request — is delivered to the session that minted its id. A modern-classified message takes the modern lane. Everything else takes the legacy lane.
The modern lane
server/discover, tools/list and tools/call — the whole modern method
surface. An unknown modern method answers HTTP 404 plus -32601: the
spec's MUST, and deliberately distinguishable from a legacy HTTP+SSE
server's 404. Wymcp.Response.send_json/2 preserves a previously-set status,
which is why one method module serves both eras' unknown-method bodies while
only this lane sets 404.
A modern notification never reaches a method: the modern core defines no
client→server notification over HTTP, and JSON-RPC forbids an error response
to a notification — so it is answered 202 and dropped, whatever its body.
That is also why Wymcp.Plugs.Validate lets it through unvalidated.
The legacy lane
initialize, notifications/initialized, ping, tools/list,
tools/call, logging/setLevel and notifications/cancelled. Anything else
falls through to the same unknown-method module with no status override, so
it answers -32601 in a 200 envelope.
The tool list this plug passes on is the router's compile-time :tools
option: Wymcp.Router copies its init options into conn.assigns[:wymcp],
and this plug reads them from there. That list is a starting point, not the
effective one — each method module resolves the effective list itself. On
the legacy lane the tools/list and tools/call modules re-read the session's
registered tools, so a runtime Wymcp.Session.register_tool/2 wins there;
the modern lane is stateless, has no session to consult, and serves the
compile-time list as passed.