Skip to main content
Glama
ariefrsee

Maritime Vessel Data MCP Server

Maritime Vessel Data MCP Server

Ask an AI assistant "which tankers are anchored near Port Klang?" and get a real answer, from ships that are broadcasting their positions right now.

This is a Model Context Protocol server. It listens to live AIS radio traffic over Malaysian waters and exposes it as standard MCP tools, so any MCP compatible client can ask about vessels without a bespoke integration.

MIT licensed. Python 3.11 or newer. No account needed to try it, and a free API key to run it live.

A real response, abbreviated:

vessels_near_port("Tanjung Pelepas", 40)

{ "data": { "source": "live", "vessel_count": 63, "oldest_position_age_seconds": 140 },
  "matches": 27,
  "vessels": [
    { "mmsi": "563186500", "name": "ALS CERES", "type": "Cargo", "flag": "Singapore",
      "length_m": 255, "status": "Moored", "destination": "MYTTP",
      "lat": 1.2612, "lon": 103.7895, "distance_nm": 16.1 } ]}

Tools

Tool

What it answers

search_vessels(vessel_type, flag, status, limit)

which ships match a type, flag state or navigational status

vessels_near_port(port, radius_nm, limit)

what is within a radius of a named port, nearest first. Radius must be above 0 and at most 500 nautical miles

vessel_details(query)

everything known about one ship, by MMSI or name

Resource vessels://all returns the whole current picture.

Ports: Port Klang, Tanjung Pelepas, Penang, Malacca, Langkawi.

Both list tools take a limit, default 25, between 1 and 200. Every response reports matches, how many qualified, and returned, how many are included, so a capped answer says so rather than looking complete. For vessels_near_port the nearest are kept.

Responses are serialised compactly and positions are rounded to four decimal places, about 11 metres, which is finer than AIS itself reports. A typical question costs roughly a fifth of what it did before this was tuned. Fields AIS has not reported remain explicitly null rather than being dropped, because absent and unknown are different claims.

Filters are case insensitive, partial, and ignore surrounding whitespace. Bad input is refused rather than answered: a radius outside the allowed range is rejected by the schema before the call runs, and a blank vessel query returns an error asking for a name or MMSI rather than reporting that nothing matched everything.

Related MCP server: vessel-traffic-mcp

Quick start

git clone https://github.com/ariefrsee/maritime-mcp-server.git
cd maritime-mcp-server
python3 -m venv .venv && source .venv/bin/activate
pip install .

That puts a maritime-mcp-server command on your PATH inside the environment. Check it works without touching the network:

python -m maritime_mcp_server.smoke_test

It should end with All smoke checks passed.

Going live

Without an API key the server answers from a bundled sample of 18 vessels and says so. Get a free key from aisstream.io, then:

export AISSTREAM_API_KEY=your-key-here
maritime-mcp-server

You should see one line, AIS stream connected, and then silence. That is correct: an MCP server over stdio prints no banner and waits for a client.

Give it a minute before asking anything. AIS is a stream, not a database. The server learns about a ship only when that ship transmits, so it starts knowing nothing and fills up over the following minutes. During testing it held 0 vessels at 3 seconds, 40 at 150 seconds and 63 at five minutes. There is no backfill to request; the feed does not replay what you missed.

The subscribed box is 0.5N to 7.5N and 98.5E to 119.5E: the Strait of Malacca, both coasts of the peninsula, and Sabah and Sarawak.

Subscribing to water is not the same as having coverage of it. aisstream is fed by volunteer land-based receivers, and there are very few on the Malaysian coast. Measured over four minutes of live feed, counting distinct vessels within 30 nm of each port:

  Tanjung Pelepas        86        Kuching                 0
  Port Dickson           19        Bintulu                 0
  Malacca                 5        Miri                    0
  Kota Kinabalu           5        Labuan                  0
  Port Klang              0        Sandakan                0
  Penang                  0        Kuantan                 0
  Langkawi                0        Kemaman                 0

Nearly everything the server sees is in the Singapore Strait and around Tanjung Pelepas. Port Klang, Malaysia's largest port, returns nothing. Widening the bounding box does not change that; only a receiver near the port, or a paid feed with satellite AIS, would.

Use it from Claude Desktop

