mcpapp

package
v0.0.0-...-0488d2e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package mcpapp serves Tempest weather data over MCP stdio. The server opens the archive read-only unless archive writes are configured. Stdout contains MCP messages only. Logs use stderr.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(ctx context.Context, opts Options) (err error)

Run serves MCP until the context is canceled or the transport fails.

Types

type ArchiveStatusOut

type ArchiveStatusOut struct {
	Observations      int64       `json:"observations"`
	FirstObs          string      `json:"first_obs,omitempty"`
	LastObs           string      `json:"last_obs,omitempty"`
	SpanDays          float64     `json:"span_days"`
	LastObsAgeSeconds int64       `json:"last_obs_age_seconds"`
	Fresh             bool        `json:"fresh"` // last observation within the gap threshold of now
	BackfillComplete  bool        `json:"backfill_complete"`
	Gaps              []store.Gap `json:"gaps"`
	Note              string      `json:"note,omitempty"`
}

ArchiveStatusOut is the archive_status output: coverage, freshness, and the largest gaps, so an agent can see what it has and target what it's missing.

type BackfillArgs

type BackfillArgs struct {
	Start   string `json:"start,omitempty" jsonschema:"oldest date to fetch back to, YYYY-MM-DD local; the walk stops here"`
	End     string `` /* 135-byte string literal not displayed */
	MaxDays int    `` /* 144-byte string literal not displayed */
}

BackfillArgs is the backfill_archive input. With no arguments it walks history backward from where it left off, one bounded batch per call; start/end aim it at a specific older window.

type BackfillOut

type BackfillOut struct {
	RowsAdded    int    `json:"rows_added"`
	Fetched      int    `json:"fetched"`
	Chunks       int    `json:"chunks"`
	ReachedBack  string `json:"reached_back,omitempty"` // oldest date this call fetched to
	HasMore      bool   `json:"has_more"`
	NextBefore   int64  `json:"next_before,omitempty"` // Resume cursor in epoch seconds when has_more is true.
	Observations int64  `json:"observations"`          // total rows stored after this call
	Coverage     string `json:"coverage,omitempty"`    // first -> last stored
	Note         string `json:"note,omitempty"`
}

BackfillOut is the backfill_archive output. Call again while has_more is true (no arguments needed; it resumes) until the whole history is stored.

type ClimateIndicesArgs

type ClimateIndicesArgs struct {
	Start             string  `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End               string  `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
	FrostMaxF         float64 `json:"frost_max_f,omitempty" jsonschema:"frost day when the daily low is below this °F (default 32)"`
	IceMaxF           float64 `json:"ice_max_f,omitempty" jsonschema:"ice day when the daily high stays below this °F (default 32)"`
	SummerMinF        float64 `json:"summer_min_f,omitempty" jsonschema:"summer day when the daily high reaches this °F (default 77)"`
	HotMinF           float64 `json:"hot_min_f,omitempty" jsonschema:"hot day when the daily high reaches this °F (default 90)"`
	TropicalNightMinF float64 `json:"tropical_night_min_f,omitempty" jsonschema:"tropical night when the daily low stays at or above this °F (default 68)"`
	Yearly            bool    `json:"yearly,omitempty" jsonschema:"include the per-year breakdown (default false: range totals only)"`
}

ClimateIndicesArgs is the climate_indices input. Thresholds are in °F; zero means "use the standard default".

type ClimateIndicesOut

type ClimateIndicesOut struct {
	From              string                   `json:"from,omitempty"`
	To                string                   `json:"to"`
	FrostMaxF         float64                  `json:"frost_max_f"`
	IceMaxF           float64                  `json:"ice_max_f"`
	SummerMinF        float64                  `json:"summer_min_f"`
	HotMinF           float64                  `json:"hot_min_f"`
	TropicalNightMinF float64                  `json:"tropical_night_min_f"`
	Total             store.ClimateIndexStat   `json:"total"`
	Years             []store.ClimateIndexStat `json:"years,omitempty"`
	Note              string                   `json:"note,omitempty"`
}

ClimateIndicesOut is the climate_indices output: threshold-day counts plus the thresholds used and, when requested, a per-year breakdown.

