درس ۱۸ از ۳۳

Roots

عنوان اصلی: Roots

هدف یادگیری: استفاده از roots تا یک server بداند کدام دایرکتوری یا workspace اجازه عملیات دارد.

مفاهیم کلیدی: capability roots، roots/list، notifications/roots/list_changed، الزام URI به‌صورت file://، دفاع در برابر path traversal.

Roots مسئله «کجا اجازه read/write دارم؟» را برای serverهای filesystem-like حل می‌کند. Client capability roots را اعلام می‌کند و می‌تواند listChanged: true ست کند. Server roots/list را صدا می‌زند (این یکی از تنها requestهای server-to-client به‌علاوه sampling و elicitation است) و یک آرایه از { uri, name } می‌گیرد، که هر uri در spec فعلی باید یک URI به‌صورت file:// باشد. سرورها بهتر است تمام عملیات filesystem را به rootهای برگشتی محدود کنند و بهتر است به notifications/roots/list_changed گوش بدهند تا refresh کنند.

این همان روشی است که Claude Code/Cursor به Filesystem MCP server می‌گویند: «اجازه داری روی /home/user/projects/myapp کار کنی و نه چیز دیگر». اگر یک server خارج از rootهایش بخواند، یا bug است یا نقض امنیت.

مثال عملی — JSON خام (request و response)

{ "jsonrpc": "2.0", "id": 1, "method": "roots/list" }
{ "jsonrpc": "2.0", "id": 1,
  "result": { "roots": [
    { "uri": "file:///home/user/repos/frontend", "name": "Frontend Repository" },
    { "uri": "file:///home/user/repos/backend",  "name": "Backend Repository" }
  ] } }

اشتباهات رایج

  • صدا زدن roots/list بدون چک اینکه client capability را اعلام کرده — -32601 Method not found می‌گیرید.
  • اعتبارسنجی نکردن سمت server که path ورودی داخل یکی از rootهای اعلام‌شده است. حملات path traversal (../../../etc/passwd) واقعی هستند.
  • cache کردن لیست roots برای همیشه. روی notifications/roots/list_changed دوباره fetch کنید.