loading…
Search for a command to run...
loading…
A comprehensive MCP server for querying historical maritime shipping records, vessel specifications, and shipwreck databases across multiple international archi
A comprehensive MCP server for querying historical maritime shipping records, vessel specifications, and shipwreck databases across multiple international archives from 1497 to 1874. It enables detailed research into voyages, crew muster rolls, cargo manifests, and historical sailing routes through specialized search and analytical tools.
Historical Maritime Archives MCP Server -- A comprehensive Model Context Protocol (MCP) server for querying historical maritime shipping records, vessel specifications, crew muster rolls, cargo manifests, shipwreck databases, historical place names, and sailing routes spanning 1497-1874. Covers Dutch (VOC), English (EIC), Portuguese (Carreira da India), Spanish (Manila Galleon), and Swedish (SOIC) maritime archives.
This is a demonstration project provided as-is for learning and testing purposes.
This MCP server provides structured access to historical maritime archives and reference data through 47 tools across 11 archives and 6 nations.
All tools return fully-typed Pydantic v2 models for type safety, validation, and excellent IDE support. All tools support output_mode="text" for human-readable output alongside the default JSON.
maritime_list_archives, maritime_get_archive)Browse 11 maritime archives across 6 nations:
Note: The EIC, Carreira, Galleon, and SOIC archives are curated datasets compiled from published academic sources. Carreira, Galleon, and SOIC include programmatically expanded records covering the full historical period. VOC Crew data requires running
scripts/download_crew.pyto download from the Nationaal Archief (774K records, ~80 MB). UKHO data requires runningscripts/download_ukho.pyto download from EMODnet (94K records). NOAA data requires runningscripts/download_noaa.pyto download from NOAA ArcGIS (13K records). Curated fallbacks of 50 representative wrecks ship with the repo viascripts/generate_ukho.pyandscripts/generate_noaa.py. Cargo and EIC have download scripts (download_cargo.py,download_eic.py) for future expansion from external sources.
maritime_search_voyages, maritime_get_voyage)Search voyage records across all 5 voyage archives (DAS, EIC, Carreira, Galleon, SOIC):
maritime_search_wrecks, maritime_get_wreck)Search shipwreck and loss records across all 7 wreck archives (MAARER, EIC, Carreira, Galleon, SOIC, UKHO, NOAA):
maritime_search_vessels, maritime_get_vessel)Search VOC vessel records:
maritime_get_hull_profile, maritime_list_hull_profiles)Hydrodynamic hull data for drift modelling:
maritime_search_crew, maritime_get_crew_member)Search crew records across multiple archives:
archive="voc_crew" or archive="dss"maritime_search_cargo, maritime_get_cargo_manifest)Search VOC cargo manifests (200 curated records, expandable via download scripts):
maritime_assess_position)Evaluate historical position quality:
maritime_lookup_location, maritime_list_locations)Historical place-name resolution:
maritime_list_routes, maritime_get_route, maritime_estimate_position)Historical sailing routes with position estimation across 5 nations:
use_speed_profiles=True adds CLIWOC-derived speed statisticsmaritime_get_speed_profile)Historical sailing speed statistics derived from CLIWOC 2.1 daily positions:
maritime_search_tracks, maritime_get_track, maritime_nearby_tracks)Historical ship track data from CLIWOC 2.1 Full logbooks (1662-1855):
lat_min/lat_max/lon_min/lon_maxmaritime_get_voyage_full)Unified voyage view with all linked records in a single call, across all archives:
maritime_get_timeline)Chronological event view combining all data sources for a voyage:
include_positions=True to sample CLIWOC daily positions into the timelinemaritime_export_geojson, maritime_get_statistics)Export and analyse wreck data:
maritime_search_narratives)Full-text search across all free-text narrative content:
particulars, wreck particulars, and loss_location across all 10 archivesmaritime_search_musters, maritime_get_muster, maritime_compare_wages)GZMVOC ship-level muster records and wage comparison from the DSS Linked Data Cloud:
das_voyage_idmaritime_compute_track_speeds, maritime_aggregate_track_speeds, maritime_compare_speed_groups, maritime_did_speed_test, maritime_track_tortuosity, maritime_aggregate_track_tortuosity, maritime_wind_rose, maritime_export_speeds, maritime_galleon_transit_times, maritime_wind_direction_by_year)Server-side speed computation and statistical analysis on CLIWOC track data:
maritime_capabilities)List full server capabilities for LLM workflow planning:
A hosted instance is available at:
https://maritime-archives.chukai.io/mcp
Use this with any MCP client -- no installation required. All 47 tools and 774K crew records are available.
uvx chuk-mcp-maritime-archives
# Install from PyPI
uv pip install chuk-mcp-maritime-archives
# Or clone and install from source
git clone <repository-url>
cd chuk-mcp-maritime-archives
uv sync --dev
pip install chuk-mcp-maritime-archives
Point any MCP client at https://maritime-archives.chukai.io/mcp -- no local setup needed.
MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"maritime": {
"command": "uvx",
"args": ["chuk-mcp-maritime-archives"]
}
}
}
{
"mcpServers": {
"maritime": {
"command": "chuk-mcp-maritime-archives"
}
}
}
Run the server directly:
# With uvx (recommended -- always latest version)
uvx chuk-mcp-maritime-archives
# With uvx in HTTP mode
uvx chuk-mcp-maritime-archives --mode http
# Or if installed locally
chuk-mcp-maritime-archives
chuk-mcp-maritime-archives --mode http
Or with uv/Python:
# STDIO mode (default, for MCP clients)
uv run chuk-mcp-maritime-archives
# or: python -m chuk_mcp_maritime_archives.server
# HTTP mode (for web access)
uv run chuk-mcp-maritime-archives --mode http
# or: python -m chuk_mcp_maritime_archives.server --mode http
STDIO mode is for MCP clients like Claude Desktop and mcp-cli. HTTP mode runs a web server on http://localhost:8005 for HTTP-based MCP clients.
Once configured with an MCP client, here are prompts organised by use case. Each prompt exercises one or more of the 47 tools and demonstrates a different capability of the server.
Start here. These require no domain knowledge and produce immediately compelling results.
"List the available maritime archives and tell me what each one covers."
→ maritime_list_archives · Overview of all 11 archives across 6 nations
"If I sailed from Texel on October 28, 1628, where would I be by Christmas?"
→ maritime_estimate_position · Position interpolation along historical routes
"Show me the full story of the Batavia — the voyage, the wreck, the vessel, and any crew records."
→ maritime_get_voyage_full · Cross-archive linking across DAS, MAARER, vessel registry, and CLIWOC tracks
"What other ships were sailing near the Batavia wreck site on June 4, 1629?"
→ maritime_nearby_tracks · Proximity search across 261K CLIWOC logbook positions
"Where are the coordinates for Batavia? What about the Cape of Good Hope?"
→ maritime_lookup_location · Historical place-name resolution with modern coordinates
"What route would a ship take from Texel to Batavia via the Roaring Forties?"
→ maritime_get_route · Full route with waypoints, hazards, and season notes
"Show me the timeline of the Batavia's final voyage — every event in chronological order."
→ maritime_get_timeline · Assembled from DAS voyages, route estimates, CLIWOC tracks, and wreck records
These follow the pattern a maritime archaeologist would use: search → assess → export.
"Search for VOC wrecks near the Cape of Good Hope. How many are still unfound?"
→ maritime_search_wrecks · Region + status filtering across 7 wreck archives
"Find all wrecks with cargo worth over 1 million guilders."
→ maritime_search_wrecks · Cargo value filtering
"Get the wreck record for the Batavia, then assess the position quality."
→ maritime_get_wreck + maritime_assess_position · Position uncertainty with navigation-era detection
"Export all Cape wrecks as GeoJSON so I can plot them on a map."
→ maritime_export_geojson · GeoJSON FeatureCollection with uncertainty radii
"Get the hull profile for a retourschip — I need drag coefficients for drift modelling."
→ maritime_get_hull_profile · Hydrodynamic data for 6 ship types
"Show me loss statistics by decade across all archives. What were the deadliest decades?"
→ maritime_get_statistics · Aggregate losses by region, cause, and decade
"Search for UKHO wrecks flagged as Dutch in the Indian Ocean."
→ maritime_search_wrecks · UKHO 94K+ global wrecks with nationality filtering
"Find NOAA wrecks in the Gulf of Mexico with high position quality."
→ maritime_search_wrecks · NOAA AWOIS wrecks with GP quality codes
The server covers Dutch, English, Portuguese, Spanish, and Swedish maritime archives.
"Search for EIC voyages involving the Earl of Abergavenny."
→ maritime_search_voyages · English East India Company (~150 voyages)
"Find Portuguese Carreira voyages commanded by Vasco da Gama."
→ maritime_search_voyages · Portuguese Carreira da India (~500 voyages, 1497–1835)
"Show me Manila Galleon wrecks in the Pacific."
→ maritime_search_wrecks · Spanish Manila Galleon (~42 wrecks)
"Search for Swedish East India Company voyages of the Gotheborg."
→ maritime_search_voyages · SOIC (~132 voyages, 1731–1813)
"Compare Portuguese Carreira wrecks with VOC wrecks in the same regions — different loss causes?"
→ maritime_search_wrecks + maritime_get_statistics · Cross-archive comparison
774,000 VOC crew records enable prosopographical research at scale.
"What crew served on the Ridderschap van Holland?"
→ maritime_search_crew · Crew muster roll search
"Show me crew survival rates by rank across the full VOC period. Were officers more likely to survive?"
→ maritime_crew_survival_analysis · Mortality and desertion rates by dimension
"What were the most common ranks on VOC ships? How did the distribution change by decade?"
→ maritime_crew_demographics · Aggregate statistics across 774K records
"Reconstruct the career of any crew member named Pietersz from Amsterdam."
→ maritime_crew_career · Career tracing across multiple voyages with rank progression
"Compare crew wages between 1691–1740 and 1741–1791. Did wages keep up?"
→ maritime_compare_wages · GZMVOC muster wage comparison between time periods
Search across all free-text fields in all archives.
"Find all mentions of monsoon across all archives."
→ maritime_search_narratives · Full-text search across voyage and wreck particulars
"Which wrecks mention cannon in their descriptions?"
→ maritime_search_narratives · Keyword search with snippet extraction
"Search for narratives about storms near the Cape of Good Hope."
→ maritime_search_narratives · Phrase matching with relevance ranking
Ship speeds as wind proxies — original research capability using 261K CLIWOC logbook positions.
"Aggregate Dutch ship speeds in the Roaring Forties by decade from 1750 to 1860, eastbound only.
Then do the same for westbound. Are ships getting faster, and is the trend different by direction?"
→ maritime_aggregate_track_speeds · If eastbound increases faster than westbound, that's wind
(strengthening westerlies), not technology. This is the core climate proxy signal.
"Compare ship speeds in the Roaring Forties between 1780–1782 (pre-Laki) and 1784–1786 (post-Laki).
Did the 1783 Laki eruption in Iceland measurably affect Southern Ocean wind patterns?"
→ maritime_compare_speed_groups · Mann-Whitney U test for volcanic signal detection. The Laki
eruption injected massive SO₂ into the atmosphere — a speed dip in this window indicates weakened
westerlies detectable in 240-year-old logbook data.
"Aggregate ship speeds in the Roaring Forties by month across all years. Which months have the
strongest winds? Then compare seasonal amplitude between 1750–1789 and 1820–1859."
→ maritime_aggregate_track_speeds · Seasonal wind cycle decomposition
"Compare ship speeds in the western Indian Ocean (lon 15–60) versus the eastern Indian Ocean
(lon 60–110) for the same latitude band. Do wind patterns differ between the two basins?"
→ maritime_aggregate_track_speeds · Spatial variation in Southern Ocean wind strength
"Search for Dutch ship tracks passing through the Roaring Forties in the 1780s."
→ maritime_search_tracks · Geographic bounding box filtering on CLIWOC data
"What were the typical sailing speeds on the outward route via the Roaring Forties?"
→ maritime_get_speed_profile · CLIWOC-derived speed statistics per route segment
"Search for pepper shipments from the Malabar coast."
→ maritime_search_cargo · Commodity search across 200 curated BGB records
"What cargo was on the most valuable VOC voyage?"
→ maritime_search_cargo + maritime_get_cargo_manifest · Value filtering and full manifests
These prompts naturally trigger 3–8 tool calls as the model builds a complete picture.
"Investigate the Batavia wreck: find the voyage, get the full linked record with crew,
assess the position quality, get the hull profile for drift modelling, and check what other
ships were in the area when it wrecked."
→ Chains: maritime_search_voyages → maritime_get_voyage_full → maritime_assess_position
→ maritime_get_hull_profile → maritime_nearby_tracks
"I want to understand VOC losses in the Cape region. Search for all Cape wrecks, show me the
statistics by cause, export the found wrecks as GeoJSON, and tell me which unfound wrecks
have the best position data for a search expedition."
→ Chains: maritime_search_wrecks → maritime_get_statistics → maritime_export_geojson
→ maritime_assess_position (for each candidate)
"Plan a historical sailing voyage: pick a route from Texel to Batavia, show me the waypoints
and hazards, estimate where I'd be after 90 days, and tell me what speeds to expect based on
historical data. Also find any wrecks along the route."
→ Chains: maritime_list_routes → maritime_get_route → maritime_estimate_position
→ maritime_get_speed_profile → maritime_search_wrecks
"Full climate analysis: aggregate Roaring Forties speeds by decade, test for a Laki volcanic
signal, decompose by month for seasonal patterns, and compare the western vs eastern Indian
Ocean for spatial variation."
→ Chains: maritime_aggregate_track_speeds (×4 with different parameters)
→ maritime_compare_speed_groups · Complete climate research workflow
The examples/ directory contains runnable demo scripts that call MCP tools directly:
cd examples
# Quick start (no network required)
python capabilities_demo.py # server capabilities, ship types, regions
python hull_profiles_demo.py # hydrodynamic data for all 6 ship types
python location_lookup_demo.py # VOC gazetteer: place names to coordinates
python route_explorer_demo.py # sailing routes + position estimation
python track_explorer_demo.py # CLIWOC ship tracks + nearby search
python cross_archive_demo.py # unified voyage view across 5 archives
python ukho_global_wrecks_demo.py # UKHO 94K+ global wrecks: flag, depth, type filters
python noaa_us_wrecks_demo.py # NOAA 13K+ US wrecks: GP quality, Gulf, Great Lakes
python narrative_search_demo.py # full-text search across all narrative fields
python speed_profile_demo.py # CLIWOC-derived speed statistics per segment
python climate_proxy_demo.py # ship speeds as climate proxies (wind & monsoon)
python volcanic_signal_demo.py # volcanic signals, E/W ratios, spatial variation
python dss_crew_demo.py # DSS musters, MDB crew, wage comparison
python entity_resolution_demo.py # fuzzy matching, confidence scores, link auditing
python timeline_demo.py # chronological voyage timeline from all sources
# Core tool demos (network required)
python voyage_search_demo.py # search + detail workflow
python wreck_investigation_demo.py # search, assess, export workflow
python vessel_search_demo.py # vessel search + ship type comparison
python crew_muster_demo.py # crew search + detail retrieval
python cargo_trade_demo.py # cargo search + commodity analysis
python geojson_export_demo.py # GeoJSON export + filtering
python statistics_demo.py # aggregate loss statistics
# Full case study (network required)
python batavia_case_study_demo.py # 12-tool chain investigating the Batavia wreck
| Script | Network | Tools Demonstrated |
|---|---|---|
capabilities_demo.py |
No | maritime_capabilities, maritime_list_archives, maritime_list_hull_profiles |
hull_profiles_demo.py |
No | maritime_list_hull_profiles, maritime_get_hull_profile |
location_lookup_demo.py |
No | maritime_lookup_location, maritime_list_locations |
route_explorer_demo.py |
No | maritime_list_routes, maritime_get_route, maritime_estimate_position |
track_explorer_demo.py |
No | maritime_search_tracks, maritime_get_track, maritime_nearby_tracks |
cross_archive_demo.py |
Partial | maritime_search_voyages, maritime_get_voyage_full (EIC/Carreira/Galleon/SOIC offline, DAS needs network) |
speed_profile_demo.py |
No | maritime_get_speed_profile, maritime_estimate_position |
climate_proxy_demo.py |
No | maritime_compute_track_speeds, maritime_get_speed_profile, maritime_get_route, maritime_aggregate_track_speeds, maritime_compare_speed_groups |
volcanic_signal_demo.py |
No | maritime_aggregate_track_speeds, maritime_compare_speed_groups (Laki eruption, E/W ratio, seasonal amplitude, spatial variation) |
dss_crew_demo.py |
No | maritime_search_musters, maritime_get_muster, maritime_compare_wages, maritime_search_crew (DSS musters, MDB crew, wage comparison) |
entity_resolution_demo.py |
No | maritime_get_voyage_full, maritime_audit_links (fuzzy matching, confidence scores, link auditing) |
timeline_demo.py |
No | maritime_get_timeline, maritime_search_voyages |
ukho_global_wrecks_demo.py |
No | maritime_search_wrecks, maritime_get_wreck, maritime_get_statistics, maritime_export_geojson (UKHO flag/type/depth filters) |
noaa_us_wrecks_demo.py |
No | maritime_search_wrecks, maritime_get_wreck, maritime_export_geojson (NOAA GP quality, Gulf, Great Lakes) |
narrative_search_demo.py |
No | maritime_search_narratives (keyword, phrase, archive/type filters, pagination) |
voyage_search_demo.py |
Partial | maritime_search_voyages, maritime_get_voyage (DAS needs network, EIC/Carreira/Galleon/SOIC offline) |
wreck_investigation_demo.py |
Partial | maritime_search_wrecks, maritime_get_wreck, maritime_assess_position, maritime_export_geojson (multi-archive, mostly offline) |
vessel_search_demo.py |
Yes | maritime_search_vessels, maritime_get_vessel, maritime_get_hull_profile |
crew_muster_demo.py |
Partial | maritime_search_crew, maritime_get_crew_member (requires download_crew.py first) |
cargo_trade_demo.py |
No | maritime_search_cargo, maritime_get_cargo_manifest (200 curated records included) |
geojson_export_demo.py |
Yes | maritime_export_geojson, maritime_search_wrecks |
statistics_demo.py |
Partial | maritime_get_statistics, maritime_search_wrecks (multi-archive, mostly offline) |
batavia_case_study_demo.py |
Yes | All tool categories chained together |
All tools accept an optional output_mode parameter ("json" default, or "text" for human-readable output). All search tools support cursor-based pagination via cursor, max_results, next_cursor, has_more, and total_count.
| Tool | Category | Description |
|---|---|---|
maritime_list_archives |
Archives | List all available maritime archives |
maritime_get_archive |
Archives | Get archive detail by ID |
maritime_search_voyages |
Voyages | Search voyages with filters |
maritime_get_voyage |
Voyages | Get voyage detail by ID |
maritime_search_wrecks |
Wrecks | Search wreck records |
maritime_get_wreck |
Wrecks | Get wreck detail by ID |
maritime_search_vessels |
Vessels | Search vessel records |
maritime_get_vessel |
Vessels | Get vessel detail by ID |
maritime_get_hull_profile |
Vessels | Hydrodynamic profile for ship type |
maritime_list_hull_profiles |
Vessels | Available ship types |
maritime_search_crew |
Crew | Search crew muster rolls |
maritime_get_crew_member |
Crew | Get crew member detail |
maritime_search_cargo |
Cargo | Search cargo manifests |
maritime_get_cargo_manifest |
Cargo | Full cargo manifest for a voyage |
maritime_lookup_location |
Location | Look up historical place name in VOC gazetteer |
maritime_list_locations |
Location | Search/browse gazetteer by region, type, or text |
maritime_list_routes |
Routes | List historical sailing routes (18 routes, 5 nations) |
maritime_get_route |
Routes | Full route with waypoints, hazards, season notes |
maritime_estimate_position |
Routes | Estimate ship position on a date from route |
maritime_search_tracks |
Tracks | Search CLIWOC ship tracks by nationality and date |
maritime_get_track |
Tracks | Get full position history for a CLIWOC voyage |
maritime_nearby_tracks |
Tracks | Find ships near a position on a given date |
maritime_get_speed_profile |
Speed | Historical sailing speed statistics per segment |
maritime_get_voyage_full |
Linking | Unified voyage view with all linked records |
maritime_get_timeline |
Timeline | Chronological event view for a voyage |
maritime_assess_position |
Position | Position quality and uncertainty assessment |
maritime_export_geojson |
Export | GeoJSON wreck position export |
maritime_get_statistics |
Export | Aggregate loss statistics |
maritime_search_musters |
Musters | Search GZMVOC ship muster records |
maritime_get_muster |
Musters | Get full muster record details |
maritime_compare_wages |
Musters | Compare wage distributions between time periods |
maritime_search_narratives |
Narratives | Full-text search across all narrative fields |
maritime_compute_track_speeds |
Analytics | Compute daily sailing speeds for a CLIWOC voyage |
maritime_aggregate_track_speeds |
Analytics | Aggregate track speeds by decade, year, month, direction, or nationality |
maritime_compare_speed_groups |
Analytics | Compare speed distributions between two time periods (Mann-Whitney U) |
maritime_did_speed_test |
Analytics | Formal 2×2 Difference-in-Differences test (direction × period) |
maritime_track_tortuosity |
Analytics | Compute route tortuosity for a single CLIWOC voyage |
maritime_aggregate_track_tortuosity |
Analytics | Aggregate route tortuosity across CLIWOC tracks |
maritime_wind_rose |
Analytics | Beaufort wind force and direction distributions from CLIWOC logbooks |
maritime_export_speeds |
Analytics | Export raw speed samples for downstream statistical analysis |
maritime_galleon_transit_times |
Analytics | Compute transit times for Manila Galleon voyages (1565–1815) |
maritime_wind_direction_by_year |
Analytics | Year-by-year wind direction distributions from CLIWOC logbooks |
maritime_crew_demographics |
Demographics | Aggregate crew statistics by rank, origin, fate, decade, or ship |
maritime_crew_career |
Demographics | Reconstruct individual crew careers across multiple voyages |
maritime_crew_survival_analysis |
Demographics | Crew survival, mortality, and desertion rates by dimension |
maritime_capabilities |
Discovery | Server capabilities and reference data |
{
"query": "monsoon", # required, keywords or "quoted phrase"
"record_type": "voyage", # optional: "voyage", "wreck", or null (both)
"archive": "eic", # optional, restrict to one archive
"max_results": 50, # optional, default 50, max 500
"cursor": null # optional, from previous next_cursor
}
{
"ship_name": "Batavia", # optional, substring match
"captain": "Jacobsz", # optional
"date_range": "1620/1640", # optional, YYYY/YYYY
"departure_port": "Texel", # optional
"fate": "wrecked", # optional
"max_results": 10, # optional, default 50, max 500
"cursor": "eyJvIjoxMH0" # optional, from previous next_cursor
}
{
"region": "cape", # optional, region code
"cause": "storm", # optional
"status": "unfound", # optional
"min_depth_m": 100, # optional
"min_cargo_value": 100000, # optional, guilders
"max_results": 50, # optional, default 100, max 500
"cursor": null # optional, from previous next_cursor
}
{
"ship_name": "Middelburg", # optional, substring match
"captain": "Pietersz", # optional
"location": "Batavia", # optional, muster location
"year_start": 1720, # optional, earliest year
"year_end": 1760, # optional, latest year
"date_range": "1720/1760", # optional, YYYY/YYYY
"das_voyage_id": "das:1234", # optional, cross-link to DAS voyage
"max_results": 50, # optional, default 50, max 500
"cursor": null # optional, from previous next_cursor
}
{
"group1_start": 1691, # required, first group start year
"group1_end": 1740, # required, first group end year
"group2_start": 1741, # required, second group start year
"group2_end": 1791, # required, second group end year
"rank": "matroos", # optional, rank filter
"origin": "Groningen", # optional, origin filter (MDB only)
"source": "musters" # "musters" (GZMVOC) or "crews" (MDB)
}
{
"ship_name": "Ridderschap van Holland", # optional
"rank": "schipper", # optional
"fate": "died_voyage", # optional
"archive": "voc_crew", # optional: "voc_crew" or "dss"
"max_results": 50, # optional, default 100, max 500
"cursor": null # optional, from previous next_cursor
}
{
"commodity": "pepper", # optional, substring match
"origin": "Malabar", # optional
"min_value": 100000, # optional, guilders
"max_results": 50, # optional, default 100, max 500
"cursor": null # optional, from previous next_cursor
}
{
"wreck_id": "maarer:VOC-0789", # assess wreck position
"source_description": "GPS surveyed site" # position source info
}
{
"region": "cape", # optional filter
"status": "found", # optional filter
"include_uncertainty": true, # include uncertainty radius
"include_voyage_data": true # include ship/cargo data
}
{
"name": "Batavia" # place name or alias
}
{
"query": "spice", # optional, text search
"region": "indonesia", # optional, region code
"location_type": "port", # optional: port, island, cape, etc.
"max_results": 50 # optional, default 50
}
{
"direction": "outward", # optional: outward, return, intra_asian, pacific_westbound, pacific_eastbound
"departure_port": "Texel", # optional, substring match
"destination_port": "Batavia" # optional, substring match
}
{
"route_id": "outward_outer" # route identifier
}
{
"route_id": "outward_outer", # route identifier
"departure_date": "1629-10-28", # YYYY-MM-DD
"target_date": "1630-02-15", # date to estimate position
"use_speed_profiles": true # optional: enrich with CLIWOC speed data
}
{
"route_id": "outward_outer", # route identifier
"departure_month": 10 # optional: month (1-12) for seasonal data
}
{
"voyage_id": "das:0372.1", # voyage ID from any archive
"include_positions": true, # optional: include CLIWOC daily positions
"max_positions": 20 # optional: max CLIWOC positions to sample
}
{
"voyage_id": "eic:0062" # voyage ID from any archive (das, eic, carreira, galleon, soic)
}
{
"nationality": "NL", # optional: NL, UK, ES, FR, SE, US, DE, DK
"year_start": 1780, # optional, earliest year
"year_end": 1800, # optional, latest year
"ship_name": "BATAVIA", # optional, substring match (CLIWOC 2.1 Full)
"lat_min": -50, # optional, bounding box min latitude
"lat_max": -30, # optional, bounding box max latitude
"lon_min": 15, # optional, bounding box min longitude
"lon_max": 110, # optional, bounding box max longitude
"max_results": 50, # optional, default 50, max 500
"cursor": null # optional, from previous next_cursor
}
{
"voyage_id": 118 # CLIWOC voyage ID (integer)
}
{
"lat": -28.49, # latitude of search point
"lon": 113.79, # longitude of search point
"date": "1629-06-04", # date to search (YYYY-MM-DD)
"radius_km": 200, # optional, default 200km
"max_results": 20 # optional, default 20
}
{
"ship_type": "retourschip" # ship type code
}
{
"voyage_id": 118, # required, CLIWOC voyage ID
"lat_min": -50, # optional, bounding box
"lat_max": -30,
"lon_min": 15,
"lon_max": 110,
"min_speed_km_day": 5.0, # optional, filter slow/anchored
"max_speed_km_day": 400.0 # optional, filter errors
}
{
"group_by": "decade", # "decade", "year", "month", "direction", "nationality"
"lat_min": -50, # optional, bounding box
"lat_max": -30,
"lon_min": 15,
"lon_max": 110,
"nationality": "NL", # optional, filter by nationality
"year_start": 1750, # optional
"year_end": 1800, # optional
"direction": "eastbound", # optional, "eastbound" or "westbound"
"min_speed_km_day": 5.0, # optional
"max_speed_km_day": 400.0 # optional
}
{
"period1_years": "1750/1789", # required, first period
"period2_years": "1820/1859", # required, second period
"lat_min": -50, # optional, bounding box
"lat_max": -30,
"lon_min": 15,
"lon_max": 110,
"nationality": "NL", # optional
"direction": "eastbound" # optional
}
# Clone the repository
git clone <repository-url>
cd chuk-mcp-maritime-archives
# Install with uv (recommended)
uv sync --dev
# Or with pip
pip install -e ".[dev]"
# Run tests
pytest tests/
# Run tests with coverage
pytest tests/ --cov=src/chuk_mcp_maritime_archives --cov-report=term-missing
# Run a specific test file
pytest tests/test_archive_manager.py -v
# Run all checks (lint, typecheck, security, test)
make check
# Lint and format with ruff
ruff check src/ tests/
ruff format src/ tests/
# Type checking
mypy src/
# Security scan
bandit -r src/ -x tests/
# Build package
python -m build
# Or with uv
uv build
All download and generation scripts support --force to regenerate even if cached data exists:
# Download/generate all datasets
python scripts/download_all.py
# Force regeneration of all data
python scripts/download_all.py --force
# Individual scripts
python scripts/download_das.py # VOC voyages/vessels/wrecks from Huygens API
python scripts/download_cliwoc.py # CLIWOC ship tracks (~261K positions)
python scripts/download_crew.py # VOC crew from Nationaal Archief (~774K records, ~80 MB)
python scripts/download_cargo.py # BGB cargo from Zenodo RDF
python scripts/download_eic.py # EIC from ThreeDecks
python scripts/generate_carreira.py # Portuguese Carreira (~500 voyages, ~100 wrecks)
python scripts/generate_galleon.py # Manila Galleon (~250 voyages, ~42 wrecks)
python scripts/generate_soic.py # Swedish SOIC (~132 voyages, ~20 wrecks)
python scripts/generate_cargo.py # Curated cargo fallback (~200 records)
python scripts/generate_dss.py # DSS musters + MDB crew (~70 musters, ~101 crew)
python scripts/download_dss.py # DSS .ttl download from DANS (falls back to generate)
python scripts/generate_reference.py # Gazetteer, routes, hull profiles
python scripts/generate_speed_profiles.py # CLIWOC speed statistics
Data volume: Core reference data is ~35 MB. With crew data downloaded, total is ~115 MB. The
data/cache/directory (raw downloads) is gitignored.
| Variable | Default | Description |
|---|---|---|
CHUK_ARTIFACTS_PROVIDER |
memory |
Storage backend: memory, filesystem, s3 |
CHUK_ARTIFACTS_PATH |
- | Filesystem storage path |
BUCKET_NAME |
- | S3 bucket name |
AWS_ACCESS_KEY_ID |
- | AWS access key for S3 |
AWS_SECRET_ACCESS_KEY |
- | AWS secret key for S3 |
AWS_ENDPOINT_URL_S3 |
- | Custom S3 endpoint (MinIO, etc.) |
MCP_STDIO |
- | Set to any value to force stdio mode |
REDIS_URL |
- | Redis URL for session management |
MARITIME_REFERENCE_MANIFEST |
- | Artifact ID of reference data manifest (see below) |
.env FileThe server loads environment variables from a .env file via python-dotenv.
Copy .env.example for a documented template:
cp .env.example .env
Minimal local development (no S3):
CHUK_ARTIFACTS_PROVIDER=memory
With filesystem storage:
CHUK_ARTIFACTS_PROVIDER=filesystem
CHUK_ARTIFACTS_PATH=/tmp/maritime-artifacts
For multi-server deployments, reference data (~35 MB across 18 JSON files) can be stored in S3 and preloaded at startup, eliminating the need to run download scripts on each server.
Configure S3 credentials in .env:
CHUK_ARTIFACTS_PROVIDER=s3
BUCKET_NAME=your-maritime-bucket
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
Upload reference data to the artifact store:
python scripts/upload_reference_data.py
Set the manifest ID printed by the script:
MARITIME_REFERENCE_MANIFEST=<manifest-artifact-id>
New servers will automatically download missing data files from S3 at startup.
docker build -t chuk-mcp-maritime-archives .
# HTTP mode (default in container)
docker run -p 8005:8005 chuk-mcp-maritime-archives
# With S3 storage
docker run -p 8005:8005 \
-e CHUK_ARTIFACTS_PROVIDER=s3 \
-e BUCKET_NAME=my-bucket \
-e AWS_ACCESS_KEY_ID=... \
-e AWS_SECRET_ACCESS_KEY=... \
chuk-mcp-maritime-archives
Built on top of chuk-mcp-server, this server uses:
asyncio.to_thread()extra="forbid" for all responses, extra="allow" for domain models_load_json() and cached in instance attributes--force and cache-check patternurllib.request -- no requests/httpx dependencyoutput_mode="text" for human-readable responsescursor / next_cursor / has_more for paging through large result sets| Archive | Records | Period | Source |
|---|---|---|---|
| Dutch Asiatic Shipping (DAS) | 8,194 voyages | 1595-1795 | resources.huygens.knaw.nl/das |
| VOC Opvarenden | up to 774,200 crew | 1633-1794 | nationaalarchief.nl |
| Boekhouder-Generaal Batavia | 200 cargo (curated) | 1700-1795 | bgb.huygens.knaw.nl |
| MAARER Wrecks | 734 wrecks | 1595-1795 | Compiled dataset |
| CLIWOC Ship Tracks | ~261,000 positions | 1662-1855 | historicalclimatology.com (CLIWOC 2.1 Full) |
| English East India Company (EIC) | ~150 voyages, ~35 wrecks | 1600-1874 | Hardy/Farrington (curated) |
| Portuguese Carreira da India | ~500 voyages, ~100 wrecks | 1497-1835 | Guinote/Frutuoso/Lopes (curated + expanded) |
| Spanish Manila Galleon | ~250 voyages, ~42 wrecks | 1565-1815 | Schurz (curated + expanded) |
| Swedish East India Company (SOIC) | ~132 voyages, ~20 wrecks | 1731-1813 | Koninckx (curated + expanded) |
| Dutch Ships and Sailors (DSS) | ~70 musters, ~101 crew | 1691-1837 | CLARIN-IV DSS (GZMVOC + MDB) |
| Dataset | Records | Source |
|---|---|---|
| VOC Gazetteer | ~170 place names | Curated from historical sources |
| Historical Routes | 18 sailing routes | Bruijn, Gaastra & Schoffer (1987) + multi-nation sources |
| Speed Profiles | 215 profiles, 6 routes | Generated from CLIWOC 2.1 daily positions |
| Hull Profiles | 6 ship types | Archaeological measurements |
| EIC Archives | ~150 voyages, ~35 wrecks | Hardy's Register of Ships (1835), Farrington (1999) |
| Carreira Archives | ~500 voyages, ~100 wrecks | Guinote/Frutuoso/Lopes "As Armadas da India" |
| Galleon Archives | ~250 voyages, ~42 wrecks | Schurz "The Manila Galleon" (1939) |
| SOIC Archives | ~132 voyages, ~20 wrecks | Koninckx "First and Second Charters of the SEIC" (1980) |
See ARCHITECTURE.md for design principles and data flow diagrams. See SPEC.md for the full tool specification with parameter tables. See ROADMAP.md for the development roadmap and planned features.
maritime_get_voyage_full returns unified voyage view with wreck, vessel, hull profile, and CLIWOC trackmaritime_search_tracks now supports ship name filteringmaritime_get_speed_profile returns CLIWOC-derived speed statistics per route segment with seasonal variationmaritime_get_timeline assembles chronological events from all data sources for a voyagemaritime_estimate_position now supports use_speed_profiles=True for CLIWOC-enriched estimatesscope="sandbox"scripts/upload_reference_data.py + MARITIME_REFERENCE_MANIFEST for automatic preloading.env.example configuration template documenting all environment variablessearch_voyages(archive="eic") queries one archive; no filter queries alldownload_utils.py with cache-check-download pattern and --force flagdownload_crew.py downloads 774K records from Nationaal Archief; crew_client.py with indexed lookups for O(1) voyage/ID searchesdownload_cargo.py for BGB Zenodo RDF, generate_cargo.py for curated fallbackdownload_eic.py for ThreeDecks scraping, generate_eic.py as curated fallback--force and cache-check pattern via download_utils.pydownload_all.py orchestrator runs all 10 scripts with --force passthroughcursor parameter on all search tools; total_count, next_cursor, has_more in all search responsesPaginatedResult dataclass and _paginate() in ArchiveManager; deterministic sort for multi-archive queriesflag (vessel nationality) and vessel_type on wreck searchdownload_ukho.py (EMODnet WFS, 94K records) + generate_ukho.py (50 curated fallback wrecks)gp_quality for NOAA position accuracy codesgulf_of_mexico, great_lakesmaritime_search_narratives searches voyage particulars, wreck particulars, and loss_location across all 10 archives with phrase matching, relevance ranking, and snippet extractionmaritime_compute_track_speeds, maritime_aggregate_track_speeds, maritime_compare_speed_groups for server-side speed computation, aggregation by decade/year/month/direction/nationality, and Mann-Whitney U statistical testingmaritime_search_tracks now supports lat/lon bounding box filteringmaritime_search_musters, maritime_get_muster, maritime_compare_wagesmaritime_search_crew now supports archive="dss" for MDB recordsmaritime_get_voyage_fullmaritime_audit_links for precision/recall metricspacific_westbound, pacific_eastbound for Manila Galleon Pacific crossingsmaritime_crew_demographics for aggregate statistics by rank, origin, fate, decade, or shipmaritime_crew_career reconstructs individual careers across multiple voyages with rank progressionmaritime_crew_survival_analysis for mortality and desertion rates by dimension"0372.1" matching "das:0372.1")Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)Apache License 2.0 -- See LICENSE for details.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"chuk-mcp-maritime-archives": {
"command": "npx",
"args": []
}
}
}