Skip to main content

relay_knowledge/interfaces/agent/mcp/runtime/
server.rs

1use crate::{
2    application::{AgentRuntimeConfig, RelayKnowledgeService},
3    interfaces::agent::{AgentAuditLog, AgentAuditSink},
4    net::{NetworkRuntime, qos::QosRuntime},
5    observability::AgentProtocolMetrics,
6};
7
8#[cfg(test)]
9use crate::interfaces::agent::AgentAuditEvent;
10
11use super::{
12    super::scope_authorization::RuntimeScopeAuthorizer,
13    super::state::{CancellationRegistry, SessionRegistry},
14};
15
16/// MCP Streamable HTTP server state shared by route handlers.
17#[derive(Clone)]
18pub struct McpServer {
19    pub(in crate::interfaces::agent::mcp) service: RelayKnowledgeService,
20    pub(in crate::interfaces::agent::mcp) network: NetworkRuntime,
21    pub(in crate::interfaces::agent::mcp) agent: AgentRuntimeConfig,
22    pub(in crate::interfaces::agent::mcp) qos: QosRuntime,
23    pub(in crate::interfaces::agent::mcp) audit: AgentAuditLog,
24    pub(in crate::interfaces::agent::mcp) metrics: AgentProtocolMetrics,
25    pub(in crate::interfaces::agent::mcp) cancellations: CancellationRegistry,
26    pub(in crate::interfaces::agent::mcp) sessions: SessionRegistry,
27    pub(in crate::interfaces::agent::mcp) scope_authorizer: RuntimeScopeAuthorizer,
28}
29
30impl McpServer {
31    /// Creates MCP server state from validated runtime boundaries.
32    pub fn new(
33        service: RelayKnowledgeService,
34        network: NetworkRuntime,
35        agent: AgentRuntimeConfig,
36    ) -> Self {
37        let metrics = service.observability().agent_metrics();
38        let qos = network.qos_runtime();
39        let audit = if agent.audit_sink_enabled {
40            AgentAuditSink::jsonl(service.agent_audit_log_path(), agent.audit_queue_depth)
41                .map(AgentAuditLog::with_sink)
42                .unwrap_or_default()
43        } else {
44            AgentAuditLog::default()
45        };
46
47        Self {
48            service,
49            network,
50            agent,
51            qos,
52            audit,
53            metrics,
54            cancellations: CancellationRegistry::default(),
55            sessions: SessionRegistry::default(),
56            scope_authorizer: RuntimeScopeAuthorizer::default(),
57        }
58    }
59
60    #[cfg(test)]
61    pub fn qos_snapshot(&self) -> crate::net::qos::QosSnapshot {
62        self.qos.snapshot()
63    }
64
65    #[cfg(test)]
66    pub fn audit_snapshot(&self) -> Vec<AgentAuditEvent> {
67        self.audit.snapshot()
68    }
69}
70
71#[cfg(test)]
72#[path = "server_tests.rs"]
73mod tests;