Skip to main content
Glama
by frap129
tools.md22.3 kB
# LoreKeeper MCP Tools Specification This document defines the MCP tools for LoreKeeper, organized by domain. ## API Assignment Strategy - **Use Open5e API** for all content lookups - **Prefer Open5e v2** over v1 when available - **Unified source**: Single API ensures consistent behavior and simplified maintenance --- ## Semantic Search LoreKeeper supports **semantic search** for finding content by meaning rather than exact text matches. This is powered by the Milvus Lite cache backend with sentence-transformers embeddings. ### Overview All search tools accept an optional `search` parameter: ```python # Find spells conceptually related to "fire damage" spells = await search_spell(search="explosive fire damage") # Combine semantic search with filters fire_spells = await search_spell( search="area of effect fire damage", level=3, school="evocation" ) ``` ### How It Works 1. Your natural language query is converted to a 384-dimensional embedding vector 2. The vector is compared against all cached entity embeddings using cosine similarity 3. Results are ranked by semantic similarity (highest first) 4. Optional filters (level, type, etc.) are applied as constraints ### Semantic Search Examples #### Spells by Concept ```python # Find healing spells without knowing exact names healing = await search_spell(search="restore health and cure wounds") # Returns: Cure Wounds, Healing Word, Mass Cure Wounds, etc. # Find crowd control spells control = await search_spell(search="stop enemies from moving or acting") # Returns: Hold Person, Web, Entangle, etc. # Find protective magic protection = await search_spell(search="shield and protect allies from harm") # Returns: Shield, Shield of Faith, Protection from Evil and Good, etc. # Find spells by damage type (without using damage_type filter) lightning = await search_spell(search="electricity and lightning damage") # Returns: Lightning Bolt, Call Lightning, Witch Bolt, etc. ``` #### Creatures by Behavior ```python # Find flying enemies flyers = await search_creature(search="creatures that fly and attack from above") # Returns: Dragon, Wyvern, Harpy, etc. # Find undead by theme undead = await search_creature(search="risen dead that drain life force") # Returns: Wraith, Specter, Vampire, etc. # Find ambush predators ambushers = await search_creature(search="stealthy hunters that attack by surprise") # Returns: Assassin, Displacer Beast, Invisible Stalker, etc. ``` #### Equipment by Use Case ```python # Find ranged weapons ranged = await search_equipment( search="weapons for attacking from a distance", type="weapon" ) # Returns: Longbow, Crossbow, Javelin, etc. # Find defensive gear defensive = await search_equipment( search="armor and shields for protection" ) # Returns: Plate Armor, Shield, Chain Mail, etc. # Find magical utility items utility = await search_equipment( search="magic items for utility and exploration", type="magic-item" ) # Returns: Bag of Holding, Rope of Climbing, Decanter of Endless Water, etc. ``` #### Hybrid Search (Semantic + Filters) Combine semantic queries with structured filters for precise results: ```python # Low-level fire spells low_fire = await search_spell( search="fire and burning damage", level=1, limit=5 ) # Undead under CR 5 weak_undead = await search_creature( search="undead creatures", cr_max=5, type="undead" ) # Rare magic weapons rare_weapons = await search_equipment( search="magical swords and blades", type="magic-item", rarity="rare" ) # SRD-only results srd_healing = await search_spell( search="healing magic", documents=["srd-5e"] ) ``` ### Similarity Scores Semantic search results include a `_score` field (0.0 to 1.0): ```python results = await search_spell(search="fire explosion") for spell in results[:3]: print(f"{spell['name']}: {spell.get('_score', 0):.3f}") # Output: # Fireball: 0.892 # Fire Storm: 0.834 # Flame Strike: 0.789 ``` ### When to Use Semantic Search **Use semantic search when:** - You don't know exact names or terminology - You want conceptually related results - Natural language queries feel more intuitive - You're exploring content by theme or use case **Use structured filters when:** - You know the exact spell level, CR, or type - You need precise filtering (e.g., all level 3 evocation spells) - Performance is critical (filters are faster than semantic search) ### Backend Requirements Semantic search requires the **Milvus Lite** cache backend (the only supported backend). --- ## Document Filtering ### Overview All LoreKeeper search tools support filtering content by source document. This enables precise control over which sources you query, allowing you to: - **Limit searches to SRD (free) content only** - Use only freely available System Reference Document content - **Filter by specific published books** - Query only content from "Tasha's Cauldron of Everything", "Xanathar's Guide", etc. - **Separate homebrew from official content** - Filter imported OrcBrew content separately from published books - **Control licensing** - Respect licensing requirements by limiting queries to appropriate sources ### Available Documents Use `list_documents()` to discover what's available in your cache: ```python # List all available documents documents = await list_documents() # Returns list with document names, sources, entity counts, etc. # List only Open5e documents open5e_docs = await list_documents(source="open5e_v2") # List only OrcBrew homebrew imports homebrew_docs = await list_documents(source="orcbrew") ``` Each document in the results contains: - `document`: The document name/identifier (use this in `documents`) - `source_api`: Which source provided this (open5e_v2, orcbrew) - `entity_count`: Total number of entities from this document - `entity_types`: Breakdown by type (spells, creatures, equipment, etc.) - `publisher`: Publisher name (Open5e documents) - `license`: License type (Open5e documents) ### Using Document Filters #### In Lookup Tools All search tools (`search_spell`, `search_creature`, `search_character_option`, `search_equipment`, `search_rule`) accept a `documents` parameter: ```python # Filter to SRD only srd_spells = await search_spell(level=3, documents=["srd-5e"]) # Filter to multiple documents multi_source = await search_creature( type="dragon", documents=["srd-5e", "tce", "phb"] ) # Complex filtering with multiple parameters wizard_evocations = await search_spell( class_key="wizard", school="evocation", level_min=1, level_max=5, documents=["srd-5e", "xgte"] ) # Equipment filtering by source plate_armor = await search_equipment( type="armor", search="plate", documents=["srd-5e"] ) # Character options from specific books tasha_feats = await search_character_option( type="feat", documents=["tce"] # Tasha's Cauldron of Everything ) ``` #### In Search Tool The `search_all()` tool also supports document filtering: ```python # Search spells in SRD only srd_results = await search_all( query="fireball", documents=["srd-5e"] ) # Search across multiple books published_results = await search_all( query="dragon", documents=["srd-5e", "tce", "xgte"] ) # General search with no filter (all documents) all_results = await search_all(query="magic item") ``` ### Common Document Keys Here are frequently-used document identifiers (use output from `list_documents()` for exact names): **Official D&D 5e SRD**: - `"srd-5e"` or `"System Reference Document 5.1"` - Core rules **Published Supplements** (examples - use `list_documents()` for current list): - `"phb"` - Player's Handbook - `"dmg"` - Dungeon Master's Guide - `"mm"` - Monster Manual - `"tce"` - Tasha's Cauldron of Everything - `"xgte"` - Xanathar's Guide to Everything - `"vrgr"` - Van Richten's Guide to Ravenloft **Homebrew**: - Document names from imported OrcBrew files (e.g., `"Homebrew Grimoire"`) ### Cross-Source Filtering Examples #### SRD-Only Content Get only free, System Reference Document content: ```python # Only SRD spells srd_spells = await search_spell(documents=["srd-5e"]) # Only SRD creatures up to CR 5 srd_creatures = await search_creature( cr_max=5, documents=["srd-5e"] ) # Only SRD equipment srd_gear = await search_equipment(documents=["srd-5e"]) ``` #### Published Books Only Get only officially published content (excluding homebrew): ```python published = await search_spell( school="evocation", documents=[ "srd-5e", "phb", "tce", "xgte", "vrgr", "dmg", "mm" ] ) ``` #### Specific Supplement Query a specific book without mixing sources: ```python # Only Tasha's content tasha_content = await search_character_option( type="feat", documents=["tce"] ) # Only Xanathar's Guide xgte_content = await search_spell( school="evocation", documents=["xgte"] ) ``` #### Homebrew Only Isolate homebrew content from official sources: ```python # First, identify homebrew documents docs = await list_documents(source="orcbrew") homebrew_keys = [d["document"] for d in docs] # Query only homebrew homebrew_creatures = await search_creature( documents=homebrew_keys ) ``` #### Exclude Specific Sources Query everything except a particular document: ```python # Note: LoreKeeper doesn't have explicit exclusion, so: # 1. Get all documents all_docs = await list_documents() # 2. Filter out ones you don't want all_keys = [d["document"] for d in all_docs] excluded = "homebrew-grimoire" filtered_keys = [k for k in all_keys if excluded not in k.lower()] # 3. Query with remaining documents results = await search_spell(documents=filtered_keys) ``` ### Performance Notes - **Indexed Queries**: The `document` field has a database index, making filtering efficient - **Combined Filters**: Document filters combine efficiently with other parameters (level, type, etc.) - **Empty Results**: Filtering may return fewer results if few entities exist in selected documents - **Backward Compatible**: The `documents` parameter is optional; omitting it queries all documents ### Implementation Details - **Document Keys**: Use exact names from `list_documents()` output - **Case Sensitive**: Document names are case-sensitive - **Multiple Documents**: Pass a list to filter across multiple documents (OR logic) - **Empty List**: Passing an empty `documents=[]` returns no results (short-circuit) --- ## Tool 1: `search_spell` **Purpose**: Search and retrieve spell information **API**: Open5e `/v2/spells/` (primary, comprehensive) **Parameters**: - `search` (string, optional): Natural language search query for semantic/vector search - `level` (integer, optional): Spell level (0-9, cantrips are 0) - `school` (string, optional): Magic school name (e.g., "evocation", "abjuration") - `class_key` (string, optional): Filter by class key (e.g., "wizard", "cleric") - `concentration` (boolean, optional): Only concentration spells - `ritual` (boolean, optional): Only ritual spells - `casting_time` (string, optional): Casting time (e.g., "action", "1 Minute", "Reaction") - `limit` (integer, optional, default=20): Maximum results to return **Available Values**: - **Schools**: abjuration, conjuration, divination, enchantment, evocation, illusion, necromancy, transmutation - **Casting Times**: Reaction, 1 Bonus Action, 1 Action, 1 Turn, 1 Round, 1 Minute, 5 Minutes, 10 Minutes, 1 Hour, etc. **Returns**: List of spells with: - Name, level, school - Components (V/S/M), material details, cost - Casting time, range, duration - Concentration requirement - Description, higher level effects - Classes that can cast it - Damage roll (if applicable) - Saving throw ability (if applicable) **Example Queries**: - "What does Fireball do?" → `search="fireball"` - "Show me 3rd level wizard evocation spells" → `level=3, class_key="wizard", school="evocation"` - "Find all concentration spells" → `concentration=true` --- ## Tool 2: `search_creature` **Purpose**: Search and retrieve monster/creature stat blocks **API**: Open5e `/v1/monsters/` (most comprehensive monster database) **Parameters**: - `search` (string, optional): Natural language search query for semantic/vector search - `cr` (float, optional): Challenge rating (supports 0.125, 0.25, 0.5, 1-30) - `cr_min` (float, optional): Minimum CR (for range searches) - `cr_max` (float, optional): Maximum CR (for range searches) - `type` (string, optional): Creature type - `size` (string, optional): Size category - `limit` (integer, optional, default=20): Maximum results to return **Available Values**: - **Types**: aberration, beast, celestial, construct, dragon, elemental, fey, fiend, giant, humanoid, monstrosity, ooze, plant, undead - **Sizes**: Tiny, Small, Medium, Large, Huge, Gargantuan **Returns**: Full stat blocks including: - Basic stats (AC, HP, speed, abilities) - Saving throws, skills, proficiencies - Damage vulnerabilities, resistances, immunities - Condition immunities - Senses, languages - Challenge rating - Special abilities, traits - Actions, bonus actions, reactions - Legendary actions (if applicable) - Lair actions (if applicable) **Example Queries**: - "Find CR 5 undead creatures" → `cr=5, type="undead"` - "Show me the Ancient Red Dragon" → `search="ancient red dragon"` - "Medium beasts CR 1 or less" → `cr_max=1, type="beast", size="Medium"` --- ## Tool 3: `search_character_option` **Purpose**: Get character creation and advancement options **API Coverage**: - **Classes**: Open5e `/v1/classes/` (includes subclasses/archetypes) - **Races**: Open5e `/v1/races/` (includes subraces) - **Backgrounds**: Open5e `/v2/backgrounds/` - **Feats**: Open5e `/v2/feats/` **Parameters**: - `type` (string, required): One of: `class`, `race`, `background`, `feat` - `search` (string, optional): Natural language search query for semantic/vector search - `limit` (integer, optional, default=20): Maximum results to return **Returns by Type**: **Classes**: - Hit dice, HP progression - Proficiencies (armor, weapons, tools, saving throws, skills) - Starting equipment - Class features table - Subclasses/archetypes with full descriptions - Spellcasting ability (if applicable) **Races**: - Ability score increases - Age, alignment, size - Speed - Languages - Darkvision and other senses - Racial traits - Subraces (if applicable) **Backgrounds**: - Skill proficiencies - Tool proficiencies - Languages - Equipment - Special features - Suggested characteristics **Feats**: - Prerequisites - Benefits - Type (GENERAL, etc.) **Example Queries**: - "What features does a Paladin get?" → `type="class", search="paladin"` - "Show me the Eldritch Knight" → `type="class", search="eldritch knight"` - "What traits do Half-Elves have?" → `type="race", search="half-elf"` - "Find the Sharpshooter feat" → `type="feat", search="sharpshooter"` --- ## Tool 4: `search_equipment` **Purpose**: Search for weapons, armor, adventuring gear, and magic items **API Coverage**: - **Weapons**: Open5e `/v2/weapons/` - **Armor**: Open5e `/v2/armor/` - **Magic Items**: Open5e `/v1/magicitems/` **Parameters**: - `type` (string, optional): One of: `weapon`, `armor`, `magic-item`, `all` (default: `all`) - `search` (string, optional): Natural language search query for semantic/vector search - `rarity` (string, optional): Magic item rarity (common, uncommon, rare, very rare, legendary, artifact) - `damage_dice` (string, optional): Weapon damage dice (e.g., "1d8", "2d6") - `is_simple` (boolean, optional): Simple weapons only - `requires_attunement` (string, optional): For magic items - "requires attunement" or "" (blank) - `limit` (integer, optional, default=20): Maximum results to return **Available Weapon Properties** (filters): - `is_light`: Light weapons - `is_versatile`: Versatile weapons - `is_thrown`: Thrown weapons - `is_finesse`: Finesse weapons - `is_two_handed`: Two-handed weapons **Returns by Type**: **Weapons**: - Name, damage dice, damage type - Properties (light, versatile, thrown, finesse, two-handed, etc.) - Range (normal and long for ranged weapons) - Simple vs martial **Armor**: - Name, armor type (light/medium/heavy/shield) - AC value - Strength requirement - Stealth disadvantage - Weight, cost **Magic Items**: - Name, type, rarity - Description and effects - Attunement requirement **Example Queries**: - "What's the damage for a longsword?" → `type="weapon", search="longsword"` - "Show me rare magic weapons" → `type="magic-item", rarity="rare"` - "Find light armor" → `type="armor"` - "What does a Bag of Holding do?" → `type="magic-item", search="bag of holding"` --- ## Tool 5: `search_rule` **Purpose**: Look up game rules, mechanics, conditions, and reference information **API Coverage**: - **Rules & Rule Sections**: Open5e `/v2/rules/`, `/v2/rule-sections/` - **Conditions**: Open5e `/v2/conditions/` - **Reference Info**: Open5e (damage-types, weapon-properties, skills, ability-scores, magic-schools, languages, proficiencies, alignments) **Parameters**: - `rule_type` (string, required): One of: `rule`, `condition`, `damage-type`, `weapon-property`, `skill`, `ability-score`, `magic-school`, `language`, `proficiency`, `alignment` - `search` (string, optional): Natural language search query for semantic/vector search - `section` (string, optional): For rules - section name (e.g., "combat", "spellcasting") - `limit` (integer, optional, default=20): Maximum results to return **Available Rule Sections**: - adventuring - appendix - combat - equipment - spellcasting - using-ability-scores **Returns by Type**: **Rules**: - Rule name, description - Subsections with detailed mechanics - References to related rules **Conditions**: - Condition name - Full description of effects - Game mechanical impact **Reference Info**: - Description - Associated mechanics - Related game elements **Example Queries**: - "What does the Grappled condition do?" → `rule_type="condition", search="grappled"` - "Explain opportunity attacks" → `rule_type="rule", section="combat", search="opportunity attack"` - "What is radiant damage?" → `rule_type="damage-type", search="radiant"` - "How does the Stealth skill work?" → `rule_type="skill", search="stealth"` - "What are weapon properties?" → `rule_type="weapon-property"` --- ## Tool 6: `search_all` **Purpose**: General-purpose search across all D&D content types with semantic search support **Parameters**: - `query` (string, required): Search query (supports natural language with semantic search) - `content_types` (list[string], optional): Limit search to specific types (spells, creatures, equipment, etc.) - `documents` (list[string], optional): Filter by source documents - `limit` (integer, optional, default=20): Maximum results per entity type **Returns**: - Results grouped by entity type - Each result includes entity data and similarity score **Example Queries**: ```python # Semantic search across all content results = await search_all(query="fire damage") # Search specific entity types results = await search_all( query="healing magic", content_types=["Spell", "Item"] ) # Search within specific documents results = await search_all( query="dragon breath", documents=["srd-5e"] ) ``` --- ## Implementation Notes ### Caching Strategy LoreKeeper uses **Milvus Lite** for caching: - Stores entity data with embedding vectors - Supports semantic/vector search - Entity embeddings generated automatically on storage - TTL: Infinite (entities never expire) ### Semantic Search When `search` is provided (Milvus backend): 1. Query text is converted to a 384-dimensional embedding vector 2. Vector similarity search finds semantically related content 3. Results are ranked by cosine similarity (0.0 to 1.0) 4. Structured filters are applied as constraints **Embedding Model**: `all-MiniLM-L6-v2` (sentence-transformers) - 384 dimensions - ~80MB model (downloaded on first use) - <10ms encoding time per query ### Error Handling - If primary API fails, log error and return user-friendly message - Log detailed errors for debugging - Cache errors with short TTL (5 minutes) to avoid hammering failed endpoints - Semantic search falls back to structured search on error ### Search Behavior - **Semantic search**: Natural language queries find conceptually related results - **Exact match**: If `search` parameter exactly matches, return single result - **Partial match**: If `search` is partial, return up to `limit` results ranked by relevance - **No search**: If no `search` provided, filter by other parameters and return up to `limit` results ### Response Formatting - Return structured data suitable for AI consumption - Include source attribution (document name/title) - Include similarity score (`_score`) for semantic search results - Format text descriptions as markdown where appropriate - Include URLs to original API resources for reference --- ## API Endpoint Summary ### Primary APIs by Tool | Tool | Category | API Endpoint | Version | |------|----------|-------------|---------| | search_spell | Spells | Open5e `/v2/spells/` | v2 ✓ | | search_creature | Monsters | Open5e `/v1/monsters/` | v1 | | search_character_option | Classes | Open5e `/v1/classes/` | v1 | | search_character_option | Races | Open5e `/v1/races/` | v1 | | search_character_option | Backgrounds | Open5e `/v2/backgrounds/` | v2 ✓ | | search_character_option | Feats | Open5e `/v2/feats/` | v2 ✓ | | search_equipment | Weapons | Open5e `/v2/weapons/` | v2 ✓ | | search_equipment | Armor | Open5e `/v2/armor/` | v2 ✓ | | search_equipment | Magic Items | Open5e `/v1/magicitems/` | v1 | | search_rule | Rules | Open5e `/v2/rules/`, `/v2/rule-sections/` | v2 ✓ | | search_rule | Conditions | Open5e `/v2/conditions/` | v2 ✓ | | search_rule | Reference | Open5e (various) | v2 ✓ | ### Why Open5e Was Chosen - **Comprehensive coverage**: Open5e v2 provides comprehensive, well-structured game data - **Open source**: Open5e data is freely available and community-supported - **Consistent maintenance**: Single API source ensures consistent updates and behavior - **Extensive content**: Includes both official SRD content and community-created content

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