diff --git a/CHANGES.md b/CHANGES.md index 55e0389..90b9f7e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,11 @@ ## Unreleased - Parameters: Added CLI option `--host` and environment variable `CRATEDB_MCP_HOST` - Parameters: Added CLI option `--path` and environment variable `CRATEDB_MCP_PATH` +- Dependencies: Allowed updating to [FastMCP 2.10], which includes a specification + update to [MCP spec 2025-06-18]. + +[FastMCP 2.10]: https://github.com/jlowin/fastmcp/releases/tag/v2.10.0 +[MCP spec 2025-06-18]: https://modelcontextprotocol.io/specification/2025-06-18/changelog ## v0.0.3 - 2025-06-18 - Dependencies: Downgraded to `fastmcp<2.7` to fix a breaking change diff --git a/cratedb_mcp/tool.py b/cratedb_mcp/tool.py index 33d7aaa..ed557aa 100644 --- a/cratedb_mcp/tool.py +++ b/cratedb_mcp/tool.py @@ -8,7 +8,7 @@ # ------------------------------------------ # Health / Status # ------------------------------------------ -def get_cluster_health() -> list[dict]: +def get_cluster_health() -> dict: """Query sys.health ordered by severity.""" return query_cratedb(Queries.HEALTH) @@ -16,7 +16,7 @@ def get_cluster_health() -> list[dict]: # ------------------------------------------ # Text-to-SQL # ------------------------------------------ -def query_cratedb(query: str) -> list[dict]: +def query_cratedb(query: str) -> dict: """Sends a `query` to the set `$CRATEDB_CLUSTER_URL`""" url = HTTP_URL if url.endswith("/"): @@ -25,13 +25,13 @@ def query_cratedb(query: str) -> list[dict]: return httpx.post(f"{url}/_sql", json={"stmt": query}, timeout=Settings.http_timeout()).json() -def query_sql(query: str): +def query_sql(query: str) -> dict: if not sql_is_permitted(query): raise PermissionError("Only queries that have a SELECT statement are allowed.") return query_cratedb(query) -def get_table_metadata() -> list[dict]: +def get_table_metadata() -> dict: """ Return an aggregation of schema:tables, e.g.: {'doc': [{name:'mytable', ...}, ...]} @@ -48,12 +48,12 @@ def get_table_metadata() -> list[dict]: documentation_index = DocumentationIndex() -def get_cratedb_documentation_index(): +def get_cratedb_documentation_index() -> dict: """Get curated CrateDB documentation index.""" return documentation_index.items() -def fetch_cratedb_docs(link: str): +def fetch_cratedb_docs(link: str) -> str: """Fetch a CrateDB documentation link.""" if not documentation_index.url_permitted(link): raise ValueError(f"Link is not permitted: {link}") diff --git a/pyproject.toml b/pyproject.toml index c17d410..88187a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "cachetools<7", "click<9", "cratedb-about==0.0.5", - "fastmcp>=2.7,<2.10", + "fastmcp>=2.7,<2.11", "hishel<0.2", "pueblo==0.0.11", "sqlparse<0.6", diff --git a/tests/test_cli.py b/tests/test_cli.py index 91d7178..ec855fc 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -78,7 +78,10 @@ def test_cli_valid_default(mocker, capsys): # Verify the outcome. assert run_mock.call_count == 1 - assert run_mock.call_args == mock.call("stdio") + assert run_mock.call_args in [ + mock.call("stdio"), + mock.call("stdio", show_banner=True), + ] def test_cli_valid_custom(mocker, capsys): @@ -99,7 +102,10 @@ def test_cli_valid_custom(mocker, capsys): # Verify the outcome. assert run_mock.call_count == 1 - assert run_mock.call_args == mock.call("http", host="127.0.0.1", port=65535, path=None) + assert run_mock.call_args in [ + mock.call("http", host="127.0.0.1", port=65535, path=None), + mock.call("http", show_banner=True, host="127.0.0.1", port=65535, path=None), + ] def test_cli_invalid_transport_option(mocker, capsys):