Add the server to claude_desktop_config.json. On macOS that lives at ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "maritime-vessel-data": {
      "command": "/absolute/path/to/.venv/bin/maritime-mcp-server",
      "env": { "AISSTREAM_API_KEY": "your-key-here" }
    }
  }
}

Run pwd in the project directory to get the absolute path. Restart Claude Desktop fully, then ask it something like "which vessels are near Tanjung Pelepas right now?" and it will call these tools for you.

Exporting the variable in your terminal does not reach a client launched process, so it has to go in the env block.

Where the data comes from

Every response opens with a data block naming its source.

"data": { "source": "snapshot", "vessel_count": 18, "snapshot_date": "2026-07-20",
          "note": "Live AIS is unavailable, so this is the bundled sample dataset." }

source is either live or snapshot. Nothing about how you call the tools changes between the two, and a snapshot answer is never mistakable for a live one.

AIS does not transmit everything these tools report. Flag state is derived from the MMSI country digits, length from the transmitted hull dimensions, and nearest port is computed here. Anything AIS has not reported is null, never guessed. A ship broadcasts its position every few seconds and its identity roughly once in ten of those, so a freshly seen vessel often has a position and no name, type or size until it next sends static data.

The feed also carries objects that are not ships, such as navigation buoys and base stations. Those are classified by their MMSI prefix and excluded.

Tests

pip install -e ".[dev]"
pytest

140 tests, well under a second. No API key, no network, no dependence on the clock. The translation layer runs against 199 real AIS messages captured over the Strait of Malacca and committed as a fixture, so it is checked against traffic that genuinely occurred rather than against invented input.

How it is built

Piece

Where

MCP tools and the source seam

maritime_mcp_server/server.py

AIS translation and lookup tables

maritime_mcp_server/ais_mapping.py

Vessel store, merging and expiry

maritime_mcp_server/store.py

Websocket client and reconnect

maritime_mcp_server/collector.py

Bundled fallback dataset

maritime_mcp_server/data/vessels.json

Built with the official mcp SDK, targeting the 2.x MCPServer API and pinned below 3.0.

Every decision, test result and mistake made while building this is written down under .shipline/, one folder per piece of work, including the plans, manual test scripts, retrospectives and runbooks.

Extending it

  • Widen the bounding box in collector.py to cover somewhere other than Malaysia.

  • Add ports to PORT_COORDS in server.py.

  • Add tools such as route ETA or anchorage occupancy. Clients discover them automatically.

  • Switch run() to the HTTP or SSE transport for remote clients, and add authentication.

Licence

MIT. See LICENSE.

Available Tools

14 tools
anchoragesA

Where vessels actually anchor, found in the recorded positions.

No chart is consulted. This looks for water where a lot of vessels reported "At anchor" and groups the touching parts into one place, so what comes back is where ships really wait rather than where they are permitted to. For a question about queueing, the first is the useful one.

Nothing is named. The cluster off eastern Singapore is obviously the eastern anchorage to anyone who works there, but AIS does not say so and this will not invent it. Each is given its extent, not a radius: an anchorage is usually a long thin thing along a coast and a circle would claim water nobody anchors in.

Bear the coverage caveat in mind. An anchorage nothing is listening to does not appear here, and that is not the same as an anchorage nobody uses.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNoArea to search instead, as 'south,west,north,east'.
daysNoHow far back to include, in days.
regionNoRegion key to search, for example 'malacca-strait'. Call list_regions for the keys. Ignored when bbox is given.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does so excellently. It discloses the methodology ('No chart is consulted', 'reported "At anchor"'), the aggregation behavior, that outputs are extents rather than radii, that nothing is named, and the coverage caveat about unmonitored vessel traffic. These are meaningful behavioral traits beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured into three focused paragraphs: core behavior, output geometry and naming limits, and coverage caveat. Every sentence earns its place, and the most important information is front-loaded. The example about eastern Singapore is illustrative without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description does not need to explain return fields and instead fills the semantic gaps: extent vs. radius, naming, and coverage interpretation. Input schema covers bbox/days/region, including the bbox-priority rule. An agent has enough to call this tool correctly and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the description does not need to compensate. It does not add param-specific meaning beyond the schema, though the coverage caveat generally reinforces the role of the 'days' parameter in limiting how far back AIS reports are considered.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific resource and behavior: it finds where vessels actually anchor from recorded AIS positions, grouping touching 'At anchor' reports into single places. It also distinguishes itself from chart-based or permitted anchorages by saying it returns 'where ships really wait rather than where they are permitted to.' However, it does not explicitly name or contrast sibling tools, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear contextual guidance, especially the line 'For a question about queueing, the first is the useful one,' which tells an agent when this tool's output is relevant. It also warns that absence from AIS data does not mean an anchorage is unused. It stops short of explicitly saying when to use this tool instead of siblings or naming alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

