@cyanheads/met-museum-mcp-server
Enriches artwork records retrieved from the Met Museum collection with Wikidata entity URLs for artists, tags, and works, letting agents follow linked-data references from objects to their Wikidata counterparts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/met-museum-mcp-serverSearch for Monet paintings with open access images."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://met-museum.caseyjhand.com/mcp
Overview
The Metropolitan Museum of Art's public Collection API. Search the collection by keyword and filters, or browse it by department and update date, then fetch full object records — metadata, provenance, and CC0 open-access images — from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Return all 19 curatorial departments with their numeric IDs and display names |
| Search the collection by keyword with filters for department, date range, medium, geography, image availability, on-view status, and highlight designation |
| List every object ID in a department, every object created or revised since a date, or both, without a keyword |
| Fetch full records for one or more object IDs — metadata, provenance, artist info, CC0 image URLs, tags, and Wikidata links |
Related MCP server: open-museum-mcp
Capability reference
met_list_departments tool
No input; returns all 19 curatorial departments, each a numeric
departmentIdwith itsdisplayName(e.g., "Egyptian Art")departmentIdvalues are the valid input for thedepartmentIdfilter onmet_search_collectionsandmet_list_objectsTyped errors:
upstream_blockedandretry_deadline_exceeded(the call's time budget ran out)
met_search_collections tool
Keyword
q(required) plus filters:departmentId,medium(a case-sensitive classification as the Met spells it —"Paintings", not"Oil on canvas"),dateBegin/dateEnd(integer years, negative = BCE, set together), onegeoLocation,hasImages,isOnView, andisHighlight(trueonly)Up to 500 IDs per page (default 20), paged by
offset/nextOffsetthrough the first 10,000 matches only;totalstill reports the full count, with anoticewhen it exceeds 10,000Typed errors:
no_results(its recovery names the filters that removed every match),invalid_date_range,invalid_filter(a blankq,medium, orgeoLocation),invalid_department,upstream_blocked,retry_deadline_exceeded
met_list_objects tool
Filters
departmentId(frommet_list_departments) andupdatedSince(YYYY-MM-DD— records created or revised on or after that day), alone or together; with neither, the whole collection (over 500,000 IDs). Up to 500 IDs per page (default 20), in ascending order, paged byoffset/nextOffsetwith no depth limitTyped errors:
invalid_department,invalid_date(an impossible date such as2026-02-30),upstream_blocked,retry_deadline_exceeded; an empty list is a result, not an error, with anoticenaming the filtersEach list is cached for up to an hour, so a record revised within the last hour may not appear yet
met_get_object tool
1–20 IDs per call, from
met_search_collectionsormet_list_objects; a repeated ID is fetched and returned oncePartial success: per-ID errors land in
failed[], and the call fails only when every ID does —all_not_foundwhen every ID was a 404,upstream_blockedwhen the Met's firewall refused a request,retry_deadline_exceededwhen every fetch ran out of the call's time budget, andall_failedotherwise; records past a 60,000-bytestructuredContentbudget are listed indeferred[]with their sizes, to re-requestisPublicDomain/hasCC0Imagegate image URLs — non-public-domain objects return emptyprimaryImage,primaryImageSmall, andadditionalImages; sparse fields are empty or null, never fabricated
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.
Met Museum-specific:
500K+ artworks spanning 5,000 years from the Met's public collection API
CC0 open-access data from The Metropolitan Museum of Art — free to use without permission or attribution
Parallel batch fetching with configurable concurrency for
met_get_objectLinked data on every object — Getty ULAN and AAT URLs, Wikidata entity URLs for artists, tags, and works
A 403 from the Met's firewall surfaces on every tool as
upstream_blocked, non-retryable: the block covers the server's address for minutes, so the recovery is to wait and send fewer requests
Agent-friendly output:
Provenance on every record —
isPublicDomainandhasCC0Imageflags distinguish CC0 objects from works with inaccessible images, so agents can reason about what they can actually displayPartial failure reporting —
met_get_objectreturnsobjectsandfailedarrays so callers receive successful records alongside structured per-ID error contextTruncation signaling —
met_search_collectionsandmet_list_objectsreturntotal,returned,truncated,remaining,nextOffset, and the resolvedoffset; the text marks each page(truncated),(complete), or(offset beyond result set), and search adds(window end)for a page that stops at its 10,000-match window short oftotalByte-budget disclosure —
met_get_objectreportsdeferred[]records with their sizes when a batch exceeds its serialized-response budget, so callers can size a follow-up call precisely
Getting started
Public Hosted Instance
A public instance is available at https://met-museum.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"met-museum-mcp-server": {
"type": "streamable-http",
"url": "https://met-museum.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"met-museum-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/met-museum-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"met-museum-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/met-museum-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"met-museum-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/met-museum-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/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key required — the Met Collection API is public and unauthenticated.
Installation
Clone the repository:
git clone https://github.com/cyanheads/met-museum-mcp-server.gitNavigate into the directory:
cd met-museum-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env as needed (all vars are optional)Configuration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts.
Variable | Description | Default |
| Transport: |
|
| HTTP server port |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only) |
|
| Log each failed tool call's arguments and result, redacted by key name and capped at |
|
| Enable OpenTelemetry instrumentation |
|
| Met Collection API root; each endpoint appends its own version ( |
|
| Per-request HTTP timeout in milliseconds |
|
| Wall-clock budget in milliseconds for one tool call, shared by every Met API request it makes, retries and backoff included. A call that runs out fails with |
|
| Max parallel fetches in |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t met-museum-mcp-server .
docker run --rm -p 3010:3010 met-museum-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/met-museum-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Met Collection API client — HTTP, call deadline, response normalization, cached object-ID lists. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools via the arrays in
createApp()insrc/index.tsWrap 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 testData attribution
Data from The Metropolitan Museum of Art Collection API (CC0).
License
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Art MCP — Metropolitan Museum of Art Collection API (free, no auth)
Unlock a world of art with the Met Museum MCP! Use the 'search_artworks' API to find stunning
Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.
Art Institute of Chicago MCP — wraps the ARTIC public API (free, no auth)
Related MCP Servers
- AlicenseAqualityBmaintenanceA MCP Server that lets user ask AI models to discover the collection of the Metropolitan Museum of Art. Adds the discovered art works as Resources on the server.4201 npm34MIT
- AlicenseAqualityAmaintenanceFederated, license-verified search across open-access museum collections — currently The Met, Cleveland, AIC, Wikimedia Commons, and Europeana, with more being added. Strict-default-deny rights gate accepts only CC0 / Public Domain Mark, returning reuse-safe artwork with citations in three styles.5140 npm13MIT
- AlicenseNot gradedqualityAmaintenanceSearch artists, releases, recordings, works, and labels; traverse relationships; resolve ISRC/ISWC/barcode; fetch cover art via MCP. STDIO or Streamable HTTP.120 npm1Apache 2.0
- AlicenseAqualityDmaintenanceMCP server for searching museum collections and viewing artwork images and metadata from multiple museums, including the Met, Art Institute of Chicago, Rijksmuseum, and more.248 npm2MIT