mcpField
U
unesco-heritage-mcp-server

unesco-heritage-mcp-server

Remote
github.com/cyanheadsMaps & Travel2Updated 2w ago
Repository

About unesco-heritage-mcp-server

unesco-heritage-mcp-server lets heritage researchers and travel planners search and retrieve UNESCO records across four programs. It supports geographic and category filters, detailed records, and dataset attribution.

Key features

  1. 01Search four UNESCO heritage datasets
  2. 02Filter by country, category, and year
  3. 03Search by coordinates and distance
  4. 04Retrieve full records and linked data
  5. 05Check danger status and reference data

Use cases

  1. 01Find World Heritage sites near a location
  2. 02Review a site's record and criteria
  3. 03Explore links to intangible heritage

MCP support

It exposes nine search, retrieval, and reference tools plus four record resources to MCP clients over STDIO or Streamable HTTP.

Configuration

Remote servers need no local install. Pick your client, then copy the config or install in one click.

Endpointhttps://unesco-heritage.caseyjhand.com/mcp
Copy install command
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.

Packages
npm@cyanheads/unesco-heritage-mcp-server0.2.1

Tools

9
ParameterTypeRequiredDescription
nearobjectNoOnly sites within radius_km of this point: a site matches when its representative point or any of its components lies within the radius, and a site with neither never matches. distance_km and the distance sort use the nearest of those points.
near.latitudenumberYesLatitude of the point, in decimal degrees (−90 to 90).
near.longitudenumberYesLongitude of the point, in decimal degrees (−180 to 180).
near.radius_kmnumberNoSearch radius in kilometres (up to 5000, default 100).
sortenumNoResult order. Default: relevance when query is set, else distance when near is set, else name. relevance needs query; distance needs near. Absent areas and Danger years sort last.relevance | name | inscribed_newest | inscribed_oldest | area_largest | danger_listed_newest | distance
limitintegerNoMaximum results per page (1–50, default 20).
querystringNoKeywords; every word must match the start of a word in a site's name (any of six languages), description, or statement of Outstanding Universal Value. Case, accents, and punctuation are ignored, so the query must contain at least one letter or digit and at most 16 distinct words; no phrases, operators, or fuzzy matching.
cursorstringNoOpaque continuation cursor from the previous call's next_cursor. Pass it with the same filters and sort to fetch the next page.
regionenumNoUNESCO region: Africa, Arab States, Asia and the Pacific, Europe and North America, or Latin America and the Caribbean (codes AFR, ARB, APA, EUR, LAC accepted).Africa | Arab States | Asia and the Pacific | Europe and North America | Latin America and the Caribbean
countrystringNoISO 3166-1 alpha-2 or alpha-3 code, any case (FR, FRA). Matches every site the country takes part in, transboundary sites included. For a country name, look up its code with unesco_list_reference (topic countries).
categoryenumNoSite category: Cultural, Natural, or Mixed.Cultural | Natural | Mixed
criteriaarrayNoInscription criteria a site must all carry. (i) A masterpiece of human creative genius. (ii) An important interchange of human values over time or within a cultural area, in architecture, technology, monumental arts, town planning, or landscape design. (iii) A unique or exceptional testimony to a cultural tradition or a civilization, living or vanished. (iv) An outstanding example of a type of building, architectural or technological ensemble, or landscape illustrating significant stages in human history. (v) An outstanding example of traditional human settlement, land use, or sea use representative of a culture or of human interaction with the environment, especially where vulnerable to irreversible change. (vi) Direct association with events, living traditions, ideas, beliefs, or artistic and literary works of outstanding universal significance. (vii) Superlative natural phenomena, or areas of exceptional natural beauty and aesthetic importance. (viii) An outstanding example of a major stage of Earth's history, including the record of life, significant ongoing geological processes, or significant landforms. (ix) An outstanding example of significant ongoing ecological and biological processes in the evolution of ecosystems and communities of plants and animals. (x) The most important natural habitats for in-situ conservation of biological diversity, including those holding threatened species of outstanding universal value. Criterion (vi) is inferred from the statement of Outstanding Universal Value, since UNESCO's criteria fields omit it.
in_dangerbooleanNotrue: only sites on the List of World Heritage in Danger. false: only sites not on it. Omit for both.
inscribed_tointegerNoLatest inscription year, inclusive.
transboundarybooleanNotrue: only sites shared by more than one State Party. false: only single-State sites.
inscribed_fromintegerNoEarliest inscription year, inclusive.
include_descriptionbooleanNoSet false to leave each row's description out of the response (default true); unesco_get_site returns it. Which sites match, their order, and matched_in are unchanged.

