""" MCP-ready Gradio app • Tool 1: save_brawlstars_key(api_key) → str • Tool 2: get_recent_battles(player_tag) → dict UI: two tabs so humans can still use the app. """ import gradio as gr import brawlstats # pip install brawlstats # ─────────────────────────────────────────────── # GLOBAL STATE (shared by all tool invocations) # ─────────────────────────────────────────────── BS_API_KEY = None # will hold the token after Tool-1 runs # ─────────────────────────────────────────────── # TOOL 1 – save the key (no echo) # ─────────────────────────────────────────────── def save_brawlstars_key(api_key: str) -> str: """ Store a Brawl Stars API key in server memory for later use. This should be the **first** tool called in a session. Once the key is saved, subsequent calls to `get_recent_battles` can access the API without requiring the LLM (or user) to resend the long token. Args: api_key (str): Your personal token generated at https://developer.brawlstars.com. Do **not** share this publicly—send it only once via this tool. Returns: str: Status message — • "✅ API key saved in server memory" on success • "❌ No key provided" if the argument was empty """ global BS_API_KEY BS_API_KEY = api_key.strip() if BS_API_KEY: return "✅ API key saved in server memory" return "❌ No key provided" # ─────────────────────────────────────────────── # TOOL 2 – fetch recent battles using saved key # ─────────────────────────────────────────────── def get_recent_battles(player_tag: str) -> dict: """ Retrieve a player's 25 most-recent Brawl Stars battles. Call `save_brawlstars_key` **once** beforehand to cache the API key. Args: player_tag (str): The player’s in-game tag, with or without the leading '#', e.g. "#V2LQY9UY" or "V2LQY9UY". Returns: dict: On success – { "player": "#TAG", "count": , # number of battles returned "battles": # raw JSON from Supercell } On failure – { "error": "" } """ if not BS_API_KEY: return {"error": "API key not set - call save_brawlstars_key first"} tag = player_tag.strip().upper().lstrip("#") try: client = brawlstats.Client(BS_API_KEY) logs = client.get_battle_logs(tag) # BattleLog object except brawlstats.Forbidden: return {"error": "Invalid API key"} except brawlstats.NotFound: return {"error": f"Player #{tag} not found"} except brawlstats.RequestError as e: return {"error": f"API request failed: {e}"} return { "player": f"#{tag}", "count": len(logs), "battles": logs.raw_data # serialisable list } # ─────────────────────────────────────────────── # HUMAN-FRIENDLY UI (optional) # ─────────────────────────────────────────────── with gr.Blocks(title="Brawl Stars MCP Tools") as demo: with gr.Tab("🔑 Save API Key"): api_box = gr.Textbox(type="password", label="API Key") save_btn = gr.Button("Save") save_out = gr.Textbox(label="Status", interactive=False) save_btn.click(save_brawlstars_key, inputs=api_box, outputs=save_out) with gr.Tab("📜 Get Recent Battles"): tag_box = gr.Textbox(label="Player Tag", placeholder="#V2LQY9UY") fetch_btn = gr.Button("Fetch") json_out = gr.JSON(label="Battle Log") fetch_btn.click(get_recent_battles, inputs=tag_box, outputs=json_out) # ─────────────────────────────────────────────── # LAUNCH AS MCP SERVER # ─────────────────────────────────────────────── if __name__ == "__main__": demo.launch(mcp_server=True)