Skip to main content
Glama

CodeGraph CLI MCP Server

by Jakedismo
protocol.rs3.54 kB
use crate::{message::*, version::*, McpError, Result}; use serde::{de::DeserializeOwned, Serialize}; use serde_json::json; use uuid::Uuid; /// MCP protocol helper to build requests and validate responses #[derive(Debug, Clone)] pub struct McpProtocol { version: ProtocolVersion, } impl McpProtocol { pub fn new(version: ProtocolVersion) -> Self { Self { version } } pub fn default() -> Self { Self { version: ProtocolVersion::latest(), } } pub fn version(&self) -> &ProtocolVersion { &self.version } pub fn build_request<T: Serialize>(&self, method: &str, params: &T) -> Result<JsonRpcRequest> { let id = json!(Uuid::new_v4().to_string()); let params_value = serde_json::to_value(params)?; Ok(JsonRpcRequest::new( id, method.to_string(), Some(params_value), )) } pub fn build_notification<T: Serialize>( &self, method: &str, params: &T, ) -> Result<JsonRpcNotification> { let params_value = serde_json::to_value(params)?; Ok(JsonRpcNotification::new( method.to_string(), Some(params_value), )) } } /// Convenience functions for core MCP handshake pub mod handshake { use super::*; pub const METHOD_INITIALIZE: &str = "initialize"; pub async fn build_initialize_request( negotiator: &VersionNegotiator, requested_version: Option<&str>, client_name: &str, client_version: &str, capabilities: Option<McpCapabilities>, ) -> Result<JsonRpcRequest> { let requested = requested_version.unwrap_or(DEFAULT_VERSION); let version = negotiator.negotiate(requested)?; let protocol = McpProtocol::new(version); let params = McpInitializeParams { protocol_version: protocol.version().to_string(), capabilities: capabilities.unwrap_or(McpCapabilities { experimental: None, sampling: None, }), client_info: McpClientInfo { name: client_name.to_string(), version: client_version.to_string(), }, }; protocol.build_request(METHOD_INITIALIZE, &params) } pub fn parse_initialize_result(msg: &JsonRpcMessage) -> Result<McpInitializeResult> { match msg { JsonRpcMessage::V2(JsonRpcV2Message::Response(res)) => match &res.result { JsonRpcResult::Success { result } => { let v: McpInitializeResult = serde_json::from_value(result.clone())?; Ok(v) } JsonRpcResult::Error { error } => Err(McpError::Protocol(error.message.clone())), }, _ => Err(McpError::InvalidMessage( "Expected initialize response".into(), )), } } } /// Typed request/response helpers pub fn parse_response_typed<R: DeserializeOwned>(msg: &JsonRpcMessage) -> Result<R> { match msg { JsonRpcMessage::V2(JsonRpcV2Message::Response(res)) => match &res.result { JsonRpcResult::Success { result } => { let v: R = serde_json::from_value(result.clone())?; Ok(v) } JsonRpcResult::Error { error } => Err(McpError::Protocol(error.message.clone())), }, _ => Err(McpError::InvalidMessage( "Expected JSON-RPC response".into(), )), } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jakedismo/codegraph-rust'

If you have feedback or need assistance with the MCP directory API, please join our Discord server