Skip to main content
Glama
BFH-JTF

LINDAS MCP Server

by BFH-JTF

LINDAS MCP Server

A Model Context Protocol server that enables LLMs to query structured data from LINDAS — the Swiss Federal Archives' Linked Data platform at https://ld.admin.ch.

LINDAS stores multi-dimensional statistical data as RDF cubes using the cube.link vocabulary, accessible via a SPARQL endpoint backed by Stardog. This server translates high-level tool calls into SPARQL queries and returns clean, LLM-friendly JSON.

What this enables

Ask an LLM questions about Swiss federal data and let it discover, inspect, and query datasets automatically:

  • "Show me forest fire danger warnings in the last week"

  • "Compare population across all cantons for 2023"

  • "Find datasets about unemployment"

The LLM uses the tools below to discover cubes, inspect their structure, find valid dimension values, and query observations — all without writing SPARQL.

Related MCP server: mcp-i14y

Prerequisites

  • Node.js ≥ 20

  • npm or pnpm

Installation

npm install
npm run build

Configuration

Environment variables (all optional):

Variable

Default

Description

LINDAS_SPARQL_ENDPOINT

https://ld.admin.ch/query

SPARQL endpoint URL

LINDAS_DEFAULT_LANGUAGE

de

Default language for labels (de, fr, it, en)

LINDAS_TRANSPORT

stdio

Transport mode: stdio or http

LINDAS_PORT

3000

HTTP port (only used when transport is http)

LINDAS_HOST

0.0.0.0

HTTP bind address (only used when transport is http)

Command-line flags override environment variables:

lindas-mcp [--transport stdio|http] [--port PORT]

Usage with Claude Desktop

Add the server to your claude_desktop_config.json:

{
  "mcpServers": {
    "lindas": {
      "command": "node",
      "args": ["C:/path/to/lindas-mcp/dist/index.js"],
      "env": {
        "LINDAS_DEFAULT_LANGUAGE": "de"
      }
    }
  }
}

For development with hot reload, use tsx:

{
  "mcpServers": {
    "lindas": {
      "command": "npx",
      "args": ["tsx", "C:/path/to/lindas-mcp/src/index.ts"]
    }
  }
}

HTTP Transport (Streamable HTTP)

For use with the MCP Inspector, web-based clients, or remote access, start the server in HTTP mode:

# Using npm scripts
npm run start:http          # node dist/index.js --transport http
npm run dev:http            # tsx src/index.ts --transport http

# Or directly
node dist/index.js --transport http --port 3000

The server exposes the MCP Streamable HTTP endpoint at http://127.0.0.1:3000/mcp.

In HTTP mode, each client session gets its own MCP server instance. The server tracks sessions via the Mcp-Session-Id header.

MCP Inspector

To inspect the server interactively, open the MCP Inspector and connect to:

http://127.0.0.1:3000/mcp

Or launch the Inspector with the server:

npx @modelcontextprotocol/inspector node dist/index.js --transport stdio

opencode

For HTTP mode in opencode, configure opencode.json:

{
  "mcp": {
    "lindas": {
      "type": "remote",
      "url": "http://127.0.0.1:3000/mcp",
      "enabled": true
    }
  }
}

LibreChat / Docker

Build the Docker image and add it to your docker-compose.yml:

services:
  lindas-mcp:
    image: lindas-mcp
    container_name: lindas-mcp
    environment:
      - LINDAS_TRANSPORT=http
      - LINDAS_PORT=8000
      - LINDAS_DEFAULT_LANGUAGE=de
    restart: unless-stopped
    # ports:                    # Only needed for host access
    #   - "8000:8000"

Then in LibreChat's config:

mcpServers:
  lindas:
    type: streamable-http
    url: http://lindas-mcp:8000/mcp

Make sure both containers share the same Docker network.

Available Tools

Tool

Description

Key Parameters

list_cubes

List available data cubes

limit, offset

search_datasets

Full-text search across cube titles/descriptions

query, limit

get_cube_metadata

Get publisher, license, status, temporal coverage, and other metadata for a cube

cube_uri

get_cube_versions

List all versions of a cube

cube_uri

get_cube_structure

Get dimensions/measures/datatypes of a cube

cube_uri

get_dimension_summary

