Skip to main content

aether_core/mcp/
exposure.rs

1use super::{ToolFilter, ToolMatcher};
2use rmcp::model::Tool;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
7#[serde(from = "ToolExposureConfig", into = "ToolExposureConfig")]
8#[schemars(with = "ToolExposureConfig")]
9pub enum ToolExposure {
10    #[default]
11    ModelVisible,
12    Deferred(ToolFilter),
13}
14
15impl ToolExposure {
16    pub fn deferred_all() -> Self {
17        Self::Deferred(ToolFilter::default())
18    }
19
20    pub fn defers_tools(&self) -> bool {
21        matches!(self, Self::Deferred(_))
22    }
23
24    pub fn is_deferred(&self, tool: &Tool) -> bool {
25        matches!(self, Self::Deferred(filter) if filter.allows(&tool.name, tool))
26    }
27}
28
29#[derive(Deserialize, Serialize, JsonSchema)]
30#[serde(untagged, deny_unknown_fields)]
31enum ToolExposureConfig {
32    Enabled(bool),
33    Rules {
34        #[serde(default, skip_serializing_if = "Vec::is_empty")]
35        include: Vec<ToolMatcher>,
36        #[serde(default, skip_serializing_if = "Vec::is_empty")]
37        exclude: Vec<ToolMatcher>,
38    },
39}
40
41impl From<ToolExposureConfig> for ToolExposure {
42    fn from(repr: ToolExposureConfig) -> Self {
43        match repr {
44            ToolExposureConfig::Enabled(false) => Self::ModelVisible,
45            ToolExposureConfig::Enabled(true) => Self::deferred_all(),
46            ToolExposureConfig::Rules { include, exclude } => {
47                Self::Deferred(ToolFilter { allow: include, deny: exclude })
48            }
49        }
50    }
51}
52
53impl From<ToolExposure> for ToolExposureConfig {
54    fn from(exposure: ToolExposure) -> Self {
55        match exposure {
56            ToolExposure::ModelVisible => Self::Enabled(false),
57            ToolExposure::Deferred(filter) if filter.is_empty() => Self::Enabled(true),
58            ToolExposure::Deferred(ToolFilter { allow, deny }) => Self::Rules { include: allow, exclude: deny },
59        }
60    }
61}