lookup_fact
Look up package versions, download counts, license info, or service status from npm, PyPI, or statuspage by specifying source, entity, and field.
Instructions
Look up any fact tracked by Grounded.
Args: source: The fact source — "npm", "pypi", or "statuspage" entity: The entity name — e.g. "react", "flask", "github" field: The fact field — e.g. "latest_version", "license", "deprecated", "dep_count", "required_runtime", "weekly_downloads", or "status"
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | ||
| entity | Yes | ||
| field | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/grounded_mcp/server.py:48-56 (handler)The lookup_fact async function is the tool handler. It delegates to _query_fact to call the Grounded API with source, entity, and field parameters.
async def lookup_fact(source: str, entity: str, field: str) -> str: """Look up any fact tracked by Grounded. Args: source: The fact source — "npm", "pypi", or "statuspage" entity: The entity name — e.g. "react", "flask", "github" field: The fact field — e.g. "latest_version", "license", "deprecated", "dep_count", "required_runtime", "weekly_downloads", or "status" """ return await _query_fact(source, entity, field) - src/grounded_mcp/server.py:47-47 (registration)The @mcp.tool() decorator registers lookup_fact as a tool with the FastMCP server instance (named 'Grounded').
@mcp.tool() - src/grounded_mcp/server.py:18-44 (helper)The _query_fact async helper function performs the actual HTTP GET request to the Grounded API and formats the response (value, source_url, fetched_at, hash, tier, TTL).
async def _query_fact(source: str, entity: str, field: str) -> str: """Query the Grounded API and return a formatted result.""" headers = {} if API_KEY: headers["X-API-Key"] = API_KEY async with httpx.AsyncClient() as client: resp = await client.get( f"{API_BASE}/v1/fact", params={"source": source, "entity": entity, "field": field}, headers=headers, timeout=10.0, ) if resp.status_code == 200: data = resp.json() return ( f"Value: {data['value']}\n" f"Source: {data['source_url']}\n" f"Fetched at: {data['fetched_at']}\n" f"Hash: {data['raw_response_hash']}\n" f"Tier: {data['tier']} (TTL: {data['ttl_seconds']}s)" ) elif resp.status_code == 404: detail = resp.json().get("detail", "Not found") return f"Not found: {detail}" else: return f"Error: HTTP {resp.status_code}"