Coastal Intelligence
Issued not yet
Assistant LLM provider: LLM …

Analysts with an AI assistant, agent builders

MCP server

The Model Context Protocol server for AI assistants and agents: endpoint and transport, the auth header, every tool with its typed arguments, the tool-error shape, client configurations, the configuration checker and example prompts.

Last reviewed

MCP in one paragraph

The Model Context Protocol (MCP) is an open protocol that lets an AI assistant or agent call tools on a server over JSON-RPC. A client lists the server's tools (tools/list), each with a JSON schema for its arguments, and calls one (tools/call); the result comes back as structured content the assistant can reason over. Coastal Intelligence exposes its agency tools as one MCP server, so an analyst can ask questions in plain language and the assistant fetches scoped, licensed data with its sources attached.

Endpoint and transport

  • Endpoint: https://coastal-intelligence.triskelionaisystems.com/api/mcp (this deployment's API origin plus /mcp).
  • Transport: MCP streamable HTTP, stateless, JSON responses. Every POST is self-contained; there is no session to keep, so a client can retry freely and a load balancer needs no affinity.
  • Server name coastal-intelligence-agency, version 1.0.0. The server's instructions to the assistant: "Coastal Intelligence agency data access. Read-only tools over the shared layers of the bays in your approved access request: bays and the public site register, daily signals, dated bay events, model skill against ground-truth stations, model, satellite and station time series, the bloom back-test and the dataset registry. Every row names its source, product, scale, lead_hours and licence; cite the attribution lines when you publish. Operator records are never available. Every call is logged."
  • Read-only: every tool is annotated read-only, non-destructive and idempotent; the server has no resources or prompts.

Authentication

Send the agency key as an HTTP header on every request: Authorization: Bearer <key> (or X-API-Key: <key>). The key is checked before the protocol starts: a missing, unknown or revoked key is answered 401 with WWW-Authenticate: Bearer, and the rate limit (60 calls per minute per key by default, shared with REST) is answered 429 with Retry-After. Both are plain HTTP responses with a JSON detail, not tool errors. See Authentication and keys.

The tools

9 tools, one per shared layer. The table lists every argument; ? marks an optional one. A date is a UTC day as YYYY-MM-DD. Each result is the envelope described on the REST API page, returned as structured content and as JSON text.

ToolArgumentsProduct neededREST route
list_baysnonenone/agency/bays
list_sitesbaynone/agency/sites
get_signalstarget, kind?, from_date?, to_date?signals/agency/signals
get_eventsbay, from_date?, to_date?events/agency/events
get_skillsite, variable?skill/agency/skill
get_timeseriessite, variable, product, from_date?, to_date?the dataset key given as product/agency/timeseries
get_backtestbaybacktest/agency/backtest
get_risk_indexbay, from_date?, to_date?risk_index/agency/risk-index
describe_datasetsnonenone/agency/datasets

list_bays: List bays

The bays this key may read, with name, country, region and bounding box [lon_min, lat_min, lon_max, lat_max].

Product needed: none. REST: GET /agency/bays.

list_sites: List sites of a bay

Sites and ground-truth stations of one bay, public register fields only: id, name, type, position (lon, lat) and licence reference. `site_level` says whether this key may ask for that site's own series.

Product needed: none. REST: GET /agency/sites.

ArgumentTypeRequiredMeaning
baystringyesA bay id inside the key's approved bays (list_bays).

get_signals: Get signals

Daily signals (thermal, bloom, runoff, growth) for a bay or a site between 'from_date' and 'to_date' (UTC days). A bay id gives the bay aggregate per kind and day (sites counted per label, max and mean value); a site id gives that site's series (needs site-level access). Labels: low, watch, stress, critical; growth carries the season stage.

Product needed: signals. REST: GET /agency/signals.