congestionA

How busy an area has been, hour by hour, from the recorded track.

Counts distinct vessels per hour by what they were reporting: at anchor, moored, or under way. The anchored count is the one that answers "how long is the queue", which is what a charterer rings an agent about.

Each vessel is counted once per hour it was heard in, so a vessel reporting twenty times in an hour counts once. An hour with no coverage reads as zero and is indistinguishable from an hour with no ships, which is why the response reports how many positions each hour was built from.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNoArea to report instead, as 'south,west,north,east' in degrees.
hoursNoHow far back to look, in hours, up to two weeks.
regionNoRegion key to report, for example 'malacca-strait'. Call list_regions for the keys. Ignored when bbox is given.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and handles it well: it discloses deduplication ('a vessel reporting twenty times in an hour counts once'), the zero-vs-no-coverage ambiguity, and the mechanism for resolving it ('reports how many positions each hour was built from'). This is precisely the kind of non-obvious behavior an agent needs to interpret results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core purpose, and every sentence adds value—counting semantics, deduplication, and zero-coverage caveat are all meaningful. The charterer analogy is brief and supports usage rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The combination of a fully documented schema, an output schema, and strong behavioral caveats makes the tool largely complete for an agent. The only notable gap is the implicit default area behavior when neither bbox nor region is supplied—the schema says 'instead' and lists empty defaults but never states what happens on a no-argument call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all three parameters (bbox, hours, region) at 100% coverage, so the description does not need to restate them. It adds no parameter-specific semantics beyond what the schema provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with 'How busy an area has been, hour by hour' and immediately specifies the mechanism: counts distinct vessels per hour by reporting status (anchored, moored, under way). This makes its scope clear and separates it from siblings like traffic_density, which would focus on density rather than status-split vessel counts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a strong domain cue—'the anchored count is the one that answers "how long is the queue"'—so an agent can infer when congestion is relevant. However, it never names sibling tools or states when to prefer this over traffic_density, anchorages, or vessels_in_area, so the choice is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fleet_trackA

Where every vessel has been over the last few hours.

Returns JSON with a "data" block and a "fleet" list, one entry per vessel, each with its identity and its positions oldest first. Intended for playback and for checking work against what was actually observed.

Each position is one AIS report that was received. The gaps between them are real: the median vessel reports only a handful of times an hour, so two fixes an hour apart are two observations and not a path. Nothing is interpolated.

When "truncated" is true the row cap was reached and this is not the whole picture. Narrow the window rather than assuming the missing vessels are gone.

ParametersJSON Schema
NameRequiredDescriptionDefault
hoursNoHow far back to look, in hours. A wider window returns proportionally more, so narrow it rather than raising the limit.
limitNoMaximum positions to return across the whole fleet. When the cap is reached the response says so, rather than quietly returning less than was asked for.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden—and it succeeds. It discloses that positions are raw AIS reports, that gaps are real and not interpolated, that nothing is extrapolated, and that 'truncated' indicates the cap was reached. This gives the agent crucial expectations about data completeness and meaning beyond what the schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, then gives output shape, intended use, data semantics, and truncation handling in a logical order. Every sentence adds value—none are filler or redundant with the schema. It is slightly longer than minimal, but the extra detail earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only fleet history tool with two well-described parameters and an output schema, this description is complete. It covers output structure, ordering, data fidelity, gaps, and truncation behavior. Nothing an agent needs to call it correctly or interpret results is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema already documents both parameters ('hours' and 'limit') with clear descriptions and defaults. The description adds behavioral context around truncation and window narrowing, but it does not add new parameter-level semantics. A baseline of 3 is appropriate because the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear colloquial summary ('Where every vessel has been') and then specifies the resource: JSON with a 'fleet' list, one entry per vessel, each with identity and positions. It is clearly distinct from siblings like vessel_track (single vessel) and vessels_in_area (current location) by emphasizing fleet-wide historical positions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states intended use cases: 'playback and for checking work against what was actually observed.' It also gives practical advice to narrow the window when truncation occurs. It does not name alternatives for exclusion, such as 'use vessel_track for a single vessel,' but the context is clear enough for an agent to select this tool appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_regionsA

