Skip to main content

claude_code/commands/
mcp.rs

1use crate::commands::command::ClaudeCommandRequest;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum McpScope {
5    Local,
6    User,
7    Project,
8}
9
10impl McpScope {
11    fn as_arg_value(self) -> &'static str {
12        match self {
13            McpScope::Local => "local",
14            McpScope::User => "user",
15            McpScope::Project => "project",
16        }
17    }
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum McpTransport {
22    Stdio,
23    Sse,
24    Http,
25}
26
27impl McpTransport {
28    fn as_arg_value(self) -> &'static str {
29        match self {
30            McpTransport::Stdio => "stdio",
31            McpTransport::Sse => "sse",
32            McpTransport::Http => "http",
33        }
34    }
35}
36
37#[derive(Debug, Clone)]
38pub struct McpAddRequest {
39    pub name: String,
40    pub command_or_url: String,
41    pub args: Vec<String>,
42    pub scope: Option<McpScope>,
43    pub transport: Option<McpTransport>,
44    pub env: Vec<String>,
45    pub headers: Vec<String>,
46}
47
48impl McpAddRequest {
49    pub fn new(name: impl Into<String>, command_or_url: impl Into<String>) -> Self {
50        Self {
51            name: name.into(),
52            command_or_url: command_or_url.into(),
53            args: Vec::new(),
54            scope: None,
55            transport: None,
56            env: Vec::new(),
57            headers: Vec::new(),
58        }
59    }
60
61    pub fn args(mut self, args: impl IntoIterator<Item = impl Into<String>>) -> Self {
62        self.args = args.into_iter().map(Into::into).collect();
63        self
64    }
65
66    pub fn scope(mut self, scope: McpScope) -> Self {
67        self.scope = Some(scope);
68        self
69    }
70
71    pub fn transport(mut self, transport: McpTransport) -> Self {
72        self.transport = Some(transport);
73        self
74    }
75
76    pub fn env(mut self, env: impl IntoIterator<Item = impl Into<String>>) -> Self {
77        self.env = env.into_iter().map(Into::into).collect();
78        self
79    }
80
81    pub fn headers(mut self, headers: impl IntoIterator<Item = impl Into<String>>) -> Self {
82        self.headers = headers.into_iter().map(Into::into).collect();
83        self
84    }
85
86    pub fn into_command(self) -> ClaudeCommandRequest {
87        let mut req = ClaudeCommandRequest::new(["mcp", "add"]);
88        if let Some(scope) = self.scope {
89            req = req.args(["--scope", scope.as_arg_value()]);
90        }
91        if let Some(transport) = self.transport {
92            req = req.args(["--transport", transport.as_arg_value()]);
93        }
94        for e in self.env {
95            req = req.args(["--env".to_string(), e]);
96        }
97        for h in self.headers {
98            req = req.args(["--header".to_string(), h]);
99        }
100        req.args([self.name, self.command_or_url]).args(self.args)
101    }
102}
103
104#[derive(Debug, Clone)]
105pub struct McpRemoveRequest {
106    pub name: String,
107    pub scope: Option<McpScope>,
108}
109
110impl McpRemoveRequest {
111    pub fn new(name: impl Into<String>) -> Self {
112        Self {
113            name: name.into(),
114            scope: None,
115        }
116    }
117
118    pub fn scope(mut self, scope: McpScope) -> Self {
119        self.scope = Some(scope);
120        self
121    }
122
123    pub fn into_command(self) -> ClaudeCommandRequest {
124        let mut req = ClaudeCommandRequest::new(["mcp", "remove"]);
125        if let Some(scope) = self.scope {
126            req = req.args(["--scope", scope.as_arg_value()]);
127        }
128        req.arg(self.name)
129    }
130}
131
132#[derive(Debug, Clone)]
133pub struct McpGetRequest {
134    pub name: String,
135}
136
137impl McpGetRequest {
138    pub fn new(name: impl Into<String>) -> Self {
139        Self { name: name.into() }
140    }
141
142    pub fn into_command(self) -> ClaudeCommandRequest {
143        ClaudeCommandRequest::new(["mcp", "get"]).arg(self.name)
144    }
145}
146
147#[derive(Debug, Clone)]
148pub struct McpAddJsonRequest {
149    pub name: String,
150    pub json: String,
151    pub scope: Option<McpScope>,
152}
153
154impl McpAddJsonRequest {
155    pub fn new(name: impl Into<String>, json: impl Into<String>) -> Self {
156        Self {
157            name: name.into(),
158            json: json.into(),
159            scope: None,
160        }
161    }
162
163    pub fn scope(mut self, scope: McpScope) -> Self {
164        self.scope = Some(scope);
165        self
166    }
167
168    pub fn into_command(self) -> ClaudeCommandRequest {
169        let mut req = ClaudeCommandRequest::new(["mcp", "add-json"]);
170        if let Some(scope) = self.scope {
171            req = req.args(["--scope", scope.as_arg_value()]);
172        }
173        req.args([self.name, self.json])
174    }
175}
176
177#[derive(Debug, Clone)]
178pub struct McpServeRequest {
179    pub args: Vec<String>,
180}
181
182impl McpServeRequest {
183    pub fn new() -> Self {
184        Self { args: Vec::new() }
185    }
186
187    pub fn args(mut self, args: impl IntoIterator<Item = impl Into<String>>) -> Self {
188        self.args = args.into_iter().map(Into::into).collect();
189        self
190    }
191
192    pub fn into_command(self) -> ClaudeCommandRequest {
193        ClaudeCommandRequest::new(["mcp", "serve"]).args(self.args)
194    }
195}
196
197impl Default for McpServeRequest {
198    fn default() -> Self {
199        Self::new()
200    }
201}
202
203#[derive(Debug, Clone)]
204pub struct McpAddFromClaudeDesktopRequest {
205    pub scope: Option<McpScope>,
206}
207
208impl McpAddFromClaudeDesktopRequest {
209    pub fn new() -> Self {
210        Self { scope: None }
211    }
212
213    pub fn scope(mut self, scope: McpScope) -> Self {
214        self.scope = Some(scope);
215        self
216    }
217
218    pub fn into_command(self) -> ClaudeCommandRequest {
219        let mut req = ClaudeCommandRequest::new(["mcp", "add-from-claude-desktop"]);
220        if let Some(scope) = self.scope {
221            req = req.args(["--scope", scope.as_arg_value()]);
222        }
223        req
224    }
225}
226
227impl Default for McpAddFromClaudeDesktopRequest {
228    fn default() -> Self {
229        Self::new()
230    }
231}