type ClimateNormalsOut

type ClimateNormalsOut struct {
	Months []store.MonthNormal `json:"months"`
	Note   string              `json:"note,omitempty"`
}

ClimateNormalsOut is the climate_normals output: the 12-month normal table.

type ClimatologyArgs

type ClimatologyArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

ClimatologyArgs is the climatology input.

type ClimatologyOut

type ClimatologyOut struct {
	From  string           `json:"from,omitempty"`
	To    string           `json:"to"`
	Hours []store.HourStat `json:"hours"`
	Note  string           `json:"note,omitempty"`
}

ClimatologyOut is the climatology output: the average day, hour by hour.

type ComfortArgs

type ComfortArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

ComfortArgs is the comfort_stats input.

type ComfortOut

type ComfortOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.ComfortStats
	Note string `json:"note,omitempty"`
}

ComfortOut is the comfort_stats output.

type ConditionsOut

type ConditionsOut struct {
	Source              string   `json:"source"` // "live" or "archive"
	Time                string   `json:"time"`
	AgeSeconds          int64    `json:"age_seconds"`
	Station             string   `json:"station,omitempty"`
	TempF               *float64 `json:"temp_f,omitempty"`
	TempC               *float64 `json:"temp_c,omitempty"`
	FeelsLikeF          *float64 `json:"feels_like_f,omitempty"`
	DewPointF           *float64 `json:"dew_point_f,omitempty"`
	HumidityPct         *float64 `json:"humidity_pct,omitempty"`
	PressureInHg        *float64 `json:"pressure_inhg,omitempty"`
	WindMph             *float64 `json:"wind_mph,omitempty"`
	GustMph             *float64 `json:"gust_mph,omitempty"`
	WindDir             string   `json:"wind_dir,omitempty"`
	UV                  *float64 `json:"uv,omitempty"`
	SolarWm2            *float64 `json:"solar_wm2,omitempty"`
	RainTodayIn         *float64 `json:"rain_today_in,omitempty"`
	LightningStrikes1hr *int     `json:"lightning_strikes_1hr,omitempty"`
	LightningLastMi     *float64 `json:"lightning_last_distance_mi,omitempty"`
	PressureTrend       string   `json:"pressure_trend,omitempty"` // rising/falling/steady over the last 3h (archive-derived)
	PressureTrend3hInHg *float64 `json:"pressure_trend_3h_inhg,omitempty"`
	Note                string   `json:"note,omitempty"`
}

ConditionsOut is the shape returned by current_conditions.

type DailyOut

type DailyOut struct {
	Date              string   `json:"date"`
	Conditions        string   `json:"conditions,omitempty"`
	Icon              string   `json:"icon,omitempty"`
	HighF             *float64 `json:"high_f,omitempty"`
	LowF              *float64 `json:"low_f,omitempty"`
	PrecipProbability *int     `json:"precip_probability,omitempty"`
	Sunrise           string   `json:"sunrise,omitempty"`
	Sunset            string   `json:"sunset,omitempty"`
}

DailyOut is one day of forecast in display units.

type DailySummaryArgs

