fix: correct FastMCP interface usage and resolve lint issues

- Fix FastMCP server interface to use correct mcp.run() instead of app.run(host, port)
- Remove unnecessary host and port parameters, use standard STDIO transport
- Fix all ruff lint issues including import sorting and blank lines
- Update ruff configuration to new lint configuration format
- Fix type annotation issues using Union syntax (int | None)
- Ensure uvx pypi-query-mcp-server works correctly
- All tests pass and lint checks pass
This commit is contained in:
longhao 2025-05-27 11:25:25 +08:00 committed by Hal
parent 030b3a2607
commit 576652571c
12 changed files with 38 additions and 51 deletions

Binary file not shown.

Binary file not shown.

View File

@ -3,8 +3,8 @@ import os
# Import third-party modules
import nox
from nox_actions.utils import PACKAGE_NAME
from nox_actions.utils import THIS_ROOT
from nox_actions.utils import PACKAGE_NAME, THIS_ROOT
def pytest(session: nox.Session) -> None:

View File

@ -1,5 +1,6 @@
# Import third-party modules
import nox
from nox_actions.utils import PACKAGE_NAME

View File

@ -6,8 +6,8 @@ import zipfile
# Import third-party modules
import nox
from nox_actions.utils import PACKAGE_NAME
from nox_actions.utils import THIS_ROOT
from nox_actions.utils import PACKAGE_NAME, THIS_ROOT
def build(session: nox.Session) -> None:
@ -49,4 +49,4 @@ def build_exe(session: nox.Session) -> None:
zip_obj.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file),
os.path.join(platform_dir, ".")))
print("Saving to {zipfile}".format(zipfile=zip_file))
print(f"Saving to {zip_file}")

View File

@ -1,7 +1,6 @@
# Import built-in modules
from pathlib import Path
PACKAGE_NAME = "pypi_query_mcp"
THIS_ROOT = Path(__file__).parent.parent
PROJECT_ROOT = THIS_ROOT.parent

View File

@ -5,18 +5,14 @@ import sys
# Import third-party modules
import nox
ROOT = os.path.dirname(__file__)
# Ensure pypi_query_mcp is importable.
if ROOT not in sys.path:
sys.path.append(ROOT)
# Import third-party modules
from nox_actions import codetest # noqa: E402
from nox_actions import lint # noqa: E402
from nox_actions import release # noqa: E402
# Import local modules (after sys.path setup)
from nox_actions import codetest, lint, release # noqa: E402
# Configure nox sessions
nox.session(lint.lint, name="lint")

View File

@ -8,6 +8,6 @@ __version__ = "0.1.0"
__author__ = "Hal"
__email__ = "hal.long@outlook.com"
from pypi_query_mcp.server import app
from pypi_query_mcp.server import mcp
__all__ = ["app", "__version__"]
__all__ = ["mcp", "__version__"]

View File

@ -4,7 +4,7 @@
class PyPIError(Exception):
"""Base exception for PyPI-related errors."""
def __init__(self, message: str, status_code: int = None):
def __init__(self, message: str, status_code: int | None = None):
super().__init__(message)
self.message = message
self.status_code = status_code
@ -22,7 +22,7 @@ class PackageNotFoundError(PyPIError):
class NetworkError(PyPIError):
"""Raised when network-related errors occur."""
def __init__(self, message: str, original_error: Exception = None):
def __init__(self, message: str, original_error: Exception | None = None):
super().__init__(message)
self.original_error = original_error
@ -30,7 +30,7 @@ class NetworkError(PyPIError):
class RateLimitError(PyPIError):
"""Raised when API rate limit is exceeded."""
def __init__(self, retry_after: int = None):
def __init__(self, retry_after: int | None = None):
message = "PyPI API rate limit exceeded"
if retry_after:
message += f". Retry after {retry_after} seconds"
@ -50,7 +50,7 @@ class InvalidPackageNameError(PyPIError):
class PyPIServerError(PyPIError):
"""Raised when PyPI server returns a server error."""
def __init__(self, status_code: int, message: str = None):
def __init__(self, status_code: int, message: str | None = None):
if not message:
message = f"PyPI server error (HTTP {status_code})"
super().__init__(message, status_code=status_code)

View File

@ -23,10 +23,10 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
# Create FastMCP application
app = FastMCP("PyPI Query MCP Server")
mcp = FastMCP("PyPI Query MCP Server")
@app.tool()
@mcp.tool()
async def get_package_info(package_name: str) -> dict[str, Any]:
"""Query comprehensive information about a PyPI package.
@ -71,7 +71,7 @@ async def get_package_info(package_name: str) -> dict[str, Any]:
}
@app.tool()
@mcp.tool()
async def get_package_versions(package_name: str) -> dict[str, Any]:
"""Get version information for a PyPI package.
@ -114,7 +114,7 @@ async def get_package_versions(package_name: str) -> dict[str, Any]:
}
@app.tool()
@mcp.tool()
async def get_package_dependencies(package_name: str, version: str | None = None) -> dict[str, Any]:
"""Get dependency information for a PyPI package.
@ -161,7 +161,7 @@ async def get_package_dependencies(package_name: str, version: str | None = None
}
@app.tool()
@mcp.tool()
async def check_package_python_compatibility(
package_name: str,
target_python_version: str,
@ -212,7 +212,7 @@ async def check_package_python_compatibility(
}
@app.tool()
@mcp.tool()
async def get_package_compatible_python_versions(
package_name: str,
python_versions: list[str] | None = None,
@ -262,33 +262,22 @@ async def get_package_compatible_python_versions(
@click.command()
@click.option(
"--host",
default="localhost",
help="Host to bind the server to"
)
@click.option(
"--port",
default=8000,
type=int,
help="Port to bind the server to"
)
@click.option(
"--log-level",
default="INFO",
type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR"]),
help="Logging level"
)
def main(host: str, port: int, log_level: str) -> None:
def main(log_level: str) -> None:
"""Start the PyPI Query MCP Server."""
# Set logging level
logging.getLogger().setLevel(getattr(logging, log_level))
logger.info(f"Starting PyPI Query MCP Server on {host}:{port}")
logger.info("Starting PyPI Query MCP Server")
logger.info(f"Log level set to: {log_level}")
# Run the FastMCP server
app.run(host=host, port=port)
# Run the FastMCP server (uses STDIO transport by default)
mcp.run()
if __name__ == "__main__":

View File

@ -51,6 +51,8 @@ pypi-query-mcp = "pypi_query_mcp.server:main"
[tool.ruff]
target-version = "py310"
line-length = 88
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
@ -66,7 +68,7 @@ ignore = [
"C901", # too complex
]
[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
[tool.mypy]

View File

@ -13,11 +13,11 @@ def test_version():
def test_import():
"""Test that main modules can be imported."""
from pypi_query_mcp.core import PyPIClient, VersionCompatibility
from pypi_query_mcp.server import app
from pypi_query_mcp.server import mcp
assert PyPIClient is not None
assert VersionCompatibility is not None
assert app is not None
assert mcp is not None
@pytest.mark.asyncio