List the sea areas this server can watch, and what each one costs.

The feed is rationed by throughput rather than by area. A subscription above roughly 25 messages a second is closed by the vendor within a couple of minutes, and a whole-world subscription dies inside one, so a selection has to be chosen to fit a budget rather than simply widened.

Each region reports its measured message rate. A rate of null means nobody has measured that region yet, and a selection containing one has an unknown total: that is reported as unknown rather than as a partial sum. Use set_regions to change what is being watched.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description discloses throughput rationing, vendor-enforced subscription limits (25 msg/s, whole-world dies within a minute), null rate semantics, and unknown total reporting behavior. This fully compensates for the missing annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then logically flows through budget constraints, rate reporting, null behavior, and the sibling tool for changes. Every sentence adds operational value without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, cost structure, rate limits, null/unknown handling, and how to change regions. With an output schema present, no return-format details are missing. Complete for an agent to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description correctly focuses on output semantics (rates, costs, null handling). Baseline for 0 params is 4, and the description adds value by explaining the meaning of the returned data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action ('List') and resource ('sea areas this server can watch') plus what each one costs. This clearly distinguishes it from siblings like set_regions (change) and vessels_in_area (vessel querying).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides operational context on throughput limits and explicitly directs to set_regions for changing the watched set, making the tool's role evident. It implies when to use this tool: to pick a budget-compliant selection of areas.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

passage_timeA

How long this leg actually takes, from ships that made it.

Not distance divided by an assumed speed. That knows nothing about the strait, the traffic, the pilot boarding, or the hour spent waiting for a berth at the far end. This is measured from recorded tracks.

The spread comes with the middle, always. A leg whose median is fourteen hours and whose range is seven to sixty two is not a leg anyone should schedule to fourteen, and reporting the median alone would invite exactly that. Below five observed passages no median is given at all.

Time spent waiting at the origin is not passage time: the clock starts when the vessel leaves the origin's reach, not when it was first seen there. A vessel seen arriving but never departing is not counted, because a record that starts mid-voyage is not evidence of a voyage.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow far back to look for passages, in days.
originYesPort to leave from, by name. One of the ports vessels_near_port accepts.
destinationYesPort to arrive at, by name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full behavioral burden and does so thoroughly. It discloses the data source ('recorded tracks'), sample-size limitations ('Below five observed passages no median is given at all'), the always-relevant spread, and boundary conditions such as excluding waiting time at origin and excluding mid-voyage records.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is front-loaded with a clear one-sentence summary and every caveat is decision-relevant. Slight redundancy exists ('This is measured from recorded tracks' restates the first sentence) and the 'fourteen hours' example is illustrative but could be tightened without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations, the description is remarkably complete: it explains measurement methodology, statistical presentation, minimum sample size, and edge cases. Since an output schema exists, the lack of explicit return-value description is not a gap. An agent can invoke this tool and interpret its result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantic detail beyond the schema by defining when the clock starts for origin/destination and what counts as a valid passage, but it adds little about the `days` parameter beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence, 'How long this leg actually takes, from ships that made it,' states precisely what the tool computes and the empirical source. It also distinguishes itself from a speed-based estimate ('Not distance divided by an assumed speed'), which separates it from sibling tools that might provide traffic or congestion data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear this is the tool to use when actual measured passage durations are needed, and explicitly rules out the speed/distance alternative. It does not name sibling tools or state explicit when-not-to-use conditions, but the context is strong enough for an agent to select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

port_callsA

When a vessel stopped, where, for how long, and whether she was working.

This is the skeleton of a Statement of Facts, read out of the recorded track rather than typed from memory: arrival, time alongside or at anchor, departure. Anchored and moored are kept apart, because in laytime terms one is waiting and the other is working.

