diff --git a/crates/mcp/src/main.rs b/crates/mcp/src/main.rs index 0e38f47..6a1cc70 100644 --- a/crates/mcp/src/main.rs +++ b/crates/mcp/src/main.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use domain::ports::{IMediaProvider, IProviderRegistry, ProviderCapabilities, StreamingProtocol}; -use domain::{DomainError, DomainResult, MediaFilter, MediaItemId, MediaItem, ScheduleEngineService}; use domain::ports::StreamQuality; +use domain::{DomainError, DomainResult, MediaFilter, MediaItem, MediaItemId, ScheduleEngineService}; use infra_wiring::DbPool; use tracing::info; use uuid::Uuid; @@ -13,6 +13,8 @@ mod tools; use server::KTvMcpServer; +const DEFAULT_DATABASE_URL: &str = "sqlite:data.db?mode=rwc"; + #[tokio::main] async fn main() -> anyhow::Result<()> { let _ = dotenvy::dotenv(); @@ -26,7 +28,7 @@ async fn main() -> anyhow::Result<()> { .init(); let database_url = std::env::var("DATABASE_URL") - .unwrap_or_else(|_| "sqlite:data.db?mode=rwc".to_string()); + .unwrap_or_else(|_| DEFAULT_DATABASE_URL.to_string()); let owner_id: Uuid = std::env::var("MCP_USER_ID") .map_err(|_| anyhow::anyhow!("MCP_USER_ID env var is required (UUID of the user)"))? @@ -127,6 +129,7 @@ fn wire_repositories(pool: &DbPool) -> anyhow::Result { library_query: w.library_query, }) } + #[cfg(not(any(feature = "sqlite", feature = "postgres")))] _ => anyhow::bail!("database backend not compiled into this binary"), } } diff --git a/crates/mcp/src/server.rs b/crates/mcp/src/server.rs index d554429..00babc1 100644 --- a/crates/mcp/src/server.rs +++ b/crates/mcp/src/server.rs @@ -16,6 +16,8 @@ use uuid::Uuid; use crate::tools::{channels, library, schedule}; +const SERVER_NAME: &str = "k-tv-mcp"; + #[derive(Clone)] pub struct KTvMcpServer { pub channel_cmd_deps: Arc, @@ -191,8 +193,8 @@ impl ServerHandler for KTvMcpServer { protocol_version: ProtocolVersion::V_2024_11_05, capabilities: ServerCapabilities::builder().enable_tools().build(), server_info: Implementation { - name: "k-tv-mcp".into(), - version: "0.1.0".into(), + name: SERVER_NAME.into(), + version: env!("CARGO_PKG_VERSION").into(), }, instructions: Some( "K-TV MCP server. Create channels, define programming blocks, generate schedules. \ diff --git a/crates/mcp/src/tools/library.rs b/crates/mcp/src/tools/library.rs index d0d9b6d..5c3dd26 100644 --- a/crates/mcp/src/tools/library.rs +++ b/crates/mcp/src/tools/library.rs @@ -7,6 +7,8 @@ use serde::Serialize; use crate::error::{domain_err, ok_json}; +const DEFAULT_SEARCH_LIMIT: u32 = 50; + #[derive(Serialize)] struct CollectionDto { id: String, @@ -38,11 +40,11 @@ struct SearchResult { total: u32, } -fn to_content_type_string(ct: &domain::ContentType) -> String { +fn content_type_to_str(ct: &domain::ContentType) -> &'static str { match ct { - domain::ContentType::Movie => "movie".to_string(), - domain::ContentType::Episode => "episode".to_string(), - domain::ContentType::Short => "short".to_string(), + domain::ContentType::Movie => "movie", + domain::ContentType::Episode => "episode", + domain::ContentType::Short => "short", } } @@ -93,7 +95,7 @@ pub async fn search_media( season_number: None, decade: None, offset: 0, - limit: 50, + limit: DEFAULT_SEARCH_LIMIT, }; match application::library::search::execute(deps, query).await { Ok((items, total)) => { @@ -104,7 +106,7 @@ pub async fn search_media( provider_id: i.provider_id().to_string(), external_id: i.external_id().to_string(), title: i.title().to_string(), - content_type: to_content_type_string(i.content_type()), + content_type: content_type_to_str(i.content_type()).to_string(), duration_secs: i.duration_secs(), series_name: i.series_name().map(|s| s.to_string()), season_number: i.season_number(),