Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ebben az oktatóanyagban megtanulhatja, hogyan teheti elérhetővé a FastAPI-alkalmazások funkcióit a Model Context Protocol (MCP) használatával, hogyan adhat hozzá eszközt a GitHub Copilothoz, és hogyan használhatja az alkalmazást természetes nyelven a Copilot Csevegőügynök módban.
Ha a webalkalmazás már rendelkezik olyan hasznos funkciókkal, mint a vásárlás, a szállodai foglalás vagy az adatkezelés, könnyen elérhetővé teheti ezeket a képességeket a következő célokra:
- Minden olyan alkalmazás, amely támogatja az MCP-integrációt, például a GitHub Copilot Csevegőügynök mód a Visual Studio Code-ban vagy a GitHub Codespacesben.
- Egy egyéni ügynök, amely egy MCP-ügyféllel fér hozzá a távoli eszközökhöz.
Ha mcp-kiszolgálót ad hozzá a webalkalmazáshoz, lehetővé teszi az ügynök számára az alkalmazás képességeinek megértését és használatát, amikor az válaszol a felhasználói kérésekre. Ez azt jelenti, hogy az alkalmazás bármit megtehet, az ügynök is.
- Adjon hozzá egy MCP-kiszolgálót a webalkalmazáshoz.
- Tesztelje az MCP-kiszolgálót helyileg a GitHub Copilot Csevegőügynök módban.
- Telepítse az MCP-kiszolgálót az Azure App Service-ben, és csatlakozzon hozzá a GitHub Copilot Chatben.
Előfeltételek
Ez az oktatóanyag feltételezi, hogy a Python FastAPI-webalkalmazás üzembe helyezéséhez használt mintával dolgozik a PostgreSQL-ben az Azure-ban.
Legalább nyissa meg a mintaalkalmazást a GitHub Codespacesben, és futtassa azd upaz alkalmazást.
MCP-kiszolgáló hozzáadása a webalkalmazáshoz
A kódtérkezelőben nyissa meg az src/pyproject.toml fájlt, adja hozzá
mcp[cli]a függőségek listájához az alábbi példában látható módon:dependencies = [ ... "mcp[cli]", ]Az src/fastapi_app hozzon létre egy mcp_server.py nevű fájlt, és illessze be a következő MCP-kiszolgáló inicializálási kódját a fájlba:
import asyncio import contextlib from contextlib import asynccontextmanager from mcp.server.fastmcp import FastMCP from sqlalchemy.sql import func from sqlmodel import Session, select from .models import Restaurant, Review, engine # Create a FastMCP server. Use stateless_http=True for simple mounting. Default path is .../mcp mcp = FastMCP("RestaurantReviewsMCP", stateless_http=True) # Lifespan context manager to start/stop the MCP session manager with the FastAPI app @asynccontextmanager async def mcp_lifespan(app): async with contextlib.AsyncExitStack() as stack: await stack.enter_async_context(mcp.session_manager.run()) yield # MCP tool: List all restaurants with their average rating and review count @mcp.tool() async def list_restaurants_mcp() -> list[dict]: """List restaurants with their average rating and review count.""" def sync(): with Session(engine) as session: statement = ( select( Restaurant, func.avg(Review.rating).label("avg_rating"), func.count(Review.id).label("review_count"), ) .outerjoin(Review, Review.restaurant == Restaurant.id) .group_by(Restaurant.id) ) results = session.exec(statement).all() rows = [] for restaurant, avg_rating, review_count in results: r = restaurant.dict() r["avg_rating"] = float(avg_rating) if avg_rating is not None else None r["review_count"] = review_count r["stars_percent"] = ( round((float(avg_rating) / 5.0) * 100) if review_count > 0 and avg_rating is not None else 0 ) rows.append(r) return rows return await asyncio.to_thread(sync) # MCP tool: Get a restaurant and all its reviews by restaurant_id @mcp.tool() async def get_details_mcp(restaurant_id: int) -> dict: """Return the restaurant and its related reviews as objects.""" def sync(): with Session(engine) as session: restaurant = session.exec(select(Restaurant).where(Restaurant.id == restaurant_id)).first() if restaurant is None: return None reviews = session.exec(select(Review).where(Review.restaurant == restaurant_id)).all() return {"restaurant": restaurant.dict(), "reviews": [r.dict() for r in reviews]} return await asyncio.to_thread(sync) # MCP tool: Create a new review for a restaurant @mcp.tool() async def create_review_mcp(restaurant_id: int, user_name: str, rating: int, review_text: str) -> dict: """Create a new review for a restaurant and return the created review dict.""" def sync(): with Session(engine) as session: review = Review() review.restaurant = restaurant_id review.review_date = __import__("datetime").datetime.now() review.user_name = user_name review.rating = int(rating) review.review_text = review_text session.add(review) session.commit() session.refresh(review) return review.dict() return await asyncio.to_thread(sync) # MCP tool: Create a new restaurant @mcp.tool() async def create_restaurant_mcp(restaurant_name: str, street_address: str, description: str) -> dict: """Create a new restaurant and return the created restaurant dict.""" def sync(): with Session(engine) as session: restaurant = Restaurant() restaurant.name = restaurant_name restaurant.street_address = street_address restaurant.description = description session.add(restaurant) session.commit() session.refresh(restaurant) return restaurant.dict() return await asyncio.to_thread(sync)A FastMCP() inicializáló egy MCP-kiszolgálót hoz létre az MCP Python SDK állapot nélküli módmintájának használatával. Alapértelmezés szerint a streamelhető HTTP-végpontja a
/mcpmellékútra van állítva.- A
@mcp.tool()dekoratőr egy eszközt ad hozzá az MCP-kiszolgálóhoz annak implementálásával. - Az eszközfüggvény leírása segít a hívóügynöknek megérteni az eszköz és paramétereinek használatát.
Az eszközök duplikálják a meglévő étterem felülvizsgálati funkcióit az űrlapalapú FastAPI-webalkalmazásban. Ha szeretné, további eszközöket is hozzáadhat a frissítési és törlési funkciókhoz.
- A
Az src/fastapi_app/app.py területen keresse meg a (24. sor) sorát
app = FastAPI(), és cserélje le a következő kódra:from .mcp_server import mcp, mcp_lifespan app = FastAPI(lifespan=mcp_lifespan) app.mount("/mcp", mcp.streamable_http_app())Ez a kód csatlakoztatja az MCP-kiszolgáló streamelhető HTTP-végpontját a meglévő FastAPI-alkalmazáshoz az elérési úton
/mcp. A streamelhető HTTP-végpont alapértelmezett elérési útjával együtt a teljes elérési út is ./mcp/mcp
Az MCP-kiszolgáló helyi tesztelése
A kódtér termináljában futtassa az alkalmazást a következő parancsokkal:
python3 -m venv .venv source .venv/bin/activate pip install -r src/requirements.txt pip install -e src python3 src/fastapi_app/seed_data.py python3 -m uvicorn fastapi_app:app --reload --port=8000Válassza a Megnyitás böngészőben lehetőséget, majd adjon hozzá néhány éttermet és véleményt.
Hagyja futni
uvicorn. Az MCP-kiszolgáló jelenleghttp://localhost:8000/mcp/mcpfut.A kódtérben nyissa meg a Copilot-csevegést, majd válassza az Ügynök mód lehetőséget a parancssorban.
Válassza az Eszközök gombot, majd válassza az MCP-kiszolgáló hozzáadása ikont az előugró ablak jobb felső sarkában.
Válassza a HTTP (HTTP vagy Server-Sent események) lehetőséget.
Írja be az Enter Server URL-címéthttp://localhost:8000/mcp/mcp.
Az Enter Server ID mezőbe írja be a restaurant_ratings vagy a kívánt nevet.
Válassza a Munkaterület beállításai lehetőséget.
Egy új Copilot-csevegőablakban írja be a következőt: "Show me the restaurant ratings".
Alapértelmezés szerint a GitHub Copilot biztonsági megerősítést jelenít meg egy MCP-kiszolgáló meghívásakor. Válassza a Folytatáslehetőséget.
Ekkor megjelenik egy válasz, amely azt jelzi, hogy az MCP-eszköz hívása sikeres.
Az MCP-kiszolgáló üzembe helyezése az App Service-ben
A kódtér termináljába visszatérve telepítse a módosításokat a módosítások véglegesítésével (GitHub Actions metódus) vagy futtassa
azd up(Azure Developer CLI-metódus).Az AZD-kimenetben keresse meg az alkalmazás URL-címét. Az URL-cím így néz ki az AZD-kimenetben:
Deploying services (azd deploy) (✓) Done: Deploying service web - Endpoint: <app-url>
A befejezés után
azd upnyissa meg a .vscode/mcp.json. Módosítsa az URL-címet a következőre<app-url>/mcp/mcp: .A módosított MCP-kiszolgáló konfigurációja felett válassza a Start lehetőséget.
Hozzon létre egy új GitHub Copilot-csevegőablakot. Meg kell tudnia tekinteni az éttermi minősítéseket, valamint új éttermeket és új minősítéseket kell létrehoznia a Copilot ügynökben.
Ajánlott biztonsági eljárások
Ha az MCP-kiszolgálót nagy nyelvi modellekkel (LLM) rendelkező ügynök hívja meg, vegye figyelembe a gyors injektálási támadásokat. Vegye figyelembe az alábbi ajánlott biztonsági eljárásokat:
- Hitelesítés és engedélyezés: Az MCP-kiszolgáló védelme Microsoft Entra-hitelesítéssel annak biztosítása érdekében, hogy csak a jogosult felhasználók vagy ügynökök férhessenek hozzá az eszközeihez. Részletes útmutatót a Visual Studio Code-ból az Azure App Service-be irányuló Biztonságos modell környezeti protokoll hívásai a Microsoft Entra-hitelesítéssel című témakörben talál.
- Bemenet-ellenőrzés és -tisztítás: Mindig ellenőrizze a bejövő adatokat az érvénytelen vagy rosszindulatú bemenetek elkerülése érdekében. Python-alkalmazások esetén a Pydantichez hasonló kódtárak használatával kényszerítse ki az adatérvényesítési szabályokat dedikált bemeneti modellekkel (például RestaurantCreate és ReviewCreate). Az ajánlott eljárásokról és a megvalósítás részleteiről a dokumentációban olvashat.
- HTTPS: A minta az Azure App Service-ra támaszkodik, amely alapértelmezés szerint kényszeríti a HTTPS-t, és ingyenes TLS-/SSL-tanúsítványokat biztosít az átvitel közbeni adatok titkosításához.
- Minimális jogosultság elve: Csak a használati esethez szükséges eszközöket és adatokat tegye elérhetővé. Ha szükséges, kerülje a bizalmas műveletek felfedését.
- Sebességkorlátozás és szabályozás: Az API Management vagy az egyéni köztes szoftver használata a visszaélések és a szolgáltatásmegtagadásos támadások megelőzésére.
- Naplózás és figyelés: Az MCP-végpontok naplóhozzáférése és használata naplózáshoz és anomáliadetektáláshoz. Gyanús tevékenységek figyelése.
- CORS-konfiguráció: Ha az MCP-kiszolgáló böngészőkből érhető el, korlátozza a forrásközi kérelmeket megbízható tartományokra. További információ: CORS engedélyezése.
- Rendszeres frissítések: A függőségek naprakészen tartása az ismert biztonsági rések csökkentése érdekében.