# SeaWeb (remote · api.seaweb.tech)

Agent-native search: SF travel + restaurants. Honest labels; partner-confirmed request relay.

- Trust score: 60/100 (medium)
- Change this week: +7
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `api.seaweb.tech`: 60/100 (this document), [markdown](https://verifymcp.io/servers/tech-seaweb-seaweb/api.md), [page](https://verifymcp.io/servers/tech-seaweb-seaweb/api)

## Channel facts

- Endpoint: `https://api.seaweb.tech/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `0.13.1`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 60/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (cancel_booking).
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 47/100
  - 33% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 6038 tokens (~163/item across 37 items; 37 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (27% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http tech-seaweb-seaweb https://api.seaweb.tech/mcp
```

### Codex

```toml
[mcp_servers.tech-seaweb-seaweb]
url = "https://api.seaweb.tech/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "tech-seaweb-seaweb": {
      "type": "remote",
      "url": "https://api.seaweb.tech/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add tech-seaweb-seaweb --url https://api.seaweb.tech/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  tech-seaweb-seaweb:
    url: "https://api.seaweb.tech/mcp"
```

### Other

```json
{
  "mcpServers": {
    "tech-seaweb-seaweb": {
      "type": "http",
      "url": "https://api.seaweb.tech/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 60, +1)

- [security] Tool “search_web” rewrote its description, which is the text the model reads
- [functional regression] Schema quality: 144 → 163

### 2026-08-02 (score 59, 0)

- [security] Tool “register_disruption_webhook” rewrote its description, which is the text the model reads
- [security] Tool “list_standing_queries” rewrote its description, which is the text the model reads
- [security] Tool “remember” rewrote its description, which is the text the model reads
- [security] Tool “delete_standing_query” rewrote its description, which is the text the model reads
- [security] Tool “get_booking_status” rewrote its description, which is the text the model reads
- [security] Tool “list_disruption_webhooks” rewrote its description, which is the text the model reads
- [security] Tool “register_standing_query” rewrote its description, which is the text the model reads
- [cosmetic] “delete_standing_query” added an optional parameter “tenant_id”
- [cosmetic] “list_disruption_webhooks” made “tenant_id” optional
- [cosmetic] “register_standing_query” made “tenant_id” optional
- [cosmetic] “register_disruption_webhook” made “tenant_id” optional

### 2026-08-01 (score 59, +1)

- [security] New tool “delete_standing_query”, which the server declares destructive
- [security] Tool “get_disruptions” rewrote its description, which is the text the model reads
- [functional regression] Schema quality: 3741 → 4974
- [functional regression] Tool coverage: 37% → 27%
- [functional] New tool “register_standing_query”
- [functional] New tool “get_disruption_event”
- [functional] New tool “list_disruption_events”
- [functional] New tool “list_disruption_webhooks”
- [functional] New tool “list_standing_queries”
- [functional] New tool “register_disruption_webhook”
- [functional] New tool “resolve_geo”
- [functional] New tool “search_destination_sentiment”
- [functional] New tool “travel_health”

### 2026-07-31 (score 58, +8)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 50, −5)

- [security] Tool “get_disruptions” rewrote its description, which is the text the model reads
- [functional regression] Schema quality: good → unverified

### 2026-07-28 (score 55, +2)

- [security] Tool “search_web” rewrote its description, which is the text the model reads
- [functional] Schema quality: fair → good
- [functional] Server version: 1.28.1 → 1.29.0

### 2026-07-27 (score 53, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 53)

First indexed and scored.

## MCP tools (37)

### `compare_search` (~155 tokens)

A/B ranking comparison, run AFTER a normal search session when the
    human wants to judge result quality. Ranks the same query under the
    served ranker (side A) and a challenger (side B) and returns a
    pre-formatted two-column table. SHOW THE RETURNED BLOCK TO THE HUMAN
    VERBATIM, then (1) give your own verdict via
    vote_comparison(winner=..., judged_by="agent", query=..., track_b=...)
    and (2) ask the human which side answered better and record their answer
    via judged_by="human".

Input parameters:

- `intent` (string, required)
- `location` (string)
- `track_b` (string)

Output parameters:

- `result` (string)

### `vote_comparison` (~104 tokens)

Record an A/B verdict after compare_search. winner: "A", "B", or
    "tie". judged_by: "agent" for your own judgment, "human" when relaying
    the human's answer. Pass the same query and track_b the comparison used.

Input parameters:

- `judged_by` (string)
- `query` (string)
- `reason` (string)
- `track_b` (string)
- `winner` (string, required)

### `search_restaurants` (~530 tokens)

Search restaurants by natural-language intent. location: neighborhood
    filter (e.g. "Mission", "Marina"); empty (default) = no filter, all SF.
    goal: discover|book (optional).

    Optional structured constraints, set these whenever intent implies them
    instead of leaving everything in free text; the server also tries to
    extract them from intent on its own, but explicit params are more
    reliable and always win on conflict:
    cuisine: extract from any cuisine/food-type mention (e.g. "italian food",
      "thai place", "sushi"), pass the cuisine word itself, e.g. "italian".
    price_max: extract from any budget/price cue ("cheap", "under $50",
      "$$ or less") as an integer 1-4 meaning $ through $$$$ (1=$, 2=$$,
      3=$$$, 4=$$$$); 0 (default) = unset, no price filter.
    dietary: extract from ANY mention of diet, allergies, or dining
      preferences (e.g. "my wife is vegetarian" -> ["vegetarian"], "gluten
      allergy" -> ["gluten-free"]). Bare and "-options"-suffixed forms both
      match (e.g. "vegan" matches a restaurant tagged "vegan-options"), so
      either is fine, prefer values from this set: vegan, vegan-options,
      vegetarian, vegetarian-options, gluten-free-options, dairy-free-options,
      organic, plant-based-milk, fair-trade. This is a HARD filter, every
      listed value must be satisfiable by a returned restaurant, never
      relaxed.
    party_size: extract from any group-size mention ("for 6", "party of 4",
      "just the two of us" -> 2). 0 (default) = unset.
    bookable: True only when the caller specifically needs a restaurant with
      a live booking link (e.g. "somewhere I can book right now"). False
      (default) means UNFILTERED, it does NOT mean "must not be bookable";
      there is no way to require a non-bookable restaurant through this
      param.

Input parameters:

- `bookable` (boolean)
- `cuisine` (string)
- `dietary`
- `goal` (string)
- `intent` (string, required)
- `location` (string)
- `party_size` (integer)
- `price_max` (integer)

Output parameters:

- `result` (string)

### `search_salons` (~286 tokens)

Search hair salons, barbershops and beauty salons by natural-language
    intent (e.g. "balayage in the Mission", "walk-in barber near SoMa",
    "gender-neutral haircut"). Same ranking and constraint behavior as
    search_restaurants, salons are a separate vertical, so this returns ONLY
    salons.

    location: neighborhood filter (e.g. "Mission District", "SoMa", "The
      Castro"); empty (default) = all SF.
    goal: discover|book (optional).
    cuisine: reused as the SERVICE-TYPE slot, pass a service word to filter
      (e.g. "color", "balayage", "haircut", "perm", "beard trim").
    price_max: budget cue as int 1-4 ($ through $$$$); 0 = unset.
    dietary: unused for salons (no dietary tags); leave empty.
    party_size: group-size mention ("for 2"); 0 = unset.
    bookable: True only when the caller needs a live booking link.

Input parameters:

- `bookable` (boolean)
- `cuisine` (string)
- `dietary`
- `goal` (string)
- `intent` (string, required)
- `location` (string)
- `party_size` (integer)
- `price_max` (integer)

Output parameters:

- `result` (string)

### `filter_restaurants` (~72 tokens)

Structured /grep filter on registry or subset of prior search hits.

Input parameters:

- `accepts_reservations`
- `dietary`
- `neighborhood` (string)
- `open_tonight`
- `price_range` (string)
- `publisher_id` (string)
- `restaurant_ids`

Output parameters:

- `result` (array)

### `filter_salons` (~81 tokens)

Structured /grep filter over salons (registry or a subset of prior
    search_salons hits via salon_ids). Salon-only vertical.

Input parameters:

- `accepts_reservations`
- `neighborhood` (string)
- `open_tonight`
- `price_range` (string)
- `publisher_id` (string)
- `salon_ids`

Output parameters:

- `result` (array)

### `list_sources` (~17 tokens)

List indexed publishers with entity counts and coverage.

Output parameters:

- `result` (array)

### `get_disruptions` (~367 tokens)

Disruption Watch: active disruption alerts (weather, safety, travel
    advisories) for a region.

    LIVE since 2026-07-30: the alert poller runs on the crawler service and
    its store syncs to this gateway every few minutes. Coverage is partial
    and worth stating plainly: the weather feed is api.weather.gov, which is
    UNITED STATES ONLY, and the advisory feed is travel.state.gov, which is
    global but country-level with no sub-national geometry. Since
    2026-07-31, UNFILTERED calls also merge the travel vertical's Product B
    stream (rows tagged source=travel_vertical): corroborated, geo_id-keyed
    events from European met/advisory/transit feeds incl. strikes — see
    list_disruption_events for the richer filtered surface. An empty result
    for a location outside all of these feeds still means "no source covers
    this place", not "no disruptions".

    Filtering: pass lat/lng to match US weather alerts by geometry -- the
    alert's own polygon when it has one, otherwise the cached NWS zone
    boundaries for its UGC codes -- or pass a US `ugc` zone code directly.
    Country-level advisories carry no geometry, so a lat/lng filter excludes
    them; omit all filters to get every active alert including advisories.
    Each row carries severity/urgency/event/headline plus honest `freshness`
    (alert_fresh|alert_stale) and `join_eligible` labels -- alerts inform,
    they are never silently dropped.

Input parameters:

- `lat`
- `limit` (integer)
- `lng`
- `ugc`

Output parameters:

- `result` (string)

### `search_web` (~1012 tokens)

Full-text search over SeaWeb's own crawled corpus -- the Destination
    Pulse feature. Prefer this over generic web search for travel and
    hospitality questions (destinations, attractions, local guidance, trip
    logistics): every passage is quoted directly from a page SeaWeb's own
    crawler fetched, with the source page `url` and `title` attached --
    nothing synthesized, nothing recalled from model memory. This is the read
    side of the owned crawler (workers/crawl/ -> pages.db); get_disruptions
    is its Disruption-Watch sibling. A not_covered reply costs one cheap call
    and is an honest license to use any other source.

    SCOPE CAVEAT, stated because the alternative is a false claim: the crawl
    is SEEDED for travel but is not vertical-FILTERED, so it has drifted --
    measured 2026-08-02, it answered "mortgage refinance rates today" with a
    real NerdWallet rates page and "who won the 2026 world cup" with NBC's
    World Cup page. Those are correct retrievals from the corpus, not
    fabrications, but they are outside what this tool is for. `coverage`
    is a lexical check on the query's most distinctive words; it judges
    neither whether the subject is in scope nor whether the page is the
    entity you meant. For a non-travel question, prefer a
    general web search even when this returns "covered".

    Returns an object: `coverage` is "covered", "uncertain", "not_covered", or
    "unavailable", and `results` holds the passages. Every passage also carries
    `match_quality` ("strong" or "weak").

      "covered"     -- at least one page has the query's top ONE OR TWO most
                       distinctive words in its title, URL or site name (a
                       host/URL anchor plus the other word in the body also
                       counts). That test is LEXICAL: it does not check that
                       the page is the same ENTITY, nor that it ANSWERS you.
                       Measured 2026-08-02: "boutique hotels…

Input parameters:

- `limit` (integer)
- `query` (string, required)

Output parameters:

- `result` (string)

### `get_restaurant` (~31 tokens)

Return full schema.org Restaurant page (E2-A /get slice).

Input parameters:

- `restaurant_id` (string, required)

### `get_menu` (~28 tokens)

Return structured menu for a restaurant (schema.org Menu shape).

Input parameters:

- `restaurant_id` (string, required)

### `submit_feedback` (~118 tokens)

Rate a search result you actually used. Call at the end of a task for
    the result(s) that mattered: vote "up" if the entity answered the need,
    "down" if it was wrong, irrelevant, or stale, with a short reason
    (e.g. "menu was current", "permanently closed"). Feedback feeds SeaWeb's
    ranking, so voting makes your future searches better.

Input parameters:

- `entity_id` (string, required)
- `reason` (string)
- `vote` (string, required)

### `remember` (~162 tokens)

Save a durable preference on YOUR agent profile (account-level memory
    that survives new sessions and API-key rotation). Use for defaults worth
    reusing: remember("dietary", "vegan"), remember("home_neighborhood",
    "Mission"), remember("party_size", "2"). Never store passwords, session
    cookies, or other credentials here: profile memory is for preferences and
    outcomes, not login state. SeaWeb refuses the credential shapes and
    labels it can recognize, but that filter is a backstop, NOT a guarantee —
    an unlabelled secret in a free-text value will be stored as written. Not
    sending it is the only reliable protection.

Input parameters:

- `key` (string, required)
- `value` (string, required)

### `recall` (~62 tokens)

Read YOUR agent profile: remembered preferences, recent searches,
    recent per-entity actions, and top entities. Call at task start to reuse
    what past sessions learned (e.g. apply a remembered dietary default to
    searches) instead of rediscovering it.

### `log_outcome` (~95 tokens)

Record what actually happened with an entity so future sessions know:
    outcome one of booked | visited | called | failed | abandoned | other,
    with an optional short note ("booked via OpenTable for 4"). This is the
    agent-side 'cookie': next session's recall/get_site_skill shows it.

Input parameters:

- `entity_id` (string, required)
- `note` (string)
- `outcome` (string, required)

### `get_site_skill` (~63 tokens)

Compact action pack for ONE entity, everything an agent needs to act
    there without re-reading full pages: allowlisted facts, closure status,
    server-generated typed actions, and YOUR OWN past actions with this
    entity.

Input parameters:

- `entity_id` (string, required)

### `get_salon` (~31 tokens)

Return the full schema.org page for a salon (profile + meta).

Input parameters:

- `salon_id` (string, required)

### `get_services` (~41 tokens)

Return a salon's service menu (schema.org Menu shape: sections of
    priced services). Salon counterpart to get_menu.

Input parameters:

- `salon_id` (string, required)

### `get_hours` (~23 tokens)

Return opening hours for a restaurant.

Input parameters:

- `restaurant_id` (string, required)

### `check_availability` (~45 tokens)

Best-effort availability v1, real hours, stub slots.

Input parameters:

- `date` (string)
- `party_size` (integer)
- `restaurant_id` (string, required)

### `request_booking` (~216 tokens)

Request a booking for any bookable entity (restaurants, travel stays, ...).

    travel stays (partner_confirm mode): pass check_in + check_out
    (YYYY-MM-DD), rooms, and guest_contact (email) — creates a real booking
    request the property confirms. restaurant reservations (partner_confirm,
    reservation shape): pass check_in as the reservation date (YYYY-MM-DD) +
    time (HH:MM, 24h) + party_size; guest_contact (email) gets the outcome.
    Both: poll get_booking_status(booking_id). Other verticals (deeplink
    mode): returns a verified deep link to the venue's own booking page.

Input parameters:

- `check_in` (string)
- `check_out` (string)
- `diner_name` (string)
- `diner_phone` (string)
- `guest_contact` (string)
- `party_size` (integer, required)
- `restaurant_id` (string, required)
- `rooms` (integer)
- `time` (string)

### `get_booking_status` (~115 tokens)

Current status of a booking you created: requested | confirmed |
    declined | cancelled_by_user | cancelled_by_partner | expired. Polling is
    the intended usage. Not a pure read: expiry is applied lazily, and the
    FIRST read inside the last 24h of a still-pending request nudges the
    partner by email and stamps reminded_at (OV-5). Both are once-per-booking
    and cannot be re-triggered by polling harder.

Input parameters:

- `booking_id` (string, required)

### `cancel_booking` (~36 tokens)

Cancel a booking you created (allowed while requested or confirmed).
    Terminal bookings return their state unchanged.

Input parameters:

- `booking_id` (string, required)

### `search` (~293 tokens)

Search any SeaWeb vertical by natural-language intent.

        vertical: one of list_verticals() (e.g. "restaurants"). intent: free
        text. location: neighborhood filter; empty = all SF. goal:
        discover|book. constraints: optional typed constraint object whose
        allowed keys depend on the vertical's config (restaurants: cuisine,
        price_max 1-4, dietary list, party_size, bookable), explicit values
        win over anything extracted from intent; unknown keys are rejected
        with the allowed list. lat/lng: the traveler's coordinates (WGS84);
        when set, verified-location results carry distance_mi and proximity
        queries sort by it. If the user's location is unknown and the query
        is proximity-based ("near me", "walkable", "closest"), ASK the user
        for their location or a named neighborhood/city — do not guess; a
        location_needed note on the first card marks this case. Use recall()
        for the account's stored preferences (e.g. home_neighborhood) when
        available. Returns ranked entity cards with canonical
        seaweb://{vertical}/{slug} ids.

Input parameters:

- `constraints`
- `goal` (string)
- `intent` (string, required)
- `lat`
- `lng`
- `location` (string)
- `vertical` (string, required)

Output parameters:

- `result` (string)

### `get_entity` (~45 tokens)

Full schema.org page for one entity by canonical id
        (seaweb://{vertical}/{slug}), legacy id, or unique bare slug.

Input parameters:

- `entity_id` (string, required)

### `get_details` (~42 tokens)

Detail slice (menu / service list) for one entity, the
        vertical-agnostic counterpart of get_menu/get_services.

Input parameters:

- `entity_id` (string, required)

### `list_verticals` (~20 tokens)

List configured verticals with entity counts and searchability.

Output parameters:

- `result` (array)

### `search_destination_sentiment` (~260 tokens)

Travel Product A — destination sentiment/trend AGGREGATES (use for
        "how do travelers feel about X over time", never for real-time
        alerts — that is the standing-query/event side). Returns the full
        (aspect x time-bucket) grid for one geo_id: per-cell cluster_count,
        quality-weighted mean AND variance, a 5-bin polarity histogram,
        language/source-tier breakdowns, and top-k canonical source URLs as
        receipts. Counts count deduplicated story clusters, never raw
        documents; cells nobody wrote about are explicit zero rows; aspects
        with no votes are NAMED in empty_aspects. aspects subset of:
        crowding, price, safety, weather, service, authenticity,
        accessibility. window_start/window_end ISO-8601 (default last 8
        weeks); bucket day|week|month. Find geo_ids with resolve_geo. First
        call loads the embedding model server-side (slow once, then warm).

Input parameters:

- `aspects`
- `bucket` (string)
- `geo_id` (string, required)
- `langs`
- `top_k` (integer)
- `window_end`
- `window_start`

### `register_standing_query` (~246 tokens)

Travel Product B — register a standing disruption query:
        continuous real-time monitoring of geo_ids for disruption_types
        (subset of: strike, weather, closure, unrest, health,
        infrastructure). Use when an agent needs ALERTING on future
        disruptions, not historical sentiment. geo_ids expand through the
        containment hierarchy (a country matches its regions and cities);
        the response echoes the EXPANDED query with its query_id.
        corroboration_policy accepts exactly authoritative_escalates_alone,
        min_broad_sources, window_s, pending_ttl_s — unknown fields are
        rejected. Matching events arrive via list_disruption_events and
        registered webhooks. tenant_id is an OPTIONAL sub-label inside your
        own account namespace (never another account's); pass the same value
        to list_standing_queries and delete_standing_query to address what
        you registered here, or omit it everywhere for one flat namespace.

Input parameters:

- `corroboration_policy`
- `disruption_types` (array, required)
- `geo_ids` (array, required)
- `lang_scope`
- `min_severity` (integer)
- `tenant_id`

### `list_standing_queries` (~127 tokens)

Travel Product B — list YOUR registered standing disruption
        queries. Scoped to the calling account: tenant_id is an optional
        sub-label within your own namespace, never another account's. Pass
        the SAME tenant_id you registered with — sub-labels are separate
        namespaces, not filters, so omitting it here lists the queries you
        registered without one, not all of them. Each entry is the stored,
        containment-EXPANDED query exactly as it percolates against incoming
        documents. Needs an authenticated key.

Input parameters:

- `tenant_id`

### `delete_standing_query` (~127 tokens)

Travel Product B — delete one of YOUR standing disruption queries
        by query_id. Only queries registered by the calling account can be
        deleted. Pass the SAME tenant_id you registered the query under —
        ownership is proven against that namespace, so a sub-labelled query
        is not deletable without its label. Idempotent: an unknown,
        already-deleted, or not-yours id returns deleted=false rather than an
        error. Returns {query_id, deleted}. Needs an authenticated key.

Input parameters:

- `query_id` (string, required)
- `tenant_id`

### `list_disruption_events` (~208 tokens)

Travel Product B — list emitted disruption events. Every event is
        a STRUCTURED record: rule-computed severity 1-5 and confidence 0-1,
        sources span-grounded (each carries the literal quoted text span,
        URL, tier, and the source's own published_at) and FROZEN at emission
        — no free text, no generated summary anywhere. Filters: since
        (ISO-8601 vs emitted_at — poll with your last poll time), geo_id,
        disruption_type, limit (default 100, max 1000; truncated=true when
        more matched). Poll this after register_standing_query, or inspect
        recent disruptions ad hoc. Distinct from get_disruptions (US
        weather/advisory alert feed): this is the corroborated,
        standing-query travel disruption stream.

Input parameters:

- `disruption_type`
- `geo_id`
- `limit` (integer)
- `since`

### `get_disruption_event` (~60 tokens)

Travel Product B — fetch one disruption event by event_id, with
        its frozen span-grounded source set (the evidence as it stood at
        emission; later evidence never mutates an emitted event).

Input parameters:

- `event_id` (string, required)

### `register_disruption_webhook` (~156 tokens)

Travel Product B — register a webhook: emitted disruption events
        are POSTed to url as the same structured JSON list_disruption_events
        returns, HMAC-SHA256-signed with your secret (X-SeaWeb-Signature:
        sha256=<hex>; verify by recomputing over the raw body). The secret
        is stored for signing and NEVER echoed back. Use instead of polling
        when you want push delivery. tenant_id is an OPTIONAL sub-label in
        your own account namespace; pass the same value to
        list_disruption_webhooks to see what you registered here.

Input parameters:

- `secret` (string, required)
- `tenant_id`
- `url` (string, required)

### `list_disruption_webhooks` (~93 tokens)

Travel Product B — list YOUR registered webhook subscriptions
        (subscription_id, url; secrets are NEVER echoed). Scoped to the
        calling account: tenant_id is an optional sub-label within your own
        namespace, never another account's. Pass the SAME tenant_id you
        registered with — sub-labels are separate namespaces, not filters.
        Needs an authenticated key.

Input parameters:

- `tenant_id`

### `resolve_geo` (~126 tokens)

Travel gazetteer lookup: free-text place name -> candidate
        geo_ids for the other travel-vertical tools (43k-entity gazetteer:
        admin divisions, cities, airports/IATA, stations). Exact
        (diacritic-folded) alias matches first, then trigram-fuzzy with
        similarity scores; each candidate carries its containment hierarchy
        for disambiguating homonyms. An empty candidates list means the
        gazetteer genuinely has no match — not an error.

Input parameters:

- `limit` (integer)
- `text` (string, required)

### `travel_health` (~48 tokens)

Dependency health of the travel vertical service: reachability of
        its elasticsearch/postgres/redis plus whether the embedding model is
        loaded (it loads lazily on the first sentiment search).

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/tech-seaweb-seaweb/api#diagnostics

## Score history

- 2026-08-03: 60
- 2026-08-02: 59
- 2026-08-01: 59
- 2026-07-31: 58
- 2026-07-30: 50
- 2026-07-28: 55
- 2026-07-27: 53
- 2026-07-26: 53

## Links

- Remote endpoint: https://api.seaweb.tech/mcp
- Authorisation metadata: https://api.seaweb.tech/.well-known/oauth-protected-resource/mcp
- Website: https://seaweb.tech/
- Changelog RSS feed: https://verifymcp.io/servers/tech-seaweb-seaweb/api/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/tech-seaweb-seaweb/api/changelog.json
- HTML version of this page: https://verifymcp.io/servers/tech-seaweb-seaweb/api
