@ryancardin/noaa-tides-currents-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.claude/settings.local.json +29 -0
  2. package/CLAUDE.md +71 -0
  3. package/Dockerfile +14 -0
  4. package/LICENSE +21 -0
  5. package/README.md +234 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +9 -0
  8. package/dist/interfaces/config.d.ts +6 -0
  9. package/dist/interfaces/config.js +1 -0
  10. package/dist/interfaces/moon.d.ts +65 -0
  11. package/dist/interfaces/moon.js +35 -0
  12. package/dist/interfaces/noaa.d.ts +334 -0
  13. package/dist/interfaces/noaa.js +98 -0
  14. package/dist/interfaces/parameters.d.ts +18 -0
  15. package/dist/interfaces/parameters.js +5 -0
  16. package/dist/interfaces/sun.d.ts +103 -0
  17. package/dist/interfaces/sun.js +45 -0
  18. package/dist/mcp-server.d.ts +12 -0
  19. package/dist/mcp-server.js +103 -0
  20. package/dist/moon-phase-service.d.ts +122 -0
  21. package/dist/moon-phase-service.js +187 -0
  22. package/dist/noaa-service.d.ts +60 -0
  23. package/dist/noaa-service.js +159 -0
  24. package/dist/schemas/common.d.ts +14 -0
  25. package/dist/schemas/common.js +18 -0
  26. package/dist/schemas/dpapi.d.ts +198 -0
  27. package/dist/schemas/dpapi.js +89 -0
  28. package/dist/server/config.d.ts +9 -0
  29. package/dist/server/config.js +40 -0
  30. package/dist/server/mcp-server.d.ts +12 -0
  31. package/dist/server/mcp-server.js +103 -0
  32. package/dist/services/dpapi-service.d.ts +72 -0
  33. package/dist/services/dpapi-service.js +164 -0
  34. package/dist/services/moon-phase-service.d.ts +34 -0
  35. package/dist/services/moon-phase-service.js +147 -0
  36. package/dist/services/noaa-parameters-service.d.ts +76 -0
  37. package/dist/services/noaa-parameters-service.js +128 -0
  38. package/dist/services/noaa-service.d.ts +52 -0
  39. package/dist/services/noaa-service.js +151 -0
  40. package/dist/services/sun-service.d.ts +60 -0
  41. package/dist/services/sun-service.js +234 -0
  42. package/dist/sun-service.d.ts +184 -0
  43. package/dist/sun-service.js +218 -0
  44. package/dist/tools/derived-product-tools.d.ts +6 -0
  45. package/dist/tools/derived-product-tools.js +168 -0
  46. package/dist/tools/index.d.ts +16 -0
  47. package/dist/tools/index.js +36 -0
  48. package/dist/tools/moon-tools.d.ts +6 -0
  49. package/dist/tools/moon-tools.js +69 -0
  50. package/dist/tools/parameter-tools.d.ts +6 -0
  51. package/dist/tools/parameter-tools.js +77 -0
  52. package/dist/tools/station-tools.d.ts +6 -0
  53. package/dist/tools/station-tools.js +51 -0
  54. package/dist/tools/sun-tools.d.ts +6 -0
  55. package/dist/tools/sun-tools.js +109 -0
  56. package/dist/tools/water-tools.d.ts +6 -0
  57. package/dist/tools/water-tools.js +150 -0
  58. package/dist/types/moon.d.ts +26 -0
  59. package/dist/types/moon.js +14 -0
  60. package/dist/types/sun.d.ts +49 -0
  61. package/dist/types/sun.js +19 -0
  62. package/dist/types.d.ts +337 -0
  63. package/dist/types.js +98 -0
  64. package/package.json +56 -0
  65. package/smithery.yaml +16 -0
  66. package/src/index.ts +13 -0
  67. package/src/interfaces/moon.ts +44 -0
  68. package/src/interfaces/noaa.ts +130 -0
  69. package/src/interfaces/parameters.ts +20 -0
  70. package/src/interfaces/sun.ts +57 -0
  71. package/src/schemas/common.ts +23 -0
  72. package/src/schemas/dpapi.ts +99 -0
  73. package/src/server/config.ts +43 -0
  74. package/src/server/mcp-server.ts +135 -0
  75. package/src/services/dpapi-service.ts +187 -0
  76. package/src/services/moon-phase-service.ts +167 -0
  77. package/src/services/noaa-parameters-service.ts +139 -0
  78. package/src/services/noaa-service.ts +171 -0
  79. package/src/services/sun-service.ts +275 -0
  80. package/src/tools/derived-product-tools.ts +180 -0
  81. package/src/tools/index.ts +40 -0
  82. package/src/tools/moon-tools.ts +79 -0
  83. package/src/tools/parameter-tools.ts +82 -0
  84. package/src/tools/station-tools.ts +57 -0
  85. package/src/tools/sun-tools.ts +120 -0
  86. package/src/tools/water-tools.ts +166 -0
  87. package/src/types/moon.ts +27 -0
  88. package/src/types/sun.ts +51 -0
  89. package/src/types/suncalc.d.ts +110 -0
  90. package/test-dpapi.js +0 -0
  91. package/tsconfig.json +15 -0
