chuk-mcp-maritime-archives 0.2.11
Historical Maritime Archives MCP Server
License: Apache-2.0
Requires Python: >=3.11

# Chuk MCP Maritime Archives

**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.

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)

## Features

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.

### 1. Archive Discovery (`maritime_list_archives`, `maritime_get_archive`)
Browse 11 maritime archives across 6 nations:
- Dutch Asiatic Shipping (DAS) -- 8,194 voyages (1595-1795)
- VOC Opvarenden -- up to 774,200 crew records (1633-1794)
- Boekhouder-Generaal Batavia -- 200 curated cargo records (1700-1795)
- MAARER Wreck Database -- 734 wreck positions (1595-1795)
- English East India Company (EIC) -- ~150 curated voyages, ~35 wrecks (1600-1874)
- Portuguese Carreira da India -- ~500 voyages, ~100 wrecks (1497-1835)
- Spanish Manila Galleon -- ~250 voyages, ~42 wrecks (1565-1815)
- Swedish East India Company (SOIC) -- ~132 voyages, ~20 wrecks (1731-1813)
- UK Hydrographic Office (UKHO) -- 94,000+ wrecks worldwide (1500-2024)
- NOAA Wrecks & Obstructions (AWOIS) -- ~13,000 wrecks in US waters (1600-2024)
- Dutch Ships and Sailors (DSS) -- GZMVOC musters + MDB crew (1691-1837)