Details

From the project README

@cyanheads/unesco-heritage-mcp-server

Search UNESCO World Heritage sites, intangible heritage, biosphere reserves, and Global Geoparks via MCP. STDIO or Streamable HTTP.

9 Tools • 4 Resources

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Overview

UNESCO's World Heritage List, Intangible Cultural Heritage lists, Biosphere Reserves, and Global Geoparks. Search and read full records, check the List of World Heritage in Danger, and find sites, reserves, or geoparks near any point. No API key required.

Tools
ToolDescription
unesco_search_sitesSearch World Heritage sites by keyword, country, category, region, criteria, inscription years, Danger-list or transboundary status, or distance from a point
unesco_get_siteFetch a site's full record: statement of Outstanding Universal Value, criteria with meanings, component parts, coordinates, and image credit
unesco_search_intangible_heritageSearch the three intangible heritage lists by keyword, country, list, inscription years, multinational status, or linked World Heritage site
unesco_get_intangible_heritage_elementFetch an element's full record: description, list, countries, concept terms, linked sites, and image credit
unesco_search_biosphere_reservesSearch biosphere reserves by keyword, country, region, MAB regional network, designation years, transboundary or SIDS status, or distance from a point
unesco_get_biosphere_reserveFetch a reserve's full record: ecological and socio-economic profile, zoned areas and population, review years, and coordinates
unesco_search_geoparksSearch UNESCO Global Geoparks by keyword, country, designation years, transnational status, or distance from a point
unesco_get_geoparkFetch a geopark's full record: introduction, description, account of sustaining local communities, recorded area and population, and coordinates
unesco_list_referenceDecode criteria, countries (name to ISO code), regions, intangible heritage lists, and MAB networks; report dataset coverage and data dates
Resources
ResourceDescription
unesco://site/{id_no}One World Heritage site record
unesco://intangible-heritage/{ich_ref}One intangible heritage element record
unesco://biosphere-reserve/{mab_id}One biosphere reserve record
unesco://geopark/{ugg_id}One UNESCO Global Geopark record

Each resource mirrors a get tool.

Capability reference

unesco_search_sites tool
  • Filters: query, country (ISO 3166-1 alpha-2 or alpha-3), category, region, criteria (every listed criterion required), in_danger, transboundary, inscribed_from / inscribed_to, and near (latitude, longitude, radius_km up to 5000, default 100), which matches a site through its representative point or any of its components
  • Up to 50 sites per page (default 20; a larger limit, up to 10,000, is served as 50 and says so in notice), continued with next_cursor; sort takes relevance, name, inscribed_newest, inscribed_oldest, area_largest, danger_listed_newest, or distance; include_description: false leaves row descriptions out
  • in_danger: true is the List of World Heritage in Danger; totalCount and facets (category, region, Danger status, criteria, top 10 countries) cover the whole match; rows carry matched_in when query is set, and distance_km to the nearest of the site's points (with nearest_component when a component is nearer) when near is set

unesco_get_site tool
  • One site by id_no: a number, a digit string, or the site's whc.unesco.org page URL; max_components lists up to 1000 component parts (default 20; a larger value, up to 10,000, is served as 1000 and says so in notice)
  • Description, statement of Outstanding Universal Value, criteria[] with meanings and source: "recorded" | "inferred", States Parties with ISO codes, coordinates, area, secondary_years, Danger-list year, names in six languages, and the main image with its credit
  • description_language (en, fr, es, ru, ar, zh) returns UNESCO's description in that language and names it in description_language; where UNESCO publishes none, the English one comes back as en with a notice. The statement of Outstanding Universal Value is English only
  • components_total is UNESCO's count and components_unparsed the entries that could not be read; an unknown id fails as site_not_found

