Update docs for MCP primitives and fix Vite allowedHosts

Document tool annotations, structured logging, sampling summaries,
and the new test_client_capabilities diagnostic tool across getting
started, reference, and architecture pages. Fix Vite 6+ host blocking
when serving behind a reverse proxy.
This commit is contained in:
Ryan Malloy 2026-02-23 15:18:25 -07:00
parent 2443d0687a
commit 10e9bf9185
4 changed files with 139 additions and 5 deletions

View File

@ -49,6 +49,7 @@ export default defineConfig({
vite: {
server: {
host: "0.0.0.0",
allowedHosts: [domain.split(":")[0]],
...(process.env.VITE_HMR_HOST && {
hmr: {
host: process.env.VITE_HMR_HOST,

View File

@ -22,10 +22,11 @@ federal data mariners and forecasters rely on.
## Capabilities
<CardGrid>
<Card title="13 Tools" icon="rocket">
<Card title="14 Tools" icon="rocket">
Station discovery, tide predictions, observed water levels, meteorological
data, marine conditions snapshots, SmartPot deployment intelligence, and
chart visualization.
data, marine conditions snapshots, SmartPot deployment intelligence,
chart visualization, and client capability diagnostics. All tools declare
MCP annotations for safe retry and caching.
[Tool reference](/reference/)
</Card>

View File

@ -1,6 +1,6 @@
---
title: Tools Reference
description: Complete reference for all 13 MCP tools
description: Complete reference for all 14 MCP tools
sidebar:
order: 1
---
@ -13,6 +13,29 @@ All tools are registered on the `mcnoaa-tides` MCP server and available through
Date parameters accept `yyyyMMdd` or `yyyyMMdd HH:mm` format. The maximum time range is 720 hours (~30 days).
</Aside>
### Tool Annotations
Every tool declares [MCP tool annotations](https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations) so clients can make informed decisions about retries, caching, and approval:
| Annotation | Value | Meaning |
|------------|-------|---------|
| `readOnlyHint` | `true` (all tools) | Tools never write or modify data -- safe to retry |
| `openWorldHint` | `true` (13 tools) | Fetches data from NOAA's external API |
| `openWorldHint` | `false` (diagnostics) | `test_client_capabilities` only inspects the MCP session |
### Structured Logging
Tools send diagnostic messages to the client via MCP `notifications/message`:
- **`ctx.info()`** before data fetches (e.g., "Fetching hilo predictions for station 8454000")
- **`ctx.warning()`** for data quality issues (preliminary/unverified readings), unavailable products, and NO-GO/CAUTION deployment assessments
- **`ctx.debug()`** for search result counts and phase classification details
These messages appear in the client's log stream, not in the tool return value.
### Sampling Summaries
Three tools -- `marine_conditions_snapshot`, `deployment_briefing`, and `water_level_anomaly` -- attempt to generate a natural-language `"summary"` key via [MCP sampling](https://spec.modelcontextprotocol.io/specification/2025-03-26/client/sampling/). If the connected client supports sampling, the server asks its LLM to synthesize a concise briefing from the raw data. If sampling is unavailable, the raw data is returned without a summary -- the feature is purely additive.
---
## Station Discovery
@ -757,6 +780,64 @@ Install visualization dependencies with `uv pip install mcnoaa-tides[viz]`. The
---
## Diagnostics
Tools for inspecting the MCP session and client capabilities.
### test_client_capabilities <Badge text="diagnostics" variant="tip" />
Report which MCP features the connected client supports. Returns the client implementation info, protocol version, and capability flags for sampling, elicitation, roots, and tasks. Useful for understanding what features are available before calling tools that depend on optional client capabilities.
*No parameters required.*
**Example call:**
```json
{
"tool": "test_client_capabilities",
"arguments": {}
}
```
**Example response:**
```json
{
"session_id": "cb6ddc2d-f866-4fa3-bf2e-15eebd133481",
"client": {
"name": "claude-code",
"version": "2.1.38"
},
"protocol_version": "2025-11-25",
"capabilities": {
"sampling": false,
"elicitation": false,
"roots": true,
"tasks": false
},
"roots_detail": {
"list_changed": false
}
}
```
When a capability is `true`, additional `*_detail` keys are included with sub-capability flags. For example, a client that supports sampling would include:
```json
{
"sampling_detail": {
"context": true,
"tools": true
}
}
```
<Aside type="tip">
Call this tool first to discover whether the client supports sampling (which enables natural-language summaries in `marine_conditions_snapshot`, `deployment_briefing`, and `water_level_anomaly`).
</Aside>
---
## Datum Options
Several tools accept a `datum` parameter. The most common options:

View File

@ -130,12 +130,13 @@ The codebase is split into focused modules, each with a `register(mcp)` function
- conditions.py -- marine_conditions_snapshot
- smartpot.py -- tidal_phase, deployment_briefing, catch_tidal_context, water_level_anomaly
- charts.py -- visualize_tides, visualize_conditions
- diagnostics.py -- test_client_capabilities
- charts/
- tides.py -- Matplotlib/Plotly tide chart renderers
- conditions.py -- Matplotlib/Plotly conditions dashboard renderers
</FileTree>
Each tool module has a single `register()` function. The server imports all six and calls them in sequence during startup. This keeps the server module small and makes it straightforward to add new tool groups without touching existing ones.
Each tool module has a single `register()` function. The server imports all seven and calls them in sequence during startup. This keeps the server module small and makes it straightforward to add new tool groups without touching existing ones.
### Pure logic separation
@ -163,3 +164,53 @@ MCP_TRANSPORT=streamable-http MCP_PORT=8000 uvx mcnoaa-tides
```
The version banner is always printed to stderr (never stdout) to avoid corrupting the JSON-RPC stream in stdio mode.
## MCP Primitives
Beyond tools, resources, and prompts, the server uses several MCP protocol features for observability and client interop.
### Tool Annotations
Every tool declares `ToolAnnotations` from the MCP spec. These are metadata hints that clients can use for automatic retry policies, caching, and approval workflows.
```python
from mcp.types import ToolAnnotations
_ANNOTATIONS = ToolAnnotations(readOnlyHint=True, openWorldHint=True)
@mcp.tool(tags={"discovery"}, annotations=_ANNOTATIONS)
async def search_stations(ctx: Context, ...) -> list[dict]:
...
```
All tools set `readOnlyHint=True` (they never write data). The `openWorldHint` is `True` for tools that call NOAA's API and `False` for `test_client_capabilities`, which only inspects the MCP session.
### Structured Logging
Tools send diagnostic messages to the client via `ctx.info()`, `ctx.warning()`, and `ctx.debug()`. These are delivered as MCP `notifications/message` -- separate from the tool return value and intended for the client's log stream.
The logging strategy is intentionally sparse:
- **`ctx.info()`** before data fetches, providing station ID and product context
- **`ctx.warning()`** for actionable signals: preliminary data quality flags, unavailable products, NO-GO/CAUTION deployment assessments, and elevated/high anomaly risk levels
- **`ctx.debug()`** for search match counts, proximity results, and phase classification details
### Sampling
Three tools use `ctx.sample()` to request natural-language summaries from the connected client's LLM:
| Tool | Summary content |
|------|----------------|
| `marine_conditions_snapshot` | 2-3 sentence marine weather briefing for a boat captain |
| `deployment_briefing` | Concise deployment briefing paragraph for a crab pot crew |
| `water_level_anomaly` | 2-sentence risk summary for a marine operator |
Sampling is purely additive -- the raw structured data is always returned regardless. Each `ctx.sample()` call is wrapped in `try/except Exception: pass` because not all clients support sampling. A compact subset of the data (latest readings only, not hundreds of 6-minute records) is sent to keep the sampling prompt efficient.
### Client Capability Discovery
The `test_client_capabilities` diagnostic tool introspects `ctx.session.client_params` to report what the connected client supports. This lets users (and the LLM) discover which optional features are available before attempting them:
- **Sampling** -- Can the server ask the client's LLM to generate summaries?
- **Elicitation** -- Can the server prompt the user for input mid-tool-call?
- **Roots** -- Does the client expose its project directory context?
- **Tasks** -- Does the client support long-running background operations?