mcp_postgres/actions/
connections.rs1use serde_json::{json, Value};
2use tokio_postgres::Client;
3use crate::errors::Result as MCPResult;
4
5pub async fn list_connections(client: &Client, _params: &Option<&Value>) -> MCPResult<Value> {
7 let rows = client
8 .query(
9 "SELECT pid, usename::text, application_name, state,
10 state_change::text, backend_start::text, query_start::text
11 FROM pg_stat_activity
12 WHERE pid != pg_backend_pid()
13 ORDER BY backend_start DESC",
14 &[],
15 )
16 .await?;
17
18 let connections: Vec<Value> = rows
19 .iter()
20 .map(|row| {
21 json!({
22 "pid": row.get::<_, i32>(0),
23 "user": row.get::<_, Option<String>>(1),
24 "application": row.get::<_, Option<String>>(2),
25 "state": row.get::<_, Option<String>>(3),
26 "state_change": row.get::<_, Option<String>>(4),
27 "backend_start": row.get::<_, Option<String>>(5),
28 "query_start": row.get::<_, Option<String>>(6),
29 })
30 })
31 .collect();
32
33 Ok(json!({ "connections": connections }))
34}
35
36pub async fn show_current_user(client: &Client, _params: &Option<&Value>) -> MCPResult<Value> {
38 let rows = client
39 .query("SELECT current_user, current_database(), version()", &[])
40 .await?;
41
42 let row = &rows[0];
43
44 Ok(json!({
45 "user": row.get::<_, String>(0),
46 "database": row.get::<_, String>(1),
47 "version": row.get::<_, String>(2),
48 }))
49}
50
51pub async fn show_running_queries(client: &Client, _params: &Option<&Value>) -> MCPResult<Value> {
53 let rows = client
54 .query(
55 "SELECT pid, usename, application_name, state, query, query_start
56 FROM pg_stat_activity
57 WHERE state != 'idle' AND pid != pg_backend_pid()
58 ORDER BY query_start DESC",
59 &[],
60 )
61 .await?;
62
63 let queries: Vec<Value> = rows
64 .iter()
65 .map(|row| {
66 json!({
67 "pid": row.get::<_, i32>(0),
68 "user": row.get::<_, String>(1),
69 "application": row.get::<_, Option<String>>(2),
70 "state": row.get::<_, String>(3),
71 "query": row.get::<_, Option<String>>(4),
72 "query_start": row.get::<_, Option<String>>(5),
73 })
74 })
75 .collect();
76
77 Ok(json!({ "queries": queries }))
78}
79
80pub async fn show_connection_summary(client: &Client, _params: &Option<&Value>) -> MCPResult<Value> {
82 let rows = client
83 .query(
84 "SELECT state, count(*) as count
85 FROM pg_stat_activity
86 GROUP BY state
87 ORDER BY count DESC",
88 &[],
89 )
90 .await?;
91
92 let summary: Vec<Value> = rows
93 .iter()
94 .map(|row| {
95 json!({
96 "state": row.get::<_, Option<String>>(0).unwrap_or_else(|| "unknown".to_string()),
97 "count": row.get::<_, i64>(1),
98 })
99 })
100 .collect();
101
102 Ok(json!({ "summary": summary }))
103}