mcp-server-sqlite 1.0.0

An MCP server for SQLite with fine-grained access control
Documentation
//! The `vacuum` tool: runs SQLite's VACUUM command to reclaim unused space and
//! defragment the database file.

use rmcp::model::{Content, IntoContents};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::ToolError;
use crate::{mcp::McpServerSqlite, traits::SqliteServerTool};

#[derive(
    Clone,
    Copy,
    Debug,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Default,
    Serialize,
    Deserialize,
    JsonSchema,
)]
/// Reclaim unused space and defragment the database file by running SQLite's
/// VACUUM command. This rebuilds the entire database into a compact, contiguous
/// file. The operation may take a while on large databases.
pub struct VacuumTool;

impl SqliteServerTool for VacuumTool {
    const NAME: &str = "vacuum";

    type Context = McpServerSqlite;
    type Error = ToolError<VacuumError>;

    type Input = VacuumInput;
    type Output = VacuumOutput;

    fn handle(
        ctx: &Self::Context,
        _input: Self::Input,
    ) -> Result<Self::Output, Self::Error> {
        let conn = ctx
            .connection()
            .map_err(|source| ToolError::Connection { source })?;

        conn.execute_batch("VACUUM").map_err(|source| {
            ToolError::Tool(VacuumError::Vacuum { source })
        })?;

        Ok(VacuumOutput { success: true })
    }
}

/// The input parameters for the `vacuum` tool.
#[derive(
    Clone,
    Copy,
    Debug,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Serialize,
    Deserialize,
    schemars::JsonSchema,
)]
pub struct VacuumInput {}

/// The result of running the VACUUM command.
#[derive(
    Clone,
    Copy,
    Debug,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Serialize,
    Deserialize,
    schemars::JsonSchema,
)]
pub struct VacuumOutput {
    /// Whether the VACUUM operation completed successfully.
    pub success: bool,
}

/// Errors specific to the `vacuum` tool.
#[derive(Debug, thiserror::Error)]
pub enum VacuumError {
    /// SQLite failed to execute the VACUUM command. This can happen if the
    /// database is locked by another connection or if there is insufficient
    /// disk space.
    #[error("failed to vacuum database: {source}")]
    Vacuum {
        /// The underlying rusqlite error.
        source: rusqlite::Error,
    },
}

/// Converts the vacuum-specific error into MCP content by rendering the display
/// string as text.
impl IntoContents for VacuumError {
    fn into_contents(self) -> Vec<Content> {
        vec![Content::text(self.to_string())]
    }
}