systemprompt_models/mcp/
deployment.rs1use 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, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
8pub enum McpServerType {
9 #[default]
10 #[serde(rename = "internal")]
11 Internal,
12 #[serde(rename = "external")]
13 External,
14}
15
16impl McpServerType {
17 pub const fn as_str(&self) -> &'static str {
18 match self {
19 Self::Internal => "internal",
20 Self::External => "external",
21 }
22 }
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, Default)]
26pub struct ToolUiConfig {
27 #[serde(default = "default_resource_uri_template")]
28 pub resource_uri_template: String,
29 #[serde(default = "default_visibility_enum")]
30 pub visibility: Vec<ToolVisibility>,
31}
32
33fn default_resource_uri_template() -> String {
34 "ui://systemprompt/{artifact_id}".to_string()
35}
36
37fn default_visibility_enum() -> Vec<ToolVisibility> {
38 vec![ToolVisibility::Model, ToolVisibility::App]
39}
40
41impl ToolUiConfig {
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn with_template(mut self, template: impl Into<String>) -> Self {
47 self.resource_uri_template = template.into();
48 self
49 }
50
51 pub fn model_only(mut self) -> Self {
52 self.visibility = vec![ToolVisibility::Model];
53 self
54 }
55
56 pub fn model_and_app(mut self) -> Self {
57 self.visibility = vec![ToolVisibility::Model, ToolVisibility::App];
58 self
59 }
60
61 pub fn to_meta_json(&self) -> serde_json::Value {
62 serde_json::json!({
63 "ui": {
64 "resourceUri": self.resource_uri_template,
65 "visibility": self.visibility
66 }
67 })
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, Default)]
72pub struct ToolMetadata {
73 #[serde(default)]
74 pub terminal_on_success: bool,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub model_config: Option<ToolModelConfig>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub ui: Option<ToolUiConfig>,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct DeploymentConfig {
83 pub deployments: HashMap<String, Deployment>,
84 pub settings: Settings,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct Deployment {
89 #[serde(default, alias = "type")]
90 pub server_type: McpServerType,
91 pub binary: String,
92 pub package: Option<String>,
93 pub port: u16,
94 pub endpoint: String,
95 pub enabled: bool,
96 pub display_in_web: bool,
97 #[serde(default)]
98 pub dev_only: bool,
99 #[serde(default)]
100 pub schemas: Vec<SchemaDefinition>,
101 pub oauth: OAuthRequirement,
102 #[serde(default)]
103 pub tools: HashMap<String, ToolMetadata>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub model_config: Option<ToolModelConfig>,
106 #[serde(default)]
107 pub env_vars: Vec<String>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct SchemaDefinition {
112 pub file: String,
113 pub table: String,
114 pub required_columns: Vec<String>,
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct OAuthRequirement {
119 pub required: bool,
120 pub scopes: Vec<Permission>,
121 pub audience: JwtAudience,
122 pub client_id: Option<String>,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct Settings {
127 pub auto_build: bool,
128 pub build_timeout: u64,
129 pub health_check_timeout: u64,
130 #[serde(default = "default_base_port")]
131 pub base_port: u16,
132 #[serde(default = "default_working_dir")]
133 pub working_dir: String,
134}
135
136const fn default_base_port() -> u16 {
137 5000
138}
139
140fn default_working_dir() -> String {
141 "/app".to_string()
142}