Spaces:
Sleeping
Sleeping
""" | |
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": <int>, # number of battles returned | |
"battles": <list[dict]> # raw JSON from Supercell | |
} | |
On failure β | |
{ "error": "<human-readable message>" } | |
""" | |
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) | |