Everything reported was observed. A vessel that has not been seen to leave has no departure time rather than an assumed one; a stop spanning a hole in coverage is cut at the hole rather than claimed as continuous; and a stop far from any known port is reported as at sea rather than given the name of the nearest one. Where an arrival was not witnessed, because the record starts mid-stop or follows a coverage hole, arrival_observed is false and the arrival time is only when this server first saw her there.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow far back to look, in days, up to the 90 day retention window. History exists only from the point this server started keeping it.
queryYesVessel to report, by exact MMSI or by (partial) name, case insensitive.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it excels: it discloses that only observed events are reported, that missing departures are not assumed, that stops are cut at coverage holes, and that arrival_observed is false when arrival was not witnessed. This is exactly the kind of data-provenance and assumption-avoidance context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but every sentence earns its place: a punchy first sentence, a clarifying analogy, a laytime distinction, then precise caveats about observation and coverage. It is front-loaded with the core purpose and structured so the most important behavioral rules come last.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with an output schema and fully documented parameters, the description is remarkably complete. It explains the meaning of key output concepts (arrival_observed, no assumed departure, at-sea stops) and the reasoning behind anchored vs moored distinctions. Nothing an agent needs to interpret results correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented. The description adds meaningful context about output semantics but no additional meaning for the query or days parameters themselves. Therefore the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence clearly states what the tool reports: when a vessel stopped, where, for how long, and whether she was working. It describes a distinct resource (recorded port calls) and adds useful framing as the skeleton of a Statement of Facts. However, it does not explicitly differentiate itself from siblings like vessel_track or passage_time.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear contextual triggers: this is the tool for observed stop-level facts (arrival, time alongside/at anchor, departure) and distinguishes waiting vs working in laytime terms. It does not name alternative tools or exclusions, but the use case is evident enough that an agent would not confuse it with a live tracking tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_vesselsA

Search the vessel dataset by type, flag state, and/or navigational status.

Any argument left blank is ignored, and surrounding whitespace is ignored. Returns JSON with a "data" block stating the source, a "matches" count of everything that matched, a "returned" count of how many are included, and a "vessels" list. When returned is less than matches the list was capped by the limit argument: raise it or narrow the search to see the rest. When data.source is "snapshot" the positions are from a fixed sample dataset and are not current: say so when answering. Fields that AIS has not reported yet are null, never guessed.

ParametersJSON Schema
NameRequiredDescriptionDefault
flagNoFlag state to match, case insensitive and partial, for example Malaysia or Singapore. Leave blank to match any flag.
limitNoMaximum number of vessels to return, between 1 and 200. The response always reports how many matched, so a truncated answer is visible rather than silent.
statusNoNavigational status to match, case insensitive and partial. Examples: Under way, At anchor, Moored. Leave blank to match any status.
vessel_typeNoShip category to match, case insensitive and partial. Examples: Tanker, Cargo, Passenger, Tug, Fishing. Leave blank to match any type.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure, and it excels: it describes the JSON response shape, the cap/truncation behavior with a visible returned-vs-matches distinction, the snapshot data caveat, and the guarantee that unreported fields are null rather than guessed. These are exactly the non-obvious behaviors an agent needs to know.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place. It front-loads the core purpose, then systematically covers response structure, truncation, data freshness, and null handling without repetition or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given four optional parameters, no annotations, and an output schema, the description covers everything needed to call the tool correctly: matching semantics, whitespace handling, result counting, the limit cap, the snapshot caveat, and null-field behavior. No critical operational context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful global parameter semantics beyond the schema: blank arguments are ignored and surrounding whitespace is ignored, which affects how the agent should construct call arguments. It also clarifies the limit's effect on the result count, adding value over the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource (search the vessel dataset) and precisely defines the filtering dimensions: type, flag state, and navigational status. It clearly differentiates this tool from area- or track-based sibling tools without needing to open their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: when searching by flag, status, or vessel type. However, it never names alternative sibling tools or states when not to use this tool, so explicit routing guidance is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_regionsA

Change which sea areas the live subscription watches.

Applied to the open connection where possible, so the feed is not interrupted. Vessels already collected are not discarded: the store keeps them until they age out of its 30-minute window, so a region just switched away from fades rather than vanishing.

A selection over the throughput budget is accepted and reported, not refused. The caller asked for it, and the honest answer is that the feed will drop and reconnect repeatedly rather than a limit that does not exist.

