Legion.MCP.Plug (Legion v0.6.0)

View Source

Mounts an MCP server over Streamable HTTP with the server's request timeout.

forward "/mcp", Legion.MCP.Plug, server: MyApp.MCP

A wrapper for Anubis.Server.Transport.StreamableHTTP.Plug, which speaks the transport: the session header, SSE streams, OAuth bearer checks. It takes that plug's options unchanged, :session_header and :subscriber_metadata included. It differs in two ways.

:request_timeout, unless given, is the server's request_timeout/0, read when a request arrives, so it is the same bound stdio gets from the child spec. See "Request timeout" in Legion.MCP.Server.

It checks the Origin header, as the MCP specification asks of servers and Anubis does not. A browser sends it, and a web page the developer has open could otherwise reach a server on localhost through DNS rebinding and call repl with the application's tools. A request with no Origin, as CLI and desktop hosts send them, is served, and so is one from localhost, 127.0.0.1 or [::1] on any port, such as the MCP Inspector. Any other origin is answered with 403 unless it is listed:

forward "/mcp", Legion.MCP.Plug,
  server: MyApp.MCP,
  allowed_origins: ["https://app.example.com"]

Entries are whole origins, scheme and port included. The request's own Host is not trusted for this: under DNS rebinding it is the attacker's name too. allowed_origins: :any turns the check off.