Get all dimensions with value counts and available ranges — single-call overview instead of calling get_dimension_values for each dimension separately

cube_uri, language

Querying

Tool

Description

Key Parameters

query_observations

Query observations with filters, pagination, and optional label resolution

cube_uri, dimensions, measures, filters, resolve_labels, limit, offset, language

count_observations

Count observations (check size before query)

cube_uri, filters

count_observations_by_dimension

Break down observation counts by dimension values (e.g., how many per canton per year)

cube_uri, dimension, filters, limit, language

get_page_info

Get pagination metadata for a query — total count, hasMore, nextPageOffset

cube_uri, dimensions, measures, filters, limit, offset

Geography

Tool

Description

Key Parameters

get_cantons

List all 26 Swiss cantons with IRIs and names

language

get_municipalities

List Swiss municipalities with IRIs and names (optionally filtered by canton)

canton_iri, language

get_districts

List Swiss districts with IRIs and names (optionally filtered by canton)

canton_iri, language

resolve_geography

Resolve a place name to its LINDAS IRI

name, language

resolve_iri

Look up a LINDAS IRI to get its label and type

iri, language

Resources

  • lindas:///cubes — Catalogue of available data cubes (Markdown)

Prompts

  • data_exploration — Step-by-step guide for exploring LINDAS data

  • canton_comparison — Compare a topic across cantons for a given year (args: topic, year)

Typical Workflow

The recommended workflow for an LLM using this server:

  1. search_datasets or list_cubes — Find cubes matching the user's topic

  2. get_cube_structure — Inspect the cube's dimensions and measures

  3. get_dimension_summary — Get a quick overview of all dimensions with value counts (replaces calling get_dimension_values for each dimension separately)

  4. resolve_geography — If the user mentions a place name, resolve it to an IRI

  5. resolve_iri — If query results contain opaque IRIs, look up their labels

  6. count_observations — Check how many results the query will return

  7. query_observations — Retrieve the data (use resolve_labels: true to get human-readable labels instead of IRIs)

For geographic comparisons, use get_cantons, get_municipalities, or get_districts to list geographic entities with their IRIs.

resolve_labels Feature

When query_observations is called with resolve_labels: true, IRI-valued dimensions are automatically joined to their schema:name labels. Instead of receiving:

{ "canton": { "value": "https://ld.admin.ch/canton/1", "label": "https://ld.admin.ch/canton/1" } }

You receive:

{ "canton": { "value": "https://ld.admin.ch/canton/1", "label": "Zürich" } }

This makes results immediately understandable without additional lookups.

Development

npm run dev          # Start stdio transport with tsx (hot reload)
npm run dev:http     # Start HTTP transport with tsx (hot reload)
npm run build        # Compile with tsc
npm start            # Run compiled stdio server
npm run start:http   # Run compiled HTTP server
npm test             # Run unit tests (vitest)
npm run test:watch   # Watch mode

Project Structure

src/
├── index.ts              # MCP server entry point (stdio + HTTP)
├── config.ts             # Configuration constants
├── sparql/
│   ├── client.ts         # SPARQL HTTP client + SparqlError
│   ├── queryBuilder.ts   # Pure SPARQL query builder functions
│   └── resultParser.ts   # SPARQL JSON → domain object parsers
├── tools/
│   ├── index.ts          # Tool registration + dispatch
│   └── *.ts              # Individual tool handlers
├── resources/
│   └── catalogue.ts      # lindas:///cubes resource
└── prompts/
    └── templates.ts      # Prompt templates
tests/
├── sparql.test.ts        # Query builder unit tests
└── resultParser.test.ts  # Parser unit tests

Notes

  • All logging goes to stderr (stdout is reserved for the MCP protocol in stdio mode).

  • User input interpolated into SPARQL is escaped to prevent injection.

  • Result limit is capped at 500 to protect LLM context windows.

  • Labels are fetched via schema:name with language filtering; IRI-valued dimensions fall back to the IRI itself if no label is found.

  • The search_datasets tool uses CONTAINS filters on schema:name and schema:description (the Stardog textMatch predicate is not supported on the public LINDAS endpoint).

  • In HTTP mode, each client session gets its own MCP server instance. Sessions are tracked via the Mcp-Session-Id header and cleaned up on disconnect.

License

MIT

Available Tools

8 tools
count_observationsA