ParametersJSON Schema
NameRequiredDescriptionDefault
region_keysYesComma separated region keys to watch, for example 'malaysia,singapore-strait'. Call list_regions for the available keys and what each one costs.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden, and it delivers: it explains that the feed is not interrupted, existing vessels are retained until they age out of the 30-minute window, and over-budget selections are accepted rather than refused with the consequence of repeated drops/reconnects. This is far more than a generic mutation description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then adds meaningful behavioral caveats. It is a bit discursive, especially the final 'honest answer' sentence, but every sentence contributes important operational information and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple in terms of parameters, the schema fully documents region_keys, and an output schema exists. The description covers key edge-case behavior thoroughly. A minor gap is that it does not clarify what happens when no open connection is available, but this is not enough to make the description inadequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers the single parameter region_keys with 100% coverage, including an example and a pointer to list_regions. The description adds no additional parameter semantics beyond restating the concept of 'sea areas,' so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description leads with a specific verb and resource: 'Change which sea areas the live subscription watches.' This clearly distinguishes it from sibling read/query tools like list_regions, vessels_in_area, and vessels_watched. No ambiguity remains about the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: the tool modifies the live subscription's watched sea areas and applies to the open connection where possible. It doesn't explicitly name alternatives or when-not-to-use conditions, but the scope is specific enough that an agent can identify when this tool is the relevant one among the siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

traffic_densityA

Where vessels have actually been, as a grid of counts.

Read this as coverage as much as traffic. It shows where positions were received, so an empty cell means either that no ship went there or that nothing was listening. Port Klang reads as empty on this map and it is one of the busiest ports in the world.

Each cell reports distinct vessels and total positions separately, because they answer different questions: one ship anchored for two days makes hundreds of positions in a single cell, which is a fact about that ship and not about how busy the cell is.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNoArea to report instead, as 'south,west,north,east'.
daysNoHow far back to include, in days, up to the 90 day retention window.
regionNoRegion key to report, for example 'malacca-strait'. Call list_regions for the keys. Ignored when bbox is given.
cell_degreesNoGrid cell size in degrees. 0.02 is about 1.2 nautical miles. Smaller resolves more and costs more.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does well: it explains that cells represent received positions, that empty cells are ambiguous ('either that no ship went there or that nothing was listening'), and that distinct vessels and total positions answer different questions. These are genuine behavioral caveats beyond what the schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs with a front-loaded one-line summary. The Port Klang example earns its place by making the coverage-vs-traffic distinction concrete, and the final paragraph clarifies a subtle output distinction that would otherwise be easy to misinterpret.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists and all parameters are fully documented in the schema, the description covers the key interpretive risks: sparse-coverage bias, empty-cell ambiguity, and the different meanings of distinct vessels vs total positions. It is slightly incomplete only in not addressing when to choose this over closely related sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: bbox, days, region, and cell_degrees all have meaningful descriptions, defaults, and bounds. The tool description does not add param-specific semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line, 'Where vessels have actually been, as a grid of counts,' clearly communicates the tool's resource and output type. It distinguishes this from port-focused siblings like congestion or anchorages by framing it as historical position coverage, though it never names a specific sibling or explicit verb like 'reports' or 'computes'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives like vessels_in_area, congestion, or vessel_track. The 'Read this as coverage as much as traffic' warning is about interpreting results, not about selecting the tool, and no when-to-use or when-not-to-use conditions are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vessel_detailsA

Look up a single vessel by exact MMSI or by (partial) name.

Returns JSON with a "data" block stating the source and a "vessel" record, or an error object if no unique match is found. When data.source is "snapshot" the position is not current. Null fields mean AIS has not reported that detail, not that the value is zero or unknown to the vessel.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA nine digit MMSI for an exact match, or part of a ship's name for a partial one. Must not be blank.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses the response shape, the error behavior when no unique match is found, that snapshot data may be stale, and the meaning of null fields. This is strong behavioral context, though it does not mention authentication, rate limits, or explicit read-only guarantees.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: the first states the operation and accepted inputs, the second explains the return and error shape, and the third clarifies two important data semantics. It is compact, well-organized, and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter lookup tool with an output schema and no annotations, this description covers all the essentials: how to query, what the response contains, what errors mean, when data may be stale, and how to interpret null fields. An agent has enough guidance to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already fully describes the query parameter and its non-blank requirement. The description largely restates this instead of adding new semantic details like case sensitivity or minimum partial-name length, so it meets the baseline but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Look up'), a single resource ('a single vessel'), and the two query modes (exact MMSI or partial name). This makes it immediately distinguishable from sibling tools like search_vessels, which imply broader or multi-result behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states when to use the tool: to look up one vessel by MMSI or name. It does not explicitly name alternatives or exclusions, but the single-vessel scope plus the sibling list provides enough context. It lacks an explicit 'use search_vessels when you need multiple results' statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vessels_in_areaA

