The smokesignal.events web application
at main 68 lines 2.0 kB view raw
1//! MCP configuration storage operations. 2//! 3//! Stores per-user MCP configuration settings. 4 5use chrono::{DateTime, Utc}; 6use serde::{Deserialize, Serialize}; 7use sqlx::FromRow; 8 9use super::{StoragePool, errors::StorageError}; 10 11/// MCP configuration for a user. 12#[derive(Clone, Debug, FromRow, Serialize, Deserialize)] 13pub struct McpConfiguration { 14 /// User's DID 15 pub did: String, 16 /// Allow dangerous operations (delete, apply_writes, etc.) 17 pub allow_dangerous: bool, 18 /// When the configuration was last updated 19 pub updated_at: DateTime<Utc>, 20} 21 22/// Get MCP configuration for a user. 23/// Returns None if no configuration exists (default settings apply). 24pub async fn mcp_config_get( 25 pool: &StoragePool, 26 did: &str, 27) -> Result<Option<McpConfiguration>, StorageError> { 28 sqlx::query_as::<_, McpConfiguration>("SELECT * FROM mcp_configuration WHERE did = $1") 29 .bind(did) 30 .fetch_optional(pool) 31 .await 32 .map_err(StorageError::UnableToExecuteQuery) 33} 34 35/// Upsert MCP configuration for a user. 36pub async fn mcp_config_upsert( 37 pool: &StoragePool, 38 did: &str, 39 allow_dangerous: bool, 40) -> Result<McpConfiguration, StorageError> { 41 let now = Utc::now(); 42 43 sqlx::query_as::<_, McpConfiguration>( 44 r#" 45 INSERT INTO mcp_configuration (did, allow_dangerous, updated_at) 46 VALUES ($1, $2, $3) 47 ON CONFLICT (did) 48 DO UPDATE SET allow_dangerous = $2, updated_at = $3 49 RETURNING * 50 "#, 51 ) 52 .bind(did) 53 .bind(allow_dangerous) 54 .bind(now) 55 .fetch_one(pool) 56 .await 57 .map_err(StorageError::UnableToExecuteQuery) 58} 59 60/// Check if dangerous operations are allowed for a user. 61/// Returns false if no configuration exists (safe default). 62pub async fn mcp_config_is_dangerous_allowed( 63 pool: &StoragePool, 64 did: &str, 65) -> Result<bool, StorageError> { 66 let config = mcp_config_get(pool, did).await?; 67 Ok(config.map(|c| c.allow_dangerous).unwrap_or(false)) 68}