MCP Server for Swiss Federal Statistical Office (BFS) data via STAT-TAB PxWeb API
Swiss Statistics MCP Server demonstrates solid tool design with 13 well-named, read-only tools accessing BFS statistical data. All tools have names starting with action verbs (list_, get_, query_, search_, resolve_). Most tools include descriptions of 100-200 chars and parameter documentation. However, output schemas are not formally documented in the visible code, parameter descriptions lack detail about format constraints and ranges, and error handling guidance is minimal. The server handles a focused domain (Swiss statistical data) cleanly but lacks the depth of specification expected for >75 scores.
Get a chapter (section) from Historical Statistics of Switzerland (HSSO) with CC BY-NC-SA 3.0 license
Download a complete statistical table in XLSX format from Historical Statistics of Switzerland
Get dimensions, variables, and value labels for a dataset by table ID
List all 682 datasets across 21 themes with German names and descriptions
List all 682 datasets across 21 themes with English names and descriptions
List all 682 datasets across 21 themes with French names and descriptions
List all 682 datasets across 21 themes with Italian names and descriptions
List all communes at a given administrative level (canton, district, or all communes)
Output schemas not formally documented. No visible JSON Schema definitions for tool responses, preventing LLMs from knowing what fields to expect in results and breaking chaining predictability.
Parameter descriptions lack format constraints and range information. For example, 'theme' parameter accepts optional filter but no guidance on valid theme codes beyond one example ('01'). 'date' parameter in list_communes lacks format spec (YYYY-MM-DD implied but not explicit). 'query' object in query_table is documented as 'Query object with dimension filters and selections' but no schema or example structure provided.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 51 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 23 | - | v1 |
List available chapters from Historical Statistics of Switzerland with CC BY-NC-SA 3.0 license
Query a BFS statistical table with optional filtering and dimension selection
Resolve BFS commune number and name to canonical current commune data with geo/LINDAS links
Resolve historical BFS commune number to current commune(s) after boundary changes
Full-text search across all BFS statistical datasets and CKAN open data descriptions
Error handling responses not visible in source code. No documented error recovery guidance. How should LLMs handle invalid table_id? Invalid theme code? Missing communes? Tools should tell LLM what to do next when failures occur.
Pagination not visible for list tools. list_catalog_* tools claim to return 'all 682 datasets' but no mention of page/limit parameters or result limits. Returning 682 items in one response would blow context windows. Large result sets should be paginated with limit, offset, and total_count.
Language parameter inconsistency. Four separate tools (list_catalog_en/de/fr/it) each return one language, forcing agents to call all four to search multilingually. Better design: single list_catalog tool accepting language parameter (defaulting to user preference or all languages). Reduces tool count and simplifies agent logic.
query_table input 'query' parameter is vaguely documented as 'Query object with dimension filters and selections' with no schema, examples, or field names. This forces LLMs to guess the structure (e.g., is it {dimension_id: [values]}? {filters: {dim1: [v1, v2]}?}). Provide explicit schema or example JSON.
Parameter naming clarity. resolve_commune accepts 'bfs' and 'name' as separate parameters with no guidance on which is required vs optional or how they interact. Must one be provided? Both? Is 'bfs' the BFS commune number or a filter? Document mutual requirements and defaults explicitly.
Tool descriptions lack 'when to use' context. 'resolve_commune' vs 'list_communes', when should an agent choose one over the other? Descriptions should answer: use resolve_commune when you have a specific BFS number or name; use list_communes when discovering available communes in a region.