Vessels inside one area of sea, rather than everywhere the server watches.

This exists because a selection covering several regions can hold far more vessels than any one caller wants at once, and sending all of them is expensive for an answer about one strait. Ask for the water you care about.

The area filters what has already been collected, which is a different question from what is subscribed to: a region switched away from still has vessels in the store until they age out, and an area nobody is subscribed to simply returns nothing.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNoArea to report, as 'south,west,north,east' in degrees, for example '1.0,103.0,2.0,104.5'. Leave blank to use region instead.
limitNoMaximum vessels to return, between 1 and 500. The response always states how many were in the area, so a truncated answer is visible rather than silent.
regionNoA region key to report instead of a bbox, for example 'malaysia'. Call list_regions for the available keys. Ignored when bbox is given.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and discloses key traits: it filters already-collected data, is independent of current subscriptions, retains vessels until they age out after a region is switched away, and returns nothing for unsubscribed areas. This goes beyond a generic read and helps an agent predict empty or stale results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with its core purpose, and each following sentence earns its place by explaining rationale and edge cases. It is slightly longer than strictly necessary, but there is no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with zero required parameters and an output schema, the description covers purpose, selection rationale, and an important behavioral edge case (empty results for unsubscribed areas). It appropriately relies on the schema for parameter syntax and on the output schema for return shape; the only gap is explicit naming of competing siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All three parameters have complete descriptions in the schema: bbox format is given as 'south,west,north,east', region has a 'malaysia' example and points to list_regions, and limit documents bounds and truncation visibility. The description adds conceptual 'area' context but no additional parameter-level semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Vessels inside one area of sea, rather than everywhere the server watches,' which clearly identifies the resource and scope. It also distinguishes the tool from the subscription question ('a different question from what is subscribed to') and explains why a caller would pick it, though it never names a sibling tool explicitly or uses a crisp action verb.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when this tool is appropriate: 'This exists because a selection covering several regions can hold far more vessels than any one caller wants at once.' It also gives direct guidance ('Ask for the water you care about') and clarifies a boundary case: 'an area nobody is subscribed to simply returns nothing.' It does not explicitly enumerate alternative sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vessels_near_portA

List vessels within a radius (nautical miles) of a named port.

Recognized ports: Port Klang, Tanjung Pelepas, Penang, Malacca, Langkawi. Returns JSON with a "data" block stating the source, a "matches" count of everything inside the radius, a "returned" count of how many are included, and a "vessels" list annotated with distance_nm, nearest first. When returned is less than matches the nearest were kept and the rest omitted. When data.source is "snapshot" the positions are not current: say so when answering.

ParametersJSON Schema
NameRequiredDescriptionDefault
portYesPort name. One of: Port Klang, Tanjung Pelepas, Penang, Malacca, Langkawi. Case insensitive.
limitNoMaximum number of vessels to return, nearest first, between 1 and 200. The response always reports how many matched, so a truncated answer is visible rather than silent.
radius_nmNoSearch radius in nautical miles, greater than 0 and at most 500. The server only receives traffic for Malaysian waters, so a radius beyond that covers sea it never sees.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly explains the response structure, the meaning of matches vs. returned, the truncation behavior (nearest kept), and the important caveat that a data.source of 'snapshot' means positions are not current. This is valuable beyond the schema, though it does not cover permissions, rate limits, or side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by concise but essential details: recognized ports, response structure, truncation behavior, and the snapshot caveat. Every sentence earns its place and there is no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema and its own explanation of the output, the description is nearly complete for correct invocation. It covers recognized ports, response fields, truncation, and the snapshot caveat. The main gap is lack of explicit sibling differentiation, but the tool can still be used correctly without it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the parameter descriptions in the schema are already rich (e.g., limit communicates truncation visibility, radius_nm notes Malaysian waters coverage). The tool description adds little parameter-specific meaning beyond what the schema already provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List vessels within a radius (nautical miles) of a named port,' and enumerates the recognized ports. This clearly states the tool's function, though it does not explicitly contrast it with sibling tools like vessels_in_area or search_vessels.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is implied by the verb 'List' and the port/radius parameters, and the recognized ports are enumerated. However, there is no explicit guidance on when to prefer this tool over sibling tools such as vessels_in_area or search_vessels, and no exclusion criteria are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vessels_watchedA

