use bytes::Bytes;
use http_body_util::Full;
use hyper::{Response, StatusCode, header};
use serde_json::Value;
use tracing::error;
use turul_mcp_json_rpc_server::{
JsonRpcError, JsonRpcResponse, error::JsonRpcErrorObject, types::RequestId,
};
type JsonRpcBody = Full<Bytes>;
pub fn jsonrpc_error_response(
id: RequestId,
code: i64,
message: &str,
data: Option<Value>,
) -> Result<Response<JsonRpcBody>, hyper::Error> {
let error_obj = JsonRpcErrorObject {
code,
message: message.to_string(),
data,
};
let err = JsonRpcError::new(Some(id), error_obj);
let body_bytes = serde_json::to_vec(&err).unwrap_or_else(|e| {
error!("Failed to serialize JSON-RPC error: {}", e);
b"{}".to_vec()
});
Ok(Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "application/json")
.body(Full::new(Bytes::from(body_bytes)))
.unwrap())
}
pub fn jsonrpc_notification_response() -> Result<Response<JsonRpcBody>, hyper::Error> {
Ok(Response::builder()
.status(StatusCode::ACCEPTED) .header(header::CONTENT_TYPE, "application/json")
.body(Full::new(Bytes::new()))
.unwrap())
}
pub fn jsonrpc_success_response(
id: RequestId,
result: Value,
) -> Result<Response<JsonRpcBody>, hyper::Error> {
let response = JsonRpcResponse::success(id, result);
let body_bytes = serde_json::to_vec(&response).unwrap_or_else(|e| {
error!("Failed to serialize JSON-RPC response: {}", e);
b"{}".to_vec()
});
Ok(Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "application/json")
.body(Full::new(Bytes::from(body_bytes)))
.unwrap())
}
pub fn jsonrpc_response_with_session(
response: JsonRpcResponse,
session_id: Option<String>,
) -> Result<Response<JsonRpcBody>, hyper::Error> {
let body_bytes = serde_json::to_vec(&response).unwrap_or_else(|e| {
error!("Failed to serialize JSON-RPC response: {}", e);
b"{}".to_vec()
});
let mut builder = Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "application/json");
if let Some(session_id) = session_id {
builder = builder.header("Mcp-Session-Id", session_id);
}
Ok(builder.body(Full::new(Bytes::from(body_bytes))).unwrap())
}
pub fn method_not_allowed_response() -> Response<JsonRpcBody> {
Response::builder()
.status(StatusCode::METHOD_NOT_ALLOWED)
.header("Allow", "GET, POST, DELETE, OPTIONS")
.body(Full::new(Bytes::from("Method not allowed")))
.unwrap()
}
pub fn not_found_response() -> Response<JsonRpcBody> {
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Full::new(Bytes::from("Not Found")))
.unwrap()
}
pub fn bad_request_response(message: &str) -> Response<JsonRpcBody> {
let error_obj = JsonRpcErrorObject {
code: -32700, message: message.to_string(),
data: None,
};
let err = JsonRpcError::new(None, error_obj);
let body_bytes = serde_json::to_vec(&err).unwrap_or_else(|_| b"{}".to_vec());
Response::builder()
.status(StatusCode::BAD_REQUEST)
.header(header::CONTENT_TYPE, "application/json")
.body(Full::new(Bytes::from(body_bytes)))
.unwrap()
}
pub fn options_response() -> Response<JsonRpcBody> {
Response::builder()
.status(StatusCode::OK)
.body(Full::new(Bytes::new()))
.unwrap()
}