1pub mod server;
6pub mod tools;
7pub mod stdio;
8pub mod sse;
9pub mod weather_api;
10
11pub use server::*;
12pub use tools::*;
13pub use weather_api::*;
14
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone)]
19pub struct McpConfig {
20 pub transport: McpTransport,
21 pub enable_telemetry_tool: bool,
22 pub enable_strategy_tool: bool,
23 pub enable_simulation_tool: bool,
24 pub enable_historical_tool: bool,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum McpTransport {
30 Stdio,
31 Sse,
32}
33
34impl Default for McpConfig {
35 fn default() -> Self {
36 McpConfig {
37 transport: McpTransport::Stdio,
38 enable_telemetry_tool: true,
39 enable_strategy_tool: true,
40 enable_simulation_tool: true,
41 enable_historical_tool: true,
42 }
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct McpTool {
49 pub name: String,
50 pub description: String,
51 pub input_schema: serde_json::Value,
52}
53
54pub fn get_mcp_tools() -> Vec<McpTool> {
56 vec![
57 McpTool {
58 name: "optimize_strategy".to_string(),
59 description: "Optimize race strategy given current conditions".to_string(),
60 input_schema: serde_json::json!({
61 "type": "object",
62 "properties": {
63 "current_lap": {"type": "number"},
64 "tire_age": {"type": "number"},
65 "fuel_remaining": {"type": "number"},
66 "position": {"type": "number"}
67 },
68 "required": ["current_lap"]
69 }),
70 },
71 McpTool {
72 name: "predict_tire_life".to_string(),
73 description: "Predict remaining tire life based on current conditions".to_string(),
74 input_schema: serde_json::json!({
75 "type": "object",
76 "properties": {
77 "compound": {"type": "string"},
78 "age_laps": {"type": "number"},
79 "track_temp": {"type": "number"}
80 },
81 "required": ["compound", "age_laps"]
82 }),
83 },
84 McpTool {
85 name: "simulate_race".to_string(),
86 description: "Run Monte Carlo race simulation with given strategy".to_string(),
87 input_schema: serde_json::json!({
88 "type": "object",
89 "properties": {
90 "strategy": {"type": "object"},
91 "num_simulations": {"type": "number"},
92 "track_id": {"type": "string"}
93 },
94 "required": ["strategy"]
95 }),
96 },
97 McpTool {
98 name: "get_weather_forecast".to_string(),
99 description: "Get real-time weather forecast for a race track".to_string(),
100 input_schema: serde_json::json!({
101 "type": "object",
102 "properties": {
103 "circuit": {"type": "string"},
104 "api_key": {"type": "string"}
105 },
106 "required": ["circuit"]
107 }),
108 },
109 McpTool {
110 name: "query_historical".to_string(),
111 description: "Find similar historical races using vector similarity search".to_string(),
112 input_schema: serde_json::json!({
113 "type": "object",
114 "properties": {
115 "track_id": {"type": "string"},
116 "weather": {"type": "string"},
117 "top_k": {"type": "number"}
118 },
119 "required": ["track_id"]
120 }),
121 },
122 McpTool {
123 name: "get_agent_consensus".to_string(),
124 description: "Get multi-agent consensus on a strategy decision".to_string(),
125 input_schema: serde_json::json!({
126 "type": "object",
127 "properties": {
128 "question": {"type": "string"},
129 "timeout_ms": {"type": "number"}
130 },
131 "required": ["question"]
132 }),
133 },
134 ]
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn test_mcp_tools() {
143 let tools = get_mcp_tools();
144 assert!(tools.len() >= 5);
145 assert!(tools.iter().any(|t| t.name == "optimize_strategy"));
146 }
147}