CCM
/MCP
SkillsMCPMarketplacesDigestToolsAdvertise

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by Category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP Servers by Category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by Category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control

Claude Code Marketplaces

Discover Claude Code plugins, extensions, and tools. Automatically updated directory of Anthropic Claude AI marketplaces with development tools, productivity plugins, and integrations.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Marketplaces
  • Skill index
  • MCP index
  • Marketplace index
  • Plugins Reference

Community

  • About
  • Tools
  • Feedback
  • Privacy Policy
  • Advertise

Built for the Claude Code community with Claude Code by mertbuilds.com

Independent project, not affiliated with Anthropic
cyanheads avatar

Met Museum Mcp Server

cyanheads/met-museum-mcp-server
33 toolsSTDIO, HTTPregistry active
Summary

Connects Claude to the Metropolitan Museum of Art's public collection API with three focused tools: list all 19 curatorial departments, search 500K+ artworks by keyword with filters for date range, medium, geography, and public domain status, and fetch full object records including provenance, artist bios, Getty and Wikidata links, and CC0 image URLs. Built on the Met's open API, so no authentication required. Handles batch fetching for up to 20 objects at once with partial failure reporting, and surfaces CC0 flags so you know which images are actually usable. Reach for this when you need structured art historical data, open access images for display, or want to let Claude search museum collections with precise filtering rather than keyword scraping.

Install to Claude Code

verified
claude mcp add --transport http met-museum https://met-museum.caseyjhand.com/mcp

Run in your terminal. Add --scope user to make it available in every project.

Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.

CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →

Tools

Verified live against the running server on Jun 10, 2026.

verified live3 tools
met_list_departmentsReturn the 19 curatorial departments at The Metropolitan Museum of Art with their numeric IDs and display names. Use before calling met_search_collections to discover valid departmentId values. The department list is fetched live on each call to remain accurate if the Met reor...

Return the 19 curatorial departments at The Metropolitan Museum of Art with their numeric IDs and display names. Use before calling met_search_collections to discover valid departmentId values. The department list is fetched live on each call to remain accurate if the Met reor...

No parameters — call it with no arguments.

met_search_collectionsSearch the Metropolitan Museum of Art collection by keyword and optional filters; returns total match count and a page of object IDs. Always chain the returned IDs to met_get_object (up to 20 at a time) to retrieve full records. Search relevance is keyword-based, not semantic...11 params

Search the Metropolitan Museum of Art collection by keyword and optional filters; returns total match count and a page of object IDs. Always chain the returned IDs to met_get_object (up to 20 at a time) to retrieve full records. Search relevance is keyword-based, not semantic...

Parameters* required
dateBegininteger
Earliest object date (year, inclusive). Negative integers for BCE (e.g., -500 for 500 BCE). Requires dateEnd.
dateEndinteger
Latest object date (year, inclusive). Negative integers for BCE. Requires dateBegin.
departmentIdinteger
Restrict results to one curatorial department. Use met_list_departments to get valid IDs (1–21, not all integers are valid). Can be combined with other filters; combining with isPublicDomain works...
geoLocationarray
Filter by geographic origin. Each value is matched broadly against geography fields and artist nationality. Multiple values are AND-combined — ["France", "Egypt"] returns objects associated with bo...
hasImagesboolean
When true, restricts results to objects that have at least one associated image. For freely reusable CC0 images, use isPublicDomain instead — hasImages includes copyrighted works whose images canno...
isHighlightboolean
When true, restricts to objects the Met has designated as highlights — major works central to the collection. Use to surface iconic pieces rather than browsing the full corpus.
isOnViewboolean
When true, restricts results to objects currently on display in a Met gallery. The GalleryNumber field on the met_get_object record identifies the specific gallery. Combine with a keyword to answer...
isPublicDomainboolean
When true, restricts results to objects released under CC0 open access — free to use without permission or attribution. These objects return direct high-resolution image URLs in met_get_object. Can...
limitinteger
Maximum number of object IDs to return from the full result set. The API returns all matches (up to tens of thousands) — this caps what is handed back. Chain the returned IDs to met_get_object in b...default: 20
mediumstring
Filter by object classification (e.g., "Paintings", "Drawings", "Prints", "Ceramics", "Sculpture", "Photographs", "Textiles"). Maps to the classification field on the object, not the materials/medi...
q*string
Keyword query. Searched across title, artist name, culture, medium, tags, and other text fields. Use concise, specific terms — broad queries return large ID sets. Tip: departmentId and geoLocation...
met_get_objectFetch full records for one or more Met Museum object IDs. Accepts up to 20 IDs per call, fetches in parallel (concurrency-limited), and returns partial-success — a single 404 does not fail the whole batch. Object IDs come from met_search_collections. Non-public-domain objects...1 params

Fetch full records for one or more Met Museum object IDs. Accepts up to 20 IDs per call, fetches in parallel (concurrency-limited), and returns partial-success — a single 404 does not fail the whole batch. Object IDs come from met_search_collections. Non-public-domain objects...

