1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//! The MCP Streamable HTTP transport, as mounted at `[mcp] path`.
//!
//! One constructor, so the route and its tests build the same service.
use Arc;
use ;
use FraiseQLMcpService;
/// The tower service mounted at `[mcp] path`.
pub type McpHttpService = ;
/// Build the Streamable HTTP service over `sessions`.
///
/// `factory` builds one [`FraiseQLMcpService`] per MCP session. Authentication happens per
/// tool call inside that service, so everything the transport does before a session's first
/// tool call — including what it allocates for a request that never becomes a session — is
/// reachable without credentials.
///
/// `require_auth` is `[mcp] require_auth`; it decides the `Host` check, see
/// [`transport_config`].
/// The transport's configuration: rmcp's defaults, with the `Host` check set by
/// `require_auth`.
///
/// rmcp accepts only loopback `Host` values by default, against DNS rebinding: a page in
/// the browser of someone running a server locally rebinds its own name to 127.0.0.1 and
/// calls it. That default refused every request to a deployment's own hostname, and every
/// tenant addressed by its domain, with 403. With `require_auth` a tool call needs a bearer
/// token, which the browser never attaches to a rebound host, so the check guards nothing
/// and is off. Without it (development only) the loopback check stays.