type DailySummaryArgs struct {
	Days  int    `json:"days,omitempty" jsonschema:"most-recent days to include (default 7, max 366); ignored when start is set"`
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; overrides days"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

DailySummaryArgs is the daily_summary input.

type DailySummaryOut

type DailySummaryOut struct {
	From string          `json:"from"`
	To   string          `json:"to"`
	Days []store.DayStat `json:"days"`
}

DailySummaryOut is the daily_summary output.

type DegreeDaysArgs

type DegreeDaysArgs struct {
	Start        string  `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End          string  `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
	HeatingBaseF float64 `json:"heating_base_f,omitempty" jsonschema:"heating degree-day base in °F (default 65)"`
	CoolingBaseF float64 `json:"cooling_base_f,omitempty" jsonschema:"cooling degree-day base in °F (default 65)"`
	GrowingBaseF float64 `json:"growing_base_f,omitempty" jsonschema:"growing degree-day base in °F (default 50)"`
	GrowingCapF  float64 `` /* 134-byte string literal not displayed */
	Monthly      bool    `json:"monthly,omitempty" jsonschema:"include the per-month breakdown (default false: range totals only)"`
}

DegreeDaysArgs is the degree_days input. Bases are in °F; zero means "use the convention default", so an agent can call it with no arguments.

type DegreeDaysOut

type DegreeDaysOut struct {
	From         string                `json:"from,omitempty"`
	To           string                `json:"to"`
	HeatingBaseF float64               `json:"heating_base_f"`
	CoolingBaseF float64               `json:"cooling_base_f"`
	GrowingBaseF float64               `json:"growing_base_f"`
	GrowingCapF  float64               `json:"growing_cap_f"`
	Total        store.DegreeDayStat   `json:"total"`
	Months       []store.DegreeDayStat `json:"months,omitempty"`
	Note         string                `json:"note,omitempty"`
}

DegreeDaysOut is the degree_days output: the range total plus the bases used and, when requested, a per-month breakdown.

type DeviceOut

type DeviceOut struct {
	DeviceID int    `json:"device_id"`
	Type     string `json:"type"`
	Serial   string `json:"serial,omitempty"`
}

DeviceOut is one device in station_details output.

type ForecastArgs

type ForecastArgs struct {
	StationID int `json:"station_id,omitempty" jsonschema:"station id; defaults to your resolved Tempest station"`
	Hours     int `json:"hours,omitempty" jsonschema:"hourly entries to return (default 24, max 240)"`
	Days      int `json:"days,omitempty" jsonschema:"daily entries to return (default 10, max 10)"`
}

ForecastArgs is the forecast tool input.

type ForecastNow

type ForecastNow struct {
	Time        string   `json:"time"`
	Conditions  string   `json:"conditions,omitempty"`
	Icon        string   `json:"icon,omitempty"`
	TempF       *float64 `json:"temp_f,omitempty"`
	FeelsLikeF  *float64 `json:"feels_like_f,omitempty"`
	HumidityPct *float64 `json:"humidity_pct,omitempty"`
}

ForecastNow is the current-conditions summary within a forecast reply.

type ForecastOut

type ForecastOut struct {
	Station string       `json:"station,omitempty"`
	Current *ForecastNow `json:"current,omitempty"`
	Daily   []DailyOut   `json:"daily"`
	Hourly  []HourlyOut  `json:"hourly"`
}

ForecastOut is the forecast tool output.

type GetObservationsArgs

type GetObservationsArgs struct {
	Start         string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to 24 hours ago"`
	End           string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to now"`
	BucketMinutes int    `` /* 152-byte string literal not displayed */
	MaxPoints     int    `json:"max_points,omitempty" jsonschema:"cap on returned points when bucket_minutes is unset (default 288, max 2000)"`
}

GetObservationsArgs is the get_observations input.

type GetObservationsOut

type GetObservationsOut struct {
	From          string              `json:"from"`
	To            string              `json:"to"`
	BucketMinutes int                 `json:"bucket_minutes"`
	Points        []store.SeriesPoint `json:"points"`
	Note          string              `json:"note,omitempty"`
}

GetObservationsOut is the get_observations output: a downsampled time series.

type HourlyOut

type HourlyOut struct {
	Time              string   `json:"time"`
	Conditions        string   `json:"conditions,omitempty"`
	Icon              string   `json:"icon,omitempty"`
	TempF             *float64 `json:"temp_f,omitempty"`
	FeelsLikeF        *float64 `json:"feels_like_f,omitempty"`
	PrecipProbability *int     `json:"precip_probability,omitempty"`
	WindMph           *float64 `json:"wind_mph,omitempty"`
	GustMph           *float64 `json:"gust_mph,omitempty"`
	WindDir           string   `json:"wind_dir,omitempty"`
}

HourlyOut is one hour of forecast in display units.

type LightningArgs

type LightningArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

LightningArgs is the lightning_activity input.

type LightningOut

type LightningOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.LightningStats
	Note string `json:"note,omitempty"`
}

LightningOut is the lightning_activity output.

type NoArgs

type NoArgs struct{}

