Skip to main content
Glama
malkreide

swiss-cultural-heritage-mcp

by malkreide

πŸ‡¨πŸ‡­ Part of the Swiss Public Data MCP Portfolio

πŸ›οΈ swiss-cultural-heritage-mcp

Version License: MIT Python 3.11+ MCP No Auth Required CI

MCP Server for Swiss cultural heritage β€” SIK-ISEA artists, Nationalmuseum collections, and the Nationalbibliothek bibliography

πŸ‡©πŸ‡ͺ Deutsche Version


Overview

swiss-cultural-heritage-mcp provides AI-native access to Swiss cultural heritage data sources, all without authentication:

Source

Data

API

SIK-ISEA (SIKART)

~17,000 Swiss artists β€” SIKART biographical data

opendata.swiss CKAN

Nationalmuseum (SNM)

Museum collections (numismatics, seals, special collections)

opendata.swiss CKAN

Nationalbibliothek (NB)

Swiss national bibliography (Helveticat)

SRU (search) + OAI-PMH (collections)

Memoriav / Memobase

Audiovisual heritage (photo, audio, video)

Linked Open Data (JSON-LD / Hydra)

Dodis

Diplomatic Documents of Switzerland (documents, persons, organisations)

JSON-REST (Solr) + permalinks

This server completes the humanistic dimension of the Swiss public data portfolio β€” history, literature, and art β€” alongside existing servers for law (fedlex-mcp), transport, statistics, and more.

The memory-institution facade (Memobase + Dodis) is exposed through three federated tools β€” search_heritage, get_heritage_item, list_heritage_collections β€” rather than one tool-family per source. Every result carries source, permalink and licence, and the licence is reported separately for metadata and for the digitised object (they diverge: metadata is open Linked Open Data, but a digitised object may be In Copyright). Only metadata and links are returned β€” copyright-protected full texts (e.g. Dodis transcriptions) are never reproduced.

Anchor demo query (art): "Find works by Zurich-based painters from the 19th century in the Nationalmuseum, and cross-reference with their biography in the SIK-ISEA artist database."

Anchor demo query (memory institutions): "Which sources on the development of the Zurich Volksschule in the 19th century can be found in the Swiss memory institutions?" β†’ search_heritage(query="Volksschule ZΓΌrich", collection="all", date_from="1800", date_to="1899").

Demo

Demo: Claude using heritage_cross_search


Related MCP server: Swiss Data Protection MCP

Features

  • πŸ›οΈ 11 tools, 2 resources, 2 prompts across five data sources

  • πŸ” heritage_cross_search β€” parallel search across SIK-ISEA + SNM + NB in a single call

  • πŸ›οΈ search_heritage β€” federated facade over Memobase + Dodis with per-result source, permalink and split metadata/digitised-object licence

  • 🌐 Bilingual output (Markdown / JSON)

  • πŸ”“ No API key required β€” all data under open licenses

  • ☁️ Dual transport β€” stdio (Claude Desktop) + Streamable HTTP (cloud)

  • πŸ“š Prompt templates for art research and finding educational materials

Project phase: Phase 1 β€” read-only. Every tool is annotated readOnlyHint: true; there are no write or destructive operations. Moving to Phase 2 (write-capable) requires the prerequisites in docs/roadmap.md.


Prerequisites

  • Python 3.11+

  • uv (recommended) or pip


Installation

# Clone the repository
git clone https://github.com/malkreide/swiss-cultural-heritage-mcp.git
cd swiss-cultural-heritage-mcp

# Install
pip install -e .
# or with uv:
uv pip install -e .

Or with uvx (no permanent installation):

uvx swiss-cultural-heritage-mcp

Quickstart

# stdio (for Claude Desktop)
python -m swiss_cultural_heritage_mcp.server

# Streamable HTTP (port 8000)
python -m swiss_cultural_heritage_mcp.server --http --port 8000

Try it immediately in Claude Desktop:

"Who is Ferdinand Hodler?" "What coins does the Nationalmuseum have from Zurich?" "Find publications about Volksschule in the Swiss national bibliography"

β†’ More use cases by audience β†’


Configuration

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "swiss-cultural-heritage": {
      "command": "python",
      "args": ["-m", "swiss_cultural_heritage_mcp.server"]
    }
  }
}

Or with uvx:

{
  "mcpServers": {
    "swiss-cultural-heritage": {
      "command": "uvx",
      "args": ["swiss-cultural-heritage-mcp"]
    }
  }
}

Config file locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Cloud Deployment (SSE for browser access)

For use via claude.ai in the browser (e.g. on managed workstations without local software):

Render.com (recommended):

  1. Push/fork the repository to GitHub

  2. On render.com: New Web Service β†’ connect GitHub repo

  3. Select region Frankfurt (EU) β€” required for Swiss public-sector use under revDSG / EDΓ–B. See docs/data-residency.md.

  4. Set start command: python -m swiss_cultural_heritage_mcp.server --http --port 8000

  5. In claude.ai under Settings β†’ MCP Servers, add: https://your-app.onrender.com/sse

πŸ’‘ "stdio for the developer laptop, SSE for the browser."

For container deployments (Docker / Kubernetes / Cloud Run): the repository ships a hardened Dockerfile (non-root UID 10001). See docs/security.md for recommended SecurityContext and docs/network-egress.md for egress policy. The service runs single-instance by default; before scaling horizontally, see docs/scaling.md for the session-affinity prerequisites.


Available Tools

SIK-ISEA (Swiss Art Research)

Tool

Description

heritage_search_artists

Search ~17,000 Swiss artists (SIKART) by name or place

heritage_get_artist

Full artist profile by SIKART ID (HAUPTNR)

Nationalmuseum (SNM)

Tool

Description

heritage_search_museum_datasets

Search SNM datasets on opendata.swiss

heritage_browse_collection

Browse objects within a collection via CKAN DataStore

Nationalbibliothek (NB)

Tool

Description

heritage_search_helveticat

Full-text search over the whole holdings (SRU), or browse one collection (OAI-PMH)

heritage_list_nb_collections

List the 68 available OAI-PMH sets

heritage_get_publication

