Skip to main content

objectiveai_sdk/agent/
mcp.rs

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