unesco_search_intangible_heritage tool
  • Filters: query, country, list (Representative List, Urgent Safeguarding List, Register of Good Safeguarding Practices; RL / USL / Art18 accepted), multinational, world_heritage_site (an id_no), and inscribed_from / inscribed_to
  • Up to 50 elements per page (default 20; a larger limit, up to 10,000, is served as 50 and says so in notice), continued with next_cursor; rows omit the description and carry primary concepts and linked world_heritage_sites
  • facets cover list, multinational status, the top 10 countries, and the top 10 concept terms

unesco_get_intangible_heritage_element tool
  • One element by ich_ref: a number, a digit string, or the element's ich.unesco.org page URL
  • Description, list, countries, inscription year, primary and secondary concepts, linked world_heritage_sites, UNESCO page, and the main image with its caption and credit; an unknown ref fails as element_not_found
  • description_language: "fr" returns UNESCO's French description (English and French are the only languages UNESCO publishes), with the same English fallback and notice as unesco_get_site

unesco_search_biosphere_reserves tool
  • Filters: query (name, introduction, and ecological or socio-economic text; there is no biome field, so search habitat words), country, region, regional_network (name or acronym), transboundary, sids, designated_from / designated_to, and near
  • Up to 50 reserves per page (default 20; a larger limit, up to 10,000, is served as 50 and says so in notice), continued with next_cursor; sort takes relevance, name, designated_newest, designated_oldest, area_largest, or distance; include_description: false leaves row introductions out
  • A transboundary reserve appears once per participating country, each with its own mab_id; facets cover region, regional network, transboundary and SIDS status, and the top 10 countries

unesco_get_biosphere_reserve tool
  • One reserve by mab_id, matched without regard to case or accents
  • Introduction, ecological and socio-economic characteristics, terrestrial and marine area by zone, population by zone, designation, extension, renaming, and periodic-review years, coordinates, website, and UNESCO page
  • Areas (hectares) and populations pass through as recorded: zone sums can differ from totals, and a population of 0 can mean none or unreported; an unknown id fails as biosphere_reserve_not_found

unesco_search_geoparks tool
  • Filters: query (name, introduction, description, and community account; search landform words such as volcanic or karst), country, transnational, designated_from / designated_to, and near, measured to each geopark's one point
  • Up to 50 geoparks per page (default 20; a larger limit, up to 10,000, is served as 50 and says so in notice), continued with next_cursor; sort takes relevance, name, designated_newest, designated_oldest, area_largest, or distance; include_description: false leaves row introductions out
  • A transnational geopark is one row listing each of its countries; facets cover transnational status and the top 10 countries; a year bound whose range starts at or before 2015 adds a notice that geoparks recognized before the designation existed are dated 2015

unesco_get_geopark tool
  • One geopark by ugg_id (such as EUFR10), in any case
  • Countries, designation year, transnational status, area and population as recorded (population is absent when UNESCO records none), coordinates, introduction, description, the account of sustaining local communities, website, and UNESCO page; an unknown id fails as geopark_not_found

unesco_list_reference tool
  • topic: criteria, countries, regions, intangible_lists, biosphere_networks, or datasets
  • filter keeps matching rows; on countries, a country name, an ISO code, or a common former name returns the codes every country input accepts, with the country's count of sites, intangible elements, reserves, and geoparks
  • datasets reports each dataset's record count, data_as_of, license, attribution line, and coverage notes

unesco://site/{id_no} resource
  • The unesco_get_site record with up to 20 components (components_total carries the full count) and the English description, plus sources, as application/json; id_no comes from unesco_search_sites

unesco://intangible-heritage/{ich_ref} resource
  • The unesco_get_intangible_heritage_element record with the English description, plus sources, as application/json; ich_ref comes from unesco_search_intangible_heritage

unesco://biosphere-reserve/{mab_id} resource
  • The unesco_get_biosphere_reserve record plus sources, as application/json; mab_id comes from unesco_search_biosphere_reserves, percent-encoded when it holds non-ASCII letters

unesco://geopark/{ugg_id} resource
  • The unesco_get_geopark record plus sources, as application/json; ugg_id comes from unesco_search_geoparks

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

