Skip to main content

mcp_server_sqlite/tools/
vacuum_tool.rs

1//! The `vacuum` tool: runs SQLite's VACUUM command to reclaim unused space and
2//! defragment the database file.
3
4use rmcp::model::{Content, IntoContents};
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8use super::ToolError;
9use crate::{mcp::McpServerSqlite, traits::SqliteServerTool};
10
11#[derive(
12    Clone,
13    Copy,
14    Debug,
15    PartialEq,
16    Eq,
17    PartialOrd,
18    Ord,
19    Hash,
20    Default,
21    Serialize,
22    Deserialize,
23    JsonSchema,
24)]
25/// Reclaim unused space and defragment the database file by running SQLite's
26/// VACUUM command. This rebuilds the entire database into a compact, contiguous
27/// file. The operation may take a while on large databases.
28pub struct VacuumTool;
29
30impl SqliteServerTool for VacuumTool {
31    const NAME: &str = "vacuum";
32
33    type Context = McpServerSqlite;
34    type Error = ToolError<VacuumError>;
35
36    type Input = VacuumInput;
37    type Output = VacuumOutput;
38
39    fn handle(
40        ctx: &Self::Context,
41        _input: Self::Input,
42    ) -> Result<Self::Output, Self::Error> {
43        let conn = ctx
44            .connection()
45            .map_err(|source| ToolError::Connection { source })?;
46
47        conn.execute_batch("VACUUM").map_err(|source| {
48            ToolError::Tool(VacuumError::Vacuum { source })
49        })?;
50
51        Ok(VacuumOutput { success: true })
52    }
53}
54
55/// The input parameters for the `vacuum` tool.
56#[derive(
57    Clone,
58    Copy,
59    Debug,
60    Default,
61    PartialEq,
62    Eq,
63    PartialOrd,
64    Ord,
65    Hash,
66    Serialize,
67    Deserialize,
68    schemars::JsonSchema,
69)]
70pub struct VacuumInput {}
71
72/// The result of running the VACUUM command.
73#[derive(
74    Clone,
75    Copy,
76    Debug,
77    PartialEq,
78    Eq,
79    PartialOrd,
80    Ord,
81    Hash,
82    Serialize,
83    Deserialize,
84    schemars::JsonSchema,
85)]
86pub struct VacuumOutput {
87    /// Whether the VACUUM operation completed successfully.
88    pub success: bool,
89}
90
91/// Errors specific to the `vacuum` tool.
92#[derive(Debug, thiserror::Error)]
93pub enum VacuumError {
94    /// SQLite failed to execute the VACUUM command. This can happen if the
95    /// database is locked by another connection or if there is insufficient
96    /// disk space.
97    #[error("failed to vacuum database: {source}")]
98    Vacuum {
99        /// The underlying rusqlite error.
100        source: rusqlite::Error,
101    },
102}
103
104/// Converts the vacuum-specific error into MCP content by rendering the display
105/// string as text.
106impl IntoContents for VacuumError {
107    fn into_contents(self) -> Vec<Content> {
108        vec![Content::text(self.to_string())]
109    }
110}