MCP ومهارات الوكيل
بناء خوادم MCP
4 دقيقة للقراءة
بناء خادم MCP يتيح لك كشف أي وظيفة—APIs، قواعد بيانات، منطق مخصص—لنماذج الذكاء الاصطناعي. لنبنِ واحداً من الصفر.
خادم MCP أدنى (Python)
# server.py
from mcp.server import Server
from mcp.types import Tool, TextContent
app = Server("my-tools")
@app.list_tools()
async def list_tools():
return [
Tool(
name="greet",
description="توليد تحية",
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "الاسم للتحية"}
},
"required": ["name"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "greet":
return [TextContent(type="text", text=f"مرحباً، {arguments['name']}!")]
raise ValueError(f"أداة غير معروفة: {name}")
if __name__ == "__main__":
import asyncio
from mcp.server.stdio import stdio_server
asyncio.run(stdio_server(app))
تشغيل خادمك
# تثبيت MCP SDK
pip install mcp
# تشغيل مباشر
python server.py
# أو استخدم مع Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"my-tools": {
"command": "python",
"args": ["server.py"]
}
}
}
إضافة الموارد
كشف البيانات التي يمكن للنموذج قراءتها:
from mcp.types import Resource
@app.list_resources()
async def list_resources():
return [
Resource(
uri="config://settings",
name="إعدادات التطبيق",
mimeType="application/json"
)
]
@app.read_resource()
async def read_resource(uri: str):
if uri == "config://settings":
return json.dumps({"theme": "dark", "language": "ar"})
raise ValueError(f"مورد غير معروف: {uri}")
إضافة البرومبتات
قوالب برومبت قابلة لإعادة الاستخدام:
from mcp.types import Prompt, PromptArgument
@app.list_prompts()
async def list_prompts():
return [
Prompt(
name="explain_code",
description="شرح الكود بمصطلحات بسيطة",
arguments=[
PromptArgument(name="language", description="لغة البرمجة"),
PromptArgument(name="level", description="مستوى الخبرة")
]
)
]
@app.get_prompt()
async def get_prompt(name: str, arguments: dict):
if name == "explain_code":
return {
"messages": [{
"role": "user",
"content": f"اشرح هذا الكود {arguments['language']} لمطور {arguments['level']}."
}]
}
مثال عملي: خادم MCP لقاعدة البيانات
import asyncpg
from mcp.server import Server
from mcp.types import Tool, TextContent
app = Server("postgres-tools")
pool = None
async def get_pool():
global pool
if pool is None:
pool = await asyncpg.create_pool("postgresql://localhost/mydb")
return pool
@app.list_tools()
async def list_tools():
return [
Tool(
name="query_database",
description="تنفيذ استعلام SQL للقراءة فقط",
inputSchema={
"type": "object",
"properties": {
"sql": {"type": "string", "description": "استعلام SQL SELECT"}
},
"required": ["sql"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "query_database":
sql = arguments["sql"]
# الأمان: السماح فقط بـ SELECT
if not sql.strip().upper().startswith("SELECT"):
return [TextContent(type="text", text="خطأ: استعلامات SELECT فقط مسموحة")]
pool = await get_pool()
async with pool.acquire() as conn:
rows = await conn.fetch(sql)
result = [dict(row) for row in rows]
return [TextContent(type="text", text=json.dumps(result, indent=2))]
بديل TypeScript
// server.ts
import { Server } from "@modelcontextprotocol/sdk/server";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";
const server = new Server({
name: "my-tools",
version: "1.0.0"
});
server.setRequestHandler("tools/list", async () => ({
tools: [{
name: "calculate",
description: "إجراء حسابات",
inputSchema: {
type: "object",
properties: {
expression: { type: "string" }
}
}
}]
}));
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "calculate") {
const result = eval(request.params.arguments.expression);
return { content: [{ type: "text", text: String(result) }] };
}
});
new StdioServerTransport(server).start();
ملاحظة نيردية: أبقِ خوادم MCP مركزة. خادم واحد لقاعدة البيانات، آخر لعمليات الملفات. القابلية للتركيب تتفوق على المونوليث.
التالي: بناء مهارات وكيل قابلة للتوسيع. :::