analyze_character_relations
Analyze character relationships in a play to identify connections and interactions between characters.
Instructions
Analyze the character relationships in a play.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| corpus_name | Yes | ||
| play_name | Yes |
Implementation Reference
- dracor_mcp_fastmcp.py:443-542 (handler)The handler function decorated with @mcp.tool(), which registers and implements the 'analyze_character_relations' tool. It analyzes character relationships by fetching play data, characters, network CSV data, parsing relations with weights, attempting to fetch formal relations, and returning structured analysis including top relations and metrics.@mcp.tool() def analyze_character_relations(corpus_name: str, play_name: str) -> Dict: """Analyze the character relationships in a play.""" try: # Get play data play = api_request(f"corpora/{corpus_name}/plays/{play_name}") # Get character data characters = api_request(f"corpora/{corpus_name}/plays/{play_name}/characters") # Get network data in CSV format url = f"{DRACOR_API_BASE_URL}/corpora/{corpus_name}/plays/{play_name}/networkdata/csv" response = requests.get(url) response.raise_for_status() csv_data = response.text # Parse CSV data to extract relations relations = [] lines = csv_data.strip().split('\n') if len(lines) > 1: # Skip header headers = lines[0].split(',') for line in lines[1:]: parts = line.split(',') if len(parts) >= 4: source = parts[0].strip('"') target = parts[2].strip('"') weight = int(parts[3]) if parts[3].isdigit() else 0 # Find character names from IDs source_name = None target_name = None for char in characters: if char.get("id") == source: source_name = char.get("name") if char.get("id") == target: target_name = char.get("name") relations.append({ "source": source_name or source, "source_id": source, "target": target_name or target, "target_id": target, "weight": weight }) # Sort by weight to identify strongest relationships relations.sort(key=lambda x: x.get("weight", 0), reverse=True) # Try to get relations data if available try: relations_url = f"{DRACOR_API_BASE_URL}/corpora/{corpus_name}/plays/{play_name}/relations/csv" relations_response = requests.get(relations_url) formal_relations = [] if relations_response.status_code == 200: rel_lines = relations_response.text.strip().split('\n') if len(rel_lines) > 1: # Skip header for line in rel_lines[1:]: parts = line.split(',') if len(parts) >= 4: source = parts[0].strip('"') target = parts[2].strip('"') relation_type = parts[3].strip('"') # Find character names from IDs source_name = None target_name = None for char in characters: if char.get("id") == source: source_name = char.get("name") if char.get("id") == target: target_name = char.get("name") formal_relations.append({ "source": source_name or source, "target": target_name or target, "type": relation_type }) except: formal_relations = [] # Get metrics metrics = api_request(f"corpora/{corpus_name}/plays/{play_name}/metrics") return { "play": { "title": play.get("title"), "author": play.get("authors", [{}])[0].get("name") if play.get("authors") else None, "year": play.get("yearNormalized") }, "totalCharacters": len(characters), "totalRelations": len(relations), "strongestRelations": relations[:10], # Top 10 strongest relations "weakestRelations": relations[-10:] if len(relations) >= 10 else relations, # Bottom 10 "formalRelations": formal_relations, # Explicit relations if available "metrics": metrics } except Exception as e: return {"error": str(e)}