Count the number of observations in a cube, optionally filtered. Use this BEFORE query_observations to check if a query will return a manageable number of results. If count is large, use filters to narrow down or use a smaller limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
filtersNo
cube_uriYes

TDQS

A4.3/5.0
Behavior4/5

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

No annotations provided, but description adequately describes the tool's behavior (count with optional filters). It doesn't mention return type or side effects, but for a read-only count operation, the transparency is sufficient.

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?

Two sentences efficiently cover purpose and usage guidelines. No redundant or unnecessary words.

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?

For a simple count tool with no output schema and no annotations, the description is fairly complete. It covers when to use and basic behavior. Lacks explicit return format but is otherwise adequate.

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

Parameters2/5

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

Schema coverage is 0%, and description adds minimal parameter detail beyond 'optionally filtered'. It does not explain cube_uri or the filter structure (dimension, value, operator). The description fails to compensate for the lack of schema descriptions.

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 verb 'Count' and the resource 'observations in a cube', and notes optional filtering. It distinguishes from sibling query_observations by implying it returns a count, not the data.

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

Usage Guidelines5/5

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

Explicitly advises using this tool before query_observations to check result size, and suggests actions if count is large (use filters or smaller limit). Provides clear when-to-use and alternatives.

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

get_cantonsB

List all 26 Swiss cantons with their LINDAS IRIs and names. Use the returned IRIs to filter observations by canton in query_observations.

ParametersJSON Schema
NameRequiredDescriptionDefault
languageNode

TDQS

B3.2/5.0
Behavior3/5

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

No annotations exist, so description carries burden. It accurately describes a non-destructive list operation but lacks details on rate limits or authentication needs, acceptable for a simple tool.

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?

Two sentences, zero waste, front-loaded with purpose and immediate next-step guidance—optimal conciseness.

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

Completeness3/5

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

No output schema; description states returned data (IRIs and names) but not structure or format. Adequate for a simple list but could specify response shape.

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

Parameters1/5

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

Schema coverage is 0% and description omits the 'language' parameter entirely, failing to explain its role or values, leaving the agent without needed context.

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

Purpose4/5

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

The description clearly states the tool lists all 26 Swiss cantons with IRIs and names, which is specific and distinguishes it from siblings like query_observations by hinting at downstream use.

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

Usage Guidelines3/5

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

Provides explicit usage hint to use returned IRIs in query_observations, but no when-not-to-use or alternatives, leaving gaps for an AI agent.

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

get_cube_structureA

Get the structure of a specific data cube: its dimensions, measures, datatypes, and constraints. ALWAYS call this before query_observations to understand what dimensions and measures are available. The 'path' field in the result is the property URI you pass to query_observations, get_dimension_values, and as filter dimensions.

ParametersJSON Schema
NameRequiredDescriptionDefault
cube_uriYesThe URI of the cube (from list_cubes results)

TDQS

A4.7/5.0
Behavior4/5

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

Without annotations, the description carries full burden. It explains the output includes a 'path' field used as property URI in other tools, which is valuable behavioral context. However, it does not explicitly state read-only nature or absence of side effects, but being a 'get' operation implies safety.

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?

Two sentences: first defines purpose, second gives usage guidance and key output detail. Every sentence adds value, no redundancy. Front-loaded with core action.

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

Completeness5/5

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

For a single-parameter tool without output schema, the description fully explains its role in the workflow, what it returns, and how the output is used. No additional context needed for correct selection and invocation.

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

Parameters4/5

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

The sole parameter cube_uri is described in schema as 'The URI of the cube (from list_cubes results)'. The description adds context that the URI comes from list_cubes, placing the parameter in the overall workflow. With 100% schema coverage, baseline is 3, but the extra guidance pushes it to 4.

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 retrieves the structure of a data cube, specifying dimensions, measures, datatypes, and constraints. It distinguishes itself from sibling tools like get_dimension_values and query_observations by outlining its role as a preliminary discovery tool.

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

Usage Guidelines5/5

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

The description explicitly mandates calling this tool before query_observations to understand available dimensions and measures. It provides a clear directive on when to use it, effectively guiding the agent in workflow sequencing.

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

get_dimension_valuesA