ArgumentTypeRequiredMeaning
targetstringyesA bay id (the bay aggregate per kind and day) or a site id (that site's series; needs site-level access).
kindstringnoOne signal kind: thermal, bloom, runoff or growth. Omitted: all four.
from_date (REST: from)datenoFirst UTC day, YYYY-MM-DD, inside the approved date range. Omitted: 30 days before the end of the window.
to_date (REST: to)datenoLast UTC day (inclusive), YYYY-MM-DD, inside the approved date range. Omitted: today plus the 10-day forecast horizon.

get_events: Get bay events

Dated bay events between 'from_date' and 'to_date' (UTC days, overlapping the window): HAB closures and phytoplankton exceedances from the Marine Institute bulletin, marine heatwaves and storms (wave or gale episodes at the bay reference cell).

Product needed: events. REST: GET /agency/events.

ArgumentTypeRequiredMeaning
baystringyesA bay id inside the key's approved bays (list_bays).
from_date (REST: from)datenoFirst UTC day, YYYY-MM-DD, inside the approved date range. Omitted: 30 days before the end of the window.
to_date (REST: to)datenoLast UTC day (inclusive), YYYY-MM-DD, inside the approved date range. Omitted: today plus the 10-day forecast horizon.

get_skill: Get model skill

How well the regional model matches ground truth at a site: bias (truth minus model), RMSE and MAE of daily means over 7, 30 and 90 days, against the bay's buoy. 'variable' is sst or hs.

Product needed: skill. REST: GET /agency/skill.

ArgumentTypeRequiredMeaning
sitestringyesA site or station id of an approved bay (list_sites). With bay aggregation only ground-truth stations are allowed.
variablestringno (default sst)The variable to read: for get_skill sst or hs; for get_timeseries a variable of the dataset (describe_datasets).

get_timeseries: Get a time series

One variable of one shared dataset ('product', a dataset key of the registry such as phy_daily, sst_l4, buoys; see describe_datasets) at a site or station between 'from_date' and 'to_date' (UTC days), grouped into series by source, product and depth. Points carry lead_hours: null observation, 0 analysis, above 0 forecast. Operator records are never returned.

Product needed: the dataset key given as product. REST: GET /agency/timeseries.

ArgumentTypeRequiredMeaning
sitestringyesA site or station id of an approved bay (list_sites). With bay aggregation only ground-truth stations are allowed.
variablestringyesThe variable to read: for get_skill sst or hs; for get_timeseries a variable of the dataset (describe_datasets).
productstringyesThe dataset key to read (describe_datasets), for example phy_daily, sst_l4, buoys. The key must be approved for it.
from_date (REST: from)datenoFirst UTC day, YYYY-MM-DD, inside the approved date range. Omitted: 30 days before the end of the window.
to_date (REST: to)datenoLast UTC day (inclusive), YYYY-MM-DD, inside the approved date range. Omitted: today plus the 10-day forecast horizon.

get_backtest: Get the bloom back-test

The back-test of the bay's bloom signal against Marine Institute HAB bulletin events: hits, misses, lead time and false-alarm rate per alert level, with the dated events inside the approved range.

Product needed: backtest. REST: GET /agency/backtest.

ArgumentTypeRequiredMeaning
baystringyesA bay id inside the key's approved bays (list_bays).

get_risk_index: Get the bay risk index

The bay risk index between 'from_date' and 'to_date' (UTC days): one row per day and peril (thermal, bloom, runoff, storm), index 0-100 aggregated across the bay's sites (half the worst site, half the mean), with its level (low, watch, stress, critical), the number of sites and the lowest confidence. A day and peril with fewer than three contributing sites is suppressed (index null). Method: the 'Insurer data sharing' help article, /help/insurer-data-sharing.

Product needed: risk_index. REST: GET /agency/risk-index.

ArgumentTypeRequiredMeaning
baystringyesA bay id inside the key's approved bays (list_bays).
from_date (REST: from)datenoFirst UTC day, YYYY-MM-DD, inside the approved date range. Omitted: 30 days before the end of the window.
to_date (REST: to)datenoLast UTC day (inclusive), YYYY-MM-DD, inside the approved date range. Omitted: today plus the 10-day forecast horizon.

describe_datasets: Describe datasets

Every shared dataset behind the data (provider ids, variables, scale, frequency), with its licence and the attribution line it requires, and the products this key may read.

Product needed: none. REST: GET /agency/datasets.

Argument naming and dates

  • Over MCP the date arguments are from_date and to_date (the REST query names are from and to). The tool schemas say additionalProperties: false: a call with an argument the tool does not declare, such as from, is refused as a tool error instead of quietly using the default window.
  • Dates are UTC days, YYYY-MM-DD, inside the key's approved range. Omitted, the window is the last 30 days up to today plus the 10-day forecast horizon; at most 366 days and 20,000 rows per call.

The tool-error shape

A refusal inside the protocol (outside the scope, unknown bay or site, bad argument, too large a window) is not an HTTP error: the call succeeds at the transport level and the result carries isError: true with the reason as a text content block, so the assistant can read it and adjust the call. Shape, with placeholders:

{
  "jsonrpc": "2.0",
  "id": "<request id>",
  "result": {
    "isError": true,
    "content": [
      {
        "type": "text",
        "text": "<the reason, for example: bay '<bay id>' is outside this key's approved scope (...)>"
      }
    ]
  }
}

The reasons are the same texts REST returns in detail for 403, 404 and 422. Only the key check (401) and the rate limit (429) are HTTP responses.

Client configurations

Any client that reads an mcpServers file with type http

Keep the key in an environment variable (AGENCY_KEY), not in the file:

{
  "mcpServers": {
    "coastal-intelligence": {
      "type": "http",
      "url": "https://coastal-intelligence.triskelionaisystems.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ${AGENCY_KEY}"
      }
    }
  }
}

