Wraps the Smithsonian Open Access API to search across 19.4 million catalog objects from 20+ museums and retrieve CC0-licensed images. Exposes five tools: full-text search with filters (museum, decade, culture, object type), single-object metadata retrieval, CC0-gated image access at multiple resolutions, category-based browsing (by museum, culture, period, or medium), and cross-collection discovery via parallel metadata fan-out. Requires a free api.data.gov key. Reach for this when you need programmatic access to Smithsonian collections with guaranteed open-access media, or when you want to surface unexpected connections across NMNH, NASM, SAAM, and other units. Built on the developer's mcp-ts-core framework with STDIO and streamable HTTP transports.
Search, explore, and retrieve CC0 media from 19.4 million Smithsonian Open Access objects across 20+ museums via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://smithsonian.caseyjhand.com/mcp
A free
api.data.govAPI key is required. Register at https://api.data.gov/signup — approval is instant. Set it asSMITHSONIAN_API_KEYin your MCP client config or.envfile. The server will not start without it.CC0 media gating:
smithsonian_get_mediaonly returns CC0-licensed (open access) images. Usesmithsonian_searchwithfilters.cc0_only: trueto find objects with downloadable media before calling it.
Six tools covering the full Smithsonian Open Access workflow — filter vocabulary discovery, search, detail retrieval, CC0 image access, and cross-collection exploration:
| Tool | Description |
|---|---|
smithsonian_search | Search across 19.4M objects by text query with optional filters (museum, type, decade, culture, place, online-only, CC0). Returns curated summaries with total count. |
smithsonian_list_terms | Enumerate the valid term vocabulary for an indexed filter field (unit_code, object_type, culture, place, date). Call before filtering to avoid empty results from invalid values. |
smithsonian_get_object | Fetch the full catalog record for an object by ID: title, dates, materials, dimensions, provenance, exhibition history, credit line, and identifiers. |
smithsonian_get_media | Return all CC0-licensed images for an object at multiple resolutions (thumbnail, screen, high-res JPEG/TIFF). Only CC0 images returned — throws when none exist. |
smithsonian_explore | Browse collections by category (museum, culture, period, medium) with total count, sample objects, and museum breakdown. Entry point for open-ended research. |
smithsonian_find_related | Discover cross-collection objects related to an anchor via parallel fan-out searches across culture, maker, topic, and period signals. |
smithsonian_searchFull-text search with structured filters across the entire Smithsonian catalog.
1920s), culture, geographic place, online-only, CC0-onlyrecord_idstart + rows for standard pagination (offset-based, max 100 per page)smithsonian_list_termsEnumerate the valid term vocabulary for an indexed filter field before applying filters.
unit_code, object_type, culture, place, date, media_usage, online_media_typesmithsonian_search produces empty results with no errorstart + rows (default 50 per page, max 100)smithsonian_get_objectFull provenance metadata for a single object.
record_id from smithsonian_search — do not construct IDs manuallysmithsonian_get_media for full image URLssmithsonian_get_mediaCC0-gated image access at multiple resolutions.
Forbidden when an object has media but none is CC0smithsonian_search with filters.cc0_only: true before calling this toolsmithsonian_exploreCategory-constrained browse for open-ended collection discovery.
museum (by unit code or full name), culture (e.g. "Aztec"), period (decade, e.g. "1940s"), medium (object type, e.g. "Painting")smithsonian_find_relatedCross-collection discovery via parallel metadata fan-out.
similarity_signals on each result show which metadata terms connected it to the anchorBuilt on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1Smithsonian-specific:
api.data.gov keysmithsonian_get_media — only open-access images returned, never restricted contentsmithsonian_find_related with graceful degradation (partial failures don't abort)Agent-friendly output:
no_results, not_found, not_cc0, no_media, invalid_id) with recovery hints for each casesimilarity_signals on related-object results let agents explain why objects were surfacedtotal_count on all search responses enables agents to communicate result scope before paginatingA public instance is available at https://smithsonian.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"smithsonian-mcp-server": {
"type": "streamable-http",
"url": "https://smithsonian.caseyjhand.com/mcp"
}
}
}
Requires a free
api.data.govAPI key — register at https://api.data.gov/signup and setSMITHSONIAN_API_KEYin your config.
Add the following to your MCP client configuration file:
{
"mcpServers": {
"smithsonian-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/smithsonian-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"SMITHSONIAN_API_KEY": "your-api-key"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"smithsonian-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/smithsonian-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"SMITHSONIAN_API_KEY": "your-api-key"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"smithsonian-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "SMITHSONIAN_API_KEY=your-api-key",
"ghcr.io/cyanheads/smithsonian-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 SMITHSONIAN_API_KEY=your-api-key bun run start:http
# Server listens at http://localhost:3010/mcp
api.data.gov API key — register at https://api.data.gov/signup. Approval is instant.git clone https://github.com/cyanheads/smithsonian-mcp-server.git
cd smithsonian-mcp-server
bun install
cp .env.example .env
# Edit .env and set SMITHSONIAN_API_KEY
| Variable | Description | Default |
|---|---|---|
SMITHSONIAN_API_KEY | Required. Free API key from api.data.gov/signup. | — |
SMITHSONIAN_BASE_URL | Smithsonian Open Access API base URL. | https://api.si.edu/openaccess/api/v1.0 |
SMITHSONIAN_MAX_ROWS | Default page size for search results (1–100). | 20 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
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 build -t smithsonian-mcp-server .
docker run --rm -e SMITHSONIAN_API_KEY=your-api-key -p 3010:3010 smithsonian-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/smithsonian-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and initializes the Smithsonian service. |
src/config | Server-specific environment variable parsing (SMITHSONIAN_API_KEY, SMITHSONIAN_BASE_URL, SMITHSONIAN_MAX_ROWS). |
src/mcp-server/tools | Tool definitions (*.tool.ts). |
src/services/smithsonian | Smithsonian Open Access API client, normalization, and type definitions. |
tests/ | Unit and integration tests. |
docs/ | Design document and directory tree. |
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/tools/definitions/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
SMITHSONIAN_API_KEY*Required. Free API key from https://api.data.gov/signup — approval is instant.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp