database_mcp_server/types.rs
1//! Request and response types for MCP tool parameters.
2//!
3//! Each struct maps to the JSON input or output schema of one MCP tool.
4
5use rmcp::schemars;
6use rmcp::schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9
10use crate::pagination::Cursor;
11
12/// Response for tools with no structured return data.
13#[derive(Debug, Serialize, JsonSchema)]
14#[serde(rename_all = "camelCase")]
15pub struct MessageResponse {
16 /// Description of the completed operation.
17 pub message: String,
18}
19
20/// Request for the `listDatabases` tool.
21#[derive(Debug, Default, Deserialize, JsonSchema)]
22#[serde(rename_all = "camelCase")]
23pub struct ListDatabasesRequest {
24 /// Opaque cursor from a prior response's `nextCursor`; omit for the first page.
25 #[serde(default)]
26 pub cursor: Option<Cursor>,
27}
28
29/// Response for the `listDatabases` tool.
30#[derive(Debug, Serialize, JsonSchema)]
31#[serde(rename_all = "camelCase")]
32pub struct ListDatabasesResponse {
33 /// Sorted list of database names for this page.
34 pub databases: Vec<String>,
35 /// Opaque cursor pointing to the next page. Absent when this is the final page.
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub next_cursor: Option<Cursor>,
38}
39
40/// Request for the `createDatabase` tool.
41#[derive(Debug, Default, Deserialize, JsonSchema)]
42#[serde(rename_all = "camelCase")]
43pub struct CreateDatabaseRequest {
44 /// Name of the database to create. Must contain only alphanumeric characters and underscores.
45 pub database: String,
46}
47
48/// Request for the `dropDatabase` tool.
49#[derive(Debug, Default, Deserialize, JsonSchema)]
50#[serde(rename_all = "camelCase")]
51pub struct DropDatabaseRequest {
52 /// Name of the database to drop. Must contain only alphanumeric characters and underscores.
53 pub database: String,
54}
55
56/// Request for the `listTables` tool.
57#[derive(Debug, Default, Deserialize, JsonSchema)]
58#[serde(rename_all = "camelCase")]
59pub struct ListTablesRequest {
60 /// The database name to list tables from. Required. Use `listDatabases` first to see available databases.
61 pub database: String,
62 /// Opaque cursor from a prior response's `nextCursor`; omit for the first page.
63 #[serde(default)]
64 pub cursor: Option<Cursor>,
65}
66
67/// Response for the `listTables` tool.
68#[derive(Debug, Serialize, JsonSchema)]
69#[serde(rename_all = "camelCase")]
70pub struct ListTablesResponse {
71 /// Sorted list of table names for this page.
72 pub tables: Vec<String>,
73 /// Opaque cursor pointing to the next page. Absent when this is the final page.
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub next_cursor: Option<Cursor>,
76}
77
78/// Request for the `getTableSchema` tool.
79#[derive(Debug, Default, Deserialize, JsonSchema)]
80#[serde(rename_all = "camelCase")]
81pub struct GetTableSchemaRequest {
82 /// The database name containing the table. Required. Use `listDatabases` first to see available databases.
83 pub database: String,
84 /// The table name to inspect. Use `listTables` first to see available tables in the database.
85 pub table: String,
86}
87
88/// Response for the `getTableSchema` tool.
89#[derive(Debug, Serialize, JsonSchema)]
90#[serde(rename_all = "camelCase")]
91pub struct TableSchemaResponse {
92 /// Name of the inspected table.
93 pub table: String,
94 /// Column definitions keyed by column name.
95 pub columns: Value,
96}
97
98/// Request for the `writeQuery` tool.
99#[derive(Debug, Default, Deserialize, JsonSchema)]
100#[serde(rename_all = "camelCase")]
101pub struct QueryRequest {
102 /// The SQL query to execute.
103 pub query: String,
104 /// The database to run the query against. Required. Use `listDatabases` first to see available databases.
105 pub database: String,
106}
107
108/// Request for the `readQuery` tool.
109#[derive(Debug, Default, Deserialize, JsonSchema)]
110#[serde(rename_all = "camelCase")]
111pub struct ReadQueryRequest {
112 /// The SQL query to execute.
113 pub query: String,
114 /// The database to run the query against. Required. Use `listDatabases` first to see available databases.
115 pub database: String,
116 /// Opaque cursor from a prior response's `nextCursor`; omit for the first page.
117 #[serde(default)]
118 pub cursor: Option<Cursor>,
119}
120
121/// Response for the `writeQuery` and `explainQuery` tools.
122#[derive(Debug, Serialize, JsonSchema)]
123#[serde(rename_all = "camelCase")]
124pub struct QueryResponse {
125 /// Result rows, each a JSON object keyed by a column name.
126 pub rows: Vec<Value>,
127}
128
129/// Response for the `readQuery` tool.
130#[derive(Debug, Serialize, JsonSchema)]
131#[serde(rename_all = "camelCase")]
132pub struct ReadQueryResponse {
133 /// Result rows, each a JSON object keyed by a column name.
134 pub rows: Vec<Value>,
135 /// Opaque cursor pointing to the next page. Absent when this is the final
136 /// page, when the result fits in one page, or when the statement is a
137 /// non-`SELECT` kind that does not paginate (e.g. `SHOW`, `EXPLAIN`).
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub next_cursor: Option<Cursor>,
140}
141
142/// Request for the `explainQuery` tool.
143#[derive(Debug, Default, Deserialize, JsonSchema)]
144#[serde(rename_all = "camelCase")]
145pub struct ExplainQueryRequest {
146 /// The database to explain against. Required. Use `listDatabases` first to see available databases.
147 pub database: String,
148 /// The SQL query to explain.
149 pub query: String,
150 /// If true, use EXPLAIN ANALYZE for actual execution statistics. In read-only mode, only allowed for read-only statements. Defaults to false.
151 #[serde(default)]
152 pub analyze: bool,
153}