File size: 1,946 Bytes
76d3296
 
 
 
 
80a2cf1
312d184
80a2cf1
76d3296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312d184
76d3296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b93b962
80a2cf1
b93b962
 
 
 
 
80a2cf1
 
 
 
 
 
b93b962
312d184
 
 
b93b962
76d3296
b93b962
312d184
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
from pydantic import AnyHttpUrl

from mcp.server.auth.provider import AccessToken, TokenVerifier
from mcp.server.auth.settings import AuthSettings
from mcp.server.fastmcp import FastMCP
from fastapi import FastAPI
from starlette.responses import JSONResponse, RedirectResponse
import contextlib


class SimpleTokenVerifier(TokenVerifier):
    """Simple token verifier for demonstration."""

    async def verify_token(self, token: str) -> AccessToken | None:
        pass  # This is where you would implement actual token validation


# Create FastMCP instance as a Resource Server
mcp = FastMCP(
    "Weather Service",
    # Token verifier for authentication
    token_verifier=SimpleTokenVerifier(),
    # Auth settings for RFC 9728 Protected Resource Metadata
    auth=AuthSettings(
        issuer_url=AnyHttpUrl("https://huggingface.co/.well-known/oauth-authorization-server"),  # Authorization Server URL
        resource_server_url=AnyHttpUrl("https://freddyaboulton-fastmcp-oauth.hf.space/"),  # This server's URL
        required_scopes=["user"],
    ),
)


@mcp.tool()
async def get_weather(city: str = "London") -> dict[str, str]:
    """Get weather data for a city"""
    return {
        "city": city,
        "temperature": "22",
        "condition": "Partly cloudy",
        "humidity": "65%",
    }

@contextlib.asynccontextmanager
async def lifespan(app: FastAPI):
    async with contextlib.AsyncExitStack() as stack:
        await stack.enter_async_context(mcp.session_manager.run())
        yield


app = FastAPI(lifespan=lifespan)
app.mount("/weather_mcp", mcp.streamable_http_app())

@app.get("/")
async def _():
    return JSONResponse({"message": "Welcome to the Weather Service!"})

@app.get("/.well-known/oauth-protected-resource")
async def _():
    return RedirectResponse("/weather_mcp/.well-known/oauth-protected-resource")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=7860)