Parameters* required
objectIDs*array
One or more Met object IDs to fetch. Maximum 20 per call. IDs come from met_search_collections. Fetches run in parallel (concurrency-limited); partial failures are reported per ID rather than faili...

@cyanheads/met-museum-mcp-server

Search the Metropolitan Museum of Art collection, browse it by department or update date, fetch full artwork records and open-access images via MCP. STDIO or Streamable HTTP.

4 Tools

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

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

ToolDescription
met_list_departmentsReturn all 19 curatorial departments with their numeric IDs and display names
met_search_collectionsSearch the collection by keyword, optionally matched in titles or tags only, with filters for department, date range, medium, geography, image availability, on-view status, and highlight designation
met_list_objectsList every object ID in a department, every object created or revised since a date, or both, without a keyword
met_get_objectFetch full records for one or more object IDs — metadata, provenance, artist info, CC0 image URLs, tags, and Wikidata links — optionally with up to 3 CC0 images as image content

Capability reference

met_list_departments tool

  • No input; returns all 19 curatorial departments, each a numeric departmentId with its displayName (e.g., "Egyptian Art")
  • departmentId values are the valid input for the departmentId filter on met_search_collections and met_list_objects
  • Typed errors: upstream_blocked, upstream_unavailable (the Met answered 500/502/503/504 through every retry), upstream_rate_limited (the Met answered 429), and retry_deadline_exceeded (the call's time budget ran out)

met_search_collections tool

  • Keyword q (required), matched across all text fields unless matchField narrows it to "title" or "tags". "*" matches every object, for a search by filters alone; an accession number from a label ranks its object first. 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), one geoLocation, hasImages, isOnView, and isHighlight (true only)
  • departmentId 7 (The Cloisters) and 17 (Medieval Art) share one search result set at the Met: each page keeps only the requested department's IDs, while total and paging count both, so a page can hold fewer than limit IDs; a notice says so, and met_list_objects gives exact department membership
  • Up to 500 IDs per page (default 20; a limit up to 10,000 reads a 500-ID page, with a notice), paged by offset / nextOffset through the first 10,000 matches only; total still reports the full count, with a notice when it exceeds 10,000
  • Zero matches is a result, not an error: total: 0 with a notice saying whether the keyword matches nothing or the filters removed every match, and which filters to correct or drop. Every result echoes the applied query as effectiveQuery
  • Typed errors: invalid_date_range, invalid_filter (a blank q, medium, or geoLocation), invalid_department, upstream_blocked, upstream_unavailable, upstream_rate_limited, retry_deadline_exceeded

met_list_objects tool

  • Filters departmentId (from met_list_departments) and updatedSince (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; a limit up to 10,000 reads a 500-ID page, with a notice), in ascending order, paged by offset / nextOffset with no depth limit
  • Typed errors: invalid_department, invalid_date (an impossible date such as 2026-02-30), upstream_blocked, upstream_unavailable, upstream_rate_limited, retry_deadline_exceeded; an empty list is a result, not an error, with a notice naming the filters, and every result echoes the applied filters as effectiveQuery
  • Each list is cached for up to an hour, so a record revised within the last hour may not appear yet

met_get_object tool

  • 20 distinct IDs fetched per call, from met_search_collections or met_list_objects; a repeated ID is fetched and returned once. A list of up to 500 (a full page) is accepted, and the distinct IDs past the first 20 come back unrequested in remainingIDs, with a notice
  • Partial success: per-ID errors land in failed[], and the call fails only when every ID does — all_not_found when every ID was a 404, upstream_blocked when the Met's firewall refused a request, upstream_rate_limited when the Met answered 429, retry_deadline_exceeded when every fetch ran out of the call's time budget, upstream_unavailable when a fetch met a Met API outage, and all_failed otherwise; records past a 60,000-byte structuredContent budget are listed in deferred[] with their sizes, to re-request
  • isPublicDomain / hasCC0Image gate image URLs — non-public-domain objects return empty primaryImage, primaryImageSmall, and additionalImages; sparse fields are empty or null, never fabricated
  • includeImages: true attaches the CC0 web-display image (about 600 px on the long edge) of the first 3 returned records that have one, as image content after a caption naming the object, and images[] gives each returned record's outcome (attached, no_cc0_image, over_cap, unavailable). The bytes ride content[] only, so a client that passes the model only structuredContent won't show them
  • The Artist line carries the full attribution and role — artistPrefix ("Style of"), the name, artistSuffix, and artistRole ("Patron") — so a follower's work or a patron never reads as the named artist's own; rightsAndReproduction names the rights holder on the copyrighted works that carry one, beside accessionYear
  • reign ("Joint reign of Hatshepsut and Thutmose III") sits beside period and dynasty, and portfolio ("Birds of America, plate LXXI") names a print's series and plate; both are empty on most records
  • metadataDate is the record's last revision, the timestamp met_list_objects updatedSince compares; departmentId resolves the record's department name (five differ from met_list_departments) to the ID met_list_objects and met_search_collections take, or null when the name is not recognized
  • The search index can list IDs the object endpoint no longer serves, so a 404's guidance is to drop the ID rather than search for it again

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_object
  • Linked 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
  • A 500, 502, 503, or 504 that outlasts the retries surfaces on every tool as upstream_unavailable; once every fetch in flight has failed without the Met answering any ID, met_get_object stops requesting the rest of the batch, so a 5xx outage costs at most MET_BATCH_CONCURRENCY × 4 requests (20 at the default) however many IDs were asked for
  • A 429 that outlasts the retries, or asks for a wait longer than they or the call's time budget allow, surfaces on every tool as upstream_rate_limited, its message naming the wait the Met asked for; met_get_object then stops requesting the rest of the batch, so a throttled batch costs at most MET_BATCH_CONCURRENCY requests (5 at the default) with a long Retry-After and MET_BATCH_CONCURRENCY × 4 (20) without one
  • No error carries the Met's HTML or JSON error page — an HTTP failure reaches the caller as its code, message, and status, or, inside a met_get_object batch, as that ID's failed[] message

