#![cfg_attr(coverage_nightly, coverage(off))]
use std::collections::HashMap;
use std::sync::Arc;
use async_trait::async_trait;
use axum::body::Body;
use axum::http::{HeaderMap, Method, StatusCode};
use axum::response::{IntoResponse, Response};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;
use uuid::Uuid;
pub mod adapters;
pub mod error;
pub mod service;
#[derive(Debug)]
pub struct UnifiedRequest {
pub method: Method,
pub path: String,
pub headers: HeaderMap,
pub body: Body,
pub extensions: HashMap<String, Value>,
pub trace_id: Uuid,
}
#[derive(Debug)]
pub struct UnifiedResponse {
pub status: StatusCode,
pub headers: HeaderMap,
pub body: Body,
pub trace_id: Uuid,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Protocol {
Mcp,
Http,
Cli,
WebSocket,
}
impl std::fmt::Display for Protocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Protocol::Mcp => write!(f, "mcp"),
Protocol::Http => write!(f, "http"),
Protocol::Cli => write!(f, "cli"),
Protocol::WebSocket => write!(f, "websocket"),
}
}
}
#[async_trait]
pub trait ProtocolAdapter: Send + Sync + 'static {
type Input: Send + 'static;
type Output: Send + 'static;
async fn decode(&self, input: Self::Input) -> Result<UnifiedRequest, ProtocolError>;
async fn encode(&self, response: UnifiedResponse) -> Result<Self::Output, ProtocolError>;
fn protocol(&self) -> Protocol;
}
#[derive(Debug, Error)]
pub enum ProtocolError {
#[error("Failed to decode request: {0}")]
DecodeError(String),
#[error("Failed to encode response: {0}")]
EncodeError(String),
#[error("Protocol not supported: {0}")]
UnsupportedProtocol(String),
#[error("Invalid request format: {0}")]
InvalidFormat(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("HTTP error: {0}")]
HttpError(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct McpContext {
pub id: Option<Value>,
pub method: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CliContext {
pub command: String,
pub args: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HttpContext {
pub remote_addr: Option<String>,
pub user_agent: Option<String>,
}
include!("protocol_request.rs");
include!("protocol_response.rs");
include!("protocol_registry.rs");
include!("protocol_tests.rs");
include!("protocol_property_tests.rs");