@@ -0,0 +1,164 @@
1
+ import axios from 'axios';
2
+ // Base URL for the NOAA Derived Product API
3
+ const DPAPI_BASE_URL = 'https://api.tidesandcurrents.noaa.gov/dpapi/prod';
4
+ /**
5
+ * Service for interacting with NOAA Derived Product API (DPAPI)
6
+ */
7
+ export class DpapiService {
8
+ /**
9
+ * Build parameters for the API request
10
+ * @param params Parameters for the request
11
+ * @returns URL-encoded parameters string
12
+ */
13
+ buildParams(params) {
14
+ // Remove undefined and null values
15
+ const filteredParams = Object.entries(params)
16
+ .filter(([_, value]) => value !== undefined && value !== null)
17
+ .reduce((acc, [key, value]) => {
18
+ acc[key] = value;
19
+ return acc;
20
+ }, {});
21
+ // Convert to URL parameters
22
+ return new URLSearchParams(filteredParams).toString();
23
+ }
24
+ /**
25
+ * Make a request to the DPAPI
26
+ * @param endpoint Endpoint path
27
+ * @param params Parameters for the request
28
+ * @returns Response data
29
+ */
30
+ async fetchDpapi(endpoint, params = {}) {
31
+ try {
32
+ const queryParams = this.buildParams(params);
33
+ const url = `${DPAPI_BASE_URL}${endpoint}${queryParams ? '?' + queryParams : ''}`;
34
+ const response = await axios.get(url);
35
+ return response.data;
36
+ }
37
+ catch (error) {
38
+ if (axios.isAxiosError(error) && error.response) {
39
+ throw new Error(`NOAA DPAPI Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
40
+ }
41
+ throw error;
42
+ }
43
+ }
44
+ /**
45
+ * Get sea level trends for a station
46
+ * @param params Parameters including station ID and affiliation
47
+ * @returns Sea level trend data
48
+ */
49
+ async getSeaLevelTrends(params) {
50
+ const { station, affil = 'Global', format = 'json', ...rest } = params;
51
+ return this.fetchDpapi('/sltrends', {
52
+ station,
53
+ affil,
54
+ format,
55
+ ...rest
56
+ });
57
+ }
58
+ /**
59
+ * Get extreme water levels for a station
60
+ * @param params Parameters including station ID and units
61
+ * @returns Extreme water level data
62
+ */
63
+ async getExtremeWaterLevels(params) {
64
+ const { station, units = 'english', format = 'json', ...rest } = params;
65
+ return this.fetchDpapi('/ewl', {
66
+ station,
67
+ units,
68
+ format,
69
+ ...rest
70
+ });
71
+ }
72
+ /**
73
+ * Get high tide flooding daily count data
74
+ * @param params Parameters including station ID, date range, and thresholds
75
+ * @returns Daily flood count data
76
+ */
77
+ async getHighTideFloodingDaily(params) {
78
+ const { station, format = 'json', ...rest } = params;
79
+ return this.fetchDpapi('/htf/daily', {
80
+ station,
81
+ format,
82
+ ...rest
83
+ });
84
+ }
85
+ /**
86
+ * Get high tide flooding monthly count data
87
+ * @param params Parameters including station ID, date range, and thresholds
88
+ * @returns Monthly flood count data
89
+ */
90
+ async getHighTideFloodingMonthly(params) {
91
+ const { station, format = 'json', ...rest } = params;
92
+ return this.fetchDpapi('/htf/monthly', {
93
+ station,
94
+ format,
95
+ ...rest
96
+ });
97
+ }
98
+ /**
99
+ * Get high tide flooding seasonal count data
100
+ * @param params Parameters including station ID, seasons, and thresholds
101
+ * @returns Seasonal flood count data
102
+ */
103
+ async getHighTideFloodingSeasonal(params) {
104
+ const { station, format = 'json', ...rest } = params;
105
+ return this.fetchDpapi('/htf/seasonal', {
106
+ station,
107
+ format,
108
+ ...rest
109
+ });
110
+ }
111
+ /**
112
+ * Get high tide flooding annual count data
113
+ * @param params Parameters including station ID, year range, and thresholds
114
+ * @returns Annual flood count data
115
+ */
116
+ async getHighTideFloodingAnnual(params) {
117
+ const { station, format = 'json', ...rest } = params;
118
+ return this.fetchDpapi('/htf/annual', {
119
+ station,
120
+ format,
121
+ ...rest
122
+ });
123
+ }
124
+ /**
125
+ * Get high tide flooding decadal projections
126
+ * @param params Parameters including station ID, scenario, and decade
127
+ * @returns Decadal projection data
128
+ */
129
+ async getHighTideFloodingProjections(params) {
130
+ const { station, scenario = 'all', format = 'json', ...rest } = params;
131
+ return this.fetchDpapi('/htf/projections', {
132
+ station,
133
+ scenario,
134
+ format,
135
+ ...rest
136
+ });
137
+ }
138
+ /**
139
+ * Get high tide flooding daily likelihoods
140
+ * @param params Parameters including station ID and date
141
+ * @returns Daily likelihood data
142
+ */
143
+ async getHighTideFloodingLikelihoods(params) {
144
+ const { station, format = 'json', ...rest } = params;
145
+ return this.fetchDpapi('/htf/likelihoods', {
146
+ station,
147
+ format,
148
+ ...rest
149
+ });
150
+ }
151
+ /**
152
+ * Get top ten water levels for a station
153
+ * @param params Parameters including station ID and analysis type
154
+ * @returns Top ten water level data
155
+ */
156
+ async getTopTenWaterLevels(params) {
157
+ const { station, format = 'json', ...rest } = params;
158
+ return this.fetchDpapi('/topten', {
159
+ station,
160
+ format,
161
+ ...rest
162
+ });
163
+ }
164
+ }
@@ -0,0 +1,34 @@
1
+ import { MoonPhaseParams, MoonPhasesRangeParams, NextMoonPhaseParams } from '../interfaces/moon.js';
2
+ import { MoonPhaseInfo } from '../types/moon.js';
3
+ /**
4
+ * Service for moon phase calculations
5
+ */
6
+ export declare class MoonPhaseService {
7
+ /**
8
+ * Get the moon phase for a specific date
9
+ * @param params Parameters for the request
10
+ * @returns Moon phase information
11
+ */
12
+ getMoonPhase(params: MoonPhaseParams): MoonPhaseInfo;
13
+ /**
14
+ * Get moon phases for a date range
15
+ * @param params Parameters for the request
16
+ * @returns Array of moon phase information
17
+ */
18
+ getMoonPhasesRange(params: MoonPhasesRangeParams): MoonPhaseInfo[];
19
+ /**
20
+ * Get the next occurrence(s) of a specific moon phase
21
+ * @param params Parameters for the request
22
+ * @returns Array of dates for the next occurrences of the specified phase
23
+ */
24
+ getNextMoonPhase(params: NextMoonPhaseParams): {
25
+ date: string;
26
+ phase: string;
27
+ }[];
28
+ /**
29
+ * Get the moon phase name based on the phase value (0-1)
30
+ * @param phase Phase value (0-1)
31
+ * @returns Moon phase name
32
+ */
33
+ private getMoonPhaseName;
34
+ }
@@ -0,0 +1,147 @@
1
+ import SunCalc from 'suncalc';
2
+ import { MoonPhaseName } from '../types/moon.js';
3
+ /**
4
+ * Service for moon phase calculations
5
+ */
6
+ export class MoonPhaseService {
7
+ /**
8
+ * Get the moon phase for a specific date
9
+ * @param params Parameters for the request
10
+ * @returns Moon phase information
11
+ */
12
+ getMoonPhase(params) {
13
+ const date = params.date ? new Date(params.date) : new Date();
14
+ // Get moon illumination data
15
+ const illuminationData = SunCalc.getMoonIllumination(date);
16
+ // Get moon position data (requires location)
17
+ const latitude = params.latitude ?? 0;
18
+ const longitude = params.longitude ?? 0;
19
+ const positionData = SunCalc.getMoonPosition(date, latitude, longitude);
20
+ // Calculate moon phase name
21
+ const phaseName = this.getMoonPhaseName(illuminationData.phase);
22
+ // Calculate if the moon is waxing (increasing illumination)
23
+ const isWaxing = illuminationData.phase < 0.5;
24
+ // Calculate approximate moon age (0-29.53 days)
25
+ const lunarMonth = 29.53; // days
26
+ const age = illuminationData.phase * lunarMonth;
27
+ // Calculate apparent diameter (in degrees)
28
+ const diameter = 0.5181 * (384400 / positionData.distance);
29
+ return {
30
+ date: date.toISOString().split('T')[0],
31
+ phase: illuminationData.phase,
32
+ phaseName,
33
+ illumination: illuminationData.fraction,
34
+ age,
35
+ distance: positionData.distance,
36
+ diameter,
37
+ isWaxing
38
+ };
39
+ }
40
+ /**
41
+ * Get moon phases for a date range
42
+ * @param params Parameters for the request
43
+ * @returns Array of moon phase information
44
+ */
45
+ getMoonPhasesRange(params) {
46
+ const startDate = new Date(params.start_date);
47
+ const endDate = new Date(params.end_date);
48
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
49
+ throw new Error('Invalid date format. Please use YYYY-MM-DD format.');
50
+ }
51
+ if (startDate > endDate) {
52
+ throw new Error('Start date must be before end date.');
53
+ }
54
+ const result = [];
55
+ const currentDate = new Date(startDate);
56
+ while (currentDate <= endDate) {
57
+ result.push(this.getMoonPhase({
58
+ date: currentDate.toISOString().split('T')[0],
59
+ latitude: params.latitude,
60
+ longitude: params.longitude
61
+ }));
62
+ // Move to next day
63
+ currentDate.setDate(currentDate.getDate() + 1);
64
+ }
65
+ return result;
66
+ }
67
+ /**
68
+ * Get the next occurrence(s) of a specific moon phase
69
+ * @param params Parameters for the request
70
+ * @returns Array of dates for the next occurrences of the specified phase
71
+ */
72
+ getNextMoonPhase(params) {
73
+ const startDate = params.date ? new Date(params.date) : new Date();
74
+ const count = params.count || 1;
75
+ const targetPhase = params.phase;
76
+ // Map phase names to their approximate values
77
+ const phaseValues = {
78
+ [MoonPhaseName.NEW_MOON]: 0,
79
+ [MoonPhaseName.FIRST_QUARTER]: 0.25,
80
+ [MoonPhaseName.FULL_MOON]: 0.5,
81
+ [MoonPhaseName.LAST_QUARTER]: 0.75
82
+ };
83
+ const targetPhaseValue = phaseValues[targetPhase];
84
+ const results = [];
85
+ let currentDate = new Date(startDate);
86
+ // Find the next occurrences
87
+ while (results.length < count) {
88
+ // Check every day (could be optimized with better algorithms)
89
+ const illuminationData = SunCalc.getMoonIllumination(currentDate);
90
+ const prevDate = new Date(currentDate);
91
+ prevDate.setDate(prevDate.getDate() - 1);
92
+ const prevIlluminationData = SunCalc.getMoonIllumination(prevDate);
93
+ // Check if we've passed the target phase between yesterday and today
94
+ const prevDiff = Math.abs(prevIlluminationData.phase - targetPhaseValue);
95
+ const currentDiff = Math.abs(illuminationData.phase - targetPhaseValue);
96
+ // If we're getting closer to the target phase and then further away, we've passed it
97
+ // Or if we're very close to the target phase (within 0.01)
98
+ if ((prevDiff > currentDiff && currentDiff < 0.01) || currentDiff < 0.005) {
99
+ results.push({
100
+ date: currentDate.toISOString().split('T')[0],
101
+ phase: targetPhase
102
+ });
103
+ }
104
+ // Move to next day
105
+ currentDate.setDate(currentDate.getDate() + 1);
106
+ // Safety check to prevent infinite loops
107
+ if (results.length === 0 && currentDate.getTime() - startDate.getTime() > 366 * 24 * 60 * 60 * 1000) {
108
+ throw new Error('Could not find the specified moon phase within a year.');
109
+ }
110
+ }
111
+ return results;
112
+ }
113
+ /**
114
+ * Get the moon phase name based on the phase value (0-1)
115
+ * @param phase Phase value (0-1)
116
+ * @returns Moon phase name
117
+ */
118
+ getMoonPhaseName(phase) {
119
+ // Normalize phase to 0-1 range
120
+ const normalizedPhase = phase < 0 ? phase + 1 : phase > 1 ? phase - 1 : phase;
121
+ // Determine moon phase based on the value
122
+ if (normalizedPhase < 0.0625 || normalizedPhase >= 0.9375) {
123
+ return MoonPhaseName.NEW_MOON;
124
+ }
125
+ else if (normalizedPhase < 0.1875) {
126
+ return MoonPhaseName.WAXING_CRESCENT;
127
+ }
128
+ else if (normalizedPhase < 0.3125) {
129
+ return MoonPhaseName.FIRST_QUARTER;
130
+ }
131
+ else if (normalizedPhase < 0.4375) {
132
+ return MoonPhaseName.WAXING_GIBBOUS;
133
+ }
134
+ else if (normalizedPhase < 0.5625) {
135
+ return MoonPhaseName.FULL_MOON;
136
+ }
137
+ else if (normalizedPhase < 0.6875) {
138
+ return MoonPhaseName.WANING_GIBBOUS;
139
+ }
140
+ else if (normalizedPhase < 0.8125) {
141
+ return MoonPhaseName.LAST_QUARTER;
142
+ }
143
+ else {
144
+ return MoonPhaseName.WANING_CRESCENT;
145
+ }
146
+ }
147
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Provides information about valid NOAA Tides and Currents API parameters
3
+ */
4
+ export declare class NoaaParametersService {
5
+ /**
6
+ * Get valid time zone values
7
+ */
8
+ getTimeZones(): {
9
+ id: string;
10
+ description: string;
11
+ }[];
12
+ /**
13
+ * Get valid datum values
14
+ */
15
+ getDatums(): {
16
+ id: string;
17
+ description: string;
18
+ }[];
19
+ /**
20
+ * Get valid units
21
+ */
22
+ getUnits(): {
23
+ id: string;
24
+ description: string;
25
+ }[];
26
+ /**
27
+ * Get valid intervals for tide predictions
28
+ */
29
+ getTidePredictionIntervals(): {
30
+ id: string;
31
+ description: string;
32
+ }[];
33
+ /**
34
+ * Get valid intervals for current predictions
35
+ */
36
+ getCurrentPredictionIntervals(): {
37
+ id: string;
38
+ description: string;
39
+ }[];
40
+ /**
41
+ * Get valid velocity types for current predictions
42
+ */
43
+ getVelocityTypes(): {
44
+ id: string;
45
+ description: string;
46
+ }[];
47
+ /**
48
+ * Get valid meteorological products
49
+ */
50
+ getMeteorologicalProducts(): {
51
+ id: string;
52
+ description: string;
53
+ }[];
54
+ /**
55
+ * Get valid station types
56
+ */
57
+ getStationTypes(): {
58
+ id: string;
59
+ description: string;
60
+ }[];
61
+ /**
62
+ * Get valid date formats
63
+ */
64
+ getDateFormats(): {
65
+ format: string;
66
+ description: string;
67
+ example: string;
68
+ }[];
69
+ /**
70
+ * Get valid output formats
71
+ */
72
+ getOutputFormats(): {
73
+ id: string;
74
+ description: string;
75
+ }[];
76
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Provides information about valid NOAA Tides and Currents API parameters
3
+ */
4
+ export class NoaaParametersService {
5
+ /**
6
+ * Get valid time zone values
7
+ */
8
+ getTimeZones() {
9
+ return [
10
+ { id: 'gmt', description: 'Greenwich Mean Time' },
11
+ { id: 'lst', description: 'Local Standard Time' },
12
+ { id: 'lst_ldt', description: 'Local Standard/Local Daylight Time' }
13
+ ];
14
+ }
15
+ /**
16
+ * Get valid datum values
17
+ */
18
+ getDatums() {
19
+ return [
20
+ { id: 'MHHW', description: 'Mean Higher High Water' },
21
+ { id: 'MHW', description: 'Mean High Water' },
22
+ { id: 'MTL', description: 'Mean Tide Level' },
23
+ { id: 'MSL', description: 'Mean Sea Level' },
24
+ { id: 'MLW', description: 'Mean Low Water' },
25
+ { id: 'MLLW', description: 'Mean Lower Low Water' },
26
+ { id: 'NAVD', description: 'North American Vertical Datum' },
27
+ { id: 'STND', description: 'Station Datum' }
28
+ ];
29
+ }
30
+ /**
31
+ * Get valid units
32
+ */
33
+ getUnits() {
34
+ return [
35
+ { id: 'english', description: 'English units (feet, mph, etc.)' },
36
+ { id: 'metric', description: 'Metric units (meters, kph, etc.)' }
37
+ ];
38
+ }
39
+ /**
40
+ * Get valid intervals for tide predictions
41
+ */
42
+ getTidePredictionIntervals() {
43
+ return [
44
+ { id: 'hilo', description: 'High/low tide predictions only' },
45
+ { id: 'h', description: 'Hourly predictions' },
46
+ { id: '6', description: '6-minute predictions' },
47
+ { id: '30', description: '30-minute predictions' },
48
+ { id: '60', description: '60-minute predictions' }
49
+ ];
50
+ }
51
+ /**
52
+ * Get valid intervals for current predictions
53
+ */
54
+ getCurrentPredictionIntervals() {
55
+ return [
56
+ { id: 'MAX_SLACK', description: 'Maximum flood/ebb and slack predictions only' },
57
+ { id: '6', description: '6-minute predictions' },
58
+ { id: '30', description: '30-minute predictions' },
59
+ { id: '60', description: '60-minute predictions' }
60
+ ];
61
+ }
62
+ /**
63
+ * Get valid velocity types for current predictions
64
+ */
65
+ getVelocityTypes() {
66
+ return [
67
+ { id: 'default', description: 'Default velocity reporting (flood/ebb direction)' },
68
+ { id: 'speed_dir', description: 'Speed and direction format' }
69
+ ];
70
+ }
71
+ /**
72
+ * Get valid meteorological products
73
+ */
74
+ getMeteorologicalProducts() {
75
+ return [
76
+ { id: 'air_temperature', description: 'Air temperature' },
77
+ { id: 'water_temperature', description: 'Water temperature' },
78
+ { id: 'wind', description: 'Wind speed and direction' },
79
+ { id: 'air_pressure', description: 'Barometric pressure' },
80
+ { id: 'air_gap', description: 'Air gap (distance between bridge and water surface)' },
81
+ { id: 'conductivity', description: 'Conductivity' },
82
+ { id: 'visibility', description: 'Visibility' },
83
+ { id: 'humidity', description: 'Relative humidity' },
84
+ { id: 'salinity', description: 'Salinity' },
85
+ { id: 'hourly_height', description: 'Verified hourly height water level' },
86
+ { id: 'high_low', description: 'Verified high/low water level' },
87
+ { id: 'daily_mean', description: 'Verified daily mean water level' },
88
+ { id: 'monthly_mean', description: 'Verified monthly mean water level' },
89
+ { id: 'one_minute_water_level', description: 'One-minute water level data' },
90
+ { id: 'datums', description: 'Datums' }
91
+ ];
92
+ }
93
+ /**
94
+ * Get valid station types
95
+ */
96
+ getStationTypes() {
97
+ return [
98
+ { id: 'waterlevels', description: 'Water level stations' },
99
+ { id: 'currentpredictions', description: 'Current prediction stations' },
100
+ { id: 'currents', description: 'Current observation stations' },
101
+ { id: 'tidepredictions', description: 'Tide prediction stations' },
102
+ { id: 'weather', description: 'Weather stations' },
103
+ { id: 'ports', description: 'Physical Oceanographic Real-Time System (PORTS) stations' }
104
+ ];
105
+ }
106
+ /**
107
+ * Get valid date formats
108
+ */
109
+ getDateFormats() {
110
+ return [
111
+ { format: 'YYYYMMDD', description: 'Year, month, day without separators', example: '20230401' },
112
+ { format: 'MM/DD/YYYY', description: 'Month/day/year with separators', example: '04/01/2023' },
113
+ { format: 'today', description: 'Current date', example: 'today' },
114
+ { format: 'latest', description: 'Latest available data', example: 'latest' },
115
+ { format: 'recent', description: 'Most recent data', example: 'recent' }
116
+ ];
117
+ }
118
+ /**
119
+ * Get valid output formats
120
+ */
121
+ getOutputFormats() {
122
+ return [
123
+ { id: 'json', description: 'JSON format' },
124
+ { id: 'xml', description: 'XML format' },
125
+ { id: 'csv', description: 'CSV format (not available for all endpoints)' }
126
+ ];
127
+ }
128
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Service for interacting with NOAA Tides and Currents APIs
3
+ */
4
+ export declare class NoaaService {
5
+ /**
6
+ * Build parameters for the API request
7
+ * @param params Parameters for the request
8
+ * @returns URL-encoded parameters string
9
+ */
10
+ private buildParams;
11
+ /**
12
+ * Make a request to the Data API
13
+ * @param params Parameters for the request
14
+ * @returns Response data
15
+ */
16
+ fetchDataApi(params: Record<string, any>): Promise<any>;
17
+ /**
18
+ * Make a request to the Metadata API
19
+ * @param endpoint Endpoint path
20
+ * @param params Parameters for the request
21
+ * @returns Response data
22
+ */
23
+ fetchMetadataApi(endpoint: string, params?: Record<string, any>): Promise<any>;
24
+ /**
25
+ * Get water level data
26
+ */
27
+ getWaterLevels(params: Record<string, any>): Promise<any>;
28
+ /**
29
+ * Get tide predictions
30
+ */
31
+ getTidePredictions(params: Record<string, any>): Promise<any>;
32
+ /**
33
+ * Get currents data
34
+ */
35
+ getCurrents(params: Record<string, any>): Promise<any>;
36
+ /**
37
+ * Get current predictions
38
+ */
39
+ getCurrentPredictions(params: Record<string, any>): Promise<any>;
40
+ /**
41
+ * Get meteorological data (air_temperature, wind, etc.)
42
+ */
43
+ getMeteorologicalData(params: Record<string, any>): Promise<any>;
44
+ /**
45
+ * Get list of stations
46
+ */
47
+ getStations(params: Record<string, any>): Promise<any>;
48
+ /**
49
+ * Get station details
50
+ */
51
+ getStationDetails(params: Record<string, any>): Promise<any>;
52
+ }