Agent-friendly output:

  • Provenance on every record — isPublicDomain and hasCC0Image flags distinguish CC0 objects from works with inaccessible images, so agents can reason about what they can actually display
  • Partial failure reporting — met_get_object returns objects and failed arrays so callers receive successful records alongside structured per-ID error context
  • Truncation signaling — met_search_collections and met_list_objects return total, returned, truncated, remaining, nextOffset, and the resolved offset; 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 of total
  • Byte-budget disclosure — met_get_object reports deferred[] 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/mcp

Prerequisites

  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key required — the Met Collection API is public and unauthenticated.

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/met-museum-mcp-server.git
  1. Navigate into the directory:
cd met-museum-mcp-server
  1. Install dependencies:
bun install
  1. Configure 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.

VariableDescriptionDefault
MCP_TRANSPORT_TYPETransport: stdio or httpstdio
MCP_HTTP_PORTHTTP server port3010
MCP_SESSION_MODEHTTP session mode: auto, stateful, or stateless. This server declares stateless in createApp(), so it applies whenever the variable is unset; an explicit value overrides it. (auto, the framework schema default, resolves to stateful.)stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauthnone
MCP_LOG_LEVELLog level (debug, info, warning, error)info
LOGS_DIRDirectory for log files (Node.js only)<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADSLog each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted.false
OTEL_ENABLEDEnable OpenTelemetry instrumentationfalse
MET_BASE_URLMet Collection API root; each endpoint appends its own version (/v1.1/search, /v1/objects, /v1/objects/{id}, /v1/departments). A value ending in /v1 or /v1.1 is read as its root. Override for local stubs.https://collectionapi.metmuseum.org/public/collection
MET_REQUEST_TIMEOUT_MSPer-request HTTP timeout in milliseconds10000
MET_CALL_DEADLINE_MSWall-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 Timeout (-32004), data.reason: 'retry_deadline_exceeded'; in met_get_object the affected IDs land in failed[], and a batch that fetched nothing because every ID ran out fails with that reason.30000
MET_BATCH_CONCURRENCYMax parallel fetches in met_get_object5

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:http
    
  • Run 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-server

The 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

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits the Met service.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts) — met_list_departments, met_search_collections, met_list_objects, met_get_object.
src/services/metMet Collection API client — HTTP, call deadline, response normalization, cached object-ID lists.
tests/Unit and integration tests mirroring src/.

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 request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools via the arrays in createApp() 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

Data attribution

Data from The Metropolitan Museum of Art Collection API (CC0).

License

Apache-2.0 — see LICENSE for details.

Featured
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →

Configuration

MCP_LOG_LEVELdefault: info

Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').

MCP_HTTP_HOSTdefault: 127.0.0.1

The hostname for the HTTP server.

MCP_HTTP_PORTdefault: 3010

The port to run the HTTP server on.

MCP_HTTP_ENDPOINT_PATHdefault: /mcp

The endpoint path for the MCP server.

MCP_AUTH_MODEdefault: none

Authentication mode to use: 'none', 'jwt', or 'oauth'.

Registryactive
Package@cyanheads/met-museum-mcp-server
TransportSTDIO, HTTP
Tools verifiedJun 10, 2026
UpdatedJun 8, 2026
View on GitHub

More from cyanheads

  • Mcp Ts Core145
  • Courtlistener Mcp Server2
  • Open Meteo Mcp Server2
  • Treasury Fiscaldata Mcp Server2
  • Usaspending Mcp Server2
  • Worldbank Mcp Server2
  • Bls Labor Mcp Server1
  • Cpsc Recalls Mcp Server1
  • Devops Status Mcp Server1
  • Earthquake Mcp Server1
  • Eia Energy Mcp Server1
  • Eurostat Mcp Server1
  • Fcc Broadband Mcp Server1
  • Gdelt Mcp Server1
  • Onebusaway Mcp Server1
  • Openfda Mcp Server1
  • Openfec Mcp Server1
  • Openfoodfacts Mcp Server1
  • Openlibrary Mcp Server1
  • Openstates Mcp Server1
  • Orcid Mcp Server1
  • Reliefweb Mcp Server1
  • Smithsonian Mcp Server1
  • Wikidata Mcp Server1