use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcRequest {
pub jsonrpc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<serde_json::Value>,
pub method: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub params: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcResponse {
pub jsonrpc: String,
pub id: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JsonRpcError>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<serde_json::Value>,
}
impl JsonRpcRequest {
pub fn new(
method: &str,
params: Option<serde_json::Value>,
id: Option<serde_json::Value>,
) -> Self {
Self {
jsonrpc: "2.0".to_string(),
method: method.to_string(),
params,
id,
}
}
pub fn notification(method: &str, params: Option<serde_json::Value>) -> Self {
Self::new(method, params, None)
}
pub fn with_id(method: &str, params: Option<serde_json::Value>, id: &str) -> Self {
Self::new(
method,
params,
Some(serde_json::Value::String(id.to_string())),
)
}
}
impl JsonRpcResponse {
pub fn success(id: Option<serde_json::Value>, result: serde_json::Value) -> Self {
Self {
jsonrpc: "2.0".to_string(),
id,
result: Some(result),
error: None,
}
}
pub fn error(id: Option<serde_json::Value>, error: JsonRpcError) -> Self {
Self {
jsonrpc: "2.0".to_string(),
id,
result: None,
error: Some(error),
}
}
}
impl JsonRpcError {
pub fn method_not_found(message: &str) -> Self {
Self {
code: -32601,
message: message.to_string(),
data: None,
}
}
pub fn invalid_params(message: &str) -> Self {
Self {
code: -32602,
message: message.to_string(),
data: None,
}
}
pub fn internal_error(message: &str) -> Self {
Self {
code: -32603,
message: message.to_string(),
data: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeRequest {
#[serde(alias = "protocol_version")]
pub protocol_version: String,
pub capabilities: ClientCapabilities,
#[serde(alias = "client_info")]
pub client_info: ClientInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeResult {
#[serde(alias = "protocol_version")]
pub protocol_version: String,
pub capabilities: ServerCapabilities,
#[serde(alias = "server_info")]
pub server_info: ServerInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientInfo {
pub name: String,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerInfo {
pub name: String,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<ToolCapabilities>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<ToolCapabilities>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolCapabilities {
pub supported: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListToolsResult {
pub tools: Vec<Tool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Tool {
pub name: String,
pub description: String,
#[serde(alias = "input_schema")]
pub input_schema: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallToolRequest {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<serde_json::Value>,
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CallToolResult {
pub content: Vec<Content>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "is_error")]
pub is_error: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Content {
#[serde(rename = "text")]
Text {
text: String,
},
}
#[derive(Debug, Clone)]
pub struct BearerToken {
pub access_token: String,
pub token_type: String,
}
impl BearerToken {
pub fn new(access_token: &str) -> Self {
Self {
access_token: access_token.to_string(),
token_type: "Bearer".to_string(),
}
}
pub fn to_authorization_header(&self) -> String {
format!("{} {}", self.token_type, self.access_token)
}
}
impl Tool {
pub fn simple(name: &str, description: &str, parameters: &[&str]) -> Self {
let mut properties = serde_json::Map::new();
for param in parameters {
properties.insert(
param.to_string(),
serde_json::json!({
"type": "string",
"description": format!("Parameter: {}", param)
}),
);
}
let schema = serde_json::json!({
"type": "object",
"properties": properties,
"required": parameters
});
Self {
name: name.to_string(),
description: description.to_string(),
input_schema: schema,
}
}
}
impl Content {
pub fn text(text: &str) -> Self {
Content::Text {
text: text.to_string(),
}
}
}