@globalfishingwatch/gfw-mcp-js
OfficialClick on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@globalfishingwatch/gfw-mcp-jsGet fishing activity for vessel MMSI 412345678 last month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@globalfishingwatch/gfw-mcp-js
Access Global Fishing Watch data from any MCP-compatible AI assistant or directly from the terminal. Search vessels, retrieve apparent fishing activity and port-visit events, look up Marine Protected Areas, Exclusive Economic Zones and RFMOs, calculate apparent fishing activity hours within any region, and compute aggregate event statistics.
This package can be used in three modes:
MCP server (stdio) — connect any MCP-compatible AI assistant (Claude, Cursor, Windsurf, VS Code…) to GFW data via a local process
MCP server (HTTP) — deploy as a Cloud Run service; AI clients connect via URL with no local install required
CLI — query GFW data directly from the terminal
Requirements
Node.js 18+
A GFW API key — if not yet available, request one at https://globalfishingwatch.org/our-apis/tokens
MCP Server
Quick start (no install)
GFW_TOKEN=your_gfw_api_key_here npx @globalfishingwatch/gfw-cli mcpmcp is a subcommand of the CLI that starts the MCP stdio server.
Authentication
The MCP server resolves the API token in this order:
GFW_TOKENenvironment variable (compatibility alias)API_KEYenvironment variable~/.gfw/config.json(saved vianpx @globalfishingwatch/gfw-cli auth login)
If you have already run npx @globalfishingwatch/gfw-cli auth login from the CLI, the MCP server will pick up the stored token automatically — no need to set environment variables in your client config.
Client configuration
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
%APPDATA%\Claude\claude_desktop_config.json (Windows)
{
"mcpServers": {
"gfw": {
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": {
"GFW_TOKEN": "your_gfw_api_key_here"
}
}
}
}Claude Code (Plugin — recommended)
First add the GFW marketplace, then install the plugin:
# 1. Add the GFW marketplace (one-time)
/plugin marketplace add GlobalFishingWatch/gfw-mcp-js
# 2. Install the plugin (will prompt for your GFW API token)
claude plugin install gfw@globalfishingwatchClaude Code (manual MCP)
claude mcp add gfw -- npx -y @globalfishingwatch/gfw-cli mcp
export GFW_TOKEN=your_gfw_api_key_hereCursor
.cursor/mcp.json
{
"mcpServers": {
"gfw": {
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": { "GFW_TOKEN": "your_gfw_api_key_here" }
}
}
}Windsurf
~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"gfw": {
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": { "GFW_TOKEN": "your_gfw_api_key_here" }
}
}
}VS Code (Copilot)
.vscode/mcp.json
{
"servers": {
"gfw": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": { "GFW_TOKEN": "your_gfw_api_key_here" }
}
}
}OpenClaw
~/.openclaw/openclaw.json
{
"tools": {
"mcp": {
"servers": {
"gfw": {
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": { "GFW_TOKEN": "your_gfw_api_key_here" }
}
}
}
}
}Gemini CLI
One-line install (Gemini Extensions):
gemini extensions install https://github.com/GlobalFishingWatch/gfw-mcp-js
export GFW_TOKEN=your_gfw_api_key_hereThis installs the MCP server, the agent instructions (SKILL.md), and registers the extension automatically.
Manual config alternative — ~/.gemini/settings.json (global) or .gemini/settings.json (per project):
{
"mcpServers": {
"gfw": {
"command": "npx",
"args": ["-y", "@globalfishingwatch/gfw-cli", "mcp"],
"env": { "GFW_TOKEN": "your_gfw_api_key_here" }
}
}
}Claude Code (Skill only)
If you want the agent guidelines without the plugin, the repo ships a SKILL.md at the root.
Install via skills.sh CLI:
npx skills add GlobalFishingWatch/gfw-mcp-jsOr clone directly into your Claude skills directory:
git clone https://github.com/GlobalFishingWatch/gfw-mcp-js ~/.claude/skills/gfw-mcp-jsClaude Code auto-discovers SKILL.md and loads the agent guidelines plus tool reference. Pair with the MCP server config above (claude mcp add gfw -- npx -y @globalfishingwatch/gfw-cli mcp) so the skill's tool documentation matches the live MCP tools.
Alternative: local clone
git clone https://github.com/globalfishingwatch/gfw-mcp-js
cd gfw-mcp-js
npm install && npm run buildThen replace npx -y @globalfishingwatch/gfw-cli with node /absolute/path/to/gfw-mcp-js/dist/bin.js in any config above.
Available MCP tools
Tool | Description |
| Search vessels by name, MMSI, IMO, callsign, flag, owner, or gear type. To avoid misinterpretation, please check data caveats here and for more details refer to GFW Vessel API. |
| Fetch full vessel profile(s) by GFW vessel ID(s); returns metadata, registry owners, a map URL, and |
| Retrieve apparent fishing, encounter, port visit, or loitering events; filter by vessel, region, date, confidence, and encounter type. To avoid misinterpretation, please check data caveats here and for more details refer to GFW Events API |
| Compute aggregate statistics (total events, unique vessels, flag breakdown) over a date range, optionally filtered by region and grouped by flag or gear type; returns a GFW map URL (except for fishing events). For more details check Stats API |
| Resolve MPA, EEZ, or RFMO names to canonical region IDs. To check the sources of the regions, please check here |
| Get the URL to fetch the GeoJSON geometry of a specific MPA, EEZ, or RFMO |
| Calculate apparent fishing, SAR, Sentinel-2, or AIS presence hours worldwide ( |
| Retrieve apparent fishing activity, AIS off event, AIS coverage, and IUU vessel list insights for one or more vessels over a date range; returns a GFW map URL per vessel. To avoid misinterpretation, review data caveats here. For more details refer to GFW Insights API |
Remote MCP Server (Cloud Run)
Deploy as an HTTP service so AI clients connect via URL — no local Node.js install required on the client side. Each client passes its own GFW API token as a Bearer header; the server forwards it to the GFW API transparently.
Deploy to Cloud Run
# Build and push image
gcloud builds submit --tag gcr.io/YOUR_PROJECT/gfw-mcp .
# Deploy
gcloud run deploy gfw-mcp \
--image gcr.io/YOUR_PROJECT/gfw-mcp \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--port 8080No secrets needed in the deployment — clients supply their own GFW token per request.
Client configuration
The client sends its GFW API token as Authorization: Bearer <token>. The server uses it to call the GFW API on behalf of the client.
Claude Desktop
{
"mcpServers": {
"gfw": {
"url": "https://mcp.globalfishingwatch.org/mcp",
"headers": { "Authorization": "Bearer your_gfw_api_key_here" }
}
}
}Claude Code
claude mcp add --transport http gfw https://mcp.globalfishingwatch.org/mcp \
--header "Authorization: Bearer your_gfw_api_key_here"Cursor
.cursor/mcp.json
{
"mcpServers": {
"gfw": {
"url": "https://mcp.globalfishingwatch.org/mcp",
"headers": { "Authorization": "Bearer your_gfw_api_key_here" }
}
}
}Windsurf
~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"gfw": {
"url": "https://mcp.globalfishingwatch.org/mcp",
"headers": { "Authorization": "Bearer your_gfw_api_key_here" }
}
}
}VS Code (Copilot)
.vscode/mcp.json
{
"servers": {
"gfw": {
"type": "http",
"url": "https://mcp.globalfishingwatch.org/mcp",
"headers": { "Authorization": "Bearer your_gfw_api_key_here" }
}
}
}Health check
curl https://mcp.globalfishingwatch.org/health
# {"status":"ok"}stdio vs HTTP comparison
stdio (local) | HTTP (Cloud Run) | |
Install required | Node.js 18+ | None |
Token location |
|
|
Multi-user | No | Yes |
Command |
|
|
CLI
Install
# Run without installing
npx @globalfishingwatch/gfw-cli --help
# Or install globally
npm install -g @globalfishingwatch/gfw-cli
npx @globalfishingwatch/gfw-cli --helpAuthentication
Token resolution order:
GFW_TOKENenvironment variableAPI_KEYenvironment variable (compatibility alias)~/.gfw/config.json(saved viaauth login)
# Save token interactively (stored in ~/.gfw/config.json)
npx @globalfishingwatch/gfw-cli auth login
# Check which token source is active
npx @globalfishingwatch/gfw-cli auth status
# Remove stored token
npx @globalfishingwatch/gfw-cli auth logoutOr pass the token inline for a single command:
GFW_TOKEN=your_key npx @globalfishingwatch/gfw-cli vessel-search --name "Maria"Commands
vessel-search
Search vessels by name, MMSI, IMO, callsign, flag, owner, or activity date range.
npx @globalfishingwatch/gfw-cli vessel-search [--name <name>] [--mmsi <mmsi>] [--imo <imo>]
[--callsign <cs>] [--flag <ISO3>] [--owner <owner>]
[--active-from <YYYY-MM-DD>] [--active-to <YYYY-MM-DD>] [--limit <n>]At least one filter must be provided.
Parameter | Format / values |
| 9-digit string |
| 7-digit string |
| ISO 3166-1 alpha-3 code (e.g. |
| Owner name or partial name (wildcard match) |
|
|
| 1–50 (default 10) |
npx @globalfishingwatch/gfw-cli vessel-search --name "Maria" --flag CHN
npx @globalfishingwatch/gfw-cli vessel-search --mmsi 123456789
npx @globalfishingwatch/gfw-cli vessel-search --flag ESP --active-from 2024-01-01 --active-to 2024-12-31 --limit 20vessel-by-id
Fetch full vessel profile(s) by GFW vessel ID.
npx @globalfishingwatch/gfw-cli vessel-by-id --ids <id> [<id2> ...]npx @globalfishingwatch/gfw-cli vessel-by-id --ids abc123
npx @globalfishingwatch/gfw-cli vessel-by-id --ids abc123 def456 ghi789Each result includes relatedIdentities — an array of other AIS identities linked to the same physical vessel (different MMSI or name/flag periods), each with its own mapUrl. Empty array if none.
vessel-events
Retrieve fishing, encounter, port visit, or loitering events.
npx @globalfishingwatch/gfw-cli vessel-events --event-type <type>
--start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD>
[--vessel-id <id>] [--limit <n>] [--offset <n>]
[--confidence <2|3|4> ...] # port_visit only
[--encounter-types <type> ...] # encounter only
[--region-type <MPA|EEZ|RFMO>] [--region-id <id>]Parameter | Format / values |
|
|
|
|
| 1–100 (default 20) |
|
|
|
|
|
|
npx @globalfishingwatch/gfw-cli vessel-events --event-type fishing --start-date 2024-01-01 --end-date 2024-06-01
npx @globalfishingwatch/gfw-cli vessel-events --event-type port_visit --vessel-id abc123 --start-date 2024-01-01 --end-date 2024-12-31
npx @globalfishingwatch/gfw-cli vessel-events --event-type encounter --start-date 2024-01-01 --end-date 2024-12-31 --encounter-types CARRIER-FISHING SUPPORT-FISHING
npx @globalfishingwatch/gfw-cli vessel-events --event-type fishing --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-06-01events-stats
Compute aggregate event statistics over a date range.
npx @globalfishingwatch/gfw-cli events-stats --event-type <type>
--start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD>
[--group-by <FLAG|GEARTYPE>]
[--region-type <MPA|EEZ|RFMO>] [--region-id <id>]
[--confidence <levels> ...] [--encounter-types <types> ...]Parameter | Format / values |
|
|
|
|
|
|
|
|
|
|
|
|
npx @globalfishingwatch/gfw-cli events-stats --event-type fishing --start-date 2024-01-01 --end-date 2024-12-31
npx @globalfishingwatch/gfw-cli events-stats --event-type fishing --start-date 2024-01-01 --end-date 2024-12-31 --group-by GEARTYPE
npx @globalfishingwatch/gfw-cli events-stats --event-type encounter --start-date 2024-01-01 --end-date 2024-12-31 --region-type RFMO --region-id WCPFCReturns: { flags[], numEvents, numFlags, numVessels, groups[], mapUrl, dataCaveats? } — groups contains { name, value } pairs sorted descending by count. mapUrl links to the GFW map to visualise the queried events; it is not present when --event-type is fishing. dataCaveats is an array of markdown strings present when --event-type is fishing — always display every item.
region-id-lookup
Resolve an MPA, EEZ, or RFMO name to its canonical ID.
npx @globalfishingwatch/gfw-cli region-id-lookup --region-type <MPA|EEZ|RFMO> --query <name> [--limit <n>]Use this before area-report or vessel-events when you only know the human-readable name of a region.
Parameter | Format / values |
|
|
| 1–20 (default 5) |
npx @globalfishingwatch/gfw-cli region-id-lookup --region-type MPA --query "Galapagos"
npx @globalfishingwatch/gfw-cli region-id-lookup --region-type EEZ --query "Patagonia" --limit 10
npx @globalfishingwatch/gfw-cli region-id-lookup --region-type RFMO --query "WCPFC"region-geometry-url
Get the GeoJSON URL for a specific region (no API token required).
npx @globalfishingwatch/gfw-cli region-geometry-url --region-type <MPA|EEZ|RFMO> --id <id>Parameter | Format / values |
|
|
npx @globalfishingwatch/gfw-cli region-geometry-url --region-type EEZ --id 8386
npx @globalfishingwatch/gfw-cli region-geometry-url --region-type MPA --id 12345area-report
Calculate fishing, SAR, Sentinel-2, or AIS presence hours inside a region or worldwide. Date range must not exceed 1 year.
Important: This command must never be run in parallel. If multiple reports are needed, run them sequentially — one at a time, waiting for each to complete before starting the next.
# Region-specific report
npx @globalfishingwatch/gfw-cli area-report --region-type <MPA|EEZ|RFMO> --region-id <id>
--start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD>
[--type <FISHING|PRESENCE|SAR|SENTINEL2>]
[--flags <ISO3> ...]
[--geartypes <type> ...] # FISHING/SAR/SENTINEL2 only
[--vessel-types <type> ...] # PRESENCE only
[--speeds <range> ...] # PRESENCE only
[--group-by <VESSEL_ID|FLAG|GEARTYPE|FLAGANDGEARTYPE>]
[--top-vessels-limit <n>] # VESSEL_ID group-by only (default 10)
# World report (mutually exclusive with --region-type / --region-id)
npx @globalfishingwatch/gfw-cli area-report --region-world
--start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD>
[--type <FISHING|PRESENCE|SAR|SENTINEL2>]
[--flags <ISO3> ...] [--geartypes <type> ...] [--group-by <...>]Parameter | Format / values |
| Boolean flag. Run the report for the entire world. Mutually exclusive with |
|
|
| Canonical region ID. Required when |
|
|
|
|
| ISO 3166-1 alpha-3 codes (e.g. |
|
|
|
|
|
|
|
|
| Integer 1–100; default |
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31
npx @globalfishingwatch/gfw-cli area-report --region-type MPA --region-id 12345 --start-date 2024-01-01 --end-date 2024-12-31 --flags CHN ESP
npx @globalfishingwatch/gfw-cli area-report --region-type RFMO --region-id WCPFC --start-date 2024-01-01 --end-date 2024-12-31 --type FISHING --group-by FLAG
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 --type PRESENCE --vessel-types fishing cargo
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 --type SAR
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 --type SENTINEL2
npx @globalfishingwatch/gfw-cli area-report --region-world --start-date 2024-01-01 --end-date 2024-12-31 --type FISHING --group-by FLAGReturns: { regionType, regionId, dateRange, gfwMapUrl } for region reports, or { regionWorld: true, dateRange, gfwMapUrl } for world reports, plus one activity value field:
fishingHours— total fishing hours (present when--type FISHING)presenceHours— total vessel presence hours (present when--type PRESENCE)detections— total SAR or Sentinel-2 vessel detections (present when--type SARor--type SENTINEL2)
And optionally:
topVessels— top N vessels sorted descending by activity (N =--top-vessels-limit, default 10), each withvesselId,shipName,mmsi,flag,geartype, andvalue(hours for FISHING/PRESENCE; detections for SAR/SENTINEL2). Only present when--group-by VESSEL_ID.rows— aggregated entries sorted descending by activity value, each containing the grouping fields plushours. Only present when--group-by FLAG,GEARTYPE, orFLAGANDGEARTYPE.dataCaveats— array of markdown strings with data caveats (present when caveats exist for the requested type). Always display every item in this array to the user.Applied filters (
flags,vesselTypes,speeds,geartypes) echoed back when provided.
vessel-insights
Retrieve insights for one or more vessels over a date range.
npx @globalfishingwatch/gfw-cli vessel-insights --vessel-ids <id> [<id2> ...]
--start-date <YYYY-MM-DD> --end-date <YYYY-MM-DD>
--includes <FISHING|GAP|COVERAGE|VESSEL-IDENTITY-IUU-VESSEL-LIST> [...]Parameter | Format / values |
| One or more GFW vessel IDs |
|
|
|
|
|
|
Returns: { period, vesselIdsWithoutIdentity, mapUrls, apparentFishing?, gap?, coverage?, vesselIdentity?, dataCaveats? } — only insight fields for requested types are present. mapUrls is an object keyed by vessel ID linking each vessel to its GFW map profile for the queried period — always show these URLs to the user in full. dataCaveats is an array of markdown strings present when --includes FISHING — always display every item.
npx @globalfishingwatch/gfw-cli vessel-insights --vessel-ids abc123 --start-date 2024-01-01 --end-date 2024-12-31 --includes FISHING GAP
npx @globalfishingwatch/gfw-cli vessel-insights --vessel-ids abc123 def456 --start-date 2024-01-01 --end-date 2024-12-31 --includes FISHING GAP COVERAGE VESSEL-IDENTITY-IUU-VESSEL-LISTscreenshot
Generate a screenshot of a GFW map URL. Requires playwright and Chromium — install once if not already present:
npm install playwright && npx playwright install chromiumnode scripts/screenshot_gfw.js <url> <output_path>Argument | Description |
| The full GFW map URL (e.g. a |
| Destination path for the PNG file (e.g. |
The script appends &screenshotMode=true to the URL, waits for network and JS idle, then saves a 1280×800 PNG. Respects https_proxy / HTTPS_PROXY / http_proxy / HTTP_PROXY environment variables.
node scripts/screenshot_gfw.js "https://globalfishingwatch.org/map/vessel/abc123" /tmp/gfw_vessel_abc123.pngOutput
All commands output JSON to stdout, ready to pipe to jq:
npx @globalfishingwatch/gfw-cli vessel-search --name "Maria" | jq '.results[].name'
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 | jq '.fishingHours'
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 --type PRESENCE | jq '.presenceHours'
npx @globalfishingwatch/gfw-cli area-report --region-type EEZ --region-id 8386 --start-date 2024-01-01 --end-date 2024-12-31 --type SAR | jq '.detections'Environment variables
Variable | Default | Description |
| — | GFW API bearer token |
| — | Alias for |
|
| Environment name sent to Sentry |
Project structure
bin.ts # Entry point: loads CLI (dist/bin.js registered as "mcp" binary)
index.ts # MCP server stdio setup (used by the `mcp` CLI command)
mcp-server.ts # McpServer creation and tool registration
cli/
index.ts # CLI entry point (commander); includes the `mcp` subcommand
auth.ts # Token resolution and auth commands
middleware/
auth.ts # Bearer / X-API-Key authentication middleware
tools/ # One file per tool; each exports register() + a pure handler
lib/
api.ts # gfwFetch() — GFW API client
response.ts # createToolResponse() / createErrorResponse()
types.ts # Shared TypeScript types and dataset constantsThis server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/GlobalFishingWatch/gfw-mcp-js'
If you have feedback or need assistance with the MCP directory API, please join our Discord server