NoArgs is the input type for tools that take no arguments.

type Options

type Options struct {
	Token    string
	DBPath   string
	ReadOnly bool
}

Options contains resolved MCP inputs. Run borrows these values for the call.

type PeriodSummaryArgs

type PeriodSummaryArgs struct {
	Period string `json:"period,omitempty" jsonschema:"bucket size: 'month' (default) or 'year'"`
	Start  string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End    string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

PeriodSummaryArgs is the period_summary input.

type PeriodSummaryOut

type PeriodSummaryOut struct {
	Period  string             `json:"period"` // "month" or "year"
	From    string             `json:"from,omitempty"`
	To      string             `json:"to,omitempty"`
	Periods []store.PeriodStat `json:"periods"`
	Note    string             `json:"note,omitempty"`
}

PeriodSummaryOut is the period_summary output.

type PressureStatsArgs

type PressureStatsArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

PressureStatsArgs is the pressure_stats input.

type PressureStatsOut

type PressureStatsOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.PressureStats
	Note string `json:"note,omitempty"`
}

PressureStatsOut is the pressure_stats output.

type PressureTrendArgs

type PressureTrendArgs struct {
	WindowHours float64 `json:"window_hours,omitempty" jsonschema:"trailing window for the tendency in hours (default 3, the meteorological standard)"`
}

PressureTrendArgs is the pressure_trend input.

type PressureTrendOut

type PressureTrendOut struct {
	store.PressureTrend
	Note string `json:"note,omitempty"`
}

PressureTrendOut is the pressure_trend output.

type QuerySQLArgs

type QuerySQLArgs struct {
	SQL     string `` /* 135-byte string literal not displayed */
	MaxRows int    `json:"max_rows,omitempty" jsonschema:"row cap (default 100, max 1000)"`
}

QuerySQLArgs is the query_sql input.

type QuerySQLOut

type QuerySQLOut struct {
	store.QueryResult
	Note string `json:"note,omitempty"`
}

QuerySQLOut is the query_sql output.

type RainStatsArgs

type RainStatsArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

RainStatsArgs is the rain_stats input.

type RainStatsOut

type RainStatsOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.RainStats
	Note string `json:"note,omitempty"`
}

RainStatsOut is the rain_stats output.

type RecordsOut

type RecordsOut struct {
	store.Records
	HottestTime        string `json:"hottest_time,omitempty"`
	ColdestTime        string `json:"coldest_time,omitempty"`
	PeakGustTime       string `json:"peak_gust_time,omitempty"`
	LowestPressureTime string `json:"lowest_pressure_time,omitempty"`
	PeakSolarTime      string `json:"peak_solar_time,omitempty"`
	PeakUVTime         string `json:"peak_uv_time,omitempty"`
}

RecordsOut wraps store.Records with human-readable local timestamps, so an agent never has to convert raw epochs itself.

type SensorHealthArgs

type SensorHealthArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

SensorHealthArgs is the sensor_health input.

type SensorHealthOut

type SensorHealthOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.SensorHealth
	Note string `json:"note,omitempty"`
}

SensorHealthOut is the sensor_health output.

type SolarArgs

type SolarArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

SolarArgs is the solar_stats input.

type SolarOut

type SolarOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.SolarStats
	Note string `json:"note,omitempty"`
}

SolarOut is the solar_stats output.

type StationDetailsArgs

type StationDetailsArgs struct {
	StationID int `json:"station_id,omitempty" jsonschema:"station id; defaults to your resolved Tempest station"`
}

StationDetailsArgs is the station_details tool input.

type StationDetailsOut

type StationDetailsOut struct {
	StationID  int         `json:"station_id"`
	Name       string      `json:"name"`
	Latitude   float64     `json:"latitude"`
	Longitude  float64     `json:"longitude"`
	ElevationM float64     `json:"elevation_m"`
	Timezone   string      `json:"timezone"`
	Devices    []DeviceOut `json:"devices"`
}

StationDetailsOut is the station_details tool output.

type StationInfoOut

