Spaces:
Running
Running
from fastmcp import FastMCP | |
import requests | |
INSTRUCTIONS="""Official French Government URL List MCP Server | |
This server provides access to official French government domain lists and URL resources through the Model Context Protocol. | |
## Available Resources | |
### 1. Official Government URL List (TXT) | |
- **URI**: `resource://sitesgouv-txt` | |
- **Source**: https://www.auracom.fr/gouv/sitesgouv.txt | |
- **Content**: Raw text file containing official French government URLs | |
### 2. Public Organization Domains (CSV) | |
- **URI**: `resource://public-org-domains-csv` | |
- **Source**: https://gitlab.adullact.net/dinum/noms-de-domaine-organismes-secteur-public/-/raw/master/domains.csv | |
- **Content**: CSV file with public organization domain information | |
## How to Use | |
1. **List Available Resources**: Use `resources/list` to see all available resources | |
2. **Read a Resource**: Use `resources/read` with the resource URI to get the content | |
3. **Get Help**: Use `prompts/get` with name `server-help` for detailed guidance | |
## Server Details | |
- **Transport**: SSE (Server-Sent Events) | |
- **Port**: 7860 | |
- **Framework**: FastMCP 2.0 | |
This server is designed to provide easy access to official French government data through the MCP protocol.""" | |
# Create a FastMCP 2.0 server instance | |
mcp = FastMCP( | |
"Official Gouv Url List MCP Server", | |
instructions=INSTRUCTIONS | |
) | |
async def get_sitesgouv_txt() -> str: | |
"""Fetches the official government URL list from auracom.fr as plain text.""" | |
response = requests.get("https://www.auracom.fr/gouv/sitesgouv.txt", timeout=10) | |
response.raise_for_status() | |
return response.text | |
async def get_public_org_domains_csv() -> str: | |
"""Fetches the CSV of public organization domains from adullact.net as plain text.""" | |
url = "https://gitlab.adullact.net/dinum/noms-de-domaine-organismes-secteur-public/-/raw/master/domains.csv" | |
response = requests.get(url, timeout=10) | |
response.raise_for_status() | |
return response.text | |
async def check_url_official(url: str) -> dict: | |
""" | |
Tool: check_url_official | |
------------------------- | |
Checks if a given URL is present in the official French government URL list (sitesgouv.txt). | |
Parameters: | |
url (str): The URL to check. The URL can be with or without protocol (http/https), and with or without a trailing slash. Example: "https://www.gouvernement.fr" or "gouvernement.fr". | |
Returns: | |
dict: A dictionary with the following keys: | |
- url (str): The input URL as provided. | |
- is_official (bool): True if the normalized URL is present in the official list, False otherwise. | |
Normalization: | |
- The tool normalizes both the input URL and the official list by: | |
* Lowercasing all characters | |
* Removing the protocol (http:// or https://) | |
* Removing any trailing slashes | |
- This ensures that URLs are compared in a consistent way, regardless of formatting. | |
Example usage: | |
>>> check_url_official("https://www.gouvernement.fr/") | |
{"url": "https://www.gouvernement.fr/", "is_official": True} | |
>>> check_url_official("example.com") | |
{"url": "example.com", "is_official": False} | |
Notes for LLMs: | |
- Use this tool to verify if a website is officially recognized as a French government site. | |
- The official list is fetched live from https://www.auracom.fr/gouv/sitesgouv.txt for each call. | |
- This tool is useful for compliance, trust, or filtering tasks involving French government domains. | |
""" | |
response = requests.get("https://www.auracom.fr/gouv/sitesgouv.txt", timeout=10) | |
response.raise_for_status() | |
official_urls = set(line.strip() for line in response.text.splitlines() if line.strip()) | |
# Simple normalization: ignore protocol and trailing slashes | |
def normalize(u): | |
return u.lower().replace("http://", "").replace("https://", "").rstrip("/") | |
normalized_official = set(normalize(u) for u in official_urls) | |
normalized_input = normalize(url) | |
return { | |
"url": url, | |
"is_official": normalized_input in normalized_official | |
} | |
if __name__ == "__main__": | |
mcp.run(transport="sse", host="0.0.0.0", port=7860) | |