use async_trait::async_trait;
use rust_mcp_schema::{
schema_utils::CallToolError, CallToolRequest, CallToolResult, ListToolsRequest,
ListToolsResult, RpcError,
};
use rust_mcp_sdk::mcp_server::ServerHandler;
use rust_mcp_sdk::McpServer;
use std::sync::Arc;
use tracing::{debug, info, instrument};
use crate::op::OpClient;
use crate::tools::OnePasswordTools;
#[derive(Debug)]
struct ToolParseError(String);
impl std::fmt::Display for ToolParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Failed to parse tool parameters: {}", self.0)
}
}
impl std::error::Error for ToolParseError {}
pub struct OnePasswordHandler {
op_client: Arc<OpClient>,
}
impl OnePasswordHandler {
pub fn new(op_client: OpClient) -> Self {
Self {
op_client: Arc::new(op_client),
}
}
#[instrument(skip(self, tool_params))]
async fn execute_tool(
&self,
tool_params: OnePasswordTools,
) -> Result<CallToolResult, CallToolError> {
match tool_params {
OnePasswordTools::WhoamiTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::SigninTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::SignoutTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::AccountListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::AccountGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::AccountAddTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::AccountForgetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultUserListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultUserGrantTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultUserRevokeTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultGroupListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultGroupGrantTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::VaultGroupRevokeTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemMoveTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemShareTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemTemplateListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ItemTemplateGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::DocumentListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::DocumentGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::DocumentCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::DocumentEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::DocumentDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserProvisionTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserConfirmTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserSuspendTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserReactivateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::UserDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupUserListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupUserGrantTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::GroupUserRevokeTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectServerListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectServerGetTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectServerCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectServerEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectServerDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectTokenListTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectTokenCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectTokenEditTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectTokenDeleteTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectVaultGrantTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ConnectVaultRevokeTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ServiceAccountCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::ServiceAccountRatelimitTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::EventsApiCreateTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::SecretReadTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::SecretInjectTool(tool) => tool.call(&self.op_client).await,
OnePasswordTools::SecretRunTool(tool) => tool.call(&self.op_client).await,
}
}
}
#[async_trait]
impl ServerHandler for OnePasswordHandler {
async fn handle_list_tools_request(
&self,
_request: ListToolsRequest,
_runtime: &dyn McpServer,
) -> Result<ListToolsResult, RpcError> {
debug!("Listing available tools");
Ok(ListToolsResult {
tools: OnePasswordTools::tools(),
meta: None,
next_cursor: None,
})
}
async fn handle_call_tool_request(
&self,
request: CallToolRequest,
_runtime: &dyn McpServer,
) -> Result<CallToolResult, CallToolError> {
let tool_name = &request.params.name;
info!(tool = %tool_name, "Executing tool");
let tool_params: OnePasswordTools =
OnePasswordTools::try_from(request.params).map_err(|e| {
CallToolError::new(ToolParseError(e.to_string()))
})?;
self.execute_tool(tool_params).await
}
}