Skip to main content
Glama

Dynamic Per-User Tool Generation MCP Server

client.py6.46 kB
""" Search Client High-level client for Elasticsearch entity searches. """ import logging import os from typing import Optional, List, Dict, Any from elasticsearch import Elasticsearch from elasticsearch_search_lib.query_builder import QueryBuilder from elasticsearch_search_lib.search_handler import SearchHandler from elasticsearch_search_lib.config.loader import ConfigLoader from elasticsearch_search_lib.models import SearchResponse, EntityConfig, FieldConfig from elasticsearch_search_lib.exceptions import ValidationError logger = logging.getLogger(__name__) class SearchClient: """ High-level client for entity searches. Provides a simple, intuitive API for searching ITSM entities in Elasticsearch. Example: >>> client = SearchClient(tenant_id="apolo") >>> results = await client.search("user", "john doe") >>> for item in results.items: ... print(item.data, item.score) """ def __init__( self, tenant_id: str, es_host: Optional[str] = None, es_port: int = 9200, config_path: Optional[str] = None, ): """ Initialize search client. Args: tenant_id: Tenant identifier for index naming es_host: Elasticsearch host (defaults to ES_HOST env var or 'localhost') es_port: Elasticsearch port (default: 9200) config_path: Path to configuration file (uses default if None) """ self.tenant_id = tenant_id self.es_host = es_host or os.getenv("ES_HOST", "localhost") self.es_port = es_port # Initialize components self.config_loader = ConfigLoader(config_path) self.query_builder = QueryBuilder(self.config_loader) # Create Elasticsearch client self.es_client = self._create_es_client() # Create search handler self.search_handler = SearchHandler( es_client=self.es_client, query_builder=self.query_builder, ) logger.info( f"SearchClient initialized for tenant '{tenant_id}' " f"with {len(self.get_supported_entities())} supported entity types" ) def _create_es_client(self) -> Elasticsearch: """Create Elasticsearch client.""" es_url = f"http://{self.es_host}:{self.es_port}" try: client = Elasticsearch( [es_url], request_timeout=30, max_retries=3, retry_on_timeout=True ) logger.info(f"Elasticsearch client created for {es_url}") return client except Exception as e: logger.warning(f"Failed to create Elasticsearch client: {e}") # Return a mock object for testing from unittest.mock import Mock return Mock() async def search( self, entity_type: str, query: str, limit: Optional[int] = None, from_offset: int = 0, ) -> SearchResponse: """ Search for entities. Args: entity_type: Type of entity to search (user, impact, etc.) query: Search query string limit: Maximum number of results (uses entity default if None) from_offset: Offset for pagination Returns: SearchResponse with results or error Example: >>> results = await client.search("user", "john doe", limit=10) >>> print(f"Found {results.total_hits} users") >>> for user in results.items: ... print(user.data['user_name'], user.score) """ return await self.search_handler.search( entity_type=entity_type, query=query, tenant_id=self.tenant_id, limit=limit, from_offset=from_offset, ) def get_supported_entities(self) -> List[str]: """ Get list of supported entity types. Returns: List of entity type names Example: >>> entities = client.get_supported_entities() >>> print(entities) ['impact', 'urgency', 'priority', 'status', ...] """ return self.query_builder.get_supported_entities() def get_entity_config(self, entity_type: str) -> EntityConfig: """ Get configuration for an entity type. Args: entity_type: Entity type name Returns: EntityConfig instance Example: >>> config = client.get_entity_config("user") >>> print(config.default_limit, config.max_limit) 10 100 """ return self.query_builder.get_entity_config(entity_type) def get_entity_fields(self, entity_type: str) -> List[FieldConfig]: """ Get enabled fields for an entity type. Args: entity_type: Entity type name Returns: List of FieldConfig instances Example: >>> fields = client.get_entity_fields("user") >>> for field in fields: ... print(field.name, field.boost, field.fuzziness) """ config = self.get_entity_config(entity_type) return config.get_enabled_fields() def is_entity_supported(self, entity_type: str) -> bool: """ Check if an entity type is supported. Args: entity_type: Entity type name Returns: True if entity is supported Example: >>> if client.is_entity_supported("user"): ... results = await client.search("user", "john") """ return self.query_builder.is_entity_supported(entity_type) def get_index_name(self, entity_type: str) -> str: """ Get Elasticsearch index name for an entity type. Args: entity_type: Entity type name Returns: Index name string Example: >>> index = client.get_index_name("user") >>> print(index) apolo_user """ return self.query_builder.get_index_name(entity_type, self.tenant_id)

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/ShivamPansuriya/MCP-server-Python'

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