type StationInfoOut struct {
	Name         string   `json:"name,omitempty"`
	StationID    int      `json:"station_id,omitempty"`
	Latitude     *float64 `json:"latitude,omitempty"`
	Longitude    *float64 `json:"longitude,omitempty"`
	Timezone     string   `json:"timezone,omitempty"`
	ElevationM   *float64 `json:"elevation_m,omitempty"`
	Observations int64    `json:"observations"`
	FirstObs     string   `json:"first_obs,omitempty"`
	LastObs      string   `json:"last_obs,omitempty"`
}

StationInfoOut is the station_info output.

type StationSummary

type StationSummary struct {
	StationID int          `json:"station_id"`
	Name      string       `json:"name"`
	Latitude  float64      `json:"latitude"`
	Longitude float64      `json:"longitude"`
	Timezone  string       `json:"timezone"`
	Devices   []api.Device `json:"devices"`
}

StationSummary is one station in list_stations output.

type StationsOut

type StationsOut struct {
	Stations []StationSummary `json:"stations"`
}

StationsOut is the list_stations output.

type SyncOut

type SyncOut struct {
	RowsAdded int    `json:"rows_added"`
	Fetched   int    `json:"fetched"`
	HasMore   bool   `json:"has_more"`
	LastObs   string `json:"last_obs,omitempty"`
	Note      string `json:"note,omitempty"`
}

SyncOut is the sync_archive output. Call again while has_more is true; a very stale archive catches up over several bounded calls.

type TemperatureSpellsArgs

type TemperatureSpellsArgs struct {
	Start    string  `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End      string  `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
	HeatMinF float64 `json:"heat_min_f,omitempty" jsonschema:"heat-wave day when the daily high reaches this °F (default 90)"`
	ColdMaxF float64 `json:"cold_max_f,omitempty" jsonschema:"cold-snap day when the daily low reaches this °F (default 32)"`
}

TemperatureSpellsArgs is the temperature_spells input. Thresholds are in °F; zero means "use the standard default".

type TemperatureSpellsOut

type TemperatureSpellsOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.TempSpells
	Note string `json:"note,omitempty"`
}

TemperatureSpellsOut is the temperature_spells output.

type TemperatureTrendOut

type TemperatureTrendOut struct {
	store.TempTrend
	Note string `json:"note,omitempty"`
}

TemperatureTrendOut is the temperature_trend output.

type ThisDayArgs

type ThisDayArgs struct {
	Date string `json:"date,omitempty" jsonschema:"calendar day as MM-DD or YYYY-MM-DD (the year is ignored); defaults to today"`
}

ThisDayArgs is the this_day_in_history input.

type ThisDayOut

type ThisDayOut struct {
	MonthDay       string          `json:"month_day"` // MM-DD
	Years          []store.YearDay `json:"years"`
	RecordHighF    *float64        `json:"record_high_f,omitempty"`
	RecordHighYear int             `json:"record_high_year,omitempty"`
	RecordLowF     *float64        `json:"record_low_f,omitempty"`
	RecordLowYear  int             `json:"record_low_year,omitempty"`
	WettestYear    int             `json:"wettest_year,omitempty"`
	WettestRainIn  *float64        `json:"wettest_rain_in,omitempty"`
	Note           string          `json:"note,omitempty"`
}

ThisDayOut is the this_day_in_history output: that calendar day in every year the archive covers, plus the records across those years.

type WindRoseArgs

type WindRoseArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

WindRoseArgs is the wind_rose input.

type WindRoseOut

type WindRoseOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to,omitempty"`
	store.WindRose
}

WindRoseOut is the wind_rose output.

type WindStatsArgs

type WindStatsArgs struct {
	Start string `json:"start,omitempty" jsonschema:"start date YYYY-MM-DD in local time; defaults to the whole archive"`
	End   string `json:"end,omitempty" jsonschema:"end date YYYY-MM-DD in local time, inclusive; defaults to today"`
}

WindStatsArgs is the wind_stats input.

type WindStatsOut

type WindStatsOut struct {
	From string `json:"from,omitempty"`
	To   string `json:"to"`
	store.WindStats
	Note string `json:"note,omitempty"`
}

WindStatsOut is the wind_stats output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL