headless_lms_mcp/protocol/
mod.rs1pub(crate) mod context;
5pub mod dispatch;
6pub mod headers;
7pub(crate) mod progress;
8
9use headless_lms_utils::http::escape_auth_param;
10use rmcp::model::{ErrorCode, ProtocolVersion};
11
12pub(crate) const PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V_2026_07_28;
14
15pub(crate) const SETUP_DOCS_URL: &str =
17 "https://github.com/rage/course-material-agent-skills/blob/main/SETUP.md";
18
19pub(crate) mod error_codes {
22 use super::ErrorCode;
23
24 pub const UNAUTHORIZED: ErrorCode = ErrorCode(-32050);
26 pub const INVALID_REQUEST_STATE: ErrorCode = ErrorCode(-32051);
28}
29
30pub(crate) fn www_authenticate_challenge(
34 resource_metadata_url: &str,
35 scope: &str,
36 error: Option<(&str, &str)>,
37) -> String {
38 let mut challenge = format!(
39 r#"Bearer resource_metadata="{}", scope="{}""#,
40 escape_auth_param(resource_metadata_url),
41 escape_auth_param(scope)
42 );
43 if let Some((code, description)) = error {
44 challenge.push_str(&format!(
45 r#", error="{}", error_description="{}""#,
46 escape_auth_param(code),
47 escape_auth_param(description)
48 ));
49 }
50 challenge
51}