Skip to main content

systemprompt_models/mcp/
deployment.rs

1use crate::ai::ToolModelConfig;
2use crate::auth::{JwtAudience, Permission};
3use crate::mcp::capabilities::ToolVisibility;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8pub struct ToolUiConfig {
9    #[serde(default = "default_resource_uri_template")]
10    pub resource_uri_template: String,
11    #[serde(default = "default_visibility_enum")]
12    pub visibility: Vec<ToolVisibility>,
13}
14
15fn default_resource_uri_template() -> String {
16    "ui://systemprompt/{artifact_id}".to_string()
17}
18
19fn default_visibility_enum() -> Vec<ToolVisibility> {
20    vec![ToolVisibility::Model, ToolVisibility::App]
21}
22
23impl ToolUiConfig {
24    pub fn new() -> Self {
25        Self::default()
26    }
27
28    pub fn with_template(mut self, template: impl Into<String>) -> Self {
29        self.resource_uri_template = template.into();
30        self
31    }
32
33    pub fn model_only(mut self) -> Self {
34        self.visibility = vec![ToolVisibility::Model];
35        self
36    }
37
38    pub fn model_and_app(mut self) -> Self {
39        self.visibility = vec![ToolVisibility::Model, ToolVisibility::App];
40        self
41    }
42
43    pub fn to_meta_json(&self) -> serde_json::Value {
44        serde_json::json!({
45            "ui": {
46                "resourceUri": self.resource_uri_template,
47                "visibility": self.visibility
48            }
49        })
50    }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, Default)]
54pub struct ToolMetadata {
55    #[serde(default)]
56    pub terminal_on_success: bool,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub model_config: Option<ToolModelConfig>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub ui: Option<ToolUiConfig>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct DeploymentConfig {
65    pub deployments: HashMap<String, Deployment>,
66    pub settings: Settings,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct Deployment {
71    pub binary: String,
72    pub package: Option<String>,
73    pub port: u16,
74    pub endpoint: String,
75    pub enabled: bool,
76    pub display_in_web: bool,
77    #[serde(default)]
78    pub dev_only: bool,
79    #[serde(default)]
80    pub schemas: Vec<SchemaDefinition>,
81    pub oauth: OAuthRequirement,
82    #[serde(default)]
83    pub tools: HashMap<String, ToolMetadata>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub model_config: Option<ToolModelConfig>,
86    #[serde(default)]
87    pub env_vars: Vec<String>,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct SchemaDefinition {
92    pub file: String,
93    pub table: String,
94    pub required_columns: Vec<String>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct OAuthRequirement {
99    pub required: bool,
100    pub scopes: Vec<Permission>,
101    pub audience: JwtAudience,
102    pub client_id: Option<String>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct Settings {
107    pub auto_build: bool,
108    pub build_timeout: u64,
109    pub health_check_timeout: u64,
110    #[serde(default = "default_base_port")]
111    pub base_port: u16,
112    #[serde(default = "default_working_dir")]
113    pub working_dir: String,
114}
115
116const fn default_base_port() -> u16 {
117    5000
118}
119
120fn default_working_dir() -> String {
121    "/app".to_string()
122}