Selected MARC21 fields for one publication, normalised to Dublin-Core-style keys (OAI-PMH GetRecord) β€” not the complete catalogue record

Cross-Source

Tool

Description

heritage_cross_search

Parallel search across SIK-ISEA + SNM + NB

Memory institutions (Memobase + Dodis) β€” federated facade

Tool

Description

search_heritage

Federated search over Memobase + Dodis (collection = memobase | dodis | all), with date_from / date_to / media_type filters. Every result carries source, permalink and a split metadata/digitised-object licence

get_heritage_item

Full metadata for one object (collection, item_id). Metadata + links only β€” protected full texts are never reproduced

list_heritage_collections

Discovery: which collections exist, their protocol, auth and licences β€” including the probed-but-not-connected sources (Bundesarchiv, Landesmuseum) and why

Example Use Cases

Query

Tool

"Who is Ferdinand Hodler?"

heritage_get_artist

"Find Swiss artists born in Basel"

heritage_search_artists

"What coins from Zurich does the Nationalmuseum have?"

heritage_browse_collection

"Find publications about Volksschule"

heritage_search_helveticat

"Search for everything about Sophie Taeuber-Arp"

heritage_cross_search

"Sources on the 19th-c. Zurich Volksschule in Swiss memory institutions"

search_heritage


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Claude / AI   │────▢│  Swiss Cultural Heritage MCP  │────▢│  SIK-ISEA                β”‚
β”‚   (MCP Host)    │◀────│  (MCP Server)                │◀────│  opendata.swiss / CKAN   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚                              β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                        β”‚  11 Tools Β· 2 Resources      │────▢│  Nationalmuseum (SNM)    β”‚
                        β”‚  2 Prompts                   │◀────│  opendata.swiss / CKAN   β”‚
                        β”‚  Stdio | SSE                 β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                        β”‚                              │────▢│  Nationalbibliothek (NB) β”‚
                        β”‚  No authentication required  │◀────│  Helveticat: SRU, OAI-PMHβ”‚
                        β”‚                              β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                        β”‚  search_heritage facade      │────▢│  Memobase (JSON-LD/Hydra)β”‚
                        β”‚                              │◀────│  Dodis (JSON-REST/Solr)  β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Source Characteristics

Source

Protocol

Coverage

Auth

SIK-ISEA (SIKART)

CKAN DataStore

~17,000 Swiss artists

None

Nationalmuseum

CKAN DataStore

Museum collections

None

Nationalbibliothek

SRU 1.2 (CQL) + OAI-PMH 2.0

Swiss national bibliography

None

Memoriav / Memobase

Linked Open Data (JSON-LD / Hydra, RiC-O)

Audiovisual heritage (~460k records)

None

Dodis

JSON-REST (Solr) + stable permalinks

Diplomatic documents, persons, organisations

None

Architecture decision β€” memory-institution facade

Verified by a live probe on 2026-07-19 (methodology: mcp-data-source-probe). Four memory institutions were evaluated; only two expose a clean, no-auth, standardised interface and are connected:

Source

Result

Why

Memobase

βœ… connected

Linked-Open-Data API (api.memobase.ch, JSON-LD/Hydra); full-text search via ?q=, single record via /record/<id>; pagination via offset/size. Metadata open; digitised objects carry per-object rightsstatements.org rights ("In Copyright", access "onsite").

Dodis

βœ… connected

JSON-REST/Solr (beta.dodis.ch/api): search via POST /api/solr/query, item via GET /api/solr/full/<id>; stable permalinks dodis.ch/<id>. Metadata open (citation required); documents carry per-document rights (TEI/PDF behind the permalink).

Bundesarchiv

β›” not connected

The recherche.bar.admin.ch backend (CMI AIS) sits behind eIAM login and Google reCAPTCHA β€” not machine-accessible without emulating a session, which is fragile and against the operator's intent.

Landesmuseum

β›” not connected

sammlung.nationalmuseum.ch has no public API (only an internal, undocumented Ajax/HTML surface) β€” connecting it would require scraping, which violates the resilience guardrails.

Consequences: three federated tools instead of four tool-families; every result carries source + permalink + a split metadata/digitised-object licence; no copyright-protected full text is reproduced (metadata + links only); bar and landesmuseum are documented as gated via list_heritage_collections, not scraped.


Project Structure

swiss-cultural-heritage-mcp/
β”œβ”€β”€ src/swiss_cultural_heritage_mcp/
β”‚   β”œβ”€β”€ __init__.py              # Package
β”‚   └── server.py                # 11 tools, 2 resources, 2 prompts
β”œβ”€β”€ tests/
β”‚   └── test_server.py           # Unit + integration tests (mocked HTTP)
β”œβ”€β”€ .github/workflows/ci.yml     # GitHub Actions (Python 3.11/3.12/3.13)
β”œβ”€β”€ .github/dependabot.yml       # Monthly dependency + SDK update PRs
β”œβ”€β”€ Dockerfile                   # Multi-stage, non-root, HEALTHCHECK
β”œβ”€β”€ docs/                        # security, network-egress, scaling, data-residency, roadmap
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ CONTRIBUTING.md
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md                    # This file (English)
└── README.de.md                 # German version

Single-file server: the 11 tools live in one server.py rather than a tools/ package. At this size a single, linear module is easier to read and review than a split; if the tool count grows materially, the SIK-ISEA / SNM / NB / cross-search blocks are the natural split points.


Safety & Limits

  • Read-only: All tools perform HTTP GET requests only β€” no data is written, modified, or deleted.

  • No personal data: The APIs return institutional records (artworks, publications, artists). No personally identifiable information (PII) is processed or stored by this server.

  • Rate limits: No throttling was observed in roughly 380 probe requests on 2026-09-20. That says nothing about the published terms: the National Library's SRU and OAI-PMH terms of use have not been checked by this project (see PROBE_REPORT_helveticat.md). Use limit parameters conservatively. The server enforces a 30s timeout per request.

  • Data freshness: Records reflect the upstream source at query time. No caching is performed by this server.

  • Terms of service: Data is subject to the ToS of each source β€” SIK-ISEA, opendata.swiss, Nationalbibliothek. The opendata.swiss datasets carry open licences (CC0 / CC BY). For the National Library this project has not verified the terms of either endpoint. Where a record carries its own rights statement it is surfaced as rights (MARC 506/540) β€” many records carry none. The licence line in the attribution footer is the source's general statement, not a per-record one, and JSON responses carry no footer at all. Check with the source before redistributing.

  • No guarantees: This server is a community project, not affiliated with SIK-ISEA, SNM, or NB. Availability depends on upstream APIs.


