objectiveai_sdk/cli/command/agents/mcp/
mod.rs1use crate::cli::command::CommandRequest;
9
10pub mod resources;
11pub mod servers;
12pub mod tools;
13
14#[derive(clap::Subcommand)]
15pub enum Command {
16 Resources {
19 #[command(subcommand)]
20 command: resources::Command,
21 },
22 Servers {
24 #[command(subcommand)]
25 command: servers::Command,
26 },
27 Tools {
30 #[command(subcommand)]
31 command: tools::Command,
32 },
33}
34
35#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
36#[serde(untagged)]
37#[schemars(rename = "cli.command.agents.mcp.Request")]
38pub enum Request {
39 #[schemars(title = "Resources")]
40 Resources(resources::Request),
41 #[schemars(title = "Servers")]
42 Servers(servers::Request),
43 #[schemars(title = "Tools")]
44 Tools(tools::Request),
45}
46
47#[objectiveai_sdk_macros::json_schema_ignore]
50#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
51#[schemars(rename = "cli.command.agents.mcp.ResponseItem")]
52#[serde(untagged)]
53pub enum ResponseItem {
54 #[schemars(title = "Resources")]
55 Resources(resources::ResponseItem),
56 #[schemars(title = "Servers")]
57 Servers(servers::ResponseItem),
58 #[schemars(title = "Tools")]
59 Tools(tools::ResponseItem),
60}
61
62#[cfg(feature = "mcp")]
63impl crate::cli::command::CommandResponse for ResponseItem {
64 fn into_mcp(self) -> crate::cli::command::McpResponseItem {
65 match self {
66 ResponseItem::Resources(v) => v.into_mcp(),
67 ResponseItem::Servers(v) => v.into_mcp(),
68 ResponseItem::Tools(v) => v.into_mcp(),
69 }
70 }
71}
72
73impl TryFrom<Command> for Request {
74 type Error = crate::cli::command::FromArgsError;
75 fn try_from(command: Command) -> Result<Self, Self::Error> {
76 match command {
77 Command::Resources { command } => {
78 Ok(Request::Resources(resources::Request::try_from(command)?))
79 }
80 Command::Servers { command } => {
81 Ok(Request::Servers(servers::Request::try_from(command)?))
82 }
83 Command::Tools { command } => {
84 Ok(Request::Tools(tools::Request::try_from(command)?))
85 }
86 }
87 }
88}
89
90impl CommandRequest for Request {
91 fn request_base(&self) -> &crate::cli::command::RequestBase {
92 match self {
93 Request::Resources(inner) => inner.request_base(),
94 Request::Servers(inner) => inner.request_base(),
95 Request::Tools(inner) => inner.request_base(),
96 }
97 }
98
99 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
100 match self {
101 Request::Resources(inner) => inner.request_base_mut(),
102 Request::Servers(inner) => inner.request_base_mut(),
103 Request::Tools(inner) => inner.request_base_mut(),
104 }
105 }
106}
107
108#[cfg(feature = "cli-executor")]
109pub async fn execute<E: crate::cli::command::CommandExecutor>(
110 executor: &E,
111 request: Request,
112 agent_arguments: Option<&crate::cli::command::AgentArguments>,
113) -> Result<
114 std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
115 E::Error,
116> {
117 use futures::StreamExt;
118 let stream: std::pin::Pin<
119 Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
120 > = match request {
121 Request::Resources(req) => {
122 let inner = resources::execute(executor, req, agent_arguments).await?;
123 Box::pin(inner.map(|r| r.map(ResponseItem::Resources)))
124 }
125 Request::Servers(req) => {
126 let inner = servers::execute(executor, req, agent_arguments).await?;
127 Box::pin(inner.map(|r| r.map(ResponseItem::Servers)))
128 }
129 Request::Tools(req) => {
130 let inner = tools::execute(executor, req, agent_arguments).await?;
131 Box::pin(inner.map(|r| r.map(ResponseItem::Tools)))
132 }
133 };
134 Ok(stream)
135}
136
137#[cfg(feature = "cli-executor")]
138pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
139 executor: &E,
140 request: Request,
141 transform: crate::cli::command::Transform,
142 agent_arguments: Option<&crate::cli::command::AgentArguments>,
143) -> Result<
144 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
145 E::Error,
146> {
147 let stream: std::pin::Pin<
148 Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
149 > = match request {
150 Request::Resources(req) => {
151 let inner = resources::execute_transform(executor, req, transform, agent_arguments).await?;
152 Box::pin(inner)
153 }
154 Request::Servers(req) => {
155 let inner = servers::execute_transform(executor, req, transform, agent_arguments).await?;
156 Box::pin(inner)
157 }
158 Request::Tools(req) => {
159 let inner = tools::execute_transform(executor, req, transform, agent_arguments).await?;
160 Box::pin(inner)
161 }
162 };
163 Ok(stream)
164}