Skip to main content
Glama
service.py4.84 kB
"""Process service for retrieving and listing development processes. Provides business logic for process operations. """ from __future__ import annotations from typing import TYPE_CHECKING, Any from sso_mcp_server import get_logger from sso_mcp_server.processes.discovery import discover_processes from sso_mcp_server.processes.parser import normalize_name, parse_process_file if TYPE_CHECKING: from pathlib import Path _logger = get_logger("process_service") class ProcessService: """Service for managing development process operations. Provides methods to get, list, and search processes from the configured directory. """ def __init__(self, process_dir: Path) -> None: """Initialize the process service. Args: process_dir: Directory containing process markdown files. """ self._process_dir = process_dir _logger.debug("process_service_initialized", directory=str(process_dir)) def get_process(self, name: str) -> dict[str, Any] | None: """Get a process by name. Performs case-insensitive matching against process names (from frontmatter) and filenames (without extension). Args: name: Name of the process to retrieve. Returns: Dictionary with name, description, content, and path. Returns None if process not found. """ _logger.debug("getting_process", name=name) name_normalized = normalize_name(name) name_lower = name.lower() for file_path in discover_processes(self._process_dir): parsed = parse_process_file(file_path) if parsed is None: continue # Match by normalized name from frontmatter (case-insensitive) if parsed.get("normalized_name") == name_normalized: _logger.info("process_found", name=parsed["name"], path=str(file_path)) return parsed # Match by name from frontmatter (case-insensitive) if parsed["name"].lower() == name_lower: _logger.info("process_found_by_name", name=parsed["name"], path=str(file_path)) return parsed # Match by filename (without extension, case-insensitive) if file_path.stem.lower() == name_lower: _logger.info( "process_found_by_filename", name=parsed["name"], path=str(file_path), ) return parsed # Match by normalized filename if normalize_name(file_path.stem) == name_normalized: _logger.info( "process_found_by_normalized_filename", name=parsed["name"], path=str(file_path), ) return parsed _logger.debug("process_not_found", name=name) return None def list_processes(self) -> list[dict[str, Any]]: """List all available processes. Returns metadata (name, description) for all processes. Does NOT include full content. Returns: List of dictionaries with name and description for each process. """ _logger.debug("listing_processes") processes = [] for file_path in discover_processes(self._process_dir): parsed = parse_process_file(file_path) if parsed is None: continue # Return metadata only, not content processes.append( { "name": parsed["name"], "description": parsed.get("description", ""), } ) _logger.info("processes_listed", count=len(processes)) return processes def get_available_names(self) -> list[str]: """Get list of available process names. Useful for error messages when a process is not found (FR-015). Returns: List of process names. """ processes = self.list_processes() return [p["name"] for p in processes] def search_processes(self, query: str) -> list[dict[str, Any]]: """Search processes by keyword. Searches across process name, description, and content. Results are ordered by relevance. Args: query: Search keyword or phrase. Returns: List of search results with name, description, relevance_score, and snippet. """ from sso_mcp_server.processes.search import SearchEngine _logger.debug("searching_processes", query=query) engine = SearchEngine(self) results = engine.search(query) _logger.info("search_completed", query=query, result_count=len(results)) return results

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/DauQuangThanh/sso-mcp-server'

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