Known Limitations

  • SIK-ISEA: Artist data is updated periodically; very recent acquisitions may not yet be reflected

  • Nationalmuseum: Only datasets published on opendata.swiss are accessible; not all SNM collections are available

  • Nationalbibliothek: maximumRecords is capped at 50 server-side, silently β€” a request for more returns 50 without a warning. SRU cannot filter by OAI set, so query and set_spec use different endpoints and cannot be combined into one server-side search. from_date/until_date are the catalogue record's modification dates, not publication years. Measured 2026-09-20; see PROBE_REPORT_helveticat.md.

  • Cross-search: Response time depends on the slowest of the three sources


Testing

# Unit tests (no API key required)
PYTHONPATH=src pytest tests/ -m "not live"

# Integration tests (live API calls)
pytest tests/ -m "live"

# Lint and format, as CI runs them
ruff check src/ tests/ scripts/
ruff format --check src/ tests/ scripts/

Ruff is pinned to an exact version in pyproject.toml ([project.optional-dependencies] dev), so pip install -e ".[dev]" gives you the version CI uses and the lint gates agree with it. Installing a newer ruff on top changes the rule set and the formatter, and reports differences on code nobody touched. See CONTRIBUTING.md.


MCP Protocol Version

Item

Value

SDK

mcp[cli]>=2.0.0,<3 (pinned in pyproject.toml)

Served via the initialize handshake

2024-11-05 … 2025-11-25 β€” the handshake ceiling

Served via the per-request envelope

2026-07-28

Who picks

The client's first request, once per connection: a request carrying the 2026-07-28 _meta envelope opens a modern connection, anything else opens a handshake connection. A later claim from the other era is refused.

Update policy

The SDK pin is the source of truth for the protocol version. Dependabot opens monthly mcp update PRs; protocol-version bumps are reviewed there and recorded in CHANGELOG.md.

This server does not override the negotiation β€” the official mcp SDK decides, and both eras are reachable over either transport (stdio and HTTP alike). Pin the SDK, not a hand-rolled version string, to control which protocol versions are spoken. The numbers above are the pinned SDK's own registry (mcp_types.version: HANDSHAKE_PROTOCOL_VERSIONS, MODERN_PROTOCOL_VERSIONS) β€” read them there rather than from this table if the pin has moved.

Both revisions are pinned in tests/test_protocol_version.py and asserted against the installed SDK β€” including the handshake ceiling, measured against a live initialize through the assembled ASGI stack. A Dependabot bump of mcp can no longer move either number without this table going stale unnoticed.

Server identity

Field

Value

Source

name

swiss-cultural-heritage-mcp

__dist__ β€” the PyPI name, also in server.json

title

Schweizer Kulturerbe

server.SERVER_TITLE

version

the shipped package version

pyproject.toml via importlib.metadata

description

the PyPI one-liner

pyproject.toml β†’ [project].description

websiteUrl

the project homepage

pyproject.toml β†’ [project.urls].Homepage

instructions

what this server is for

server.INSTRUCTIONS

The identifier is hyphenated, like the repository, the PyPI package and the console script. The Python module keeps underscores β€” python -m swiss_cultural_heritage_mcp.server above is not an inconsistency, it is the only spelling Python allows for a package name.

The 2026-07-28 era has no handshake. Instead of sending serverInfo once per connection, the SDK stamps the identity into the _meta of every response, and server/discover carries exactly one field beyond the capabilities: instructions.

The SDK supplies none of these on its own β€” Server.server_info says so outright: "An unversioned server reports an empty version; the SDK never substitutes its own." Until 18 September 2026 this server passed none of them and reported "version": "" on every call. That is now measured in tests/test_server_identity.py, across both eras and through real HTTP requests: a constructor argument that is set is not yet a field on the wire.

Version, description and URL are derived, not written. A literal in the shipped path would be a second truth next to pyproject.toml β€” the very drift scripts/check_version_sync.py forbids for the version number.


Changelog

See CHANGELOG.md


Contributing

See CONTRIBUTING.md


Security

See SECURITY.md (Deutsch) for the security posture and how to report a vulnerability.


License

MIT License β€” see LICENSE


Author

Hayal Oezkan Β· malkreide


Installation

Run via uv's uvx β€” no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):

{
  "mcpServers": {
    "swiss-cultural-heritage-mcp": {
      "command": "uvx",
      "args": [
        "swiss-cultural-heritage-mcp"
      ]
    }
  }
}

Available Tools

11 tools
get_heritage_itemA
Read-onlyIdempotent

Ruft die vollstΓ€ndigen Metadaten eines Objekts aus Memobase oder Dodis ab.

Liefert Metadaten, Permalink und Lizenz (Metadaten- und Digitalisat-/Dokument- recht getrennt). GeschΓΌtzte Volltexte (Dodis-Transkriptionen) werden nicht reproduziert β€” dafΓΌr verweist die Antwort auf den Permalink.

Args: params (HeritageItemInput): - collection: 'memobase' oder 'dodis' - item_id (str): Objekt-ID aus search_heritage - response_format: 'markdown' oder 'json'

Returns: ResultEnvelope | str: Objekt-Metadaten inkl. Provenienz und Lizenz.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds meaningful behavioral context beyond annotations, notably that protected full texts (Dodis transcriptions) are not reproduced and the response links to the permalink instead. It also discloses the response format options (markdown/json), improving transparency.

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 and well-structured, using an Args/Returns layout. It front-loads the main action, adds a key caveat, and lists parameters in a compact way. Every sentence contributes 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?