> **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.py` to download from the Nationaal Archief (774K records, ~80 MB). UKHO data requires running `scripts/download_ukho.py` to download from EMODnet (94K records). NOAA data requires running `scripts/download_noaa.py` to download from NOAA ArcGIS (13K records). Curated fallbacks of 50 representative wrecks ship with the repo via `scripts/generate_ukho.py` and `scripts/generate_noaa.py`. Cargo and EIC have download scripts (`download_cargo.py`, `download_eic.py`) for future expansion from external sources.

### 2. Voyage Search (`maritime_search_voyages`, `maritime_get_voyage`)
Search voyage records across all 5 voyage archives (DAS, EIC, Carreira, Galleon, SOIC):
- Filter by ship name, captain, ports, date range, fate, archive
- Multi-archive search: query all archives at once or filter by specific archive
- Full voyage detail including incident narratives and vessel data

### 3. Wreck Search (`maritime_search_wrecks`, `maritime_get_wreck`)
Search shipwreck and loss records across all 7 wreck archives (MAARER, EIC, Carreira, Galleon, SOIC, UKHO, NOAA):
- Filter by region, cause, depth, cargo value, status, archive, flag, vessel type, GP quality
- Multi-archive wreck search or single-archive filtering
- UKHO adds 94,000+ global wrecks; NOAA adds ~13,000 US coastal wrecks with position quality codes
- Position data with uncertainty estimates
- Archaeological status and notes

### 4. Vessel Search (`maritime_search_vessels`, `maritime_get_vessel`)
Search VOC vessel records:
- Filter by ship type, tonnage, chamber, shipyard
- 6 ship types: retourschip, fluit, jacht, hooker, pinas, fregat
- Construction and service history

### 5. Hull Profiles (`maritime_get_hull_profile`, `maritime_list_hull_profiles`)
Hydrodynamic hull data for drift modelling:
- Dimensions, displacement, drag coefficients
- Windage area and coefficients
- Sinking characteristics and orientation weights
- Reference wrecks and LLM guidance notes

### 6. Crew Search (`maritime_search_crew`, `maritime_get_crew_member`)
Search crew records across multiple archives:
- **VOC Opvarenden** (default): up to 774,200 records from Nationaal Archief (1633-1794)
- **DSS (MDB)**: 77,043 individual crew records from northern Dutch provinces (1803-1837)
- Filter by name, rank, ship, origin, fate, archive
- Personnel records: rank, pay, embarkation/service dates
- Multi-archive dispatch: `archive="voc_crew"` or `archive="dss"`
- Indexed lookups for fast search across large datasets

### 7. Cargo Search (`maritime_search_cargo`, `maritime_get_cargo_manifest`)
Search VOC cargo manifests (200 curated records, expandable via download scripts):
- Filter by commodity, origin, destination, value
- Full voyage manifests with quantities and values
- Dutch and English commodity names

### 8. Position Assessment (`maritime_assess_position`)
Evaluate historical position quality:
- Navigation era detection (4 technology periods)
- 5 uncertainty levels from precise to regional
- Recommendations for drift modelling and search planning

### 9. Location Gazetteer (`maritime_lookup_location`, `maritime_list_locations`)
Historical place-name resolution:
- ~170 VOC-era place names with modern coordinates
- Alias resolution (e.g., "Batavia" -> Jakarta, "Formosa" -> Taiwan)
- Region classification matching wreck and route data
- Filter by region, location type, or text search

### 10. Sailing Routes (`maritime_list_routes`, `maritime_get_route`, `maritime_estimate_position`)
Historical sailing routes with position estimation across 5 nations:
- 18 routes: VOC (8), EIC (4), Carreira da India (2), Manila Galleon (2), SOIC (2)
- Waypoints with coordinates, typical sailing days, stop durations
- Hazards and seasonal navigation notes
- **Position estimation**: interpolate a ship's likely position on any date
- **Speed profile enrichment**: `use_speed_profiles=True` adds CLIWOC-derived speed statistics

### 11. Speed Profiles (`maritime_get_speed_profile`)
Historical sailing speed statistics derived from CLIWOC 2.1 daily positions:
- 215 profiles across 6 routes (outward_outer, return, ceylon, coromandel, japan, malabar)
- Mean, median, std dev, and percentile speeds (km/day) per route segment
- Seasonal variation: filter by departure month for month-specific data
- Generated from ~61K daily observations matched to standard routes

### 12. Ship Tracks (`maritime_search_tracks`, `maritime_get_track`, `maritime_nearby_tracks`)
Historical ship track data from CLIWOC 2.1 Full logbooks (1662-1855):
- ~261K daily position observations from 8 European maritime nations
- Search by nationality (NL, UK, ES, FR, SE, US, DE, DK), year range, and ship name
- **Geographic bounding box**: filter tracks by `lat_min`/`lat_max`/`lon_min`/`lon_max`
- Full position histories for individual voyages with ship names, company, and DAS numbers
- **Nearby ship search**: find what other ships were near a position on a given date
- Useful for wreck investigation context and route reconstruction

### 13. Cross-Archive Linking (`maritime_get_voyage_full`)
Unified voyage view with all linked records in a single call, across all archives:
- Works with DAS, EIC, Carreira, Galleon, and SOIC voyages
- Wreck record (linked via voyage_id, across all wreck archives)
- Vessel record (linked via voyage_ids array, DAS voyages)
- Hull profile (linked via ship_type)
- CLIWOC track (linked via DAS number or ship name + nationality matching)
- Replaces the need to call get_voyage, get_wreck, get_vessel, and get_hull_profile separately

### 14. Timeline (`maritime_get_timeline`)
Chronological event view combining all data sources for a voyage:
- Assembles events from DAS voyages, route estimates, CLIWOC tracks, and wreck records
- Event types: departure, waypoint estimates, CLIWOC positions, loss/wreck, arrival
- Optional `include_positions=True` to sample CLIWOC daily positions into the timeline
- GeoJSON LineString output from positioned events

### 15. Export & Statistics (`maritime_export_geojson`, `maritime_get_statistics`)
Export and analyse wreck data:
- GeoJSON FeatureCollection export with optional uncertainty
- Aggregate loss statistics by region, cause, decade
- Artifact store integration for persistent export

### 16. Narrative Search (`maritime_search_narratives`)
Full-text search across all free-text narrative content:
- Searches voyage `particulars`, wreck `particulars`, and `loss_location` across all 10 archives
- Keyword and quoted phrase matching with AND logic
- Filter by record type (voyage/wreck) and archive
- Relevance-ranked results with text snippets and match context
- Cursor-based pagination

### 17. Ship Musters (`maritime_search_musters`, `maritime_get_muster`, `maritime_compare_wages`)
GZMVOC ship-level muster records and wage comparison from the DSS Linked Data Cloud:
- Search ship muster records from Asian waters (1691-1791)
- Crew composition by rank, European/Asian crew counts, aggregate wages
- Cross-link to DAS voyages via `das_voyage_id`
- Compare wage distributions between time periods (GZMVOC or MDB data)

### 18. Track Analytics (`maritime_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:
- **Per-voyage speeds**: compute daily haversine-based speeds from consecutive logbook positions
- **Bulk aggregation**: aggregate speeds across all matching tracks by decade, year, month, direction, or nationality
- **Statistical testing**: Mann-Whitney U test comparing speed distributions between two time periods (no scipy needed)
- Geographic bounding box filtering, speed bounds, direction filtering
- Enables climate proxy analysis: detect wind trends, seasonal patterns, volcanic signals in historical ship speeds
- **Difference-in-differences**: formal 2×2 DiD test (direction × period) with bootstrap confidence intervals
- **Route tortuosity**: per-voyage and aggregate tortuosity (great-circle vs. actual distance) with optional period comparison
- **Wind rose**: Beaufort wind force and wind direction distributions from CLIWOC logbooks
- **Speed export**: raw speed samples for downstream statistical analysis (CSV-ready JSON)
- **Galleon transit times**: compute transit durations for Manila Galleon voyages (1565–1815) by trade direction
- **Wind direction by year**: year-by-year wind direction distributions for trend detection

