Rename package from noaa-tides to mcnoaa-tides
Distribution name, import package, entry point script, MCP config, and all internal references updated. Git tracks the directory rename so file history is preserved.
This commit is contained in:
parent
66ec2ba9e7
commit
9f6d7bb4ac
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"noaa-tides": {
|
"mcnoaa-tides": {
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": ["run", "--directory", "/home/rpm/claude/mat/noaa-tides", "noaa-tides"]
|
"args": ["run", "--directory", "/home/rpm/claude/mat/noaa-tides", "mcnoaa-tides"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
README.md
20
README.md
@ -1,4 +1,4 @@
|
|||||||
# noaa-tides
|
# mcnoaa-tides
|
||||||
|
|
||||||
MCP server for [NOAA CO-OPS Tides and Currents](https://tidesandcurrents.noaa.gov/). Exposes tide predictions, observed water levels, and meteorological data from ~301 U.S. coastal stations as tools, resources, and prompts via [FastMCP 3.0](https://gofastmcp.com/).
|
MCP server for [NOAA CO-OPS Tides and Currents](https://tidesandcurrents.noaa.gov/). Exposes tide predictions, observed water levels, and meteorological data from ~301 U.S. coastal stations as tools, resources, and prompts via [FastMCP 3.0](https://gofastmcp.com/).
|
||||||
|
|
||||||
@ -8,16 +8,16 @@ Built for marine planning — fishing trips, boating, crabbing, safety checks.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run directly (no install needed)
|
# Run directly (no install needed)
|
||||||
uvx noaa-tides
|
uvx mcnoaa-tides
|
||||||
|
|
||||||
# Or add to Claude Code
|
# Or add to Claude Code
|
||||||
claude mcp add noaa-tides -- uvx noaa-tides
|
claude mcp add mcnoaa-tides -- uvx mcnoaa-tides
|
||||||
|
|
||||||
# With visualization support (charts)
|
# With visualization support (charts)
|
||||||
uv pip install noaa-tides[viz]
|
uv pip install mcnoaa-tides[viz]
|
||||||
|
|
||||||
# Local development
|
# Local development
|
||||||
uv run noaa-tides
|
uv run mcnoaa-tides
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
@ -192,7 +192,7 @@ Parameters:
|
|||||||
- `include_observed` — overlay actual readings (default true)
|
- `include_observed` — overlay actual readings (default true)
|
||||||
- `format` — `"png"` (inline image) or `"html"` (interactive file)
|
- `format` — `"png"` (inline image) or `"html"` (interactive file)
|
||||||
|
|
||||||
Requires `noaa-tides[viz]` — install with `uv pip install noaa-tides[viz]`.
|
Requires `mcnoaa-tides[viz]` — install with `uv pip install mcnoaa-tides[viz]`.
|
||||||
|
|
||||||
### `visualize_conditions` — Multi-panel conditions dashboard
|
### `visualize_conditions` — Multi-panel conditions dashboard
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ Parameters:
|
|||||||
- `hours` — data window (default 24)
|
- `hours` — data window (default 24)
|
||||||
- `format` — `"png"` (inline image) or `"html"` (interactive file)
|
- `format` — `"png"` (inline image) or `"html"` (interactive file)
|
||||||
|
|
||||||
Requires `noaa-tides[viz]`.
|
Requires `mcnoaa-tides[viz]`.
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ marine_safety_check(station_id="9447130")
|
|||||||
## Development
|
## Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <repo-url> && cd noaa-tides
|
git clone <repo-url> && cd mcnoaa-tides
|
||||||
uv sync --dev
|
uv sync --dev
|
||||||
|
|
||||||
# Run tests (mock client, no network)
|
# Run tests (mock client, no network)
|
||||||
@ -263,12 +263,12 @@ uv run pytest tests/ -v
|
|||||||
uv run ruff check src/
|
uv run ruff check src/
|
||||||
|
|
||||||
# Start server locally
|
# Start server locally
|
||||||
uv run noaa-tides
|
uv run mcnoaa-tides
|
||||||
|
|
||||||
# Headless test with Claude
|
# Headless test with Claude
|
||||||
claude -p "Search for tide stations in Rhode Island" \
|
claude -p "Search for tide stations in Rhode Island" \
|
||||||
--mcp-config .mcp.json \
|
--mcp-config .mcp.json \
|
||||||
--allowedTools "mcp__noaa-tides__*"
|
--allowedTools "mcp__mcnoaa-tides__*"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Data source
|
## Data source
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "noaa-tides"
|
name = "mcnoaa-tides"
|
||||||
version = "2026.02.21"
|
version = "2026.02.21"
|
||||||
description = "FastMCP server for NOAA CO-OPS Tides and Currents API"
|
description = "FastMCP server for NOAA CO-OPS Tides and Currents API"
|
||||||
authors = [{ name = "Ryan Malloy", email = "ryan@supported.systems" }]
|
authors = [{ name = "Ryan Malloy", email = "ryan@supported.systems" }]
|
||||||
@ -12,14 +12,14 @@ license = "MIT"
|
|||||||
viz = ["matplotlib>=3.8", "plotly>=5.18"]
|
viz = ["matplotlib>=3.8", "plotly>=5.18"]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
noaa-tides = "noaa_tides.server:main"
|
mcnoaa-tides = "mcnoaa_tides.server:main"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
build-backend = "hatchling.build"
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
[tool.hatch.build.targets.wheel]
|
||||||
packages = ["src/noaa_tides"]
|
packages = ["src/mcnoaa_tides"]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
target-version = "py312"
|
target-version = "py312"
|
||||||
@ -32,4 +32,4 @@ select = ["E", "F", "I", "W"]
|
|||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = ["pytest>=8", "pytest-asyncio>=0.24", "ruff>=0.9", "noaa-tides[viz]"]
|
dev = ["pytest>=8", "pytest-asyncio>=0.24", "ruff>=0.9", "mcnoaa-tides[viz]"]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from importlib.metadata import PackageNotFoundError, version
|
from importlib.metadata import PackageNotFoundError, version
|
||||||
|
|
||||||
try:
|
try:
|
||||||
__version__ = version("noaa-tides")
|
__version__ = version("mcnoaa-tides")
|
||||||
except PackageNotFoundError:
|
except PackageNotFoundError:
|
||||||
__version__ = "0.0.0-dev"
|
__version__ = "0.0.0-dev"
|
||||||
@ -1,6 +1,6 @@
|
|||||||
"""Chart rendering for NOAA tide and conditions data.
|
"""Chart rendering for NOAA tide and conditions data.
|
||||||
|
|
||||||
Optional dependency — requires noaa-tides[viz] to be installed.
|
Optional dependency — requires mcnoaa-tides[viz] to be installed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Marine color palette — shared across all chart renderers
|
# Marine color palette — shared across all chart renderers
|
||||||
@ -21,7 +21,7 @@ def check_deps(format: str) -> None:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"PNG charts require matplotlib. Install with: "
|
"PNG charts require matplotlib. Install with: "
|
||||||
"uv pip install noaa-tides[viz]"
|
"uv pip install mcnoaa-tides[viz]"
|
||||||
)
|
)
|
||||||
elif format == "html":
|
elif format == "html":
|
||||||
try:
|
try:
|
||||||
@ -29,5 +29,5 @@ def check_deps(format: str) -> None:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"HTML charts require plotly. Install with: "
|
"HTML charts require plotly. Install with: "
|
||||||
"uv pip install noaa-tides[viz]"
|
"uv pip install mcnoaa-tides[viz]"
|
||||||
)
|
)
|
||||||
@ -3,7 +3,7 @@
|
|||||||
import io
|
import io
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from noaa_tides.charts import BG_COLOR, CORAL, GRID_COLOR, OCEAN_BLUE, SAND, SLATE, TEAL
|
from mcnoaa_tides.charts import BG_COLOR, CORAL, GRID_COLOR, OCEAN_BLUE, SAND, SLATE, TEAL
|
||||||
|
|
||||||
|
|
||||||
def _parse_time_series(data: list[dict], value_key: str = "v") -> tuple[list, list]:
|
def _parse_time_series(data: list[dict], value_key: str = "v") -> tuple[list, list]:
|
||||||
@ -105,7 +105,7 @@ def render_conditions_png(snapshot: dict, station_name: str = "") -> bytes:
|
|||||||
if has_predictions:
|
if has_predictions:
|
||||||
preds = snapshot["predictions"].get("predictions", [])
|
preds = snapshot["predictions"].get("predictions", [])
|
||||||
if preds:
|
if preds:
|
||||||
from noaa_tides.charts.tides import _parse_predictions
|
from mcnoaa_tides.charts.tides import _parse_predictions
|
||||||
|
|
||||||
p_times, p_values, markers = _parse_predictions(preds)
|
p_times, p_values, markers = _parse_predictions(preds)
|
||||||
ax.plot(
|
ax.plot(
|
||||||
@ -122,7 +122,7 @@ def render_conditions_png(snapshot: dict, station_name: str = "") -> bytes:
|
|||||||
if has_water_level:
|
if has_water_level:
|
||||||
obs_data = snapshot["water_level"].get("data", [])
|
obs_data = snapshot["water_level"].get("data", [])
|
||||||
if obs_data:
|
if obs_data:
|
||||||
from noaa_tides.charts.tides import _parse_observed
|
from mcnoaa_tides.charts.tides import _parse_observed
|
||||||
|
|
||||||
o_times, o_values = _parse_observed(obs_data)
|
o_times, o_values = _parse_observed(obs_data)
|
||||||
if o_times:
|
if o_times:
|
||||||
@ -255,7 +255,7 @@ def render_conditions_html(snapshot: dict, station_name: str = "") -> str:
|
|||||||
if has_predictions:
|
if has_predictions:
|
||||||
preds = snapshot["predictions"].get("predictions", [])
|
preds = snapshot["predictions"].get("predictions", [])
|
||||||
if preds:
|
if preds:
|
||||||
from noaa_tides.charts.tides import _parse_predictions
|
from mcnoaa_tides.charts.tides import _parse_predictions
|
||||||
|
|
||||||
p_times, p_values, markers = _parse_predictions(preds)
|
p_times, p_values, markers = _parse_predictions(preds)
|
||||||
fig.add_trace(
|
fig.add_trace(
|
||||||
@ -290,7 +290,7 @@ def render_conditions_html(snapshot: dict, station_name: str = "") -> str:
|
|||||||
if has_water_level:
|
if has_water_level:
|
||||||
obs_data = snapshot["water_level"].get("data", [])
|
obs_data = snapshot["water_level"].get("data", [])
|
||||||
if obs_data:
|
if obs_data:
|
||||||
from noaa_tides.charts.tides import _parse_observed
|
from mcnoaa_tides.charts.tides import _parse_observed
|
||||||
|
|
||||||
o_times, o_values = _parse_observed(obs_data)
|
o_times, o_values = _parse_observed(obs_data)
|
||||||
if o_times:
|
if o_times:
|
||||||
@ -3,7 +3,7 @@
|
|||||||
import io
|
import io
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from noaa_tides.charts import BG_COLOR, CORAL, GRID_COLOR, OCEAN_BLUE, SAND, SLATE, TEAL
|
from mcnoaa_tides.charts import BG_COLOR, CORAL, GRID_COLOR, OCEAN_BLUE, SAND, SLATE, TEAL
|
||||||
|
|
||||||
|
|
||||||
def _parse_predictions(predictions: list[dict]) -> tuple[list[datetime], list[float], list[dict]]:
|
def _parse_predictions(predictions: list[dict]) -> tuple[list[datetime], list[float], list[dict]]:
|
||||||
@ -7,7 +7,7 @@ import time
|
|||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
from noaa_tides.models import Station
|
from mcnoaa_tides.models import Station
|
||||||
|
|
||||||
DATA_URL = "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter"
|
DATA_URL = "https://api.tidesandcurrents.noaa.gov/api/prod/datagetter"
|
||||||
META_URL = "https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi"
|
META_URL = "https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi"
|
||||||
@ -139,7 +139,7 @@ class NOAAClient:
|
|||||||
"units": units,
|
"units": units,
|
||||||
"time_zone": time_zone,
|
"time_zone": time_zone,
|
||||||
"format": "json",
|
"format": "json",
|
||||||
"application": "noaa-tides-mcp",
|
"application": "mcnoaa-tides-mcp",
|
||||||
}
|
}
|
||||||
if begin_date:
|
if begin_date:
|
||||||
params["begin_date"] = begin_date
|
params["begin_date"] = begin_date
|
||||||
@ -4,7 +4,7 @@ import json
|
|||||||
|
|
||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
|
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
|
|
||||||
def register(mcp: FastMCP) -> None:
|
def register(mcp: FastMCP) -> None:
|
||||||
@ -5,9 +5,9 @@ from contextlib import asynccontextmanager
|
|||||||
|
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
|
|
||||||
from noaa_tides import __version__, prompts, resources
|
from mcnoaa_tides import __version__, prompts, resources
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
from noaa_tides.tools import charts, conditions, meteorological, stations, tides
|
from mcnoaa_tides.tools import charts, conditions, meteorological, stations, tides
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
@ -34,7 +34,7 @@ async def lifespan(server: FastMCP):
|
|||||||
|
|
||||||
|
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"noaa-tides",
|
"mcnoaa-tides",
|
||||||
instructions=(
|
instructions=(
|
||||||
"NOAA Tides & Currents data server. "
|
"NOAA Tides & Currents data server. "
|
||||||
"Provides tide predictions, observed water levels, and meteorological data "
|
"Provides tide predictions, observed water levels, and meteorological data "
|
||||||
@ -57,5 +57,5 @@ prompts.register(mcp)
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print(f"noaa-tides v{__version__}", file=sys.stderr)
|
print(f"mcnoaa-tides v{__version__}", file=sys.stderr)
|
||||||
mcp.run()
|
mcp.run()
|
||||||
@ -8,8 +8,8 @@ from typing import Literal
|
|||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
from fastmcp.utilities.types import Image
|
from fastmcp.utilities.types import Image
|
||||||
|
|
||||||
from noaa_tides.charts import check_deps
|
from mcnoaa_tides.charts import check_deps
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
|
|
||||||
def register(mcp: FastMCP) -> None:
|
def register(mcp: FastMCP) -> None:
|
||||||
@ -30,7 +30,7 @@ def register(mcp: FastMCP) -> None:
|
|||||||
PNG format returns an inline image. HTML format saves an interactive
|
PNG format returns an inline image. HTML format saves an interactive
|
||||||
chart to artifacts/charts/ and returns the file path.
|
chart to artifacts/charts/ and returns the file path.
|
||||||
|
|
||||||
Requires noaa-tides[viz] to be installed.
|
Requires mcnoaa-tides[viz] to be installed.
|
||||||
"""
|
"""
|
||||||
check_deps(format)
|
check_deps(format)
|
||||||
noaa: NOAAClient = ctx.lifespan_context["noaa_client"]
|
noaa: NOAAClient = ctx.lifespan_context["noaa_client"]
|
||||||
@ -81,12 +81,12 @@ def register(mcp: FastMCP) -> None:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if format == "png":
|
if format == "png":
|
||||||
from noaa_tides.charts.tides import render_tide_chart_png
|
from mcnoaa_tides.charts.tides import render_tide_chart_png
|
||||||
|
|
||||||
png_bytes = render_tide_chart_png(predictions, observed, station_name)
|
png_bytes = render_tide_chart_png(predictions, observed, station_name)
|
||||||
return Image(data=png_bytes, format="image/png")
|
return Image(data=png_bytes, format="image/png")
|
||||||
else:
|
else:
|
||||||
from noaa_tides.charts.tides import render_tide_chart_html
|
from mcnoaa_tides.charts.tides import render_tide_chart_html
|
||||||
|
|
||||||
html = render_tide_chart_html(predictions, observed, station_name)
|
html = render_tide_chart_html(predictions, observed, station_name)
|
||||||
path = _save_html(html, station_id, "tides")
|
path = _save_html(html, station_id, "tides")
|
||||||
@ -112,7 +112,7 @@ def register(mcp: FastMCP) -> None:
|
|||||||
PNG format returns an inline image. HTML format saves an interactive
|
PNG format returns an inline image. HTML format saves an interactive
|
||||||
chart to artifacts/charts/ and returns the file path.
|
chart to artifacts/charts/ and returns the file path.
|
||||||
|
|
||||||
Requires noaa-tides[viz] to be installed.
|
Requires mcnoaa-tides[viz] to be installed.
|
||||||
"""
|
"""
|
||||||
check_deps(format)
|
check_deps(format)
|
||||||
noaa: NOAAClient = ctx.lifespan_context["noaa_client"]
|
noaa: NOAAClient = ctx.lifespan_context["noaa_client"]
|
||||||
@ -159,12 +159,12 @@ def register(mcp: FastMCP) -> None:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if format == "png":
|
if format == "png":
|
||||||
from noaa_tides.charts.conditions import render_conditions_png
|
from mcnoaa_tides.charts.conditions import render_conditions_png
|
||||||
|
|
||||||
png_bytes = render_conditions_png(snapshot, station_name)
|
png_bytes = render_conditions_png(snapshot, station_name)
|
||||||
return Image(data=png_bytes, format="image/png")
|
return Image(data=png_bytes, format="image/png")
|
||||||
else:
|
else:
|
||||||
from noaa_tides.charts.conditions import render_conditions_html
|
from mcnoaa_tides.charts.conditions import render_conditions_html
|
||||||
|
|
||||||
html = render_conditions_html(snapshot, station_name)
|
html = render_conditions_html(snapshot, station_name)
|
||||||
path = _save_html(html, station_id, "conditions")
|
path = _save_html(html, station_id, "conditions")
|
||||||
@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
|||||||
|
|
||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
|
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
|
|
||||||
def register(mcp: FastMCP) -> None:
|
def register(mcp: FastMCP) -> None:
|
||||||
@ -4,7 +4,7 @@ from typing import Literal
|
|||||||
|
|
||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
|
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
MetProduct = Literal[
|
MetProduct = Literal[
|
||||||
"air_temperature",
|
"air_temperature",
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
|
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
|
|
||||||
def register(mcp: FastMCP) -> None:
|
def register(mcp: FastMCP) -> None:
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from fastmcp import Context, FastMCP
|
from fastmcp import Context, FastMCP
|
||||||
|
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
|
|
||||||
|
|
||||||
def register(mcp: FastMCP) -> None:
|
def register(mcp: FastMCP) -> None:
|
||||||
@ -8,9 +8,9 @@ from fastmcp import Client, FastMCP
|
|||||||
from fastmcp.client.transports import StreamableHttpTransport
|
from fastmcp.client.transports import StreamableHttpTransport
|
||||||
from fastmcp.utilities.tests import run_server_async
|
from fastmcp.utilities.tests import run_server_async
|
||||||
|
|
||||||
from noaa_tides import prompts, resources
|
from mcnoaa_tides import prompts, resources
|
||||||
from noaa_tides.client import NOAAClient
|
from mcnoaa_tides.client import NOAAClient
|
||||||
from noaa_tides.tools import charts, conditions, meteorological, stations, tides
|
from mcnoaa_tides.tools import charts, conditions, meteorological, stations, tides
|
||||||
|
|
||||||
# Realistic station fixtures
|
# Realistic station fixtures
|
||||||
MOCK_STATIONS_RAW = [
|
MOCK_STATIONS_RAW = [
|
||||||
@ -98,7 +98,7 @@ MOCK_METADATA = {
|
|||||||
|
|
||||||
def _build_mock_client() -> NOAAClient:
|
def _build_mock_client() -> NOAAClient:
|
||||||
"""Build a NOAAClient with mocked HTTP but real search/nearest logic."""
|
"""Build a NOAAClient with mocked HTTP but real search/nearest logic."""
|
||||||
from noaa_tides.models import Station
|
from mcnoaa_tides.models import Station
|
||||||
|
|
||||||
client = NOAAClient()
|
client = NOAAClient()
|
||||||
client._stations = [Station(**s) for s in MOCK_STATIONS_RAW]
|
client._stations = [Station(**s) for s in MOCK_STATIONS_RAW]
|
||||||
@ -135,7 +135,7 @@ async def _test_lifespan(server: FastMCP):
|
|||||||
|
|
||||||
|
|
||||||
def _build_test_server() -> FastMCP:
|
def _build_test_server() -> FastMCP:
|
||||||
mcp = FastMCP("noaa-tides-test", lifespan=_test_lifespan)
|
mcp = FastMCP("mcnoaa-tides-test", lifespan=_test_lifespan)
|
||||||
stations.register(mcp)
|
stations.register(mcp)
|
||||||
tides.register(mcp)
|
tides.register(mcp)
|
||||||
meteorological.register(mcp)
|
meteorological.register(mcp)
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from fastmcp import Client
|
from fastmcp import Client
|
||||||
|
|
||||||
from noaa_tides.charts.conditions import render_conditions_html, render_conditions_png
|
from mcnoaa_tides.charts.conditions import render_conditions_html, render_conditions_png
|
||||||
from noaa_tides.charts.tides import (
|
from mcnoaa_tides.charts.tides import (
|
||||||
_parse_observed,
|
_parse_observed,
|
||||||
_parse_predictions,
|
_parse_predictions,
|
||||||
render_tide_chart_html,
|
render_tide_chart_html,
|
||||||
|
|||||||
76
uv.lock
generated
76
uv.lock
generated
@ -767,6 +767,44 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" },
|
{ url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mcnoaa-tides"
|
||||||
|
version = "2026.2.21"
|
||||||
|
source = { editable = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "fastmcp" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.optional-dependencies]
|
||||||
|
viz = [
|
||||||
|
{ name = "matplotlib" },
|
||||||
|
{ name = "plotly" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dev-dependencies]
|
||||||
|
dev = [
|
||||||
|
{ name = "mcnoaa-tides", extra = ["viz"] },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "fastmcp", specifier = ">=3.0.1" },
|
||||||
|
{ name = "matplotlib", marker = "extra == 'viz'", specifier = ">=3.8" },
|
||||||
|
{ name = "plotly", marker = "extra == 'viz'", specifier = ">=5.18" },
|
||||||
|
]
|
||||||
|
provides-extras = ["viz"]
|
||||||
|
|
||||||
|
[package.metadata.requires-dev]
|
||||||
|
dev = [
|
||||||
|
{ name = "mcnoaa-tides", extras = ["viz"] },
|
||||||
|
{ name = "pytest", specifier = ">=8" },
|
||||||
|
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
||||||
|
{ name = "ruff", specifier = ">=0.9" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mcp"
|
name = "mcp"
|
||||||
version = "1.26.0"
|
version = "1.26.0"
|
||||||
@ -819,44 +857,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/03/cc/7cb74758e6df95e0c4e1253f203b6dd7f348bf2f29cf89e9210a2416d535/narwhals-2.16.0-py3-none-any.whl", hash = "sha256:846f1fd7093ac69d63526e50732033e86c30ea0026a44d9b23991010c7d1485d", size = 443951, upload-time = "2026-02-02T10:30:58.635Z" },
|
{ url = "https://files.pythonhosted.org/packages/03/cc/7cb74758e6df95e0c4e1253f203b6dd7f348bf2f29cf89e9210a2416d535/narwhals-2.16.0-py3-none-any.whl", hash = "sha256:846f1fd7093ac69d63526e50732033e86c30ea0026a44d9b23991010c7d1485d", size = 443951, upload-time = "2026-02-02T10:30:58.635Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "noaa-tides"
|
|
||||||
version = "2026.2.21"
|
|
||||||
source = { editable = "." }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "fastmcp" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.optional-dependencies]
|
|
||||||
viz = [
|
|
||||||
{ name = "matplotlib" },
|
|
||||||
{ name = "plotly" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dev-dependencies]
|
|
||||||
dev = [
|
|
||||||
{ name = "noaa-tides", extra = ["viz"] },
|
|
||||||
{ name = "pytest" },
|
|
||||||
{ name = "pytest-asyncio" },
|
|
||||||
{ name = "ruff" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
requires-dist = [
|
|
||||||
{ name = "fastmcp", specifier = ">=3.0.1" },
|
|
||||||
{ name = "matplotlib", marker = "extra == 'viz'", specifier = ">=3.8" },
|
|
||||||
{ name = "plotly", marker = "extra == 'viz'", specifier = ">=5.18" },
|
|
||||||
]
|
|
||||||
provides-extras = ["viz"]
|
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
|
||||||
dev = [
|
|
||||||
{ name = "noaa-tides", extras = ["viz"] },
|
|
||||||
{ name = "pytest", specifier = ">=8" },
|
|
||||||
{ name = "pytest-asyncio", specifier = ">=0.24" },
|
|
||||||
{ name = "ruff", specifier = ">=0.9" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "numpy"
|
name = "numpy"
|
||||||
version = "2.4.2"
|
version = "2.4.2"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user