Get the distinct values for a dimension of a cube, with human-readable labels. Use this after get_cube_structure to discover what values you can filter on (e.g., which cantons, which years, which categories). Pass the 'path' value from get_cube_structure as dimension_path.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cube_uriYes
languageNode
dimension_pathYesThe property path URI of the dimension (from get_cube_structure 'path' field)

TDQS

A4/5.0
Behavior3/5

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

No annotations provided. Description indicates read-only behavior (getting values) and mentions human-readable labels, but lacks details on response format, pagination, or error conditions. Adequate but not thorough.

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?

Two sentences, concise and front-loaded with purpose. Every sentence adds value without redundancy.

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 no output schema and limited annotations, description effectively covers purpose, usage, and relationship to sibling. Lacks return value details but sufficient for core task.

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 coverage at 25% (only dimension_path described). Description adds context for dimension_path (use path from get_cube_structure) but doesn't elaborate on cube_uri, limit, or language. Compensates partially for low coverage.

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?

Clear verb 'get distinct values' with specific resource 'dimension of a cube' and hints about human-readable labels. Includes examples and links to sibling tool get_cube_structure, distinguishing it from other tools.

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?

Explicitly states use case: 'after get_cube_structure to discover what values you can filter on.' Instructs to pass the 'path' value. No explicit when-not-to-use, but context is clear.

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

list_cubesB

List available data cubes on LINDAS with their titles and descriptions. Use this to discover what datasets are available. Call get_cube_structure next to understand a cube's dimensions.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

B3.4/5.0
Behavior2/5

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

No annotations provided, so description must fully disclose behavior. It only states 'list' (read-only), but omits details on pagination, ordering, authorization, or data freshness. The limit/offset parameters imply pagination but are not explained.

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?

Two sentences with no wasted words. First sentence states purpose, second provides actionable next step. Highly efficient.

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

Completeness3/5

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

For a simple list tool, it gives basic purpose and next steps but lacks output format details (e.g., fields returned, error handling, empty results). Moderate completeness given no output schema.

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

Parameters1/5

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

Schema description coverage is 0%, and the description does not mention the 'limit' or 'offset' parameters at all, leaving the agent without guidance on how to control pagination or row count.

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 'List available data cubes on LINDAS with their titles and descriptions' and positions it as a discovery tool, distinguishing it from siblings like get_cube_structure which is for understanding dimensions.

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 explicitly advises using this for discovery and suggests next step: 'Call get_cube_structure next to understand a cube's dimensions.' It provides clear context on when to use but no exclusions.

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

query_observationsA

Query observations from a data cube with optional filtering and pagination. ALWAYS call get_cube_structure first to learn the cube's dimension and measure paths. Pass dimension paths in the 'dimensions' array and measure paths in the 'measures' array. Use get_dimension_values to find valid filter values.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo
filtersNo
cube_uriYes
languageNode
measuresNoMeasure property path URIs to include in results
dimensionsNoDimension property path URIs to include in results

TDQS

A4.7/5.0
Behavior4/5

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

No annotations are provided, but the description discloses the need to learn cube structure beforehand and the use of dimension/measure paths. It could mention output format or side effects, but queries are inherently safe.

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 concise (3 sentences) with key instructions front-loaded. Every sentence is informative, no redundancy.

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 no output schema, the description could explain the return format. However, it sufficiently covers usage and prerequisites, making it largely complete for a query tool.

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

Parameters5/5

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

Schema coverage is only 29% (measures and dimensions have descriptions), but the description adds crucial context: dimensions and measures should be paths from get_cube_structure, and filters should use values from get_dimension_values.

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 it queries observations from a data cube with optional filtering and pagination. It distinguishes from siblings by referencing related tools like get_cube_structure and get_dimension_values.

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

Usage Guidelines5/5

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

It explicitly says 'ALWAYS call get_cube_structure first' and instructs to use get_dimension_values for valid filter values, providing clear when-to-use and alternative tools.

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

resolve_geographyA

Resolve a place name to its LINDAS IRI. Works for cantons, municipalities, and districts. Use this when a user mentions a Swiss place name and you need its IRI to filter cube observations.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesPlace name to search for (e.g., 'Zürich', 'Ticino', 'Bern')
languageNode

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, placing the full burden on the description. The description only states the tool works for specific place types and gives a usage scenario, but does not disclose behaviors like error handling, case sensitivity, or whether it returns multiple matches. This is adequate but not thorough.

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 extremely concise with two sentences: the first states the purpose and scope, the second gives usage guidance. Every word adds value, and the structure is front-loaded with the core function.

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?

