Skip to content

@mostlyrightmd/core/hosted

A misconfiguration of the opt-in hosted seams (MOSTLYRIGHT_WEATHER_HOSTED_URL / MOSTLYRIGHT_FINANCE_HOSTED_URL / MOSTLYRIGHT_API_KEY) — raised before any network call so the caller gets a clear, actionable error instead of a raw 401/null.

Mirrors the Python _hosted_client “clear config error” contract: a missing seam is a caller/deployment bug, not a transport failure, so it is a distinct typed error a caller can branch on.

new HostedConfigError(message, options): HostedConfigError

string

MostlyrightErrorOptions = {}

HostedConfigError

MostlyrightError.constructor

static defaultErrorCode: string = "HOSTED_CONFIG"

Subclass override — the stable string enum surfaced via errorCode.

MostlyrightError.defaultErrorCode

readonly errorCode: string

MostlyrightError.errorCode

readonly requestId: null | string

MostlyrightError.requestId

readonly source: null | string

MostlyrightError.source

toDict(): Record<string, unknown>

Return a JSON-safe dict suitable for MCP error.data.

Record<string, unknown>

MostlyrightError.toDict


A non-2xx (or otherwise failed) response from the hosted API — carries the HTTP status and the server message so the caller can branch (401 → bad key, 429 → global ceiling hit, 5xx → serving down).

Distinct from HostedConfigError, which fires before the request: this is a transport failure after the request was issued. Mirrors the Python hosted client’s “typed error with status + message” contract.

new HostedResponseError(message, options): HostedResponseError

string

MostlyrightErrorOptions & object = {}

HostedResponseError

MostlyrightError.constructor

static defaultErrorCode: string = "HOSTED_RESPONSE"

Subclass override — the stable string enum surfaced via errorCode.

MostlyrightError.defaultErrorCode

readonly errorCode: string

MostlyrightError.errorCode

readonly requestId: null | string

MostlyrightError.requestId

readonly source: null | string

MostlyrightError.source

readonly status: null | number

The HTTP status code (e.g. 401, 429, 500), or null for a network error.

toDict(): Record<string, unknown>

Return a JSON-safe dict suitable for MCP error.data.

Record<string, unknown>

MostlyrightError.toDict

readonly apiKey: string

The MOSTLYRIGHT_API_KEY sent as the x-api-key header on every request. In the MV3 extension this is read from chrome.storage at call time (onboarding UX) — see docs/internal/hosted-api.md. Required: a missing key throws HostedConfigError before any network call.

readonly optional fetchImpl: FetchLike

Injectable fetch (default: the browser/MV3 global fetch). Tests pass a mock; production leaves it undefined and uses the platform fetch.

readonly optional signal: AbortSignal

Optional AbortSignal for cancellation (propagated to the underlying fetch). A caller-fired abort propagates as the abort rejection, not a HostedResponseError — callers distinguish cancellation from a server 4xx.


The minimal Response surface the shim reads. Matches the browser/MV3 Response (status + ok + .json()).

readonly ok: boolean

readonly status: number

json(): Promise<unknown>

Promise<unknown>

text(): Promise<string>

Promise<string>

FetchLike: (input, init?) => Promise<HostedResponseLike>

The minimal fetch surface the shim needs — declared structurally so tests can inject a mock without a global fetch (and so we never reach for a Node HTTP client). Matches the browser/MV3 fetch.

string

Record<string, string>

string

AbortSignal

Promise<HostedResponseLike>

const HOSTED_API_KEY_HEADER: "x-api-key"

The auth header the hosted serving middleware reads. Matches the server contract (curl -H "x-api-key: $MOSTLYRIGHT_API_KEY" ...).

hostedFetchJson(url, options): Promise<unknown>

Issue a GET against the hosted API, adding the MOSTLYRIGHT_API_KEY header, and parse the JSON body.

MV3-safe: uses only the browser/MV3 fetch + JSON — no node:*, no http/https, no Buffer. The API key is sent as x-api-key on every request; it is a public secret, and abuse is bounded server-side by the global request ceiling, not by this shim.

string

HostedFetchOptions

Promise<unknown>

when apiKey is empty/missing, or when no fetch is available and none was injected — raised before any request.

when the response is non-2xx, or the body is not valid JSON — carries the HTTP status + server message. A caller-fired AbortSignal rejection is re-thrown as-is (not wrapped), so cancellation is distinguishable from a server error.


joinHostedUrl(baseUrl, path): string

Join a base URL and a path, tolerating a trailing slash on the base and a leading slash on the path (so MOSTLYRIGHT_WEATHER_HOSTED_URL="https://x/" + /satellite yields https://x/satellite, never a double slash). Query strings pass through unchanged on the path.

string

string

string


requireHostedUrl(value, seamName): string

Require a configured hosted base URL seam — a small helper the per-endpoint shims (satellite, hostedStream) share so the “missing MOSTLYRIGHT_WEATHER_HOSTED_URL / MOSTLYRIGHT_FINANCE_HOSTED_URL” error is uniform and typed (HostedConfigError).

undefined | null | string

string

string

when value is empty/missing. seamName names the env seam in the message (e.g. "MOSTLYRIGHT_WEATHER_HOSTED_URL").