syslog_server_mcp/
config.rs1use crate::cli::ServeArgs;
2use crate::error::{Error, Result};
3use serde::Deserialize;
4use std::time::Duration;
5use url::Url;
6
7#[derive(Debug, Clone)]
8pub struct Config {
9 pub base_url: Url,
10 pub api_key: String,
11 pub http_addr: Option<String>,
12 pub insecure: bool,
13 pub probe_once: bool,
14 pub mcp_client: Option<String>,
15 pub config_path: Option<std::path::PathBuf>,
16 pub capability_probe_interval: Duration,
17 pub phase_override: Option<crate::probe::ServerPhase>,
18}
19
20impl Config {
21 pub fn from_args(args: &ServeArgs) -> Result<Self> {
22 if args.api_key.is_empty() {
23 return Err(Error::Config("api_key must be non-empty".into()));
24 }
25 Ok(Config {
26 base_url: args.base_url.clone(),
27 api_key: args.api_key.clone(),
28 http_addr: args.http.clone(),
29 insecure: args.insecure,
30 probe_once: args.probe_once,
31 mcp_client: args.mcp_client.clone(),
32 config_path: args.config.clone(),
33 capability_probe_interval: Duration::from_secs(args.capability_probe_interval_secs),
34 phase_override: args.phase_override.as_ref().map(|phase| match phase {
35 crate::cli::PhaseOverride::Phase0 => crate::probe::ServerPhase::Phase0,
36 crate::cli::PhaseOverride::Phase1 => crate::probe::ServerPhase::Phase1,
37 }),
38 })
39 }
40}
41
42#[derive(Deserialize, Default, Debug, Clone)]
43pub struct ProbeConfig {
44 pub capability_interval_secs: Option<u64>,
45 pub phase_override: Option<String>,
46}
47
48#[derive(Deserialize, Default, Debug, Clone)]
49pub struct HttpConfig {
50 pub allowed_hosts: Vec<String>,
51 #[serde(default)]
52 pub backend_api_key: Option<String>,
53 #[serde(default = "default_session_cap")]
54 pub max_concurrent_calls_per_session: u32,
55 #[serde(default = "default_process_cap")]
56 pub max_concurrent_calls_total: u32,
57 #[serde(default)]
58 pub operator_keys: std::collections::HashMap<String, String>,
59 #[serde(default)]
60 pub probe: Option<ProbeConfig>,
61}
62
63fn default_session_cap() -> u32 {
64 8
65}
66fn default_process_cap() -> u32 {
67 64
68}
69
70#[derive(Deserialize, Default, Debug, Clone)]
71pub struct TomlConfig {
72 pub mcp: Option<HttpConfig>,
73}
74
75impl Config {
76 pub fn load_toml(&self) -> Result<Option<HttpConfig>> {
77 let path = match &self.config_path {
78 Some(p) => p,
79 None => return Ok(None),
80 };
81 let bytes = std::fs::read(path)?;
82 let toml: TomlConfig =
83 toml::from_str(std::str::from_utf8(&bytes).map_err(|e| Error::Config(e.to_string()))?)?;
84 Ok(toml.mcp)
85 }
86}