Skip to main content

syslog_server_mcp/
config.rs

1use 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}