use rust_mcp_schema::schema_utils::CallToolError;
use rust_mcp_schema::CallToolResult;
use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use serde::{Deserialize, Serialize};
use crate::op::OpClient;
use crate::tools::{json_result, op_error_to_tool_error, text_result};
#[mcp_tool(
name = "user_list",
description = "List all users in the 1Password account. Can filter by group membership. Returns user IDs, emails, names, and status."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserListTool {
#[serde(default)]
pub group: Option<String>,
#[serde(default)]
pub vault: Option<String>,
}
impl UserListTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_list(self.group.as_deref(), self.vault.as_deref())
.await
.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "user_get",
description = "Get detailed information about a specific user including their name, email, state, role, and when they were created."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserGetTool {
pub user: String,
}
impl UserGetTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_get(&self.user)
.await
.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "user_provision",
description = "Provision a new user in the 1Password account. An invitation will be sent to the user's email address."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserProvisionTool {
pub email: String,
pub name: String,
#[serde(default)]
pub language: Option<String>,
}
impl UserProvisionTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_provision(&self.email, &self.name, self.language.as_deref())
.await
.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "user_confirm",
description = "Confirm a pending user who has accepted their invitation. This activates their account."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserConfirmTool {
pub user: String,
}
impl UserConfirmTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_confirm(&self.user)
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}
#[mcp_tool(
name = "user_edit",
description = "Edit a user's name or travel mode setting."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserEditTool {
pub user: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub travel_mode: Option<bool>,
}
impl UserEditTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_edit(&self.user, self.name.as_deref(), self.travel_mode)
.await
.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "user_suspend",
description = "Suspend a user's access to the 1Password account. The user will not be able to sign in until reactivated."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserSuspendTool {
pub user: String,
#[serde(default)]
pub deauthorize_devices_after: Option<i64>,
}
impl UserSuspendTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_suspend(&self.user, self.deauthorize_devices_after)
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}
#[mcp_tool(
name = "user_reactivate",
description = "Reactivate a previously suspended user, restoring their access to the 1Password account."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserReactivateTool {
pub user: String,
}
impl UserReactivateTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_reactivate(&self.user)
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}
#[mcp_tool(
name = "user_delete",
description = "Permanently remove a user from the 1Password account. This action cannot be undone. The user's personal vaults and items will be deleted."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct UserDeleteTool {
pub user: String,
}
impl UserDeleteTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.user_delete(&self.user)
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}