Skip to main content
Glama
xplainable

Xplainable MCP Server

Official
by xplainable
cli.py9.26 kB
#!/usr/bin/env python """ CLI utilities for the Xplainable MCP Server. Provides commands for: - Generating tool documentation - Validating configuration - Testing connectivity """ import argparse import json import sys import os from pathlib import Path def cmd_list_tools(args): """List all available tools.""" try: from xplainable_mcp.tool_discovery import get_modular_tools_registry discovery = get_modular_tools_registry() tools = discovery.discovered_tools if args.format == "json": # Create JSON-serializable data tools_data = { "summary": discovery.get_summary(), "tools": {name: { "name": tool.name, "description": tool.description, "category": tool.category, "module": tool.module, "parameters": tool.parameters, "enabled": tool.enabled } for name, tool in tools.items()} } print(json.dumps(tools_data, indent=2)) elif args.format == "markdown": print(discovery.generate_markdown_docs()) else: # table format summary = discovery.get_summary() tools_by_category = discovery.get_tools_by_category() print(f"\nXplainable MCP Server - Available Tools") print(f"=" * 60) print(f"Total Tools: {summary['total_tools']}") print(f"Enabled Tools: {summary['enabled_tools']}") print(f"Services: {', '.join(summary['services'])}") print(f"\nTools by Category:") print(f"-" * 60) for category, category_tools in tools_by_category.items(): print(f"\n{category.upper()} ({len(category_tools)} tools):") for tool in sorted(category_tools, key=lambda t: t.name): enabled = "✓" if tool.enabled else "✗" print(f" [{enabled}] {tool.name} ({tool.module}): {tool.description}") print(f"\n" + "=" * 60) print(f"Category Summary:") for category, count in summary['categories'].items(): print(f" {category.title()}: {count}") except Exception as e: print(f"Error listing tools: {e}", file=sys.stderr) return 1 return 0 def cmd_validate_config(args): """Validate configuration.""" try: from dotenv import load_dotenv from xplainable_mcp.server import ServerConfig # Load environment if args.env_file: load_dotenv(args.env_file) else: load_dotenv() # Check required variables issues = [] api_key = os.getenv("XPLAINABLE_API_KEY") if not api_key: issues.append("XPLAINABLE_API_KEY is not set") elif api_key == "your-api-key-here": issues.append("XPLAINABLE_API_KEY has not been configured (still using example value)") # Try to create config try: config = ServerConfig( api_key=api_key or "dummy", hostname=os.getenv("XPLAINABLE_HOST", "https://platform.xplainable.io"), org_id=os.getenv("XPLAINABLE_ORG_ID"), team_id=os.getenv("XPLAINABLE_TEAM_ID"), enable_write_tools=os.getenv("ENABLE_WRITE_TOOLS", "false").lower() == "true", rate_limit_enabled=os.getenv("RATE_LIMIT_ENABLED", "true").lower() == "true", ) print("Configuration Summary:") print(f" Hostname: {config.hostname}") print(f" Organization ID: {config.org_id or 'Not set'}") print(f" Team ID: {config.team_id or 'Not set'}") print(f" Write Tools: {'Enabled' if config.enable_write_tools else 'Disabled'}") print(f" Rate Limiting: {'Enabled' if config.rate_limit_enabled else 'Disabled'}") except Exception as e: issues.append(f"Failed to create configuration: {e}") if issues: print("\nConfiguration Issues Found:") for issue in issues: print(f" ❌ {issue}") return 1 else: print("\n✅ Configuration is valid") return 0 except Exception as e: print(f"Error validating configuration: {e}", file=sys.stderr) return 1 def cmd_test_connection(args): """Test connection to Xplainable API.""" try: from dotenv import load_dotenv # Load environment if args.env_file: load_dotenv(args.env_file) else: load_dotenv() api_key = os.getenv("XPLAINABLE_API_KEY") if not api_key: print("Error: XPLAINABLE_API_KEY not set", file=sys.stderr) return 1 print("Testing connection to Xplainable API...") try: from xplainable_client.client.client import XplainableClient client = XplainableClient( api_key=api_key, hostname=os.getenv("XPLAINABLE_HOST", "https://platform.xplainable.io"), org_id=os.getenv("XPLAINABLE_ORG_ID"), team_id=os.getenv("XPLAINABLE_TEAM_ID") ) # Test connection by getting version info info = client.misc.get_version_info() print("\n✅ Successfully connected to Xplainable API") print(f"\nConnection Details:") print(f" Username: {client.session.username}") print(f" Hostname: {client.session.hostname}") print(f" API Version: {info.model_dump().get('api_version', 'Unknown')}") return 0 except ImportError: print("Error: xplainable-client not installed", file=sys.stderr) print("Install with: pip install xplainable-client", file=sys.stderr) return 1 except Exception as e: print(f"❌ Connection failed: {e}", file=sys.stderr) return 1 except Exception as e: print(f"Error testing connection: {e}", file=sys.stderr) return 1 def cmd_generate_docs(args): """Generate documentation.""" try: from xplainable_mcp.tool_discovery import get_modular_tools_registry discovery = get_modular_tools_registry() docs = discovery.generate_markdown_docs() if args.output: output_path = Path(args.output) output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text(docs) print(f"✅ Documentation written to {args.output}") else: print(docs) return 0 except Exception as e: print(f"Error generating documentation: {e}", file=sys.stderr) return 1 def main(): """Main CLI entry point.""" parser = argparse.ArgumentParser( description="Xplainable MCP Server CLI", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: %(prog)s list-tools # List all available tools %(prog)s list-tools --format json # Output as JSON %(prog)s validate-config # Validate configuration %(prog)s test-connection # Test API connection %(prog)s generate-docs # Generate tool documentation """ ) subparsers = parser.add_subparsers(dest='command', help='Commands') # list-tools command list_parser = subparsers.add_parser('list-tools', help='List available MCP tools') list_parser.add_argument( '--format', choices=['table', 'json', 'markdown'], default='table', help='Output format (default: table)' ) # validate-config command validate_parser = subparsers.add_parser('validate-config', help='Validate server configuration') validate_parser.add_argument( '--env-file', help='Path to .env file (default: .env in current directory)' ) # test-connection command test_parser = subparsers.add_parser('test-connection', help='Test connection to Xplainable API') test_parser.add_argument( '--env-file', help='Path to .env file (default: .env in current directory)' ) # generate-docs command docs_parser = subparsers.add_parser('generate-docs', help='Generate tool documentation') docs_parser.add_argument( '--output', help='Output file path (default: stdout)' ) args = parser.parse_args() if not args.command: parser.print_help() return 1 # Route to appropriate command commands = { 'list-tools': cmd_list_tools, 'validate-config': cmd_validate_config, 'test-connection': cmd_test_connection, 'generate-docs': cmd_generate_docs, } return commands[args.command](args) if __name__ == '__main__': sys.exit(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xplainable/xplainable-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server