Skip to main content

objectiveai_sdk/agent/
mcp.rs

1//! MCP server configuration for agents.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// An MCP server that the agent can connect to.
7#[derive(
8    Debug,
9    Clone,
10    Serialize,
11    Deserialize,
12    PartialEq,
13    Eq,
14    PartialOrd,
15    Ord,
16    JsonSchema,
17    arbitrary::Arbitrary,
18)]
19#[schemars(rename = "agent.McpServer")]
20pub struct McpServer {
21    /// The URL of the MCP server.
22    pub url: String,
23    /// Whether this MCP server uses authorization.
24    #[serde(default)]
25    pub authorization: bool,
26}
27
28impl McpServer {
29    /// Validates the MCP server configuration.
30    ///
31    /// The URL must start with `http://localhost` or `https://`.
32    pub fn validate(&self) -> Result<(), String> {
33        // if !self.url.starts_with("http://localhost") && !self.url.starts_with("https://") {
34        //     return Err(format!(
35        //         "`mcp.url` must start with \"http://localhost\" or \"https://\", got: \"{}\"",
36        //         self.url
37        //     ));
38        // }
39        Ok(())
40    }
41}
42
43/// A list of MCP servers.
44pub type McpServers = Vec<McpServer>;
45
46pub mod mcp_servers {
47    //! Functions for working with [`McpServers`](super::McpServers).
48
49    /// Validates all MCP servers in the list.
50    ///
51    /// Checks that no duplicate servers exist.
52    pub fn validate(this: &super::McpServers) -> Result<(), String> {
53        for server in this {
54            server.validate()?;
55        }
56        for (i, a) in this.iter().enumerate() {
57            for b in &this[i + 1..] {
58                if a == b {
59                    return Err(format!(
60                        "`mcp_servers` contains duplicate entry: \"{}\"",
61                        a.url
62                    ));
63                }
64            }
65        }
66        Ok(())
67    }
68
69    /// Sorts the MCP servers for deterministic ordering.
70    ///
71    /// Empty lists become `None`.
72    pub fn prepare(mut this: super::McpServers) -> Option<super::McpServers> {
73        if this.is_empty() {
74            None
75        } else {
76            this.sort();
77            Some(this)
78        }
79    }
80}