Skip to main content

atd_server_http/
config.rs

1//! `HttpServerConfig` — HTTP-listener-specific configuration.
2//!
3//! SP-streamable-http §6.2: HTTP-specific fields (listen socket, extra
4//! origins, body cap, bearer policy) live here; the shared dispatch
5//! fields (cwd, audit_sink, token_broker, server_version,
6//! granted_capabilities, max_output_bytes) live on
7//! `atd_runtime::dispatch::SharedServerConfig`. Adopters pass both into
8//! the `Server::builder` chain.
9
10use std::net::{IpAddr, Ipv4Addr, SocketAddr};
11use std::sync::Arc;
12
13use atd_runtime::dispatch::SharedServerConfig;
14
15/// Default body-size cap for `POST /mcp`. Mirrors the
16/// `atd-protocol::wire` 10 MiB frame cap so HTTP and UDS share the same
17/// upper bound — there is no MCP scenario where the JSON-RPC envelope
18/// should exceed an ATD frame.
19pub const DEFAULT_MAX_BODY_BYTES: usize = 10 * 1024 * 1024;
20
21/// Configuration for [`crate::Server`]. All fields are public so adopters
22/// can use struct-literal construction; `Default::default()` returns
23/// loopback `127.0.0.1:0` with anonymous-mode bearer policy (matches the
24/// Celia http_server.rs precedent in `celia-cli/src/http_server.rs:114-130`).
25#[derive(Clone)]
26pub struct HttpServerConfig {
27    /// Address the listener binds to. SP-streamable-http §4.6 mandates
28    /// loopback default — fail-closed against DNS rebinding per MCP
29    /// Security Warning. Use `127.0.0.1:0` in tests to let the kernel
30    /// pick a free port.
31    pub listen: SocketAddr,
32
33    /// Origin patterns added to the default allow-list
34    /// (`http://127.0.0.1*`, `http://localhost*`, `https://127.0.0.1*`,
35    /// `https://localhost*`, `tauri://*`). Matched against the request's
36    /// `Origin` header verbatim — full string equality, not prefix.
37    /// Operators surface this from the `--allow-origin` CLI flag,
38    /// repeatable.
39    pub extra_origins: Vec<String>,
40
41    /// When `true`, requests without `Authorization: Bearer …` are
42    /// rejected with HTTP 401 / JSON-RPC `-32002`. When `false` (default),
43    /// bearer-less requests fall through to anonymous mode with empty
44    /// `CapabilitySet` — matching `celia-cli/src/http_server.rs:295-306`
45    /// Tier-0 trust. Bearer-bearing requests are always validated
46    /// regardless of this flag.
47    pub require_bearer: bool,
48
49    /// Body-size cap for `POST /mcp`. Larger requests rejected with HTTP
50    /// 413. Defaults to [`DEFAULT_MAX_BODY_BYTES`] (10 MiB) to match the
51    /// `atd-protocol::wire::MAX_FRAME_BYTES` cap.
52    pub max_body_bytes: usize,
53
54    /// Shared dispatch-side configuration. Adopters who run UDS + HTTP
55    /// from the same process build one `SharedServerConfig`, wrap it in
56    /// `Arc`, and pass clones to both transports so they share the audit
57    /// sink, token broker, capability allow-list, and server identity by
58    /// reference.
59    pub shared: Arc<SharedServerConfig>,
60}
61
62impl Default for HttpServerConfig {
63    fn default() -> Self {
64        Self {
65            listen: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0),
66            extra_origins: Vec::new(),
67            require_bearer: false,
68            max_body_bytes: DEFAULT_MAX_BODY_BYTES,
69            shared: Arc::new(SharedServerConfig::for_test()),
70        }
71    }
72}