MCP clients
عنوان اصلی: MCP clients
هدف یادگیری: شناسایی مسئولیتهای یک MCP client و آشنایی با اکوسیستم client موجود.
مفاهیم کلیدی: client lifecycle، capability negotiation، request/response correlation، notification handling، host integration.
Client مولفهای داخل host است که یک اتصال را مالک است. مسئولیتهایش: راهاندازی یا اتصال به serverش، اجرای handshake به نام initialize، اعلام capabilityهای host (roots، sampling، elicitation)، دریافت capabilityهای اعلامشده server (tools، resources، prompts، logging، completions)، صدا زدن tools/list/resources/list/prompts/list برای پر کردن UI host، route کردن تصمیم tool-call مدل به tools/call، گوش دادن به notifications/tools/list_changed (و معادلهای resource و prompt) برای sync نگه داشتن state، و shutdown تمیز.
اکوسیستم client موجود شامل Claude Desktop، Claude Code، Cursor، VS Code (با extensionهای Claude Code یا Continue)، Zed، Cline و فهرست رو به رشدی از IDEهای agentic است. هر UI، primitiveها را متفاوت surface میکند: Claude Desktop ابزارها را بهعنوان function قابل فراخوانی مدل و prompts را بهعنوان slash command نمایش میدهد؛ Cursor، resources را بهصورت @-mentionable context نشان میدهد.
مثال عملی — Python (SDK رسمی، minimal client)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from pydantic import AnyUrl
server_params = StdioServerParameters(
command="uv",
args=["run", "server", "fastmcp_quickstart", "stdio"],
)
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print(f"Available tools: {[t.name for t in tools.tools]}")
result = await session.call_tool("add", arguments={"a": 5, "b": 3})
print(f"Tool result: {result.content[0].text}")
content = await session.read_resource(AnyUrl("greeting://World"))
print(f"Resource: {content.contents[0].text}")
asyncio.run(run())
دیاگرام معماری (متنی): یک جعبه «Client» که داخلش به چهار خط تقسیم شده: «Lifecycle Manager»، «Request Router»، «Notification Listener»، «Capability Registry». فلشهای خروجی به Server میروند؛ فلشهای ورودی از Server به Notification Listener میخورند.
اشتباهات رایج
- ارسال requestهایی غیر از
pingقبل از اینکه server بهinitializeپاسخ بدهد. - فراموش کردن handle کردن
notifications/tools/list_changed— لیست tool داخل client کهنه میشود. - رفتار با notification مثل request (notificationها
idندارند و هیچوقت پاسخ نمیگیرند).