Claude Code

Save the file above as .mcp.json in your project, or add the server from the command line:

claude mcp add --transport http coastal-intelligence https://coastal-intelligence.triskelionaisystems.com/api/mcp \
  --header "Authorization: Bearer $AGENCY_KEY"

Claude Desktop and other clients that only start local commands

Bridge to the HTTP endpoint with mcp-remote (needs Node.js):

{
  "mcpServers": {
    "coastal-intelligence": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://coastal-intelligence.triskelionaisystems.com/api/mcp",
        "--header",
        "Authorization:Bearer ${AGENCY_KEY}"
      ],
      "env": {
        "AGENCY_KEY": "<your key>"
      }
    }
  }
}

Checking a configuration

The backend ships a checker, the Python module app.agency.client_check (it needs the official MCP Python SDK). It reads an mcpServers file, expands ${VAR} from the environment, connects with the SDK client, lists the tools and calls one; it prints the tool list and the call's row count and licences, never the key, and exits non-zero on any error:

AGENCY_KEY=<your key> python -m app.agency.client_check \
  --config agency.mcp.json --call get_events \
  --args '{"bay": "<bay id>", "from_date": "<YYYY-MM-DD>", "to_date": "<YYYY-MM-DD>"}'

Without --call it only lists the tools. The type: http configuration above was tested this way against the API.

Three example prompts

Once the server is connected, a user can type requests like these to their assistant:

  • "List the bays my key can read, then give me the bay-level bloom signal for <bay> over the last 30 days and tell me which days were at stress or above."
  • "Which HAB closures, heatwaves and storm events did <bay> have between <from> and <to>? Give the dates and the source of each, with the attribution lines I must cite."
  • "Show the daily risk index for <bay> in <month> as a table per peril, note any suppressed days, and summarise the model skill for sea temperature at the bay's buoy."

Tool descriptions carry the AI disclosure, and every result names its sources and the attribution lines to cite. Signals are favourable, marginal or unfavourable style indicators, not food-safety advice. The REST face of the same tools is at https://coastal-intelligence.triskelionaisystems.com/api/agency/.

MCP server · Developers · Coastal Intelligence