إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
في هذا البرنامج التعليمي، ستتعلم كيفية عرض وظائف تطبيق FastAPI من خلال بروتوكول سياق النموذج (MCP)، وإضافتها كأداة إلى GitHub Copilot، والتفاعل مع تطبيقك باستخدام لغة طبيعية في وضع وكيل دردشة Copilot.
إذا كان تطبيق الويب الخاص بك يحتوي بالفعل على ميزات مفيدة، مثل التسوق أو حجز الفنادق أو إدارة البيانات، فمن السهل إتاحة هذه الإمكانات من أجل:
- أي تطبيق يدعم تكامل MCP، مثل وضع عامل الدردشة GitHub Copilot في Visual Studio Code أو في GitHub Codespaces.
- عامل مخصص يصل إلى الأدوات البعيدة باستخدام عميل MCP.
من خلال إضافة خادم MCP إلى تطبيق الويب الخاص بك، فإنك تمكن الوكيل من فهم إمكانات تطبيقك واستخدامها عندما يستجيب لمطالبات المستخدم. هذا يعني أن أي شيء يمكن أن يفعله تطبيقك ، يمكن للوكيل القيام به أيضا.
- أضف خادم MCP إلى تطبيق الويب الخاص بك.
- اختبر خادم MCP محليا في وضع عامل الدردشة GitHub Copilot.
- انشر خادم MCP إلى Azure App Service واتصل به في GitHub Copilot Chat.
المتطلبات
يفترض هذا البرنامج التعليمي أنك تعمل مع النموذج المستخدم في نشر تطبيق ويب Python FastAPI باستخدام PostgreSQL في Azure.
كحد أدنى، افتح نموذج التطبيق في GitHub Codespaces ونشر التطبيق عن طريق تشغيل azd up.
إضافة خادم MCP إلى تطبيق الويب الخاص بك
في مستكشف مساحة التعليمات البرمجية، افتح src/pyproject.toml، وأضفه
mcp[cli]إلى قائمة التبعيات، كما هو موضح في المثال التالي:dependencies = [ ... "mcp[cli]", ]في src/fastapi_app، قم بإنشاء ملف يسمى mcp_server.py والصق التعليمات البرمجية التالية لتهيئة خادم MCP في الملف:
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)يقوم مهيئ FastMCP() بإنشاء خادم MCP باستخدام نمط الوضع عديم الحالة في MCP Python SDK. بشكل افتراضي، يتم تعيين نقطة نهاية HTTP القابلة للبث إلى المسار الفرعي
/mcp.-
@mcp.tool()يضيف الديكور أداة إلى خادم MCP مع تنفيذه. - يساعد وصف وظيفة الأداة وكيل الاتصال على فهم كيفية استخدام الأداة ومعلماتها.
تقوم الأدوات بتكرار وظيفة مراجعات المطاعم الحالية في تطبيق الويب FastAPI المستند إلى النموذج. إذا كنت ترغب في ذلك ، يمكنك إضافة المزيد من الأدوات لوظيفة التحديث والحذف.
-
في src/fastapi_app/app.py، أوجد السطر (
app = FastAPI()السطر 24) واستبدله بالرمز التالي:from .mcp_server import mcp, mcp_lifespan app = FastAPI(lifespan=mcp_lifespan) app.mount("/mcp", mcp.streamable_http_app())تقوم هذه التعليمات البرمجية بتحميل نقطة نهاية HTTP القابلة للبث لخادم MCP إلى تطبيق FastAPI الحالي في المسار
/mcp. جنبا إلى جنب مع المسار الافتراضي لنقطة نهاية HTTP القابلة للدفق، يكون المسار الكامل هو/mcp/mcp.
اختبار خادم MCP محليا
في محطة codespace، قم بتشغيل التطبيق باستخدام الأوامر التالية:
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=8000حدد فتح في المتصفح، ثم أضف بعض المطاعم والمراجعات.
اترك
uvicornالجري. خادم MCP الخاص بك قيد التشغيلhttp://localhost:8000/mcp/mcpالآن.مرة أخرى في مساحة التعليمات البرمجية، افتح دردشة Copilot، ثم حدد وضع الوكيل في مربع المطالبة.
حدد الزر "أدوات "، ثم حدد أيقونة إضافة خادم MCP في الزاوية العلوية اليمنى من النافذة المنبثقة.
حدد HTTP (HTTP أو أحداث Server-Sent).
في إدخال عنوان URL للخادم، اكتب http://localhost:8000/mcp/mcp.
في إدخال معرف الخادم، اكتب restaurant_ratings أو أي اسم تريده.
حدد إعدادات مساحة العمل.
في نافذة دردشة مساعد الطيار الجديدة، اكتب شيئا مثل "أرني تقييمات المطعم".
بشكل افتراضي، يعرض لك GitHub Copilot تأكيدا أمنيا عند استدعاء خادم MCP. حدد متابعة.
يجب أن ترى الآن استجابة تشير إلى نجاح استدعاء أداة MCP.
نشر خادم MCP الخاص بك إلى App Service
مرة أخرى في المحطة الطرفية لمساحة التعليمات البرمجية، انشر التغييرات عن طريق تنفيذ التغييرات (أسلوب GitHub Actions) أو قم بتشغيل
azd up(أسلوب Azure Developer CLI).في إخراج AZD ، ابحث عن عنوان URL لتطبيقك. يبدو عنوان URL كما يلي في إخراج AZD:
Deploying services (azd deploy) (✓) Done: Deploying service web - Endpoint: <app-url>
بمجرد
azd upالانتهاء ، افتح .vscode/mcp.json. قم بتغيير عنوان URL إلى<app-url>/mcp/mcp.أعلى تكوين خادم MCP المعدل، حدد ابدأ.
ابدأ نافذة دردشة GitHub Copilot جديدة. يجب أن تكون قادرا على عرض تقييمات المطاعم ، بالإضافة إلى إنشاء مطاعم جديدة وتقييمات جديدة في وكيل Copilot.
أفضل الممارسات الأمنية
عندما يتم استدعاء خادم MCP الخاص بك بواسطة وكيل مدعوم بنماذج لغوية كبيرة (LLM)، كن على دراية بهجمات الحقن الفوري . ضع في اعتبارك أفضل ممارسات الأمان التالية:
- المصادقة والتفويض: قم بتأمين خادم MCP الخاص بك باستخدام مصادقة Microsoft Entra لضمان وصول المستخدمين أو الوكلاء المصرح لهم فقط إلى أدواتك. انظر استدعاءات بروتوكول السياق الآمن إلى Azure App Service من Visual Studio Code with Microsoft Entra Authentication للحصول على دليل خطوة بخطوة.
- التحقق من صحة الإدخال والتعقيم: تحقق دائما من صحة البيانات الواردة لمنع الإدخال غير الصالح أو الضار. بالنسبة لتطبيقات Python، استخدم مكتبات مثل Pydantic لفرض قواعد التحقق من صحة البيانات باستخدام نماذج إدخال مخصصة (مثل RestaurantCreate وReviewCreate). راجع وثائقهم للحصول على أفضل الممارسات وتفاصيل التنفيذ.
- HTTPS: يعتمد النموذج على Azure App Service، الذي يفرض HTTPS بشكل افتراضي ويوفر شهادات TLS/SSL مجانية لتشفير البيانات أثناء النقل.
- مبدأ الامتياز الأقل: اعرض فقط الأدوات والبيانات الضرورية المطلوبة لحالة الاستخدام الخاصة بك. تجنب تعريض العمليات الحساسة إلا إذا لزم الأمر.
- تحديد المعدل والتقييد: استخدم إدارة واجهة برمجة التطبيقات أو البرامج الوسيطة المخصصة لمنع هجمات إساءة الاستخدام ورفض الخدمة.
- التسجيل والمراقبة: الوصول إلى السجل واستخدام نقاط نهاية MCP للتدقيق واكتشاف الحالات الشاذة. مراقبة النشاط المشبوه.
- تكوين CORS: تقييد الطلبات عبر الأصل بالمجالات الموثوق بها إذا تم الوصول إلى خادم MCP الخاص بك من المستعرضات. لمزيد من المعلومات، راجع تمكين CORS.
- تحديثات منتظمة: حافظ على تحديث تبعياتك للتخفيف من الثغرات الأمنية المعروفة.