For a simple lookup tool, the description provides essential context about the types of places and the use case. However, it lacks details about error conditions and multiple results, which would improve completeness for an agent. Given the low complexity, the description is mostly adequate.

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?

The schema covers one parameter (name) with a description; language has enum and default but no description (50% coverage). The description does not add meaning beyond what the schema provides for the language parameter, nor does it compensate for the missing parameter description.

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 resolves a place name to a LINDAS IRI, specifying it works for cantons, municipalities, and districts. This distinguishes it from sibling tools like get_cantons or query_observations.

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 explicitly says to use this tool when a user mentions a Swiss place name and needs its IRI to filter cube observations. It does not explicitly mention when not to use it, but the context of sibling tools provides implicit guidance.

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

search_datasetsA

Full-text search across LINDAS cubes by title and description. Use this when looking for datasets about a specific topic (e.g., 'population', 'forest', 'unemployment').

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYesText to search for

TDQS

A3.6/5.0
Behavior2/5

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

With no annotations provided, the description bears full responsibility for behavioral disclosure. It only states the search scope and does not mention whether the operation is read-only, any authentication requirements, rate limits, pagination, or result format. This is insufficient for an agent to understand the tool's full behavior.

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 two sentences with no extraneous information. The first sentence declares the core function, and the second provides usage guidance. Every word is useful, and it is front-loaded with the key action.

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

Completeness3/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 params, no output schema), the description provides the core purpose and usage guidance. However, it lacks detail about the return format, pagination, or how results are ranked. Without an output schema, more information about what the agent should expect would improve completeness. Score 3 is adequate but with gaps.

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

Parameters2/5

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

The schema description coverage is 50% (query has 'Text to search for', limit has no description). The tool description adds no meaning to either parameter beyond what the schema provides. It mentions 'by title and description' but that describes the search scope, not the parameter semantics. For a tool with less than 80% coverage, the description should compensate, but it does not.

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 'Full-text search across LINDAS cubes by title and description', providing a specific verb, resource, and scope. It distinguishes itself from sibling tools like list_cubes (which lists all cubes without search) and query_observations (which queries data). The examples ('population', 'forest', 'unemployment') further clarify the tool's purpose.

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 explicitly states when to use the tool: 'Use this when looking for datasets about a specific topic'. This provides clear context. However, it does not explicitly mention when not to use it or name alternative tools, though siblings are listed. This aligns with the '4=clear context, no exclusions' level.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedcount_observations
    • First observedget_cantons
    • First observedget_cube_structure
    • First observedget_dimension_values
    • First observedlist_cubes
    • First observedquery_observations
    • First observedresolve_geography
    • First observedsearch_datasets

TDQS

A4.1/5.0

Scored across 8 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: discovery (list_cubes, search_datasets), schema exploration (get_cube_structure, get_dimension_values, get_cantons), counting (count_observations), querying (query_observations), and geography resolution (resolve_geography). No two tools overlap in function.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., count_observations, get_cube_structure, list_cubes). The naming is predictable and easy to parse.

Tool Count5/5

With 8 tools, the server is well-scoped for its purpose of exploring and querying Swiss open data cubes. Each tool earns its place, covering discovery, schema analysis, and data retrieval without unnecessary redundancy.

Completeness5/5

The tool set covers the full workflow for a read-only data cube explorer: discovering cubes, understanding structure and dimensions, filtering with valid values, counting results, and fetching observations. The inclusion of geography resolution and text search fills common needs.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Provides AI-native access to Swiss Federal Statistical Office datasets through 9 tools for querying education, population, and cross-cantonal comparisons without authentication.
    15
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to the Swiss I14Y Interoperability Platform, enabling natural language exploration of government datasets, APIs, codelists, and public services.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables reproducible analysis of 100 curated Swiss open-data resources by searching profiles, materializing PXWeb data, validating and executing SQL, and formatting reproduction details, with reasoning delegated to the MCP client.
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    MCP server for LINDAS, the linked-data knowledge graph of the Swiss administration, enabling querying of Swiss public data cubes via guarded SPARQL tools.
    7
    MIT