Vessels inside the regions currently being watched, and nothing else.

The store keeps every vessel it has collected until the position ages out of the thirty minute window, which includes vessels from a region that has since been deselected. That is the right thing for the store to do and the wrong thing to show: someone who selects Malaysia means show me Malaysia, not Malaysia plus whatever was on screen ten minutes ago.

With no live subscription there is nothing being watched, so no filter applies and everything is returned with a note saying so.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum vessels to return, between 1 and 1000. The response always states how many were in the watched regions, so a truncated answer is visible rather than silent.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does so excellently. It discloses the 30-minute retention of stale vessels, the deliberate filtering to watched regions, and the no-subscription fallback that returns everything with a note, all of which an agent must know to interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core behavior is front-loaded in the first sentence, and the later paragraphs explain important edge cases rather than restating the schema. Some editorial phrasing is a bit verbose, but the length is justified by the subtle behavioral context it communicates.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single optional parameter, a rich schema description, and an output schema, the definition covers the important edge cases: stale deselected-region vessels, no-subscription behavior, and truncation visibility. An agent has enough information to invoke and interpret the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the limit parameter already has a thorough description including default, maximum, and truncation visibility. The tool description adds no additional parameter-level meaning, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line, 'Vessels inside the regions currently being watched, and nothing else,' states a specific resource and scope with a clear contrast to broader vessel queries. It also clarifies the semantics against siblings by explaining that deselected regions' vessels must not be shown.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes clear context: this tool should reflect only currently watched regions, and if no live subscription exists, no filter applies and everything is returned. It does not explicitly name sibling alternatives as 'do not use this for X,' but the intended usage is unmistakable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vessel_trackA

Where a vessel has been over the last few hours.

Returns JSON with a "data" block and a "track" list of positions, oldest first. Each position is one AIS report that was actually received: the gaps between them are real, and nothing is interpolated to fill them.

History only exists from the point this server started keeping it. An empty track means nothing was heard, not that the vessel did not move.

ParametersJSON Schema
NameRequiredDescriptionDefault
hoursNoHow far back to look, in hours, up to the retention window of 90 days. History exists only from the point this server started keeping it.
queryYesVessel to track, by exact MMSI or by (partial) name, case insensitive.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description takes full responsibility for disclosing behavior. It explicitly states that the track is a list of actual AIS reports with no interpolation, gaps are real, history exists only from server start, and an empty track means nothing was heard (not that the vessel didn't move). These details go far beyond the schema and give the agent crucial interpretive context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short paragraphs, each serving a distinct purpose: the purpose, the return structure and data authenticity, and the retention/empty-track nuance. It is front-loaded with the main purpose and contains zero filler. Every sentence adds value without being overly verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, and the description still clarifies the structure (data block, track list, oldest first). It covers edge cases like empty track and history retention. While it doesn't address error conditions or authentication, for a data-retrieval tool this is fairly complete. A minor gap is that it doesn't mention the query can be MMSI or name, but that is in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents both parameters (hours, query) with full descriptions and constraints. The tool description does not add additional meaning about parameters; it focuses on the returned track. Given the 100% schema coverage, the baseline of 3 is appropriate; the description neither enhances nor detracts from parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Where a vessel has been over the last few hours,' clearly indicating the tool returns historical positions for a single vessel. However, it limits the time range to 'a few hours' when the schema allows up to 90 days, creating a slight inconsistency. It does not explicitly distinguish from fleet_track, but the singular 'vessel' makes the scope obvious enough.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit statement about when to use this tool versus alternatives like fleet_track or vessel_details. The usage context is implied by the description and schema (exact MMSI or partial name), but no exclusions or alternative tool names are given, leaving the agent to infer when this is the appropriate choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 14 tool updatesv0.1.0
    • First observedanchorages
    • First observedcongestion
    • First observedfleet_track
    • First observedlist_regions
    • First observedpassage_time
    • First observedport_calls
    • First observedsearch_vessels
    • First observedset_regions
    • First observedtraffic_density
    • First observedvessel_details
    • First observedvessel_track
    • First observedvessels_in_area
    • First observedvessels_near_port
    • First observedvessels_watched

Related MCP Connectors

Related MCP Servers