mcp_server_sqlite/tools/
list_tables_tool.rs1use 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)]
25pub struct ListTablesTool;
29
30impl SqliteServerTool for ListTablesTool {
31 const NAME: &str = "list_tables";
32
33 type Context = McpServerSqlite;
34 type Error = ToolError<ListTablesError>;
35
36 type Input = ListTablesInput;
37 type Output = ListTablesOutput;
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 let mut stmt = conn
48 .prepare(
49 "SELECT name, sql FROM sqlite_master \
50 WHERE type = 'table' ORDER BY name",
51 )
52 .map_err(|source| {
53 ToolError::Tool(ListTablesError::Query { source })
54 })?;
55
56 let tables = stmt
57 .query_map([], |row| {
58 Ok(TableInfo {
59 name: row.get(0)?,
60 sql: row.get(1)?,
61 })
62 })
63 .map_err(|source| {
64 ToolError::Tool(ListTablesError::Query { source })
65 })?
66 .collect::<Result<Vec<_>, _>>()
67 .map_err(|source| {
68 ToolError::Tool(ListTablesError::Query { source })
69 })?;
70
71 Ok(ListTablesOutput { tables })
72 }
73}
74
75#[derive(
77 Clone,
78 Copy,
79 Debug,
80 Default,
81 PartialEq,
82 Eq,
83 PartialOrd,
84 Ord,
85 Hash,
86 Serialize,
87 Deserialize,
88 schemars::JsonSchema,
89)]
90pub struct ListTablesInput {}
91
92#[derive(
94 Clone,
95 Debug,
96 PartialEq,
97 Eq,
98 PartialOrd,
99 Ord,
100 Hash,
101 Serialize,
102 Deserialize,
103 schemars::JsonSchema,
104)]
105pub struct ListTablesOutput {
106 pub tables: Vec<TableInfo>,
108}
109
110#[derive(
112 Clone,
113 Debug,
114 PartialEq,
115 Eq,
116 PartialOrd,
117 Ord,
118 Hash,
119 Serialize,
120 Deserialize,
121 schemars::JsonSchema,
122)]
123pub struct TableInfo {
124 pub name: String,
126 pub sql: Option<String>,
129}
130
131#[derive(Debug, thiserror::Error)]
133pub enum ListTablesError {
134 #[error("failed to list tables: {source}")]
136 Query {
137 source: rusqlite::Error,
139 },
140}
141
142impl IntoContents for ListTablesError {
145 fn into_contents(self) -> Vec<Content> {
146 vec![Content::text(self.to_string())]
147 }
148}