Skip to main content

stygian_plugin/
config.rs

1//! Runtime configuration for the standalone MCP server.
2
3use clap::{Parser, ValueEnum};
4use std::path::PathBuf;
5
6/// Transport mode for the MCP server.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Default)]
8pub enum TransportMode {
9    /// JSON-RPC 2.0 over stdin/stdout (default; for LLM tool integrations).
10    #[default]
11    Stdio,
12    /// JSON-RPC 2.0 over HTTP (for Chrome extension and browser clients).
13    Http,
14}
15
16/// Command-line configuration for stygian-plugin MCP server.
17#[derive(Debug, Clone, Parser)]
18#[command(name = "stygian-plugin-mcp")]
19#[command(about = "Standalone MCP server for stygian-plugin extraction", long_about = None)]
20pub struct Config {
21    /// Directory where extraction templates are stored (JSON files)
22    #[arg(long, value_name = "PATH", default_value = "./plugin-templates")]
23    pub templates_dir: PathBuf,
24
25    /// Logging level (off, error, warn, info, debug, trace)
26    #[arg(long, value_name = "LEVEL", default_value = "info")]
27    pub log_level: String,
28
29    /// Server name advertised in MCP initialize response
30    #[arg(long, value_name = "NAME", default_value = "stygian-plugin")]
31    pub server_name: String,
32
33    /// Transport mode: stdio (default) or http
34    ///
35    /// Use `http` to expose JSON-RPC 2.0 over HTTP so the Chrome browser
36    /// extension can connect directly via `http://localhost:<port>/mcp/tools/call`.
37    #[arg(long, value_name = "MODE", default_value = "stdio")]
38    pub transport: TransportMode,
39
40    /// Port for the HTTP transport (only used when --transport=http)
41    #[arg(long, value_name = "PORT", default_value = "3000")]
42    pub http_port: u16,
43}
44
45impl Config {
46    /// Parse configuration from command-line arguments and environment variables.
47    pub fn from_args() -> Self {
48        Self::parse()
49    }
50
51    /// Create a test configuration with sensible defaults.
52    pub fn testing() -> Self {
53        Self {
54            templates_dir: PathBuf::from("./test-templates"),
55            log_level: "debug".to_string(),
56            server_name: "stygian-plugin-test".to_string(),
57            transport: TransportMode::Stdio,
58            http_port: 3000,
59        }
60    }
61
62    /// Create a test configuration pointing to an HTTP transport on a given port.
63    pub fn testing_http(port: u16) -> Self {
64        Self {
65            templates_dir: PathBuf::from("./test-templates"),
66            log_level: "debug".to_string(),
67            server_name: "stygian-plugin-test".to_string(),
68            transport: TransportMode::Http,
69            http_port: port,
70        }
71    }
72}
73
74/// Supported MCP protocol versions, in preferred order.
75pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &["2025-11-25", "2025-06-18", "2024-11-05"];
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_config_defaults() {
83        let cfg = Config::testing();
84        assert_eq!(cfg.server_name, "stygian-plugin-test");
85        assert_eq!(cfg.log_level, "debug");
86        assert_eq!(cfg.transport, TransportMode::Stdio);
87        assert_eq!(cfg.http_port, 3000);
88    }
89
90    #[test]
91    fn test_config_http() {
92        let cfg = Config::testing_http(8080);
93        assert_eq!(cfg.transport, TransportMode::Http);
94        assert_eq!(cfg.http_port, 8080);
95    }
96}