agentox_core/checks/conformance/
init_capabilities.rs1use crate::checks::runner::{Check, CheckContext};
4use crate::checks::types::{CheckCategory, CheckResult, Severity};
5
6pub struct InitializeCapabilities;
7
8#[async_trait::async_trait]
9impl Check for InitializeCapabilities {
10 fn id(&self) -> &str {
11 "CONF-001"
12 }
13
14 fn name(&self) -> &str {
15 "Initialize returns valid capabilities"
16 }
17
18 fn category(&self) -> CheckCategory {
19 CheckCategory::Conformance
20 }
21
22 async fn run(&self, ctx: &mut CheckContext) -> Vec<CheckResult> {
23 let mut results = Vec::new();
24 let desc = "Validates that the initialize response contains protocolVersion, capabilities, and serverInfo";
25
26 match &ctx.init_result {
27 Some(init) => {
28 if init.protocol_version.is_empty() {
30 results.push(CheckResult::fail(
31 self.id(),
32 self.name(),
33 self.category(),
34 Severity::Critical,
35 desc,
36 "protocolVersion is empty",
37 ));
38 } else {
39 results.push(CheckResult::pass(
40 self.id(),
41 self.name(),
42 self.category(),
43 desc,
44 ));
45 }
46
47 if init.server_info.name.is_empty() {
49 results.push(CheckResult::fail(
50 self.id(),
51 "Server info has name",
52 self.category(),
53 Severity::High,
54 "serverInfo.name must not be empty",
55 "serverInfo.name is empty",
56 ));
57 }
58
59 if init.server_info.version.is_none() {
61 results.push(CheckResult::fail(
62 self.id(),
63 "Server info has version",
64 self.category(),
65 Severity::Low,
66 "serverInfo.version is recommended",
67 "serverInfo.version is missing (recommended but not required)",
68 ));
69 }
70 }
71 None => {
72 results.push(CheckResult::fail(
73 self.id(),
74 self.name(),
75 self.category(),
76 Severity::Critical,
77 desc,
78 "Initialize was not called or failed — no result available",
79 ));
80 }
81 }
82
83 results
84 }
85}