Skip to main content
Glama
by frap129
search_rule.py9.47 kB
"""Rule search tool using the repository pattern for caching. This module provides comprehensive D&D 5e game rules, conditions, and reference information with automatic database caching through the repository pattern. The repository abstracts away cache management and handles multi-type rule routing. Architecture: - Uses RuleRepository for cache-aside pattern with rule-type routing - Repository manages Milvus cache automatically - Supports dependency injection for testing - Handles rule, condition, damage-type, skill, and other reference data filtering Examples: Default usage (automatically creates repository): conditions = await search_rule(rule_type="condition") skills = await search_rule(rule_type="skill", search="stealth") With custom repository (dependency injection): from lorekeeper_mcp.repositories.rule import RuleRepository from lorekeeper_mcp.cache.milvus import MilvusCache cache = MilvusCache(db_path="/path/to/cache.db") repository = RuleRepository(cache=cache) rules = await search_rule(rule_type="rule", repository=repository) Reference data queries: abilities = await search_rule(rule_type="ability-score") damage_types = await search_rule(rule_type="damage-type") alignments = await search_rule(rule_type="alignment")""" from typing import Any, Literal, cast from lorekeeper_mcp.repositories.factory import RepositoryFactory from lorekeeper_mcp.repositories.rule import RuleRepository _repository_context: dict[str, Any] = {} def _get_repository() -> RuleRepository: """Get rule repository, respecting test context. Returns the repository from _repository_context if set, otherwise creates a default RuleRepository using RepositoryFactory. Returns: RuleRepository instance for rule lookups. """ if "repository" in _repository_context: return cast(RuleRepository, _repository_context["repository"]) return RepositoryFactory.create_rule_repository() RuleType = Literal[ "rule", "condition", "damage-type", "weapon-property", "skill", "ability-score", "magic-school", "language", "proficiency", "alignment", ] async def search_rule( rule_type: RuleType, section: str | None = None, documents: list[str] | None = None, search: str | None = None, limit: int = 20, ) -> list[dict[str, Any]]: """ Look up D&D 5e game rules, conditions, and reference information. This comprehensive reference tool provides access to core rules, special conditions, damage types, skills, and game mechanics. Essential for resolving rules questions during play or character building. All data is sourced from official D&D 5e materials. Uses the repository pattern with database caching for improved performance. Examples: - search_rule(rule_type="condition", search="grappled") - Find grappled condition rules - search_rule(rule_type="skill", search="stealth") - Find stealth skill details - search_rule(rule_type="damage-type", search="fire") - Find fire damage rules - search_rule(rule_type="rule", section="combat") - Find all combat rules - search_rule(rule_type="ability-score") - Get all ability score info - search_rule(rule_type="alignment") - Find alignment descriptions - search_rule(rule_type="magic-school", search="evocation") - Find evocation school info - search_rule(rule_type="rule", documents=["srd-5e"]) - Find rules from SRD only - search_rule(rule_type="condition", search="grappled", documents=["srd-5e", "tce"]) - Filter conditions by documents Semantic search (natural language queries): - search_rule(rule_type="condition", search="movement restricted") - Find conditions affecting movement - search_rule(rule_type="damage-type", search="burning heat") - Find fire-related damage - search_rule(rule_type="skill", search="sneaking hiding") - Find stealth-related skills Hybrid search (search + filters): - search_rule(rule_type="condition", search="cannot see", documents=["srd-5e"]) - Find blindness/vision conditions Args: rule_type: **REQUIRED.** Type of game reference to lookup. Must be one of: - "rule": Core game rules and mechanics (combat, spellcasting, movement, etc.) - "condition": Status effects (grappled, stunned, poisoned, unconscious, etc.) - "damage-type": Damage categories (acid, bludgeoning, cold, fire, force, lightning, necrotic, piercing, poison, psychic, radiant, slashing, thunder) - "weapon-property": Weapon special properties (finesse, heavy, light, reach, two-handed, versatile, ammunition, loading, thrown, etc.) - "skill": Ability-based skills (Acrobatics, Animal Handling, Arcana, Athletics, Deception, History, Insight, Intimidation, Investigation, Medicine, Nature, Perception, Performance, Persuasion, Religion, Sleight of Hand, Stealth, Survival) - "ability-score": Core abilities (Strength, Dexterity, Constitution, Intelligence, Wisdom, Charisma) and their uses - "magic-school": Schools of magic (Abjuration, Conjuration, Divination, Enchantment, Evocation, Illusion, Necromancy, Transmutation) - "language": Languages available in D&D (Common, Dwarvish, Elvish, Giant, Gnomish, Goblin, Orc, Primordial, Sylvan, Undercommon, Celestial, Draconic, Deep Speech, Infernal) - "proficiency": Character proficiency types (armor, weapon, tool, saving throw, skill) - "alignment": Character alignment axes (Lawful/Chaotic, Good/Evil, Neutral options) section: For rule_type="rule" only. Filter rules by section/chapter. Examples: "combat", "spellcasting", "movement", "actions-in-combat" Ignored for other rule types. documents: Filter to specific source documents. Provide a list of document names/identifiers from list_documents() tool. Examples: ["srd-5e"] for SRD only, ["srd-5e", "tce"] for SRD and Tasha's. Use list_documents() to see available documents. search: Natural language search query for semantic/vector search. When provided, uses vector similarity to find rules matching the conceptual meaning rather than exact text matches. Can be combined with other filters for hybrid search. Examples: "movement restricted", "fire burning damage", "stealth hiding sneaking" limit: Maximum number of results to return. Default 20 for performance. Examples: 1, 10, 50 Returns: List of rule/reference dictionaries. Structure varies by rule_type: For rule_type="rule": - name: Rule name/title - desc: Full rule description and examples - section: Section/chapter this rule belongs to For rule_type="condition": - name: Condition name - desc: Effects and duration of this condition For rule_type="damage-type": - name: Damage type name - desc: Description of damage type and uses For rule_type="weapon-property": - name: Property name - desc: How the property affects weapon use For rule_type="skill": - name: Skill name - ability_score: Associated ability (STR, DEX, CON, INT, WIS, CHA) - desc: How skill is used and common checks For rule_type="ability-score": - name: Ability name - desc: What ability represents and how it's used - skills: Related skills For rule_type="magic-school": - name: School name - desc: Philosophy and types of spells in this school For rule_type="language": - name: Language name - type: Language type (common, exotic, etc.) - script: Writing system if any For rule_type="proficiency": - name: Proficiency type - class: What type of proficiency (class, background, race) - desc: Details about this proficiency type For rule_type="alignment": - name: Alignment - desc: Alignment description and common character types Raises: ValueError: If rule_type is not one of the valid options APIError: If the API request fails due to network issues or server errors """ valid_types = { "rule", "condition", "damage-type", "weapon-property", "skill", "ability-score", "magic-school", "language", "proficiency", "alignment", } if rule_type not in valid_types: raise ValueError( f"Invalid type '{rule_type}'. Must be one of: {', '.join(sorted(valid_types))}" ) repository = _get_repository() params: dict[str, Any] = {"rule_type": rule_type} if limit is not None: params["limit"] = limit if rule_type == "rule" and section is not None: params["section"] = section if documents is not None: params["document"] = documents if search is not None: params["search"] = search return await repository.search(**params)

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/frap129/lorekeeper-mcp'

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