use serde_json::json;
use std::time::Duration;
use liteforge::mcp::{
AuthConfig, McpConfig, McpServerConfig, McpTool, McpToolRegistry, McpToolWrapper,
ToolDiscoveryResult, TransportType,
};
use liteforge::tools::{Tool, ToolRegistry};
fn main() {
println!("=== LiteForge MCP Server Example ===\n");
println!("1. Creating MCP server configurations...\n");
let filesystem_server = McpServerConfig::stdio("filesystem", "npx")
.with_arg("-y")
.with_arg("@modelcontextprotocol/server-filesystem")
.with_arg("/tmp")
.with_timeout(Duration::from_secs(30))
.with_auto_reconnect(true);
println!(" Filesystem server (stdio):");
println!(" Name: {}", filesystem_server.name);
println!(" Transport: {}", filesystem_server.transport);
println!(" Command: {:?}", filesystem_server.command);
println!(" Args: {:?}", filesystem_server.args);
let remote_server = McpServerConfig::sse("remote-api", "https://api.example.com/mcp/sse")
.with_bearer_token("your-api-token")
.with_timeout(Duration::from_secs(60))
.with_max_reconnects(5);
println!("\n Remote API server (SSE):");
println!(" Name: {}", remote_server.name);
println!(" Transport: {}", remote_server.transport);
println!(" URL: {:?}", remote_server.url);
println!(" Auto-reconnect: {}", remote_server.auto_reconnect);
let http_server = McpServerConfig::http("rest-api", "https://api.example.com/mcp")
.with_timeout(Duration::from_secs(30));
println!("\n REST API server (HTTP):");
println!(" Name: {}", http_server.name);
println!(" Transport: {}", http_server.transport);
println!(" URL: {:?}", http_server.url);
let python_server = McpServerConfig::stdio("python-tools", "python")
.with_arg("-m")
.with_arg("mcp_server")
.with_env_var("PYTHONPATH", "/opt/mcp-tools")
.with_env_var("DEBUG", "1");
println!("\n Python tools server (stdio with env):");
println!(" Name: {}", python_server.name);
println!(" Args: {:?}", python_server.args);
println!(" Env vars: {:?}", python_server.env);
println!("\n2. Building MCP configuration...");
let mut config = McpConfig::new();
config.add_server(filesystem_server);
config.add_server(remote_server);
config.add_server(http_server);
config.add_server(python_server);
println!(" Configured servers: {:?}", config.server_names());
if let Some(fs_config) = config.get_server("filesystem") {
println!(
" Retrieved 'filesystem' config: transport={}",
fs_config.transport
);
}
println!("\n3. Creating MCP tool definitions...");
let read_file_tool = McpTool {
name: "read_file".to_string(),
description: Some("Read the contents of a file".to_string()),
input_schema: json!({
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to read"
}
},
"required": ["path"]
}),
};
let write_file_tool = McpTool {
name: "write_file".to_string(),
description: Some("Write content to a file".to_string()),
input_schema: json!({
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to write"
},
"content": {
"type": "string",
"description": "Content to write"
}
},
"required": ["path", "content"]
}),
};
let list_dir_tool = McpTool {
name: "list_directory".to_string(),
description: Some("List contents of a directory".to_string()),
input_schema: json!({
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Directory path"
}
},
"required": ["path"]
}),
};
for tool in [&read_file_tool, &write_file_tool, &list_dir_tool] {
println!(
" Tool: {} - {}",
tool.name,
tool.description.as_deref().unwrap_or("")
);
}
println!("\n4. Wrapping MCP tools for ToolRegistry...");
let wrapper =
McpToolWrapper::new(read_file_tool.clone(), "filesystem").with_executor(|params| {
Ok(liteforge::mcp::CallToolResult {
content: vec![liteforge::mcp::ToolResultContent::Text {
text: format!("Mock file contents for: {}", params.name),
}],
is_error: None,
})
});
println!(" Created wrapper for: {}", wrapper.name());
println!(" Server: {}", wrapper.server_name());
println!(" Description: {}", wrapper.description());
let result = wrapper.execute(json!({"path": "/tmp/test.txt"}));
println!(" Mock execution result: {:?}", result);
println!("\n5. Simulating tool discovery...");
let discovery_result = ToolDiscoveryResult::success(
"filesystem",
vec![read_file_tool, write_file_tool, list_dir_tool],
);
println!(
" Discovery from '{}' server:",
discovery_result.server_name
);
println!(" Success: {}", discovery_result.is_success());
println!(" Tools found: {}", discovery_result.tool_count());
for tool in &discovery_result.tools {
println!(" - {}", tool.name);
}
let failed_discovery =
ToolDiscoveryResult::failure("unavailable-server", "Connection timeout after 30 seconds");
println!(
"\n Discovery from '{}' server:",
failed_discovery.server_name
);
println!(" Success: {}", failed_discovery.is_success());
println!(" Errors: {:?}", failed_discovery.errors);
println!("\n6. Registering MCP tools with ToolRegistry...");
let mut registry = ToolRegistry::new();
let count = registry.register_mcp_tools(&discovery_result);
println!(" Registered {} tools from MCP server", count);
println!(" Registry contains: {:?}", registry.names());
let definitions = registry.definitions();
println!(
" {} tool definitions ready for LLM API",
definitions.len()
);
println!("\n7. Authentication options...");
let bearer_auth = AuthConfig::Bearer {
token: "secret-token-123".to_string(),
};
println!(" Bearer auth: {:?}", bearer_auth);
let api_key_auth = AuthConfig::ApiKey {
header: "X-API-Key".to_string(),
key: "my-api-key".to_string(),
};
println!(" API key auth: {:?}", api_key_auth);
let oauth_auth = AuthConfig::OAuth {
client_id: "my-client-id".to_string(),
client_secret: Some("my-secret".to_string()),
token_url: "https://auth.example.com/token".to_string(),
scopes: Some(vec!["read".to_string(), "write".to_string()]),
};
println!(
" OAuth2 auth: client_id={}",
match &oauth_auth {
AuthConfig::OAuth { client_id, .. } => client_id,
_ => "",
}
);
println!("\n8. Available transport types...");
println!(
" {} - Subprocess communication via stdin/stdout",
TransportType::Stdio
);
println!(
" {} - Server-Sent Events for real-time updates",
TransportType::Sse
);
println!(" {} - Standard HTTP/REST endpoints", TransportType::Http);
println!("\n=== Example Complete ===");
println!("\nNote: To actually use MCP servers, you would need:");
println!(" - An MCP server process (for stdio) or");
println!(" - An MCP server endpoint (for SSE/HTTP)");
println!(" - The mcp_server.run() or similar to start communication");
}