Skip to main content

opencode_sdk/http/
mcp.rs

1//! MCP API for OpenCode.
2//!
3//! Endpoints for Model Context Protocol server management.
4
5use crate::error::Result;
6use crate::http::HttpClient;
7use crate::types::api::McpActionResponse;
8use crate::types::mcp::{
9    McpAddRequest, McpAuthCallbackRequest, McpAuthStartRequest, McpAuthStartResponse,
10    McpAuthenticateRequest, McpStatus,
11};
12use reqwest::Method;
13
14/// MCP API client.
15#[derive(Clone)]
16pub struct McpApi {
17    http: HttpClient,
18}
19
20impl McpApi {
21    /// Create a new MCP API client.
22    pub fn new(http: HttpClient) -> Self {
23        Self { http }
24    }
25
26    /// Get MCP status.
27    ///
28    /// # Errors
29    ///
30    /// Returns an error if the request fails.
31    pub async fn status(&self) -> Result<McpStatus> {
32        self.http.request_json(Method::GET, "/mcp", None).await
33    }
34
35    /// Add an MCP server.
36    ///
37    /// # Errors
38    ///
39    /// Returns an error if the request fails.
40    pub async fn add(&self, req: &McpAddRequest) -> Result<McpActionResponse> {
41        let body = serde_json::to_value(req)?;
42        self.http
43            .request_json(Method::POST, "/mcp", Some(body))
44            .await
45    }
46
47    /// Start MCP auth flow.
48    ///
49    /// # Errors
50    ///
51    /// Returns an error if the request fails.
52    pub async fn auth_start(
53        &self,
54        name: &str,
55        req: &McpAuthStartRequest,
56    ) -> Result<McpAuthStartResponse> {
57        let body = serde_json::to_value(req)?;
58        self.http
59            .request_json(Method::POST, &format!("/mcp/{}/auth", name), Some(body))
60            .await
61    }
62
63    /// Complete MCP auth callback.
64    ///
65    /// # Errors
66    ///
67    /// Returns an error if the request fails.
68    pub async fn auth_callback(
69        &self,
70        name: &str,
71        req: &McpAuthCallbackRequest,
72    ) -> Result<McpActionResponse> {
73        let body = serde_json::to_value(req)?;
74        self.http
75            .request_json(
76                Method::POST,
77                &format!("/mcp/{}/auth/callback", name),
78                Some(body),
79            )
80            .await
81    }
82
83    /// Authenticate with API key.
84    ///
85    /// # Errors
86    ///
87    /// Returns an error if the request fails.
88    pub async fn authenticate(
89        &self,
90        name: &str,
91        req: &McpAuthenticateRequest,
92    ) -> Result<McpActionResponse> {
93        let body = serde_json::to_value(req)?;
94        self.http
95            .request_json(
96                Method::POST,
97                &format!("/mcp/{}/auth/authenticate", name),
98                Some(body),
99            )
100            .await
101    }
102
103    /// Remove MCP auth.
104    ///
105    /// # Errors
106    ///
107    /// Returns an error if the request fails.
108    pub async fn auth_remove(&self, name: &str) -> Result<()> {
109        self.http
110            .request_empty(Method::DELETE, &format!("/mcp/{}/auth", name), None)
111            .await
112    }
113
114    /// Connect to an MCP server.
115    ///
116    /// # Errors
117    ///
118    /// Returns an error if the request fails.
119    pub async fn connect(&self, name: &str) -> Result<McpActionResponse> {
120        self.http
121            .request_json(
122                Method::POST,
123                &format!("/mcp/{}/connect", name),
124                None, // OpenCode API expects no request body
125            )
126            .await
127    }
128
129    /// Disconnect from an MCP server.
130    ///
131    /// # Errors
132    ///
133    /// Returns an error if the request fails.
134    pub async fn disconnect(&self, name: &str) -> Result<McpActionResponse> {
135        self.http
136            .request_json(
137                Method::POST,
138                &format!("/mcp/{}/disconnect", name),
139                None, // OpenCode API expects no request body
140            )
141            .await
142    }
143}