File size: 4,873 Bytes
3094113
 
 
fb5baf2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3094113
fb5baf2
 
7bb2406
fb5baf2
3094113
 
 
 
 
 
 
0788b72
3094113
 
 
 
 
 
 
 
 
 
 
0788b72
3094113
 
 
 
 
 
6fba1cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3094113
7bb2406
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
)

@mcp.resource(
    uri="resource://sitesgouv-txt",
    name="Official Gouv URL List (TXT)",
    description="Exposes the raw content of https://www.auracom.fr/gouv/sitesgouv.txt",
    mime_type="text/plain"
)
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

@mcp.resource(
    uri="resource://public-org-domains-csv",
    name="Public Org Domains (CSV)",
    description="Exposes the raw CSV content of https://gitlab.adullact.net/dinum/noms-de-domaine-organismes-secteur-public/-/blob/master/domains.csv?ref_type=heads",
    mime_type="text/csv"
)
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

@mcp.tool(
    name="check_url_official",
    description="Check if a given URL is present in the official French government URL list (sitesgouv.txt)."
)
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)