Skip to main content
Glama

get_population

Retrieve Swiss population statistics from the Federal Statistical Office, including national totals, canton-specific data, or comprehensive canton listings for years 2010-2024.

Instructions

Get Swiss population data from the Federal Statistical Office (FSO/BFS). Returns population figures for Switzerland, a canton, or all cantons. Data source: BFS STATPOP (permanent resident population).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cantonNoCanton name or 2-letter code (e.g. 'ZH', 'Zürich', 'Geneva', 'BE'). Omit to get Switzerland total. Use 'all' to list all cantons.
yearNoYear of data (2010–2024). Defaults to latest (2024).

Implementation Reference

  • The handleGetPopulation function processes the 'get_population' tool request by fetching data from the Swiss Federal Statistical Office (BFS) API and formatting it based on the requested canton and year.
    async function handleGetPopulation(args: Record<string, unknown>): Promise<string> {
      const rawCanton = typeof args.canton === "string" ? args.canton.trim() : "";
      const rawYear = args.year;
      const year = rawYear !== undefined ? String(rawYear) : LATEST_YEAR;
    
      if (!AVAILABLE_YEARS.includes(year)) {
        throw new Error(`Year must be between ${AVAILABLE_YEARS[0]} and ${LATEST_YEAR}. Got: ${year}`);
      }
    
      const url = `${PXWEB_BASE}/${POPULATION_TABLE}/${POPULATION_TABLE}.px`;
    
      // Determine which locations to query
      let locationCodes: string[];
      let mode: "switzerland" | "canton" | "all";
    
      if (!rawCanton || rawCanton.toLowerCase() === "switzerland" || rawCanton === "8100") {
        locationCodes = ["8100"];
        mode = "switzerland";
      } else if (rawCanton.toLowerCase() === "all") {
        locationCodes = ["8100", ...ALL_CANTON_CODES];
        mode = "all";
      } else {
        const code = resolveCantonCode(rawCanton);
        if (!code) {
          throw new Error(
            `Unknown canton: "${rawCanton}". Use a 2-letter code (ZH, BE, GE…) or canton name. ` +
            `Or use "all" to list all cantons.`
          );
        }
        locationCodes = [code];
        mode = "canton";
      }
    
      const body = {
        query: [
          { code: "Jahr", selection: { filter: "item", values: [year] } },
          {
            code: "Kanton (-) / Bezirk (>>) / Gemeinde (......)",
            selection: { filter: "item", values: locationCodes },
          },
          { code: "Bevölkerungstyp", selection: { filter: "item", values: ["1"] } },
          { code: "Staatsangehörigkeit (Kategorie)", selection: { filter: "item", values: ["-99999"] } },
          { code: "Geschlecht", selection: { filter: "item", values: ["-99999"] } },
          { code: "Alter", selection: { filter: "item", values: ["-99999"] } },
        ],
        response: { format: "json" },
      };
    
      const data = await fetchJSON<PxWebResponse>(url, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
    
      if (mode === "switzerland") {
        const row = data.data[0];
        const pop = row ? parseInt(row.values[0], 10) : null;
        return JSON.stringify({
          location: "Switzerland",
          year: parseInt(year, 10),
          population: pop,
          population_type: "Permanent resident population",
          source: "Federal Statistical Office (FSO/BFS) — STATPOP",
          source_url: "https://www.bfs.admin.ch/bfs/en/home/statistics/population.html",
        });
      }
    
      if (mode === "canton") {
        const code = locationCodes[0];
        const row = data.data[0];
        const pop = row ? parseInt(row.values[0], 10) : null;
        return JSON.stringify({
          /* c8 ignore next */
          location: CANTON_NAMES[code] ?? code, // defensive: code always in CANTON_NAMES
          canton_code: code,
          year: parseInt(year, 10),
          population: pop,
          population_type: "Permanent resident population",
          source: "Federal Statistical Office (FSO/BFS) — STATPOP",
          source_url: "https://www.bfs.admin.ch/bfs/en/home/statistics/population.html",
        });
      }
    
      // mode === "all"
      // Build a code→name map from the response keys
      const cantons: Array<{ canton: string; code: string; population: number }> = [];
      let switzerland: number | null = null;
    
      for (const row of data.data) {
        const locCode = row.key[1]; // year, location, poptype, citizenship, sex, age
        const pop = parseInt(row.values[0], 10);
        if (locCode === "8100") {
          switzerland = pop;
        } else {
          cantons.push({
            canton: CANTON_NAMES[locCode] ?? locCode,
            code: locCode,
            population: pop,
          });
        }
      }
    
      // Sort by population descending
      cantons.sort((a, b) => b.population - a.population);
    
      return JSON.stringify({
        year: parseInt(year, 10),
        switzerland_total: switzerland,
        cantons,
        population_type: "Permanent resident population",
        source: "Federal Statistical Office (FSO/BFS) — STATPOP",
        source_url: "https://www.bfs.admin.ch/bfs/en/home/statistics/population.html",
      });
    }
  • The get_population tool definition, which includes the input schema for arguments 'canton' and 'year'.
    export const statisticsTools = [
      {
        name: "get_population",
        description:
          "Get Swiss population data from the Federal Statistical Office (FSO/BFS). " +
          "Returns population figures for Switzerland, a canton, or all cantons. " +
          "Data source: BFS STATPOP (permanent resident population).",
        inputSchema: {
          type: "object",
          properties: {
            canton: {
              type: "string",
              description:
                "Canton name or 2-letter code (e.g. 'ZH', 'Zürich', 'Geneva', 'BE'). " +
                "Omit to get Switzerland total. Use 'all' to list all cantons.",
            },
            year: {
              type: "number",
              description: `Year of data (${AVAILABLE_YEARS[0]}–${LATEST_YEAR}). Defaults to latest (${LATEST_YEAR}).`,
            },
          },
        },
      },
  • The main dispatcher function 'handleStatistics' routes the 'get_population' tool name to the 'handleGetPopulation' handler.
    export async function handleStatistics(
      name: string,
      args: Record<string, unknown>
    ): Promise<string> {
      switch (name) {
        case "get_population":
          return handleGetPopulation(args);
        case "search_statistics":
          return handleSearchStatistics(args);
        case "get_statistic":
          return handleGetStatistic(args);
        default:
          throw new Error(`Unknown statistics tool: ${name}`);
      }
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It adds useful context about the data source (BFS STATPOP) and what it returns (population figures), but does not cover other behavioral traits such as rate limits, error handling, or authentication needs. It adequately describes the operation as a read-only data fetch without contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded, with two sentences that efficiently convey the tool's purpose, scope, and data source without any wasted words. Every sentence adds value, making it easy to understand at a glance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (2 optional parameters, 100% schema coverage, no output schema), the description is complete enough for a read-only data retrieval tool. It covers what the tool does, the data source, and the scope, though it lacks details on output format or error cases, which is a minor gap given the straightforward nature of the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already fully documents the parameters (canton and year). The description adds minimal value beyond the schema by mentioning the scope (Switzerland, canton, or all cantons) and data source, but does not provide additional syntax or format details. Baseline 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Get Swiss population data') and resources ('from the Federal Statistical Office'), and distinguishes it from siblings by focusing on population data rather than other Swiss statistics like weather, traffic, or parliamentary information. It specifies the data source (BFS STATPOP) and scope (Switzerland, canton, or all cantons).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool—for Swiss population data—and implies usage by specifying the data source and scope. However, it does not explicitly state when not to use it or name alternatives (e.g., 'get_statistic' might overlap), though the sibling list shows distinct tools for other data types, reducing ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vikramgorla/mcp-swiss'

If you have feedback or need assistance with the MCP directory API, please join our Discord server