Skip to main content
Glama
boecht

BitSight Community MCP Server

by boecht
test_birre_online.py4.99 kB
"""Live integration tests for BiRRe using the in-process FastMCP client.""" from __future__ import annotations import json import os import sys from collections.abc import Sequence from dataclasses import asdict, is_dataclass from pathlib import Path from typing import Any import pytest import pytest_asyncio from pydantic import BaseModel PROJECT_ROOT = Path(__file__).resolve().parents[2] if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) try: from fastmcp.client import Client from fastmcp.client.client import CallToolResult except ImportError: pytest.skip( "fastmcp client not installed; skipping online tests", allow_module_level=True ) from birre import create_birre_server # noqa: E402 from birre.config.settings import resolve_birre_settings # noqa: E402 from birre.infrastructure.logging import get_logger # noqa: E402 pytestmark = [pytest.mark.integration, pytest.mark.online] def _unwrap(result: CallToolResult) -> dict[str, Any]: """Normalize a CallToolResult into a plain dictionary.""" normalized = _normalize_data(result.data) if normalized is not None: return normalized normalized = _normalize_structured(result.structured_content) if normalized is not None: return normalized normalized = _normalize_blocks(result.content) if normalized is not None: return normalized raise AssertionError("Unable to unwrap CallToolResult into structured data") def _normalize_data(data: Any) -> dict[str, Any] | None: if data is None: return None if is_dataclass(data): return asdict(data) if isinstance(data, BaseModel): return data.model_dump(mode="json") # type: ignore[return-value] model_dump = getattr(data, "model_dump", None) if callable(model_dump): dumped = model_dump(mode="json") # type: ignore[call-arg] if isinstance(dumped, dict): return dumped if isinstance(data, dict): return data return None def _normalize_structured(structured: Any) -> dict[str, Any] | None: if not structured or not isinstance(structured, dict): return None inner = structured.get("result") if isinstance(inner, dict): return inner return structured def _normalize_blocks( blocks: Sequence[Any] | None, ) -> dict[str, Any] | None: if not blocks: return None text = getattr(blocks[0], "text", None) if not text: return None parsed = json.loads(text) return parsed if isinstance(parsed, dict) else None @pytest.fixture(scope="session") def require_online_api_key() -> str: """Ensure a BitSight API key is available for online integration runs.""" api_key = os.getenv("BITSIGHT_API_KEY") if not api_key: pytest.skip("BITSIGHT_API_KEY not configured; skipping online tests") return api_key @pytest_asyncio.fixture async def birre_client(require_online_api_key: str): """Provide an in-process FastMCP client for BiRRe.""" settings = resolve_birre_settings() logger = get_logger("birre.online.test") server = create_birre_server(settings, logger=logger) async with Client(server) as client: yield client async def _fetch_first_company(client: Client, query: str = "GitHub") -> dict[str, Any]: result = await client.call_tool("company_search", {"name": query}) payload = _unwrap(result) companies = payload.get("companies", []) assert companies, "expected at least one company from BitSight search" return companies[0] async def _fetch_company_by_name( client: Client, query: str, target_name: str ) -> dict[str, Any]: result = await client.call_tool("company_search", {"name": query}) payload = _unwrap(result) for company in payload.get("companies", []): if company.get("name") == target_name: return company pytest.skip(f"Company '{target_name}' not found in BitSight search results") @pytest.mark.asyncio async def test_company_search_returns_results(birre_client: Client) -> None: company = await _fetch_first_company(birre_client, "Rheinmetall") assert company["guid"], "company GUID missing" assert company["name"].lower().startswith("rheinmetall") @pytest.mark.asyncio async def test_company_rating_contains_rating_data(birre_client: Client) -> None: company = await _fetch_company_by_name( birre_client, "Rheinmetall", "Rheinmetall AG" ) guid = company["guid"] result = await birre_client.call_tool("get_company_rating", {"guid": guid}) rating_payload = _unwrap(result) current = rating_payload["current_rating"] assert isinstance(current, dict) assert set(current.keys()) == {"value", "color"} assert current["value"] is None or isinstance(current["value"], int | float) trend = rating_payload.get("trend_8_weeks") assert isinstance(trend, dict) assert set(trend.keys()) == {"direction", "change"}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/boecht/bitsight-community-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server