remote_mcp_kernel/
server_info.rs1use rmcp::model::*;
7use serde_json::json;
8
9pub struct ServerInfo {
11 pub name: &'static str,
12 pub version: &'static str,
13 pub description: &'static str,
14 pub protocol_version: ProtocolVersion,
15}
16
17impl ServerInfo {
18 pub const fn default() -> Self {
20 Self {
21 name: "MCP OAuth Server",
22 version: env!("CARGO_PKG_VERSION"),
23 description: "MCP server with OAuth authentication capabilities",
24 protocol_version: ProtocolVersion::V_2025_03_26,
25 }
26 }
27
28 pub fn tool_capabilities() -> ServerCapabilities {
30 ServerCapabilities::builder().enable_tools().build()
31 }
32
33 pub fn full_capabilities() -> ServerCapabilities {
35 ServerCapabilities::builder()
36 .enable_tools()
37 .enable_resources()
38 .build()
39 }
40
41 pub fn implementation(&self) -> Implementation {
43 Implementation {
44 name: self.name.to_string(),
45 version: self.version.to_string(),
46 }
47 }
48
49 pub fn server_info(&self) -> rmcp::model::ServerInfo {
51 rmcp::model::ServerInfo {
52 protocol_version: self.protocol_version.clone(),
53 capabilities: Self::tool_capabilities(),
54 server_info: self.implementation(),
55 instructions: Some(self.description.to_string()),
56 }
57 }
58
59 pub fn initialize_result(&self) -> InitializeResult {
61 InitializeResult {
62 protocol_version: self.protocol_version.clone(),
63 capabilities: Self::tool_capabilities(),
64 server_info: self.implementation(),
65 instructions: Some(self.description.to_string()),
66 }
67 }
68
69 pub fn api_info(&self) -> serde_json::Value {
71 json!({
72 "name": self.name,
73 "version": self.version,
74 "description": self.description,
75 "protocol_version": format!("{:?}", self.protocol_version),
76 "capabilities": {
77 "tools": true,
78 "resources": false,
79 "prompts": false
80 },
81 "endpoints": {
82 "authorization": "/oauth/authorize",
83 "token": "/oauth/token",
84 "register": "/oauth/register",
85 "callback": "/oauth/callback",
86 "streamable": "/mcp/streamable",
87 "info": "/info"
88 }
89 })
90 }
91
92 pub fn health_response(&self) -> serde_json::Value {
94 json!({
95 "status": "healthy",
96 "service": self.name,
97 "version": self.version,
98 "timestamp": chrono::Utc::now().to_rfc3339()
99 })
100 }
101
102 pub fn oauth_provider_info(&self) -> serde_json::Value {
104 json!({
105 "name": "MCP GitHub OAuth Provider",
106 "version": self.version,
107 "description": "OAuth provider for MCP server with GitHub authentication",
108 "endpoints": {
109 "authorization": "/oauth/authorize",
110 "token": "/oauth/token",
111 "register": "/oauth/register",
112 "callback": "/oauth/callback"
113 },
114 "supported_scopes": ["read", "write"],
115 "github_integration": true
116 })
117 }
118}
119
120pub static SERVER_INFO: ServerInfo = ServerInfo::default();
122
123pub mod helpers {
125 use super::*;
126
127 pub fn mcp_server_info() -> rmcp::model::ServerInfo {
129 SERVER_INFO.server_info()
130 }
131
132 pub fn mcp_initialize_result() -> InitializeResult {
134 SERVER_INFO.initialize_result()
135 }
136
137 pub fn health_check_response() -> serde_json::Value {
139 SERVER_INFO.health_response()
140 }
141
142 pub fn api_info_response() -> serde_json::Value {
144 SERVER_INFO.api_info()
145 }
146
147 pub fn oauth_provider_info_response() -> serde_json::Value {
149 SERVER_INFO.oauth_provider_info()
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn test_server_info_consistency() {
159 let info = ServerInfo::default();
160 let server_info = info.server_info();
161 let init_result = info.initialize_result();
162
163 assert_eq!(server_info.server_info.name, init_result.server_info.name);
164 assert_eq!(
165 server_info.server_info.version,
166 init_result.server_info.version
167 );
168 assert_eq!(server_info.protocol_version, init_result.protocol_version);
169 }
170
171 #[test]
172 fn test_api_info_structure() {
173 let info = ServerInfo::default();
174 let api_info = info.api_info();
175
176 assert_eq!(api_info["name"], info.name);
177 assert_eq!(api_info["version"], info.version);
178 assert_eq!(api_info["description"], info.description);
179 assert!(api_info["endpoints"].is_object());
180 assert!(api_info["capabilities"].is_object());
181 }
182
183 #[test]
184 fn test_health_response_format() {
185 let info = ServerInfo::default();
186 let health = info.health_response();
187
188 assert_eq!(health["status"], "healthy");
189 assert_eq!(health["service"], info.name);
190 assert_eq!(health["version"], info.version);
191 assert!(health["timestamp"].is_string());
192 }
193
194 #[test]
195 fn test_oauth_provider_info() {
196 let info = ServerInfo::default();
197 let oauth_info = info.oauth_provider_info();
198
199 assert_eq!(oauth_info["name"], "MCP GitHub OAuth Provider");
200 assert_eq!(oauth_info["version"], info.version);
201 assert_eq!(oauth_info["github_integration"], true);
202 assert!(oauth_info["supported_scopes"].is_array());
203 }
204}