From 5a9073385c723789680c6d9640030c772121bd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20G=C3=B3mez-Padilla?= Date: Tue, 7 Jul 2026 02:12:07 -0500 Subject: [PATCH] Fix 403 errors by sending a proper User-Agent to Wikidata `get_metadata` and `execute_sparql` issued their HTTP requests without the shared HEADER, so httpx fell back to its default User-Agent (`python-httpx/...`). Wikimedia rejects default library User-Agents with HTTP 403, so both tools failed on every call while `search_*` and `get_properties` (which already pass HEADER) worked. Changes: - Pass `headers=HEADER` in `execute_sparql` and `get_metadata`. - Replace the placeholder `"foobar"` User-Agent with a descriptive, policy-compliant value including the project URL, per the Wikimedia User-Agent policy (https://meta.wikimedia.org/wiki/User-Agent_policy). --- src/server.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server.py b/src/server.py index c50c013..4236bcb 100644 --- a/src/server.py +++ b/src/server.py @@ -7,7 +7,10 @@ server = FastMCP("Wikidata MCP Server") WIKIDATA_URL = "https://www.wikidata.org/w/api.php" -HEADER = {"Accept": "application/json", "User-Agent": "foobar"} +HEADER = { + "Accept": "application/json", + "User-Agent": "mcp-wikidata/0.1 (https://github.com/zzaebok/mcp-wikidata)", +} async def search_wikidata(query: str, is_entity: bool = True, limit: int=1) -> str: @@ -108,7 +111,7 @@ async def execute_sparql(sparql_query: str) -> str: url = "https://query.wikidata.org/sparql" async with httpx.AsyncClient() as client: response = await client.get( - url, params={"query": sparql_query, "format": "json"} + url, headers=HEADER, params={"query": sparql_query, "format": "json"} ) response.raise_for_status() result = response.json()["results"]["bindings"] @@ -135,7 +138,7 @@ async def get_metadata(entity_id: str, language: str = "en") -> Dict[str, str]: "format": "json", } async with httpx.AsyncClient() as client: - response = await client.get(WIKIDATA_URL, params=params) + response = await client.get(WIKIDATA_URL, headers=HEADER, params=params) response.raise_for_status() data = response.json() entity_data = data.get("entities", {}).get(entity_id, {})