UNESCO-specific:

  • Datasets whc001 (World Heritage List), ich001 (Intangible Heritage List), mab001 (Man and the Biosphere Programme), and eg0001 (UNESCO Global Geoparks) each load on first use as an in-memory snapshot (two upstream requests) and refresh every 24 hours; searching, facets, and distance run locally, and a failed refresh keeps serving the previous snapshot
  • Upstream traffic is paced at two concurrent requests and at most 200 a day, with a cooldown after a 429 that honors Retry-After
  • Criterion (vi), which UNESCO's criteria fields omit, is inferred from each site's statement of Outstanding Universal Value and marked as inferred wherever it appears
  • Country inputs take ISO 3166-1 alpha-2 or alpha-3 codes in any case and match every transboundary site, multinational element, or transnational geopark a country takes part in; site and element ids also accept their UNESCO page URLs

Agent-friendly output:

  • Attribution on every response: sources names each dataset with its data_as_of date, license, and credit line
  • Search results report the whole match: totalCount, facets, and an applied_filters echo of the filters and sort the server ran
  • Keyword matching is word-prefix with every word required (up to 16 distinct words), and matched_in says which field tier matched; a zero-hit notice names the filter whose removal would match the most records
  • Typed errors (unknown_country, invalid_year_range, sort_needs_input, cursor_mismatch, invalid_cursor, *_not_found, snapshot_unavailable) carry a recovery hint naming the next call; snapshot_unavailable is retryable with retryAfter when the Data Hub is unreachable, and not retryable when it rejects the request or serves data the server cannot use

Data and licensing

All four datasets come from the UNESCO Data Hub and are licensed CC BY-SA 4.0. Credit UNESCO when you reuse the data; every response's sources block carries a ready-made credit line. Under ShareAlike, adapted data must be shared under the same license.

Images are not covered by that license. Each World Heritage and intangible heritage image keeps its own copyright, and its holder and photographer travel with the image record. The server returns image links but never fetches or proxies them.

This server is an independent project and is not affiliated with or endorsed by UNESCO.

Getting started

Public Hosted Instance

A public instance is available at https://unesco-heritage.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "unesco-heritage-mcp-server": {
      "type": "streamable-http",
      "url": "https://unesco-heritage.caseyjhand.com/mcp"
    }
  }
}
Self-Hosted / Local

Add the following to your MCP client configuration file.

{
  "mcpServers": {
    "unesco-heritage-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/unesco-heritage-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "unesco-heritage-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/unesco-heritage-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "unesco-heritage-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/unesco-heritage-mcp-server:latest"]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key or account: the UNESCO Data Hub is open.
Installation
  1. Clone the repository:
git clone https://github.com/cyanheads/unesco-heritage-mcp-server.git
  1. Navigate into the directory:
cd unesco-heritage-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment (optional):
cp .env.example .env
# edit .env to change the transport, port, or log level

Configuration

The server has no settings of its own; these framework variables apply.

VariableDescriptionDefault
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_HTTP_HOSTHTTP server host.127.0.0.1
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto. .env.example and the Docker image set stateless.auto
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<app-root>/logs
OTEL_ENABLEDEnable OpenTelemetry.false

See .env.example for the common framework overrides.

Running the server

Local development
  • Build and run the production version:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:http
    # or
    bun run start:stdio
    
  • Run checks and tests:

    bun run devcheck  # Lints, formats, type-checks, and more
    bun run test      # Runs the test suite
    

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point: registers the tools and resources, serves the server instructions from src/mcp-server/instructions.ts, and starts and stops the service.
src/mcp-server/toolsTool definitions (*.tool.ts).
src/mcp-server/resourcesOne record resource per dataset.
src/mcp-server/sharedInput schemas and normalizers, enrichment fields, and markdown helpers shared by the tools and resources.
src/services/unesco-datahubUNESCO Data Hub service: snapshot loading and refresh, row validation and repair, search and facets, the ISO 3166 table, and vocabularies.
tests/Unit tests over synthetic fixtures, mirroring the src/ structure.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for logging and ctx.enrich for attribution, totals, and notices
  • Register new tools and resources in the createApp() arrays in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.