The description covers the core functionality, supported collections, output contents, protected-text behavior, and response formats. Minor gaps include no mention of error handling or default response_format, but given the presence of annotations and an output schema, the overall context is adequate for correct tool usage.

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?

Despite the schema description coverage being 0%, the description's Args section summarizes all three parameters (collection, item_id, response_format) with their valid values and clarifies that item_id originates from search_heritage. While it omits the schema's concrete examples, it provides a functional overview that helps the agent understand parameter roles.

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 opens with a specific verb and resource: 'Ruft die vollstΓ€ndigen Metadaten eines Objekts aus Memobase oder Dodis ab.' It clearly distinguishes itself from sibling search and list tools by targeting single-object metadata retrieval, and further specifies that it returns permalink, license, provenance, and a caveat about protected full texts.

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 implies the expected workflow by stating that item_id comes from 'search_heritage', which gives clear context for when to use this tool. However, it does not explicitly name alternative tools or provide exclusion criteria (e.g., 'don't use for full-text extraction'), so it falls just short of full explicit guidance.

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

heritage_browse_collectionA
Read-onlyIdempotent

Durchsucht Objekte innerhalb eines SNM-Sammlungsdatensatzes via CKAN DataStore.

Voraussetzung: Resource-ID aus heritage_search_museum_datasets.

Args: params (CollectionBrowseInput): - resource_id (str): CKAN Resource-ID (aus heritage_search_museum_datasets) - query (str | None): Suchbegriff (z. B. 'ZΓΌrich', 'Karl der Grosse', 'Gold') - limit / offset: Paginierung - response_format: 'markdown' oder 'json'

Returns: str: Liste von Sammlungsobjekten mit verfΓΌgbaren Feldern.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description's addition of return format and prerequisite adds context but does not significantly extend beyond what annotations imply. No behavioral aspects like rate limits or auth are mentioned, but annotations suffice.

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?

Structured with a concise intro, prerequisite line, bullet-pointed args, and returns line. Every sentence is purposeful and front-loaded with the main action. No wasted words, appropriate length.

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?

Given rich annotations and an existing output schema, the description covers the prerequisite, input parameters, and return format. It explains pagination via limit/offset and response_format choices. It feels complete for a browsing tool, with no missing critical information.

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?

Description adds value beyond the schema by listing parameters with examples (e.g., query: 'ZΓΌrich', 'Karl der Grosse', 'Gold') and clarifying the prerequisite for resource_id. Although schema coverage is 0%, the description compensates well by explaining each parameter's purpose and usage.

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?

Description clearly states it searches objects within an SNM collection dataset via CKAN DataStore. The verb 'Durchsucht' and specific resource 'Objekte innerhalb eines SNM-Sammlungsdatensatzes' provide clear purpose. The prerequisite for resource ID from heritage_search_museum_datasets further distinguishes it from sibling tools like heritage_cross_search.

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 the prerequisite of having a resource ID from heritage_search_museum_datasets, guiding when to use this tool. However, it does not explicitly state when not to use it or provide alternative tools for similar tasks, though sibling names give implicit context.

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

heritage_get_artistA
Read-onlyIdempotent

Ruft den vollstΓ€ndigen SIKART-Datensatz zu einer KΓΌnstlerΒ·in ab.

Args: params (ArtistDetailInput): - artist_id (str): SIKART-ID (HAUPTNR aus heritage_search_artists) - response_format: 'markdown' oder 'json'

Returns: str: VollstΓ€ndiges Profil mit Lebensdaten, Orten, Kurzbiografie und Links.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive. Description adds return value details (profile with life data, places, biography, links). No contradictions.

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

Conciseness4/5

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

Description is well-structured with Args and Returns sections, but could be slightly more front-loaded. No fluff, but the bullet list could be more compact.

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?

Given the simple nature (one parameter object with two fields), annotations, and presumed output schema, the description covers everything needed: input usage, return format, and data included.

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?

Despite schema description coverage at 0%, the description clearly explains both parameters: artist_id cross-references sibling tool, and response_format lists possible values with default. Adds meaning beyond schema.

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?

Description clearly states it retrieves the complete SIKART dataset for an artist. Distinguishes from sibling 'heritage_search_artists' which is for searching, as this tool takes a specific ID to get full details.

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 notes the prerequisite: artist_id from heritage_search_artists. Does not provide when-not or alternatives, but context is sufficient for a simple retrieval tool.

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

heritage_get_publicationA
Read-onlyIdempotent

Ruft die Metadaten einer Publikation der NB ab β€” ausgewΓ€hlte MARC21-Felder.

Die Quelle liefert MARCXML. Dieses Werkzeug bildet daraus eine Auswahl von Feldern auf Dublin-Core-Γ€hnliche SchlΓΌssel ab: Titel, UrheberΒ·innen, Mitwirkende, Verlag, Erscheinungsjahr, Typ, Umfang, Sprache, SchlagwΓΆrter, Beschreibung, Rechte, Reihe und Identifier.

Was NICHT enthalten ist: alles ausserhalb dieser Auswahl β€” Kontrollfelder, die Ausgabebezeichnung (MARC 250), Erscheinungsverlauf, lokale Felder. Β«VollstΓ€ndige MetadatenΒ» wΓ€re also falsch, und die Antwort darf nicht als der ganze Katalogsatz gelesen werden. Wer den braucht, nimmt den Permalink aus identifier und geht an die Quelle.

Args: params (PublicationDetailInput): - identifier (str): OAI-ID aus heritage_search_helveticat - response_format: 'markdown' oder 'json'

Returns: str: AusgewΓ€hlte, auf DC-SchlΓΌssel normalisierte Felder β€” nicht der vollstΓ€ndige Katalogsatz.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already mark the tool as read-only and idempotent, but the description adds substantial behavioral context: the source is MARCXML, the output is a selective Dublin-Core-like mapping, and it explicitly lists excluded fields such as MARC 250, control fields, and local fields. The warning not to interpret the response as the complete catalog record is particularly valuable.

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 compact relative to the ground it covers: purpose, field selection, exclusion list, and docstring-style Args/Returns sections. Every sentence earns its place, and the most important misuse riskβ€”treating the result as the full catalog recordβ€”is clearly emphasized.

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 read-only retrieval tool with one required identifier plus an optional format, the description is complete: it states the input provenance, the output mapping, the excluded fields, and the fallback for full metadata. Since an output schema exists, the absence of a detailed return schema is not a gap.

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 Args block names both parameters and restates what the embedded schema already provides: identifier is the OAI-ID from heritage_search_helveticat and response_format is 'markdown' or 'json'. It adds no new parameter-level semantics, such as how the markdown and json outputs differ, so it meets the baseline but does not exceed it.

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 names a concrete operation: 'Ruft die Metadaten einer Publikation der NB ab' and immediately scopes it to 'ausgewΓ€hlte MARC21-Felder'. It also explicitly distinguishes the result from a full catalog record, making it easy to separate from sibling search 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?

The description implies the right entry point by saying the identifier comes from heritage_search_helveticat, and it gives a clear alternative for full metadata: 'Wer den braucht, nimmt den Permalink aus identifier und geht an die Quelle.' It does not enumerate all sibling tools, but for its scope the guidance is clear.

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

heritage_list_nb_collectionsA
Read-onlyIdempotent

Listet verfΓΌgbare Sammlungen/Sets der Nationalbibliothek auf (OAI-PMH ListSets).

Args: params (NbCollectionsInput | None): - response_format: 'markdown' (Standard) oder 'json'

Returns: str: Liste aller OAI-PMH Sets mit Bezeichner (setSpec) und Name.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=true, indicating no side effects. The description adds that the tool performs an OAI-PMH ListSets request and returns a list with setSpec and name, which is useful but does not significantly enhance the behavioral profile beyond what annotations provide. No contradictions.

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

Conciseness4/5

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

The description is concise with a clear one-sentence purpose followed by structured Args and Returns sections. It front-loads the main action and avoids fluff. The total length is appropriate for the tool's simplicity.

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?

The description covers the input parameter and return format comprehensively for a simple list tool. It mentions the output contains setSpec and name. However, it lacks details on pagination, if applicable, or sample output. Given the tool's low complexity and presence of an output schema (per context), the description is nearly complete.

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 has descriptions for NbCollectionsInput and ResponseFormat, but context indicates low schema coverage. The description adds the default value and explains that response_format can be 'markdown' (default) or 'json'. This is helpful but largely redundant given the schema's enum and default. With only one parameter and schema already providing structure, the description adds marginal value.

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 lists available collections/sets of the national library via OAI-PMH ListSets. It specifies the verb 'listet' (lists) and the resource 'Sammlungen/Sets der Nationalbibliothek', making the purpose unambiguous. This distinguishes it from sibling tools like 'heritage_browse_collection' which likely explores a specific collection.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus alternatives. The description does not mention prerequisites, use cases, or exclude scenarios. While the sibling tools offer browsing, searching, and retrieval, the description fails to explicitly differentiate usage, leaving the agent to infer from tool names.

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

heritage_search_artistsA
Read-onlyIdempotent

Sucht Schweizer KΓΌnstlerΒ·innen in den SIKART-Daten (~17'000 EintrΓ€ge).

SIKART (Lexikon zur Kunst in der Schweiz, herausgegeben vom Schweizerischen Institut fΓΌr Kunstwissenschaft SIK-ISEA) dokumentiert historische und zeitgenΓΆssische Kunstschaffende mit biografischen Grunddaten. Die Suche lΓ€uft als CKAN-DataStore-Volltextsuche ΓΌber alle Felder; mehrere Begriffe werden UND-verknΓΌpft. Liefert die exakte Suche keine Treffer, wird automatisch breiter mit dem spezifischsten Begriff gesucht und das Resultat als match_type: fuzzy markiert (ARCH-003); bleibt es leer, match_type: none.

Args: params (ArtistSearchInput): - query (str | None): Name, Beruf oder Stichwort (z. B. 'Hodler') - region (str | None): Geburts-/Sterbeort oder Kanton (z. B. 'Basel') - limit (int): Max. Ergebnisse (Standard: 20) - offset (int): Paginierungs-Offset - response_format: 'markdown' oder 'json'

Returns: str: Liste gefundener KΓΌnstlerΒ·innen mit Name, Lebensdaten, Kanton, Kurzbiografie.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Discloses full-text search, AND combination, automatic fuzzy fallback, and match_type markers. Annotations already indicate readOnly and idempotent, so the description adds value beyond that.

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?

Efficient structure: purpose sentence, data source, search mechanics, then bullet-point Args, and Returns. No wasted words; front-loaded with key 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?

Given the tool's complexity (search, fallback, pagination, output format), the description covers all aspects including return format and examples. Output schema is described in the 'Returns' section.

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 description lists each parameter with meanings and examples (e.g., 'Hodler', 'Basel') Add meaningful context beyond the schema, which has descriptions but context signal indicates 0% overlay 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?

The description clearly states it searches for Swiss artists in the SIKART database using a specific verb ('Sucht') and resource. It distinguishes from sibling tools like heritage_get_artist (single artist) and heritage_search_helveticat (library catalog).

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool versus alternatives like heritage_cross_search or heritage_get_artist. The description focuses on search mechanics but omits situational advice.

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

heritage_search_helveticatA
Read-onlyIdempotent

Durchsucht die Schweizerische Nationalbibliothek (Helveticat).

Zwei ZugΓ€nge derselben Quelle, und der Aufruf wΓ€hlt sie:

  • query ohne set_spec β†’ SRU, eine echte serverseitige Volltextsuche ΓΌber den Gesamtbestand, mit Trefferzahl. Findet die Anfrage nichts, wird einmal gelockert wiederholt (alle WΓΆrter statt der Wortfolge) und das Ergebnis als match_type: fuzzy markiert.

  • set_spec (mit oder ohne Zeitfenster) β†’ OAI-PMH, das eine Sammlung seitenweise ausliefert. query filtert dann nur noch innerhalb der abgerufenen Seite; die Ausgabe sagt das.

Die Trennung ist nicht Geschmack, sondern gemessen: SRU kennt die OAI-Sets nicht (alma.mms_memberOf="helveticat" β†’ 0 Treffer), und OAI-PMH kennt keine Volltextsuche. Beide Identifier sind dieselben, also frisst heritage_get_publication jedes Ergebnis von beiden Wegen.

Args: params (HelvticatSearchInput): - query (str | None): Suchbegriff (serverseitig ohne set_spec) - set_spec (str | None): Sammlung aus heritage_list_nb_collections - from_date (str | None): Γ„nderungsdatum von (nur mit set_spec) - until_date (str | None): Γ„nderungsdatum bis (nur mit set_spec) - limit (int): Max. Ergebnisse 1–50 (Standard: 10) - response_format: 'markdown' oder 'json'

Returns: str: Liste von Publikationen mit Titel, Autor, Jahr, SchlagwΓΆrtern und Identifier.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/openWorldHint/idempotentHint=true and destructiveHint=false, covering the safety profile. The description adds genuinely valuable behavioral context beyond that: the one-time loosened fuzzy retry marked as match_type: fuzzy, the pagination semantics of OAI-PMH (query filters only within the fetched page), and the measured incompatibility of the two protocols. This is rich additional disclosure, though the date-parameter caveat partly lives in the schema.

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

Conciseness4/5

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

The description is dense but every sentence earns its place: purpose, two-mode bullet list, the bolded measured-split rationale, then a compact Args list and Returns line. It is front-loaded with the purpose and scannable via bullets. Only modest over-length from the appended protocol-comparison paragraph, which is justified by the tool's genuine complexity.

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 tool combining two protocols with conditional parameters, a fuzzy retry, date-semantics caveats, and an output-format choice (markdown/json), the description covers purpose, both usage paths, param constraints, and return shape ('Liste von Publikationen mit Titel, Autor, Jahr, SchlagwΓΆrtern und Identifier'). It is near-complete; the only minor gap is no explicit statement of how the markdown vs json output differs.

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 description's Args section adds key interaction semantics the schema alone cannot convey: query is a server-side full-text search WITHOUT set_spec but only filters within the fetched page WITH it; from_date/until_date apply solely with set_spec. While the schema properties do carry their own descriptions, the conditional relationships and the two-protocol branching are unique to the description. Strong compensation despite the 0% schema-coverage signal.

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 opening line 'Durchsucht die Schweizerische Nationalbibliothek (Helveticat)' names a specific verb, resource, and institution. The description then distinguishes two concrete access modes (SRU full-text vs OAI-PMH collection browse), and explicitly references the sibling heritage_get_publication for consuming results β€” clearly differentiating it from siblings like heritage_search_artists and heritage_browse_collection.

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 gives explicit when-to-use guidance for each mode: 'query ohne set_spec' β†’ SRU full-text search, 'set_spec' β†’ OAI-PMH collection browse, and explains why they are not interchangeable ('SRU kennt die OAI-Sets nicht... OAI-PMH kennt keine Volltextsuche'). It names the alternative heritage_get_publication for fetching results and heritage_list_nb_collections for obtaining set specs. Nothing is left to inference.

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

heritage_search_museum_datasetsA
Read-onlyIdempotent

Sucht DatensΓ€tze des Schweizerischen Nationalmuseums (SNM) auf opendata.swiss.

Das SNM publiziert Sammlungsdaten als Open Data: Numismatik (~100'000 MΓΌnzen), Siegelsammlung (~80'000 Objekte), Spezialsammlungen und weitere. Bei 0 exakten Treffern wird die Solr-Suche automatisch gelockert (OR-verknΓΌpfte PrΓ€fix-Wildcards) und das Resultat als match_type: fuzzy markiert (ARCH-003).

Args: params (MuseumSearchInput): - query (str | None): Suchbegriff ΓΌber Titel/Beschreibung - collection (str | None): Sammlungsfilter (z. B. 'numismatik') - limit / offset: Paginierung - response_format: 'markdown' oder 'json'

Returns: str: Liste verfΓΌgbarer SNM-DatensΓ€tze mit Titel, Beschreibung und Download-URLs (CSV, XLSX, JSON).

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already mark readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds valuable behavioral detail: automatic query relaxation to OR wildcards on zero exact hits and fuzzy marking. No contradictions.

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

Conciseness4/5

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

The description is well-structured with clear sections: purpose, data scope, special behavior, args, returns. It is concise and informative, though the fuzzy matching detail could be integrated more tightly. No wasted sentences.

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?

Given the presence of an output schema, the description adequately covers all necessary aspects: tool purpose, data source, query behavior, parameter details, and return format. It is complete for agent invocation without additional context.

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?

Despite schema coverage of 0% in the description, the text includes a detailed args section explaining each parameter's purpose, type, and examples (e.g., 'query' searches title/description, 'collection' filters like 'numismatik'). This adds significant meaning beyond the schema alone.

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 and resource: 'Sucht DatensΓ€tze des Schweizerischen Nationalmuseums auf opendata.swiss', specifying the exact domain and data source. It differentiates from siblings like heritage_browse_collection by focusing on cross-collection search via opendata.swiss, though not explicitly.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It does not mention when not to use it, prerequisites, or compare with sibling tools like heritage_cross_search. Usage context is implied but not explicit.

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

list_heritage_collectionsA
Read-onlyIdempotent

Listet die GedΓ€chtnisinstitutionen der fΓΆderierten Fassade und ihren Status auf.

Discovery-Tool fΓΌr search_heritage / get_heritage_item: welche collection-Werte gibt es, welches Protokoll, welche Auth, welche Lizenz (Metadaten vs. Digitalisat)? Auch die geprΓΌften, aber bewusst nicht angebundenen Quellen (Bundesarchiv, Landesmuseum) werden mit Grund ausgewiesen.

Args: params (HeritageCollectionsInput | None): - response_format: 'markdown' (Standard) oder 'json'

Returns: ResultEnvelope | str: Sammlungen mit Status, Protokoll, Auth und Lizenzen.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds behavioral context by explaining that the tool lists status, protocols, auth, licenses, and even discloses deliberately non-connected sources with reasons. This goes beyond the annotation flags and gives the agent a realistic picture of the tool's output scope.

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 compact and well-structured: a front-loaded purpose sentence, a discovery context sentence, a note about excluded sources, and a structured Args/Returns block. Every sentence contributes useful information, with no redundancy or filler.

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?

With an output schema present and a moderate complexity, the description covers the essential aspects: purpose, usage relationship to sibling tools, parameter options, and return content (ResultEnvelope | str with collections/status/protocol/auth/licenses). It does not discuss error cases or format details, but overall it is complete enough for reliable 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?

Despite schema description coverage of 0%, the description compensates by documenting the params structure: HeritageCollectionsInput | None, with response_format accepting 'markdown' (default) or 'json'. It adds meaning beyond the raw schema by stating the default and the allowed values. However, it does not explain what the markdown vs. json output looks like, which is a minor gap.

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 opens with a specific verb+resource claim: 'Listet die GedΓ€chtnisinstitutionen der fΓΆderierten Fassade und ihren Status auf.' It further distinguishes itself from siblings by positioning it as a discovery tool for search_heritage/get_heritage_item and specifying what it reveals (collection values, protocol, auth, license). This clearly separates it from the sibling list tools like heritage_list_nb_collections.

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: as a Discovery-Tool for search_heritage and get_heritage_item, to enumerate available collection values and their protocols/auth/licenses. It also explains that non-connected sources are included with reasons. It lacks an explicit 'when not to use' statement but provides sufficient context for appropriate selection.

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

search_heritageA
Read-onlyIdempotent

Durchsucht Schweizer GedΓ€chtnisinstitutionen (Memobase, Dodis) fΓΆderiert.

FΓΆderierte Fassade ΓΌber zwei Quellen mit offenen, standardisierten Schnittstellen: Memobase (audiovisuelles Kulturerbe, Linked-Open-Data-API) und Dodis (Diplomatische Dokumente der Schweiz, JSON-REST/Solr). Bei collection='all' wird parallel gesucht; fΓ€llt eine Quelle aus, liefern die ΓΌbrigen trotzdem (die Fehlerquelle wird im meta.errors und β€” sofern ein Progress-Token vorliegt β€” via ctx.warning gemeldet).

Jeder Treffer trΓ€gt Quelle, Permalink und Lizenz, wobei Metadaten- und Digitalisat-Lizenz getrennt ausgewiesen werden (sie fallen bei diesen Quellen auseinander). Es werden nur Metadaten und Links geliefert β€” keine geschΓΌtzten Volltexte.

date_from/date_to/media_type werden clientseitig auf die je Quelle abgerufene Seite angewandt (die Upstreams bieten hierfΓΌr keine verlΓ€sslichen Serverfilter); die Trefferzahl kann dadurch kleiner als limit sein β€” ggf. offset erhΓΆhen.

Args: params (HeritageSearchInput): - query (str): Suchbegriff - collection: 'memobase' | 'dodis' | 'all' - date_from/date_to: Jahr-Filter (clientseitig) - media_type (str): Typ-Filter (clientseitig) - limit/offset: Paginierung pro Quelle - response_format: 'markdown' oder 'json' ctx (Context): vom MCP-SDK injiziert (Progress/Warnungen); bei direktem Aufruf None.

Returns: ResultEnvelope | str: Aggregierte, normalisierte Treffer inkl. Provenienz.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

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

Even with annotations declaring readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, the description adds substantial behavioral detail: parallel federated search, partial failure tolerance with error reporting via meta.errors and ctx.warning, separate metadata/digitization licenses, and the explicit statement that only metadata and links are returnedβ€”no protected full texts. It also explains client-side filtering and its impact on result counts, which is valuable beyond the annotations.

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

Conciseness4/5

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

The description is well-structured: a clear one-liner opening, followed by paragraphs on federated behavior, hit details, client-side filtering, Args, and Returns. It front-loads the purpose and uses headers/bullets effectively. It is somewhat longer than strictly necessary because the Args section partially duplicates schema information, but the additional context earns its place, so it remains appropriately concise.

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 complex federated search tool with multiple parameters and edge cases, the description is complete. It covers error handling, licensing, client-side filtering, pagination, and the output format (ResultEnvelope | str). The presence of an output schema means detailed return values are not needed, but the description still states that results include provenance. This is a thorough and self-sufficient description.

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?

The description includes an 'Args:' section that covers all parameters and adds meaning beyond the schema. For example, it specifies that date_from/date_to and media_type are applied client-side, that limit/offset paginate per source, and that ctx is injected by the MCP SDK. The schema itself has basic descriptions, but the description enriches them with behavioral context and clarifies the federated semantics.

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 starts with 'Durchsucht Schweizer GedΓ€chtnisinstitutionen (Memobase, Dodis) fΓΆderiert,' which clearly states the verb (searches), resource (Swiss memory institutions), and scope (federated across Memobase and Dodis). It is specific, but it does not explicitly differentiate itself from sibling tools like heritage_cross_search or heritage_search_helveticat, so it stops short of a 5.

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 the tool is appropriate: it searches specific sources (Memobase and Dodis), and explains the default behavior for collection='all' including failure tolerance. It also notes that date and media type filters are client-side, which guides expectations. However, it does not explicitly mention alternatives or 'when not to use' this tool, so it lacks the exclusionary guidance needed for a 5.

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. 1 tool updatev0.6.0
    • Changedheritage_search_helveticat4 fields changed
      • changedInput schema / $defs / HelvticatSearchInput / properties / from_date / description
        Previous value: -"Publikationen ab diesem Datum (YYYY oder YYYY-MM-DD)"New value: +"Nur KatalogsΓ€tze, die seit diesem Datum geΓ€ndert wurden (YYYY-MM-DD). ACHTUNG: Γ„nderungsdatum des Katalogsatzes, NICHT Erscheinungsjahr β€” ein Buch von 1890 kann letzte Woche bearbeitet worden sein. Nur zusammen mit `set_spec`."
      • changedInput schema / $defs / HelvticatSearchInput / properties / query / description
        Previous value: -"Suchbegriff fΓΌr clientseitige Filterung (Titel, Autor, Schlagwort) β€” z. B. 'Volksschule ZΓΌrich', 'Gottfried Keller', 'Bildungspolitik'. Hinweis: OAI-PMH unterstΓΌtzt keine serverseitige Volltextsuche."New value: +"Suchbegriff (Titel, AutorΒ·in, Schlagwort) β€” z. B. 'Volksschule ZΓΌrich', 'Gottfried Keller', 'Bildungspolitik'. Ohne `set_spec` lΓ€uft er als serverseitige Volltextsuche ΓΌber den ganzen Bestand; zusammen mit `set_spec` filtert er nur innerhalb der abgerufenen Seite dieser Sammlung."
      • changedInput schema / $defs / HelvticatSearchInput / properties / set_spec / description
        Previous value: -"OAI-Set-Bezeichner (aus heritage_list_nb_collections) β€” z. B. 'swissbook'"New value: +"Sammlung durchblΓ€ttern statt suchen β€” OAI-Set-Bezeichner aus heritage_list_nb_collections (z. B. 'swissbook', 'xrara'). Schliesst die serverseitige Volltextsuche aus: die Sammlungen sind dort nicht abbildbar."
      • changedInput schema / $defs / HelvticatSearchInput / properties / until_date / description
        Previous value: -"Publikationen bis zu diesem Datum (YYYY oder YYYY-MM-DD)"New value: +"Nur KatalogsΓ€tze, die bis zu diesem Datum geΓ€ndert wurden (YYYY-MM-DD). Γ„nderungsdatum, nicht Erscheinungsjahr. Nur zusammen mit `set_spec`."
  2. 3 tool updatesv0.5.0
    • Addedget_heritage_item
    • Addedlist_heritage_collections
    • Addedsearch_heritage
  3. 8 tool updatesv0.3.0
    • Changedheritage_browse_collection3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_cross_search5 fields changed
      • addedInput schema / $defs / CrossSearchInput / properties / response_format
        Added value: +{
        +  "$ref": "#/$defs/ResponseFormat",
        +  "default": "markdown"
        +}
      • addedInput schema / $defs / ResponseFormat
        Added value: +{
        +  "description": "Ausgabeformat fΓΌr Tool-Antworten.",
        +  "enum": [
        +    "markdown",
        +    "json"
        +  ],
        +  "title": "ResponseFormat",
        +  "type": "string"
        +}
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_get_artist3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_get_publication3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_list_nb_collections3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_search_artists3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_search_helveticat3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
    • Changedheritage_search_museum_datasets3 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "ResultEnvelope": {
        +    "description": "Einheitlicher Response-Envelope fΓΌr Such-/Listen-Tools.",
        +    "properties": {
        +      "count": {
        +        "description": "Anzahl zurΓΌckgegebener EintrΓ€ge",
        +        "title": "Count",
        +        "type": "integer"
        +      },
        +      "has_more": {
        +        "default": false,
        +        "description": "Weitere Ergebnisse verfΓΌgbar",
        +        "title": "Has More",
        +        "type": "boolean"
        +      },
        +      "match_type": {
        +        "default": "exact",
        +        "description": "Trefferart (ARCH-003): 'exact' = direkte Suche, 'fuzzy' = gelockerte/erweiterte Suche nach 0 exakten Treffern, 'none' = keine Treffer",
        +        "enum": [
        +          "exact",
        +          "fuzzy",
        +          "none"
        +        ],
        +        "title": "Match Type",
        +        "type": "string"
        +      },
        +      "meta": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Tool-spezifische Zusatzfelder",
        +        "title": "Meta"
        +      },
        +      "offset": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Paginierungs-Offset",
        +        "title": "Offset"
        +      },
        +      "results": {
        +        "description": "DatensΓ€tze (quellnah)",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "title": "Results",
        +        "type": "array"
        +      },
        +      "source": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/SourceInfo"
        +          },
        +          {
        +            "items": {
        +              "$ref": "#/$defs/SourceInfo"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "Quelle(n) inkl. Lizenz",
        +        "title": "Source"
        +      },
        +      "total": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Gesamtzahl upstream verfΓΌgbar",
        +        "title": "Total"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "count"
        +    ],
        +    "title": "ResultEnvelope",
        +    "type": "object"
        +  },
        +  "SourceInfo": {
        +    "description": "Provenienz und Lizenz einer Datenquelle.",
        +    "properties": {
        +      "license": {
        +        "title": "License",
        +        "type": "string"
        +      },
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "url": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Url"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "license"
        +    ],
        +    "title": "SourceInfo",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/$defs/ResultEnvelope"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / properties / result / type
        Removed value: -"string"
  4. 8 tool updatesv0.2.0
    • First observedheritage_browse_collection
    • First observedheritage_cross_search
    • First observedheritage_get_artist
    • First observedheritage_get_publication
    • First observedheritage_list_nb_collections
    • First observedheritage_search_artists
    • First observedheritage_search_helveticat
    • First observedheritage_search_museum_datasets

TDQS

A3.9/5.0

Scored across 11 tools

Disambiguation3/5

The source-specific tools are clearly separated into search/detail pairs for SIKART, the National Library, the SNM, and the Memobase/Dodis facade. However, `heritage_cross_search` and `search_heritage` are both multi-source search tools covering different institutions, and `heritage_list_nb_collections` vs. `list_heritage_collections` have similar names, so descriptions are needed to avoid misselection.

Naming Consistency3/5

Eight tools follow a `heritage_<verb>_<object>` pattern, but `search_heritage`, `get_heritage_item`, and `list_heritage_collections` reverse the order, breaking predictability. The verbs are specific and all names are readable snake_case, so the naming is mixed rather than chaotic.

Tool Count5/5

11 tools is a well-scoped count for the stated purpose of searching Swiss cultural heritage sources. Each search tool has a corresponding detail/lookup tool, plus collection discovery and cross-search tools, without unnecessary redundancy.

Completeness4/5

The set covers search and detail for SIKART, the National Library, the National Museum datasets/objects, and the Memobase/Dodis facade, along with collection discovery and cross-searching. Minor gaps remain: there is no single-object retrieval for SNM objects beyond a browse query, and no unified cross-search across all five sources.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers