Skip to main content
Glama
stijn-meijers

DraCor MCP Server

search_plays

Find plays in the DraCor database using filters for text, corpus, characters, country, language, author, date range, and gender ratio.

Instructions

Advanced search for plays in the DraCor database with multiple filter options.

Parameters:
- query: General text search across title, subtitle, and author
- corpus_name: Specific corpus to search within (e.g., "shake", "ger", "rus", "span", "dutch")
- character_name: Name of a character that should appear in the play
- country: Country of origin for the play
- language: Language of the play
- author: Name of the playwright
- year_from: Starting year for date range filter
- year_to: Ending year for date range filter
- gender_filter: Filter by plays with a certain gender ratio ("female_dominated", "male_dominated", "balanced")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNo
corpus_nameNo
character_nameNo
countryNo
languageNo
authorNo
year_fromNo
year_toNo
gender_filterNo

Implementation Reference

  • The primary handler function for the 'search_plays' tool. Decorated with @mcp.tool() which handles registration and schema inference from parameters and docstring. Implements comprehensive filtering logic across DraCor corpora using query, corpus, character, country, language, author, year range, and gender filters.
    @mcp.tool()
    def search_plays(
        query: str = None, 
        corpus_name: str = None,
        character_name: str = None, 
        country: str = None,
        language: str = None,
        author: str = None,
        year_from: int = None,
        year_to: int = None,
        gender_filter: str = None
    ) -> Dict:
        """
        Advanced search for plays in the DraCor database with multiple filter options.
        
        Parameters:
        - query: General text search across title, subtitle, and author
        - corpus_name: Specific corpus to search within (e.g., "shake", "ger", "rus", "span", "dutch")
        - character_name: Name of a character that should appear in the play
        - country: Country of origin for the play
        - language: Language of the play
        - author: Name of the playwright
        - year_from: Starting year for date range filter
        - year_to: Ending year for date range filter
        - gender_filter: Filter by plays with a certain gender ratio ("female_dominated", "male_dominated", "balanced")
        """
        try:
            # Get corpora to search in
            corpora_result = get_corpora()
            if "error" in corpora_result:
                return {"error": corpora_result["error"]}
            
            all_corpora = corpora_result.get("corpora", [])
            target_corpora = []
            
            # Filter corpora if specified
            if corpus_name:
                target_corpora = [corp for corp in all_corpora if corpus_name.lower() in corp.get("name", "").lower()]
            else:
                target_corpora = all_corpora
            
            # Initialize results
            results = []
            detailed_results = []
            
            # For each corpus, search for plays
            for corpus in target_corpora:
                corpus_name = corpus.get("name")
                
                # Get all plays from this corpus
                plays_result = get_plays(corpus_name)
                if "error" in plays_result:
                    continue
                
                # Iterate through plays and apply filters
                for play in plays_result.get("plays", []):
                    # Initialize as a match until proven otherwise by filters
                    is_match = True
                    
                    # Apply general text search if specified
                    if query and is_match:
                        searchable_text = (
                            play.get("title", "") + " " +
                            " ".join([a.get("name", "") for a in play.get("authors", [])]) + " " +
                            play.get("subtitle", "") + " " +
                            play.get("originalTitle", "")
                        ).lower()
                        
                        if query.lower() not in searchable_text:
                            is_match = False
                    
                    # Apply country filter if specified
                    if country and is_match:
                        play_country = (
                            play.get("writtenIn", "") + " " + 
                            play.get("printedIn", "") + " " +
                            " ".join([a.get("country", "") for a in play.get("authors", [])])
                        ).lower()
                        
                        if country.lower() not in play_country:
                            is_match = False
                    
                    # Apply language filter if specified
                    if language and is_match:
                        if language.lower() not in play.get("originalLanguage", "").lower():
                            is_match = False
                    
                    # Apply author filter if specified
                    if author and is_match:
                        author_names = [a.get("name", "").lower() for a in play.get("authors", [])]
                        if not any(author.lower() in name for name in author_names):
                            is_match = False
                    
                    # Apply year range filter if specified
                    if (year_from or year_to) and is_match:
                        play_year = play.get("yearNormalized") or play.get("yearWritten") or play.get("yearPrinted") or 0
                        
                        if year_from and play_year < year_from:
                            is_match = False
                        
                        if year_to and play_year > year_to:
                            is_match = False
                    
                    # If character name is specified, need to check character list
                    if character_name and is_match:
                        try:
                            # Get characters for this play
                            play_name = play.get("name")
                            characters_result = get_characters(corpus_name, play_name)
                            
                            if "error" not in characters_result:
                                character_found = False
                                for character in characters_result.get("characters", []):
                                    if character_name.lower() in character.get("name", "").lower():
                                        character_found = True
                                        break
                                
                                if not character_found:
                                    is_match = False
                            else:
                                # If we can't get characters, we assume it's not a match
                                is_match = False
                        except:
                            # If error occurs, we assume it's not a match
                            is_match = False
                    
                    # Apply gender filter if specified
                    if gender_filter and is_match:
                        try:
                            # Get characters for this play
                            play_name = play.get("name")
                            characters_result = get_characters(corpus_name, play_name)
                            
                            if "error" not in characters_result:
                                male_count = sum(1 for c in characters_result.get("characters", []) if c.get("gender") == "MALE")
                                female_count = sum(1 for c in characters_result.get("characters", []) if c.get("gender") == "FEMALE")
                                total = male_count + female_count
                                
                                if total > 0:
                                    female_ratio = female_count / total
                                    
                                    if gender_filter == "female_dominated" and female_ratio <= 0.5:
                                        is_match = False
                                    elif gender_filter == "male_dominated" and female_ratio >= 0.5:
                                        is_match = False
                                    elif gender_filter == "balanced" and (female_ratio < 0.4 or female_ratio > 0.6):
                                        is_match = False
                        except:
                            # If error occurs, we keep it as a match
                            pass
                    
                    # If all filters passed, add to results
                    if is_match:
                        # Add basic info to results
                        results.append({
                            "corpus": corpus_name,
                            "play": play
                        })
                        
                        # Try to add more detailed info for top results
                        if len(detailed_results) < 5:
                            try:
                                play_name = play.get("name")
                                # Get more details
                                play_info = get_play(corpus_name, play_name)
                                
                                if "error" not in play_info:
                                    detailed_results.append({
                                        "corpus": corpus_name,
                                        "play_name": play_name,
                                        "title": play.get("title"),
                                        "author": play.get("authors", [{}])[0].get("name") if play.get("authors") else "Unknown",
                                        "year": play.get("yearNormalized"),
                                        "language": play.get("originalLanguage"),
                                        "characters": len(play_info.get("characters", [])),
                                        "link": f"https://dracor.org/{corpus_name}/{play_name}"
                                    })
                            except:
                                pass
            
            return {
                "count": len(results),
                "results": results,
                "top_results": detailed_results,
                "filters_applied": {
                    "query": query,
                    "corpus_name": corpus_name,
                    "character_name": character_name,
                    "country": country,
                    "language": language,
                    "author": author,
                    "year_range": f"{year_from}-{year_to}" if year_from or year_to else None,
                    "gender_filter": gender_filter
                }
            }
        except Exception as e:
            return {"error": str(e)}
  • The @mcp.tool() decorator registers the search_plays function as an MCP tool, automatically generating input schema from type hints and docstring.
    @mcp.tool()
  • Input schema inferred from function parameters (all optional) and comprehensive docstring describing each filter parameter and their usage.
    def search_plays(
        query: str = None, 
        corpus_name: str = None,
        character_name: str = None, 
        country: str = None,
        language: str = None,
        author: str = None,
        year_from: int = None,
        year_to: int = None,
        gender_filter: str = None
    ) -> Dict:
        """
        Advanced search for plays in the DraCor database with multiple filter options.
        
        Parameters:
        - query: General text search across title, subtitle, and author
        - corpus_name: Specific corpus to search within (e.g., "shake", "ger", "rus", "span", "dutch")
        - character_name: Name of a character that should appear in the play
        - country: Country of origin for the play
        - language: Language of the play
        - author: Name of the playwright
        - year_from: Starting year for date range filter
        - year_to: Ending year for date range filter
        - gender_filter: Filter by plays with a certain gender ratio ("female_dominated", "male_dominated", "balanced")
        """

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/stijn-meijers/dracor-mcp'

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