### 19. Server Discovery (`maritime_capabilities`)
List full server capabilities for LLM workflow planning:
- Available archives with metadata
- All registered tools with descriptions
- Ship types and geographic regions

## Public MCP Server

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.

## Installation

### Using uvx (Recommended -- No Installation Required!)

```bash
uvx chuk-mcp-maritime-archives
```

### Using uv (Recommended for Development)

```bash
# 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
```

### Using pip (Traditional)

```bash
pip install chuk-mcp-maritime-archives
```

## Usage

### With the Public Server

Point any MCP client at `https://maritime-archives.chukai.io/mcp` -- no local setup needed.

### With Claude Desktop

#### Option 1: Run Locally with uvx

**MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "maritime": {
      "command": "uvx",
      "args": ["chuk-mcp-maritime-archives"]
    }
  }
}
```

#### Option 2: Run Locally with pip

```json
{
  "mcpServers": {
    "maritime": {
      "command": "chuk-mcp-maritime-archives"
    }
  }
}
```

### Standalone

Run the server directly:

```bash
# 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:

```bash
# 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.

## Example Prompts

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.

### Exploration & Discovery

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

### Wreck Investigation

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

### Multi-Nation Voyages

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

### Crew & Social History

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

### Narrative & Full-Text Search

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

### Climate Science & Speed Analytics

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

### Cargo & Trade

```
"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

### Advanced: Multi-Tool Investigation Chains

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

### Running the Examples

The `examples/` directory contains runnable demo scripts that call MCP tools directly:

```bash
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 |

## Tool Reference

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 |

### maritime_search_narratives

```python
{
  "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
}
```

### maritime_search_voyages

```python
{
  "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
}
```

### maritime_search_wrecks

```python
{
  "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
}
```

### maritime_search_musters

```python
{
  "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
}
```

### maritime_compare_wages

```python
{
  "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)
}
```

### maritime_search_crew

```python
{
  "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
}
```

### maritime_search_cargo

```python
{
  "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
}
```

### maritime_assess_position

```python
{
  "wreck_id": "maarer:VOC-0789",                 # assess wreck position
  "source_description": "GPS surveyed site"      # position source info
}
```

### maritime_export_geojson

```python
{
  "region": "cape",                              # optional filter
  "status": "found",                             # optional filter
  "include_uncertainty": true,                   # include uncertainty radius
  "include_voyage_data": true                    # include ship/cargo data
}
```

### maritime_lookup_location

```python
{
  "name": "Batavia"                              # place name or alias
}
```

### maritime_list_locations

```python
{
  "query": "spice",                              # optional, text search
  "region": "indonesia",                         # optional, region code
  "location_type": "port",                       # optional: port, island, cape, etc.
  "max_results": 50                              # optional, default 50
}
```

### maritime_list_routes

```python
{
  "direction": "outward",                        # optional: outward, return, intra_asian, pacific_westbound, pacific_eastbound
  "departure_port": "Texel",                     # optional, substring match
  "destination_port": "Batavia"                  # optional, substring match
}
```

### maritime_get_route

```python
{
  "route_id": "outward_outer"                    # route identifier
}
```

### maritime_estimate_position

```python
{
  "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
}
```

### maritime_get_speed_profile

```python
{
  "route_id": "outward_outer",                   # route identifier
  "departure_month": 10                          # optional: month (1-12) for seasonal data
}
```

### maritime_get_timeline

```python
{
  "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
}
```

### maritime_get_voyage_full

```python
{
  "voyage_id": "eic:0062"                          # voyage ID from any archive (das, eic, carreira, galleon, soic)
}
```

### maritime_search_tracks

```python
{
  "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
}
```

### maritime_get_track

```python
{
  "voyage_id": 118                                # CLIWOC voyage ID (integer)
}
```

### maritime_nearby_tracks

```python
{
  "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
}
```

### maritime_get_hull_profile

```python
{
  "ship_type": "retourschip"                     # ship type code
}
```

### maritime_compute_track_speeds

```python
{
  "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
}
```

### maritime_aggregate_track_speeds

```python
{
  "group_by": "decade",                            # "decade", "year", "month", "direction", "nationality