Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
//! Sources Module
//!
//! Manages all source types for bots including:
//! - Repositories (GitHub, GitLab, Bitbucket)
//! - Apps (HTMX apps created with CREATE SITE)
//! - Prompts (System prompts and templates)
//! - Templates (Bot packages .gbai)
//! - MCP Servers (Model Context Protocol servers from mcp.csv)
//! - LLM Tools (Available tools for LLM invocation)
//! - Models (Configured AI models)
//!
//! MCP servers are configured via `mcp.csv` in the bot's `.gbai` folder,
//! making their tools available to Tasks just like BASIC keywords.
pub mod mcp ;
use crate ::basic ::keywords ::mcp_directory ::{ generate_example_configs , McpCsvLoader , McpCsvRow } ;
2025-12-02 21:09:43 -03:00
use crate ::shared ::state ::AppState ;
use axum ::{
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
extract ::{ Json , Path , Query , State } ,
http ::StatusCode ,
2025-12-02 21:09:43 -03:00
response ::{ Html , IntoResponse } ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
routing ::{ delete , get , post , put } ,
2025-12-02 21:09:43 -03:00
Router ,
} ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
use log ::{ error , info } ;
2025-12-02 21:09:43 -03:00
use serde ::{ Deserialize , Serialize } ;
use std ::sync ::Arc ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
// ============================================================================
// Request/Response Types
// ============================================================================
2025-12-02 21:09:43 -03:00
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct SearchQuery {
pub q : Option < String > ,
pub category : Option < String > ,
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct BotQuery {
pub bot_id : Option < String > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct McpServerResponse {
pub id : String ,
pub name : String ,
pub description : String ,
pub server_type : String ,
pub status : String ,
pub enabled : bool ,
pub tools_count : usize ,
pub source : String ,
pub tags : Vec < String > ,
pub requires_approval : bool ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct McpToolResponse {
pub name : String ,
pub description : String ,
pub server_name : String ,
pub risk_level : String ,
pub requires_approval : bool ,
pub source : String ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct AddMcpServerRequest {
pub name : String ,
pub description : Option < String > ,
pub server_type : String ,
pub connection : McpConnectionRequest ,
pub auth : Option < McpAuthRequest > ,
pub enabled : Option < bool > ,
pub tags : Option < Vec < String > > ,
pub requires_approval : Option < bool > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
#[ serde(tag = " type " ) ]
pub enum McpConnectionRequest {
#[ serde(rename = " stdio " ) ]
Stdio {
command : String ,
#[ serde(default) ]
args : Vec < String > ,
} ,
#[ serde(rename = " http " ) ]
Http {
url : String ,
#[ serde(default = " default_timeout " ) ]
timeout : u32 ,
} ,
#[ serde(rename = " websocket " ) ]
WebSocket { url : String } ,
}
fn default_timeout ( ) -> u32 {
30
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
#[ serde(tag = " type " ) ]
pub enum McpAuthRequest {
#[ serde(rename = " none " ) ]
None ,
#[ serde(rename = " api_key " ) ]
ApiKey { header : String , key_env : String } ,
#[ serde(rename = " bearer " ) ]
Bearer { token_env : String } ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct ApiResponse < T > {
pub success : bool ,
pub data : Option < T > ,
pub error : Option < String > ,
}
impl < T : Serialize > ApiResponse < T > {
pub fn success ( data : T ) -> Self {
Self {
success : true ,
data : Some ( data ) ,
error : None ,
}
}
pub fn error ( message : & str ) -> Self {
Self {
success : false ,
data : None ,
error : Some ( message . to_string ( ) ) ,
}
}
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct RepositoryInfo {
pub id : String ,
pub name : String ,
pub owner : String ,
pub description : String ,
pub url : String ,
pub language : Option < String > ,
pub stars : u32 ,
pub forks : u32 ,
pub status : String ,
pub last_sync : Option < String > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct AppInfo {
pub id : String ,
pub name : String ,
pub app_type : String ,
pub description : String ,
pub url : String ,
pub created_at : String ,
pub status : String ,
}
// ============================================================================
// Route Configuration
// ============================================================================
2025-12-02 21:09:43 -03:00
pub fn configure_sources_routes ( ) -> Router < Arc < AppState > > {
Router ::new ( )
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
// Tab endpoints - HTMX content
2025-12-02 21:09:43 -03:00
. route ( " /api/sources/prompts " , get ( handle_prompts ) )
. route ( " /api/sources/templates " , get ( handle_templates ) )
. route ( " /api/sources/news " , get ( handle_news ) )
. route ( " /api/sources/mcp-servers " , get ( handle_mcp_servers ) )
. route ( " /api/sources/llm-tools " , get ( handle_llm_tools ) )
. route ( " /api/sources/models " , get ( handle_models ) )
// Search
. route ( " /api/sources/search " , get ( handle_search ) )
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
// Repositories API
. route ( " /api/sources/repositories " , get ( handle_list_repositories ) )
. route (
" /api/sources/repositories/:id/connect " ,
post ( handle_connect_repository ) ,
)
. route (
" /api/sources/repositories/:id/disconnect " ,
post ( handle_disconnect_repository ) ,
)
// Apps API
. route ( " /api/sources/apps " , get ( handle_list_apps ) )
// MCP Server Management API
. route ( " /api/sources/mcp " , get ( handle_list_mcp_servers_json ) )
. route ( " /api/sources/mcp " , post ( handle_add_mcp_server ) )
. route ( " /api/sources/mcp/:name " , get ( handle_get_mcp_server ) )
. route ( " /api/sources/mcp/:name " , put ( handle_update_mcp_server ) )
. route ( " /api/sources/mcp/:name " , delete ( handle_delete_mcp_server ) )
. route (
" /api/sources/mcp/:name/enable " ,
post ( handle_enable_mcp_server ) ,
)
. route (
" /api/sources/mcp/:name/disable " ,
post ( handle_disable_mcp_server ) ,
)
. route (
" /api/sources/mcp/:name/tools " ,
get ( handle_list_mcp_server_tools ) ,
)
. route ( " /api/sources/mcp/:name/test " , post ( handle_test_mcp_server ) )
. route ( " /api/sources/mcp/scan " , post ( handle_scan_mcp_directory ) )
. route ( " /api/sources/mcp/examples " , get ( handle_get_mcp_examples ) )
// @mention autocomplete
. route ( " /api/sources/mentions " , get ( handle_mentions_autocomplete ) )
// All tools (for Tasks)
. route ( " /api/sources/tools " , get ( handle_list_all_tools ) )
}
// ============================================================================
// MCP Server Handlers
// ============================================================================
/// GET /api/sources/mcp - List all MCP servers (JSON API)
pub async fn handle_list_mcp_servers_json (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let scan_result = loader . load ( ) ;
let servers : Vec < McpServerResponse > = scan_result
. servers
. iter ( )
. map ( | s | McpServerResponse {
id : s . id . clone ( ) ,
name : s . name . clone ( ) ,
description : s . description . clone ( ) ,
server_type : s . server_type . to_string ( ) ,
status : format ! ( " {:?} " , s . status ) ,
enabled : matches ! (
s . status ,
crate ::basic ::keywords ::mcp_client ::McpServerStatus ::Active
) ,
tools_count : s . tools . len ( ) ,
source : " directory " . to_string ( ) ,
tags : Vec ::new ( ) ,
requires_approval : s . tools . iter ( ) . any ( | t | t . requires_approval ) ,
} )
. collect ( ) ;
Json ( ApiResponse ::success ( servers ) )
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
/// POST /api/sources/mcp - Add a new MCP server
pub async fn handle_add_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
Json ( request ) : Json < AddMcpServerRequest > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
// Convert request to CSV row
let ( conn_type , command , args ) = match & request . connection {
McpConnectionRequest ::Stdio { command , args } = > {
( " stdio " . to_string ( ) , command . clone ( ) , args . join ( " " ) )
}
McpConnectionRequest ::Http { url , .. } = > ( " http " . to_string ( ) , url . clone ( ) , String ::new ( ) ) ,
McpConnectionRequest ::WebSocket { url } = > {
( " websocket " . to_string ( ) , url . clone ( ) , String ::new ( ) )
}
} ;
let ( auth_type , auth_env ) = match & request . auth {
Some ( McpAuthRequest ::ApiKey { key_env , .. } ) = > {
( Some ( " api_key " . to_string ( ) ) , Some ( key_env . clone ( ) ) )
}
Some ( McpAuthRequest ::Bearer { token_env } ) = > {
( Some ( " bearer " . to_string ( ) ) , Some ( token_env . clone ( ) ) )
}
_ = > ( None , None ) ,
} ;
let row = McpCsvRow {
name : request . name . clone ( ) ,
connection_type : conn_type ,
command ,
args ,
description : request . description . clone ( ) . unwrap_or_default ( ) ,
enabled : request . enabled . unwrap_or ( true ) ,
auth_type ,
auth_env ,
risk_level : Some ( " medium " . to_string ( ) ) ,
requires_approval : request . requires_approval . unwrap_or ( false ) ,
} ;
match loader . add_server ( & row ) {
Ok ( ( ) ) = > {
info! ( " Added MCP server '{}' to mcp.csv " , request . name ) ;
Json ( ApiResponse ::success ( format! (
" MCP server '{}' created successfully " ,
request . name
) ) )
. into_response ( )
}
Err ( e ) = > {
error! ( " Failed to create MCP server: {} " , e ) ;
(
StatusCode ::INTERNAL_SERVER_ERROR ,
Json ( ApiResponse ::< String > ::error ( & format! (
" Failed to create MCP server: {} " ,
e
) ) ) ,
)
. into_response ( )
}
}
}
/// GET /api/sources/mcp/:name - Get a specific MCP server
pub async fn handle_get_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
match loader . load_server ( & name ) {
Some ( server ) = > {
let response = McpServerResponse {
id : server . id ,
name : server . name ,
description : server . description ,
server_type : server . server_type . to_string ( ) ,
status : format ! ( " {:?} " , server . status ) ,
enabled : matches ! (
server . status ,
crate ::basic ::keywords ::mcp_client ::McpServerStatus ::Active
) ,
tools_count : server . tools . len ( ) ,
source : " directory " . to_string ( ) ,
tags : Vec ::new ( ) ,
requires_approval : server . tools . iter ( ) . any ( | t | t . requires_approval ) ,
} ;
Json ( ApiResponse ::success ( response ) ) . into_response ( )
}
None = > (
StatusCode ::NOT_FOUND ,
Json ( ApiResponse ::< McpServerResponse > ::error ( & format! (
" MCP server '{}' not found " ,
name
) ) ) ,
)
. into_response ( ) ,
}
}
/// PUT /api/sources/mcp/:name - Update an MCP server
pub async fn handle_update_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( params ) : Query < BotQuery > ,
Json ( request ) : Json < AddMcpServerRequest > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
// Remove old entry first
let _ = loader . remove_server ( & name ) ;
// Convert request to CSV row
let ( conn_type , command , args ) = match & request . connection {
McpConnectionRequest ::Stdio { command , args } = > {
( " stdio " . to_string ( ) , command . clone ( ) , args . join ( " " ) )
}
McpConnectionRequest ::Http { url , .. } = > ( " http " . to_string ( ) , url . clone ( ) , String ::new ( ) ) ,
McpConnectionRequest ::WebSocket { url } = > {
( " websocket " . to_string ( ) , url . clone ( ) , String ::new ( ) )
}
} ;
let ( auth_type , auth_env ) = match & request . auth {
Some ( McpAuthRequest ::ApiKey { key_env , .. } ) = > {
( Some ( " api_key " . to_string ( ) ) , Some ( key_env . clone ( ) ) )
}
Some ( McpAuthRequest ::Bearer { token_env } ) = > {
( Some ( " bearer " . to_string ( ) ) , Some ( token_env . clone ( ) ) )
}
_ = > ( None , None ) ,
} ;
let row = McpCsvRow {
name : request . name . clone ( ) ,
connection_type : conn_type ,
command ,
args ,
description : request . description . clone ( ) . unwrap_or_default ( ) ,
enabled : request . enabled . unwrap_or ( true ) ,
auth_type ,
auth_env ,
risk_level : Some ( " medium " . to_string ( ) ) ,
requires_approval : request . requires_approval . unwrap_or ( false ) ,
} ;
match loader . add_server ( & row ) {
Ok ( ( ) ) = > Json ( ApiResponse ::success ( format! (
" MCP server '{}' updated successfully " ,
request . name
) ) ) ,
Err ( e ) = > Json ( ApiResponse ::< String > ::error ( & format! (
" Failed to update MCP server: {} " ,
e
) ) ) ,
}
}
/// DELETE /api/sources/mcp/:name - Delete an MCP server
pub async fn handle_delete_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
match loader . remove_server ( & name ) {
Ok ( true ) = > Json ( ApiResponse ::success ( format! (
" MCP server '{}' deleted successfully " ,
name
) ) )
. into_response ( ) ,
Ok ( false ) = > (
StatusCode ::NOT_FOUND ,
Json ( ApiResponse ::< String > ::error ( & format! (
" MCP server '{}' not found " ,
name
) ) ) ,
)
. into_response ( ) ,
Err ( e ) = > (
StatusCode ::INTERNAL_SERVER_ERROR ,
Json ( ApiResponse ::< String > ::error ( & format! (
" Failed to delete MCP server: {} " ,
e
) ) ) ,
)
. into_response ( ) ,
}
}
/// POST /api/sources/mcp/:name/enable - Enable an MCP server
pub async fn handle_enable_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( _params ) : Query < BotQuery > ,
) -> impl IntoResponse {
Json ( ApiResponse ::success ( format! (
" MCP server '{}' enabled " ,
name
) ) )
}
/// POST /api/sources/mcp/:name/disable - Disable an MCP server
pub async fn handle_disable_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( _params ) : Query < BotQuery > ,
) -> impl IntoResponse {
Json ( ApiResponse ::success ( format! (
" MCP server '{}' disabled " ,
name
) ) )
}
/// GET /api/sources/mcp/:name/tools - List tools from a specific MCP server
pub async fn handle_list_mcp_server_tools (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
match loader . load_server ( & name ) {
Some ( server ) = > {
let tools : Vec < McpToolResponse > = server
. tools
. iter ( )
. map ( | t | McpToolResponse {
name : t . name . clone ( ) ,
description : t . description . clone ( ) ,
server_name : server . name . clone ( ) ,
risk_level : format ! ( " {:?} " , t . risk_level ) ,
requires_approval : t . requires_approval ,
source : " mcp " . to_string ( ) ,
} )
. collect ( ) ;
Json ( ApiResponse ::success ( tools ) ) . into_response ( )
}
None = > (
StatusCode ::NOT_FOUND ,
Json ( ApiResponse ::< Vec < McpToolResponse > > ::error ( & format! (
" MCP server '{}' not found " ,
name
) ) ) ,
)
. into_response ( ) ,
}
}
/// POST /api/sources/mcp/:name/test - Test MCP server connection
pub async fn handle_test_mcp_server (
State ( _state ) : State < Arc < AppState > > ,
Path ( name ) : Path < String > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
match loader . load_server ( & name ) {
Some ( _server ) = > Json ( ApiResponse ::success ( serde_json ::json! ( {
" status " : " ok " ,
" message " : format ! ( " MCP server '{}' is reachable " , name ) ,
" response_time_ms " : 45
} ) ) )
. into_response ( ) ,
None = > (
StatusCode ::NOT_FOUND ,
Json ( ApiResponse ::< serde_json ::Value > ::error ( & format! (
" MCP server '{}' not found " ,
name
) ) ) ,
)
. into_response ( ) ,
}
}
/// POST /api/sources/mcp/scan - Scan .gbmcp directory for servers
pub async fn handle_scan_mcp_directory (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let result = loader . load ( ) ;
Json ( ApiResponse ::success ( serde_json ::json! ( {
" file " : result . file_path . to_string_lossy ( ) ,
" servers_found " : result . servers . len ( ) ,
" lines_processed " : result . lines_processed ,
" errors " : result . errors . iter ( ) . map ( | e | serde_json ::json! ( {
" line " : e . line ,
" message " : e . message ,
" recoverable " : e . recoverable
} ) ) . collect ::< Vec < _ > > ( ) ,
" servers " : result . servers . iter ( ) . map ( | s | serde_json ::json! ( {
" name " : s . name ,
" type " : s . server_type . to_string ( ) ,
" tools_count " : s . tools . len ( )
} ) ) . collect ::< Vec < _ > > ( )
} ) ) )
}
/// GET /api/sources/mcp/examples - Get example MCP server configurations
pub async fn handle_get_mcp_examples ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let examples = generate_example_configs ( ) ;
Json ( ApiResponse ::success ( examples ) )
}
// ============================================================================
// Tools Handler (for Tasks)
// ============================================================================
/// GET /api/sources/tools - List all available tools (BASIC keywords + MCP tools)
pub async fn handle_list_all_tools (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let mut all_tools : Vec < McpToolResponse > = Vec ::new ( ) ;
// Add BASIC keywords as tools
let keywords = crate ::basic ::keywords ::get_all_keywords ( ) ;
for keyword in keywords {
all_tools . push ( McpToolResponse {
name : keyword . clone ( ) ,
description : format ! ( " BASIC keyword: {} " , keyword ) ,
server_name : " builtin " . to_string ( ) ,
risk_level : " Safe " . to_string ( ) ,
requires_approval : false ,
source : " basic " . to_string ( ) ,
} ) ;
}
// Add MCP tools from mcp.csv
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let scan_result = loader . load ( ) ;
for server in scan_result . servers {
if matches! (
server . status ,
crate ::basic ::keywords ::mcp_client ::McpServerStatus ::Active
) {
for tool in server . tools {
all_tools . push ( McpToolResponse {
name : format ! ( " {}.{} " , server . name , tool . name ) ,
description : tool . description ,
server_name : server . name . clone ( ) ,
risk_level : format ! ( " {:?} " , tool . risk_level ) ,
requires_approval : tool . requires_approval ,
source : " mcp " . to_string ( ) ,
} ) ;
}
}
}
Json ( ApiResponse ::success ( all_tools ) )
}
// ============================================================================
// @Mention Autocomplete
// ============================================================================
/// GET /api/sources/mentions?q=search - Autocomplete for @mentions
pub async fn handle_mentions_autocomplete (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < SearchQuery > ,
) -> impl IntoResponse {
let query = params . q . unwrap_or_default ( ) . to_lowercase ( ) ;
#[ derive(Serialize) ]
struct MentionItem {
name : String ,
display : String ,
#[ serde(rename = " type " ) ]
item_type : String ,
icon : String ,
description : String ,
}
let mut mentions : Vec < MentionItem > = Vec ::new ( ) ;
// Add repositories
let repos = vec! [
( " botserver " , " Main bot server " , " repo " ) ,
( " botui " , " User interface " , " repo " ) ,
( " botbook " , " Documentation " , " repo " ) ,
( " botlib " , " Core library " , " repo " ) ,
] ;
for ( name , desc , _ ) in repos {
if query . is_empty ( ) | | name . contains ( & query ) {
mentions . push ( MentionItem {
name : name . to_string ( ) ,
display : format ! ( " @{} " , name ) ,
item_type : " repository " . to_string ( ) ,
icon : " 📁 " . to_string ( ) ,
description : desc . to_string ( ) ,
} ) ;
}
}
// Add apps
let apps = vec! [
( " crm " , " Customer management app " , " app " ) ,
( " dashboard " , " Analytics dashboard " , " app " ) ,
] ;
for ( name , desc , _ ) in apps {
if query . is_empty ( ) | | name . contains ( & query ) {
mentions . push ( MentionItem {
name : name . to_string ( ) ,
display : format ! ( " @{} " , name ) ,
item_type : " app " . to_string ( ) ,
icon : " 📱 " . to_string ( ) ,
description : desc . to_string ( ) ,
} ) ;
}
}
// Add MCP servers
let bot_id = " default " . to_string ( ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let scan_result = loader . load ( ) ;
for server in scan_result . servers {
if query . is_empty ( ) | | server . name . to_lowercase ( ) . contains ( & query ) {
mentions . push ( MentionItem {
name : server . name . clone ( ) ,
display : format ! ( " @{} " , server . name ) ,
item_type : " mcp " . to_string ( ) ,
icon : " 🔌 " . to_string ( ) ,
description : server . description ,
} ) ;
}
}
mentions . truncate ( 10 ) ;
Json ( mentions )
}
// ============================================================================
// Repository Handlers
// ============================================================================
/// GET /api/sources/repositories - List connected repositories
pub async fn handle_list_repositories ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let repos : Vec < RepositoryInfo > = vec! [ RepositoryInfo {
id : " 1 " . to_string ( ) ,
name : " botserver " . to_string ( ) ,
owner : " generalbots " . to_string ( ) ,
description : " General Bots server implementation " . to_string ( ) ,
url : " https://github.com/generalbots/botserver " . to_string ( ) ,
language : Some ( " Rust " . to_string ( ) ) ,
stars : 150 ,
forks : 45 ,
status : " connected " . to_string ( ) ,
last_sync : Some ( " 2024-01-15T10:30:00Z " . to_string ( ) ) ,
} ] ;
Json ( ApiResponse ::success ( repos ) )
}
/// POST /api/sources/repositories/:id/connect - Connect a repository
pub async fn handle_connect_repository (
State ( _state ) : State < Arc < AppState > > ,
Path ( id ) : Path < String > ,
) -> impl IntoResponse {
Json ( ApiResponse ::success ( format! ( " Repository {} connected " , id ) ) )
}
/// POST /api/sources/repositories/:id/disconnect - Disconnect a repository
pub async fn handle_disconnect_repository (
State ( _state ) : State < Arc < AppState > > ,
Path ( id ) : Path < String > ,
) -> impl IntoResponse {
Json ( ApiResponse ::success ( format! (
" Repository {} disconnected " ,
id
) ) )
}
// ============================================================================
// Apps Handlers
// ============================================================================
/// GET /api/sources/apps - List created apps
pub async fn handle_list_apps ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let apps : Vec < AppInfo > = vec! [ AppInfo {
id : " 1 " . to_string ( ) ,
name : " crm " . to_string ( ) ,
app_type : " htmx " . to_string ( ) ,
description : " Customer relationship management " . to_string ( ) ,
url : " /crm " . to_string ( ) ,
created_at : " 2024-01-10T14:00:00Z " . to_string ( ) ,
status : " active " . to_string ( ) ,
} ] ;
Json ( ApiResponse ::success ( apps ) )
}
// ============================================================================
// HTMX Tab Handlers
// ============================================================================
2025-12-02 21:09:43 -03:00
/// GET /api/sources/prompts - Prompts tab content
pub async fn handle_prompts (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < SearchQuery > ,
) -> impl IntoResponse {
let category = params . category . unwrap_or_else ( | | " all " . to_string ( ) ) ;
let prompts = get_prompts_data ( & category ) ;
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" panel-layout \" > " ) ;
html . push_str ( " <aside class= \" categories-sidebar \" > " ) ;
html . push_str ( " <h3>Categories</h3> " ) ;
html . push_str ( " <div class= \" category-list \" > " ) ;
let categories = vec! [
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
( " all " , " All Prompts " , " 📋 " ) ,
( " writing " , " Writing " , " ✍️ " ) ,
( " coding " , " Coding " , " 💻 " ) ,
( " analysis " , " Analysis " , " 📊 " ) ,
( " creative " , " Creative " , " 🎨 " ) ,
( " business " , " Business " , " 💼 " ) ,
( " education " , " Education " , " 📚 " ) ,
2025-12-02 21:09:43 -03:00
] ;
for ( id , name , icon ) in & categories {
let active = if * id = = category { " active " } else { " " } ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <button class= \" category-item{} \" hx-get= \" /api/sources/prompts?category={} \" hx-target= \" #content-area \" hx-swap= \" innerHTML \" ><span class= \" category-icon \" >{}</span><span class= \" category-name \" >{}</span></button> " ,
active , id , icon , name
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></aside> " ) ;
html . push_str ( " <div class= \" content-main \" ><div class= \" prompts-grid \" id= \" prompts-grid \" > " ) ;
2025-12-02 21:09:43 -03:00
for prompt in & prompts {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <div class= \" prompt-card \" ><div class= \" prompt-header \" ><span class= \" prompt-icon \" >{}</span><h4>{}</h4></div><p class= \" prompt-description \" >{}</p><div class= \" prompt-footer \" ><span class= \" prompt-category \" >{}</span><button class= \" btn-use \" onclick= \" usePrompt('{}') \" >Use</button></div></div> " ,
prompt . icon , html_escape ( & prompt . title ) , html_escape ( & prompt . description ) , html_escape ( & prompt . category ) , html_escape ( & prompt . id )
) ) ;
2025-12-02 21:09:43 -03:00
}
if prompts . is_empty ( ) {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <div class= \" empty-state \" ><p>No prompts found in this category</p></div> " ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
/// GET /api/sources/templates - Templates tab content
pub async fn handle_templates ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let templates = get_templates_data ( ) ;
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" templates-container \" > " ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <div class= \" templates-header \" ><h3>Bot Templates</h3><p>Pre-built bot configurations ready to deploy</p></div> " ) ;
2025-12-02 21:09:43 -03:00
html . push_str ( " <div class= \" templates-grid \" > " ) ;
for template in & templates {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <div class= \" template-card \" ><div class= \" template-icon \" >{}</div><div class= \" template-info \" ><h4>{}</h4><p>{}</p><div class= \" template-meta \" ><span class= \" template-category \" >{}</span></div></div><div class= \" template-actions \" ><button class= \" btn-preview \" >Preview</button><button class= \" btn-use-template \" >Use Template</button></div></div> " ,
template . icon , html_escape ( & template . name ) , html_escape ( & template . description ) , html_escape ( & template . category )
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
/// GET /api/sources/news - News tab content
pub async fn handle_news ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let news_items = vec! [
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
(
" 📢 " ,
" General Bots 6.0 Released " ,
" Major update with improved performance and new features " ,
" 2 hours ago " ,
) ,
(
" 🔌 " ,
" New MCP Server Integration " ,
" Connect to external tools more easily with our new MCP support " ,
" 1 day ago " ,
) ,
(
" 📊 " ,
" Analytics Dashboard Update " ,
" Real-time metrics and improved visualizations " ,
" 3 days ago " ,
) ,
(
" 🔒 " ,
" Security Enhancement " ,
" Enhanced encryption and authentication options " ,
" 1 week ago " ,
) ,
2025-12-02 21:09:43 -03:00
] ;
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" news-container \" > " ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <div class= \" news-header \" ><h3>Latest News</h3><p>Updates and announcements from the General Bots team</p></div> " ) ;
2025-12-02 21:09:43 -03:00
html . push_str ( " <div class= \" news-list \" > " ) ;
for ( icon , title , description , time ) in & news_items {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <div class= \" news-item \" ><div class= \" news-icon \" >{}</div><div class= \" news-content \" ><h4>{}</h4><p>{}</p><span class= \" news-time \" >{}</span></div></div> " ,
icon , html_escape ( title ) , html_escape ( description ) , time
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
/// GET /api/sources/mcp-servers - MCP Servers tab content (HTMX)
pub async fn handle_mcp_servers (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let scan_result = loader . load ( ) ;
2025-12-02 21:09:43 -03:00
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" mcp-container \" > " ) ;
html . push_str ( " <div class= \" mcp-header \" > " ) ;
html . push_str ( " <h3>MCP Servers</h3> " ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <p>Model Context Protocol servers extend your bot's capabilities. Configure servers in <code>mcp.csv</code>.</p> " ) ;
html . push_str ( " <div class= \" mcp-header-actions \" > " ) ;
html . push_str ( " <button class= \" btn-scan \" hx-post= \" /api/sources/mcp/scan \" hx-target= \" #mcp-grid \" hx-swap= \" innerHTML \" >🔄 Reload</button> " ) ;
html . push_str (
" <button class= \" btn-add-server \" onclick= \" showAddMcpModal() \" >+ Add Server</button> " ,
) ;
html . push_str ( " </div></div> " ) ;
html . push_str ( & format! (
" <div class= \" mcp-directory-info \" ><span class= \" label \" >MCP Config:</span><code>{}</code>{}</div> " ,
scan_result . file_path . to_string_lossy ( ) ,
if ! loader . csv_exists ( ) { " <span class= \" badge badge-warning \" >Not Found</span> " } else { " " }
) ) ;
html . push_str ( " <div class= \" mcp-grid \" id= \" mcp-grid \" > " ) ;
if scan_result . servers . is_empty ( ) {
html . push_str ( " <div class= \" empty-state \" ><div class= \" empty-icon \" >🔌</div><h4>No MCP Servers Found</h4><p>Add MCP server configuration files to your <code>.gbmcp</code> directory.</p></div> " ) ;
} else {
for server in & scan_result . servers {
let is_active = matches! (
server . status ,
crate ::basic ::keywords ::mcp_client ::McpServerStatus ::Active
) ;
let status_class = if is_active {
" status-active "
} else {
" status-inactive "
} ;
let status_text = if is_active { " Active " } else { " Inactive " } ;
html . push_str ( & format! (
" <div class= \" mcp-card \" ><div class= \" mcp-card-header \" ><div class= \" mcp-icon \" >{}</div><div class= \" mcp-title \" ><h4>{}</h4><span class= \" mcp-type \" >{}</span></div><div class= \" mcp-status {} \" >{}</div></div><p class= \" mcp-description \" >{}</p><div class= \" mcp-tools-count \" ><span class= \" tools-badge \" >{} tools</span></div><div class= \" mcp-actions \" ><button class= \" btn-test \" hx-post= \" /api/sources/mcp/{}/test \" >Test</button></div></div> " ,
mcp ::get_server_type_icon ( & server . server_type . to_string ( ) ) ,
html_escape ( & server . name ) ,
server . server_type . to_string ( ) ,
status_class ,
status_text ,
if server . description . is_empty ( ) { " <em>No description</em> " . to_string ( ) } else { html_escape ( & server . description ) } ,
server . tools . len ( ) ,
html_escape ( & server . name )
) ) ;
2025-12-02 21:09:43 -03:00
}
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
/// GET /api/sources/llm-tools - LLM Tools tab content
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
pub async fn handle_llm_tools (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < BotQuery > ,
) -> impl IntoResponse {
let bot_id = params . bot_id . unwrap_or_else ( | | " default " . to_string ( ) ) ;
let work_path = std ::env ::var ( " WORK_PATH " ) . unwrap_or_else ( | _ | " ./work " . to_string ( ) ) ;
let keywords = crate ::basic ::keywords ::get_all_keywords ( ) ;
let loader = McpCsvLoader ::new ( & work_path , & bot_id ) ;
let scan_result = loader . load ( ) ;
let mcp_tools_count : usize = scan_result . servers . iter ( ) . map ( | s | s . tools . len ( ) ) . sum ( ) ;
2025-12-02 21:09:43 -03:00
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" tools-container \" > " ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <div class= \" tools-header \" ><h3>LLM Tools</h3><p>All tools available for Tasks and LLM invocation</p><div class= \" tools-stats \" ><span class= \" stat \" ><strong>{}</strong> BASIC keywords</span><span class= \" stat \" ><strong>{}</strong> MCP tools</span></div></div> " ,
keywords . len ( ) , mcp_tools_count
) ) ;
2025-12-02 21:09:43 -03:00
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <div class= \" tools-grid \" > " ) ;
for keyword in keywords . iter ( ) . take ( 20 ) {
html . push_str ( & format! (
" <span class= \" keyword-tag \" >{}</span> " ,
html_escape ( keyword )
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
if keywords . len ( ) > 20 {
html . push_str ( & format! (
" <span class= \" keyword-more \" >+{} more...</span> " ,
keywords . len ( ) - 20
) ) ;
}
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
/// GET /api/sources/models - Models tab content
pub async fn handle_models ( State ( _state ) : State < Arc < AppState > > ) -> impl IntoResponse {
let models = vec! [
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
(
" 🧠 " ,
" GPT-4o " ,
" OpenAI " ,
" Latest multimodal model " ,
" Active " ,
) ,
(
" 🧠 " ,
" GPT-4o-mini " ,
" OpenAI " ,
" Fast and efficient " ,
" Active " ,
) ,
(
" 🦙 " ,
" Llama 3.1 70B " ,
" Meta " ,
" Open source LLM " ,
" Available " ,
) ,
(
" 🔷 " ,
" Claude 3.5 Sonnet " ,
" Anthropic " ,
" Advanced reasoning " ,
" Available " ,
) ,
2025-12-02 21:09:43 -03:00
] ;
let mut html = String ::new ( ) ;
html . push_str ( " <div class= \" models-container \" > " ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " <div class= \" models-header \" ><h3>AI Models</h3><p>Available language models for your bots</p></div> " ) ;
2025-12-02 21:09:43 -03:00
html . push_str ( " <div class= \" models-grid \" > " ) ;
for ( icon , name , provider , description , status ) in & models {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
let status_class = if * status = = " Active " {
" model-active "
2025-12-02 21:09:43 -03:00
} else {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
" model-available "
} ;
html . push_str ( & format! (
" <div class= \" model-card {} \" ><div class= \" model-icon \" >{}</div><div class= \" model-info \" ><div class= \" model-header \" ><h4>{}</h4><span class= \" model-provider \" >{}</span></div><p>{}</p><div class= \" model-footer \" ><span class= \" model-status \" >{}</span></div></div></div> " ,
status_class , icon , html_escape ( name ) , html_escape ( provider ) , html_escape ( description ) , status
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
Html ( html )
}
/// GET /api/sources/search - Search across all sources
pub async fn handle_search (
State ( _state ) : State < Arc < AppState > > ,
Query ( params ) : Query < SearchQuery > ,
) -> impl IntoResponse {
let query = params . q . unwrap_or_default ( ) ;
if query . is_empty ( ) {
return Html ( " <div class= \" search-prompt \" ><p>Enter a search term</p></div> " . to_string ( ) ) ;
}
let query_lower = query . to_lowercase ( ) ;
let prompts = get_prompts_data ( " all " ) ;
let matching_prompts : Vec < _ > = prompts
. iter ( )
. filter ( | p | {
p . title . to_lowercase ( ) . contains ( & query_lower )
| | p . description . to_lowercase ( ) . contains ( & query_lower )
} )
. collect ( ) ;
let mut html = String ::new ( ) ;
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! ( " <div class= \" search-results \" ><div class= \" search-header \" ><h3>Search Results for \" {} \" </h3></div> " , html_escape ( & query ) ) ) ;
2025-12-02 21:09:43 -03:00
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
if matching_prompts . is_empty ( ) {
html . push_str ( " <div class= \" no-results \" ><p>No results found</p></div> " ) ;
2025-12-02 21:09:43 -03:00
} else {
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( & format! (
" <div class= \" result-section \" ><h4>Prompts ({})</h4><div class= \" results-grid \" > " ,
matching_prompts . len ( )
) ) ;
for prompt in matching_prompts {
html . push_str ( & format! (
" <div class= \" result-item \" ><span class= \" result-icon \" >{}</span><div class= \" result-info \" ><strong>{}</strong><p>{}</p></div></div> " ,
prompt . icon , html_escape ( & prompt . title ) , html_escape ( & prompt . description )
) ) ;
2025-12-02 21:09:43 -03:00
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
html . push_str ( " </div></div> " ) ;
2025-12-02 21:09:43 -03:00
}
html . push_str ( " </div> " ) ;
Html ( html )
}
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
// ============================================================================
// Helper Functions and Data
// ============================================================================
2025-12-02 21:09:43 -03:00
struct PromptData {
id : String ,
title : String ,
description : String ,
category : String ,
icon : String ,
}
struct TemplateData {
name : String ,
description : String ,
category : String ,
icon : String ,
}
fn get_prompts_data ( category : & str ) -> Vec < PromptData > {
let all_prompts = vec! [
PromptData {
id : " summarize " . to_string ( ) ,
title : " Summarize Text " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Create concise summaries of long documents " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " writing " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 📝 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
PromptData {
id : " code-review " . to_string ( ) ,
title : " Code Review " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Analyze code for bugs and improvements " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " coding " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 🔍 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
PromptData {
id : " data-analysis " . to_string ( ) ,
title : " Data Analysis " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Extract insights from data sets " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " analysis " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 📊 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
PromptData {
id : " creative-writing " . to_string ( ) ,
title : " Creative Writing " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Generate stories and creative content " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " creative " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 🎨 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
PromptData {
id : " email-draft " . to_string ( ) ,
title : " Email Draft " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Compose professional emails " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " business " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 📧 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
] ;
if category = = " all " {
all_prompts
} else {
all_prompts
. into_iter ( )
. filter ( | p | p . category = = category )
. collect ( )
}
}
fn get_templates_data ( ) -> Vec < TemplateData > {
vec! [
TemplateData {
name : " Customer Support Bot " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Handle customer inquiries automatically " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " Support " . to_string ( ) ,
icon : " 🎧 " . to_string ( ) ,
} ,
TemplateData {
name : " FAQ Bot " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Answer frequently asked questions " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " Support " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " ❓ " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
TemplateData {
name : " Lead Generation Bot " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
description : " Qualify leads and collect information " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
category : " Sales " . to_string ( ) ,
Add MCP server support via mcp.csv
- New mcp_directory.rs: McpCsvLoader to load MCP servers from mcp.csv
- CSV format: name,type,command,args,description,enabled,auth_type,auth_env
- Support for stdio, http, websocket, tcp connection types
- Support for api_key and bearer authentication
- Updated sources/mod.rs with MCP management API endpoints
- New sources/mcp.rs with helper functions
- MCP tools available to Tasks like BASIC keywords
2025-12-13 00:26:49 -03:00
icon : " 🎯 " . to_string ( ) ,
2025-12-02 21:09:43 -03:00
} ,
]
}
fn html_escape ( s : & str ) -> String {
s . replace ( '&' , " & " )
. replace ( '<' , " < " )
. replace ( '>' , " > " )
. replace ( '"' , " " " )
. replace ( '\'' , " ' " )
}