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 = "account_list",
description = "List all 1Password accounts configured on this device. Shows account URL, email, user UUID, and account UUID for each account."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AccountListTool {}
impl AccountListTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client.account_list().await.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "account_get",
description = "Get detailed information about a specific 1Password account. Returns account UUID, name, domain, type, state, and creation date."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AccountGetTool {
#[serde(default)]
pub account: Option<String>,
}
impl AccountGetTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.account_get(self.account.as_deref())
.await
.map_err(op_error_to_tool_error)?;
json_result(&result)
}
}
#[mcp_tool(
name = "account_add",
description = "Add a new 1Password account to this device. This typically requires interactive authentication. The account will be available for use after successful sign-in."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AccountAddTool {
pub address: String,
pub email: String,
#[serde(default)]
pub shorthand: Option<String>,
}
impl AccountAddTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.account_add(&self.address, &self.email, self.shorthand.as_deref())
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}
#[mcp_tool(
name = "account_forget",
description = "Remove a 1Password account from this device. This signs out and removes all local data for the account. The account itself is not deleted, only removed from this device."
)]
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct AccountForgetTool {
pub account: String,
}
impl AccountForgetTool {
pub async fn call(&self, client: &OpClient) -> Result<CallToolResult, CallToolError> {
let result = client
.account_forget(&self.account)
.await
.map_err(op_error_to_tool_error)?;
text_result(result)
}
}