چگونه MCP Server شخصی روی VPS راه‌اندازی کنیم؟

چگونه MCP Server شخصی روی VPS راه‌اندازی کنیم؟

جدول محتوا 👇

MCP Server به ایجنت‌ها و دستیارهای هوش مصنوعی اجازه می‌دهد از ابزارها و داده‌های شما استفاده کنند. اگر می‌خواهید چند نفر از تیم یا یک ایجنت همیشه فعال از همان ابزارها استفاده کنند، باید MCP Server را روی یک سرور اجرا کنید، نه روی لپ‌تاپ. در این آموزش یک MCP Server شخصی روی VPS با پایتون می‌سازیم، آن را به‌صورت سرویس دائمی اجرا می‌کنیم، پشت Nginx با HTTPS و احراز هویت قرار می‌دهیم و به کلاینت وصل می‌کنیم.

معماری و پیش‌نیازها

اگر با مفاهیم MCP آشنا نیستید، ابتدا MCP Server چیست را بخوانید. معماری این آموزش:

  • MCP Server با SDK رسمی پایتون، با روش ارتباط Streamable HTTP، فقط روی 127.0.0.1 گوش می‌دهد.
  • Nginx جلوی آن قرار می‌گیرد، HTTPS را مدیریت می‌کند و درخواست‌های بدون توکن معتبر را رد می‌کند.
  • سرویس با کاربر جداگانه و محدود و تحت systemd اجرا می‌شود.

پیش‌نیازها: یک VPS با Ubuntu، یک ساب‌دامنه مثل mcp.example.com که به IP سرور اشاره کند، و تنظیمات امنیتی پایه VPS.

گام ۱: آماده‌سازی سرور و محیط پایتون

sudo adduser --system --group --home /opt/mcp mcp
sudo apt install -y python3-venv
sudo -u mcp python3 -m venv /opt/mcp/venv
sudo -u mcp /opt/mcp/venv/bin/pip install "mcp[cli]"

کاربر mcp یک کاربر سیستمی بدون دسترسی sudo است. اگر ابزارها روزی مورد سوءاستفاده قرار بگیرند، آسیب به همین کاربر محدود می‌ماند.

گام ۲: نوشتن MCP Server

فایل /opt/mcp/server.py را بسازید. در این مثال دو ابزار فقط‌خواندنی برای پایش سرور تعریف می‌کنیم:

import os
import shutil
import subprocess

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("server-tools", host="127.0.0.1", port=8100)

ALLOWED_SERVICES = {"nginx", "postgresql", "docker"}


@mcp.tool()
def disk_usage(path: str = "/") -> str:
    """فضای کل، استفاده‌شده و آزاد دیسک را برای یک مسیر برمی‌گرداند."""
    total, used, free = shutil.disk_usage(path)
    gb = 1024 ** 3
    return f"کل {total // gb} GB، استفاده‌شده {used // gb} GB، آزاد {free // gb} GB"


@mcp.tool()
def service_status(name: str) -> str:
    """وضعیت یکی از سرویس‌های مجاز (nginx، postgresql، docker) را برمی‌گرداند."""
    if name not in ALLOWED_SERVICES:
        return f"سرویس {name} مجاز نیست. سرویس‌های مجاز: {', '.join(sorted(ALLOWED_SERVICES))}"
    result = subprocess.run(
        ["systemctl", "is-active", name], capture_output=True, text=True, timeout=5
    )
    return f"{name}: {result.stdout.strip()}"


@mcp.tool()
def load_average() -> str:
    """میانگین بار پردازنده در ۱، ۵ و ۱۵ دقیقه اخیر را برمی‌گرداند."""
    one, five, fifteen = os.getloadavg()
    return f"بار: {one:.2f} / {five:.2f} / {fifteen:.2f}"


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

چند اصل که در این کد رعایت شده است:

  • فهرست سفید: ابزار service_status فقط نام سرویس‌های مشخص را می‌پذیرد. ورودی مدل هرگز مستقیم به شل داده نمی‌شود.
  • بدون shell=True: دستور به‌صورت لیست آرگومان اجرا می‌شود تا تزریق دستور ممکن نباشد.
  • Timeout: هیچ ابزاری نباید بی‌پایان منتظر بماند.
  • توضیح دقیق: مدل بر اساس Docstring هر ابزار تصمیم می‌گیرد کی از آن استفاده کند.

گام ۳: تست محلی با MCP Inspector

سرور را اجرا کنید:

sudo -u mcp /opt/mcp/venv/bin/python /opt/mcp/server.py

MCP Inspector یک ابزار رسمی برای مشاهده و آزمایش ابزارهای یک MCP Server است. روی کامپیوتر خودتان (با Node.js) یک تونل SSH بزنید و Inspector را اجرا کنید:

ssh -L 8100:127.0.0.1:8100 admin@SERVER_IP
npx @modelcontextprotocol/inspector

در رابط Inspector، نوع اتصال را Streamable HTTP و آدرس را http://127.0.0.1:8100/mcp وارد کنید. باید سه ابزار را ببینید و بتوانید آن‌ها را اجرا کنید.

گام ۴: اجرای دائمی با systemd

فایل /etc/systemd/system/mcp-server.service:

[Unit]
Description=MCP Server
After=network-online.target

[Service]
User=mcp
Group=mcp
WorkingDirectory=/opt/mcp
ExecStart=/opt/mcp/venv/bin/python /opt/mcp/server.py
Restart=always
RestartSec=5
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-server
sudo journalctl -u mcp-server -f

تنظیمات ProtectSystem و ProtectHome فایل‌سیستم را برای این سرویس فقط‌خواندنی می‌کنند. اگر ابزاری باید در جایی بنویسد، آن مسیر را با ReadWritePaths مجاز کنید. الگوهای بیشتر برای اجرای پایدار سرویس‌ها در اجرای ۲۴ ساعته AI Agent روی VPS.

گام ۵: Nginx، HTTPS و احراز هویت

یک توکن تصادفی بسازید و پیکربندی Nginx را بنویسید:

openssl rand -hex 32
server {
    listen 443 ssl;
    http2 on;
    server_name mcp.example.com;

    ssl_certificate     /etc/letsencrypt/live/mcp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mcp.example.com/privkey.pem;

    location /mcp {
        if ($http_authorization != "Bearer YOUR_RANDOM_TOKEN") { return 401; }

        proxy_pass http://127.0.0.1:8100;
        proxy_http_version 1.1;
        proxy_set_header Host 127.0.0.1:8100;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }

    location / { return 404; }
}
sudo certbot certonly --nginx -d mcp.example.com
sudo nginx -t && sudo systemctl reload nginx
  • proxy_buffering off برای پاسخ‌های جریانی (Streaming) لازم است.
  • هدر Host به آدرس داخلی تنظیم شده، چون SDK برای جلوگیری از حملات DNS Rebinding ممکن است درخواست‌هایی با Host ناشناخته را رد کند.
  • توکن ثابت برای استفاده شخصی یا تیم کوچک کافی است. برای کاربران متعدد، مشخصات MCP احراز هویت OAuth را پیش‌بینی کرده است.

اگر کاربران از IP ثابت یا VPN وصل می‌شوند، با allow و deny در Nginx دسترسی را به همان IPها هم محدود کنید.

گام ۶: اتصال کلاینت

در کلاینت‌هایی که از MCP Server راه دور با HTTP پشتیبانی می‌کنند، آدرس https://mcp.example.com/mcp و هدر Authorization: Bearer YOUR_RANDOM_TOKEN را وارد کنید. ساختار تنظیمات در هر کلاینت متفاوت است؛ مثلاً در برخی ویرایشگرهای کد به این شکل است:

{
  "servers": {
    "server-tools": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_RANDOM_TOKEN" }
    }
  }
}

کلاینت‌هایی که فقط از stdio پشتیبانی می‌کنند، می‌توانند از یک پل محلی مثل بسته mcp-remote برای اتصال به سرور راه دور استفاده کنند. در پلتفرم‌های ایجنت مثل n8n هم نود MCP Client Tool همین آدرس و هدر را می‌پذیرد.

سخت‌سازی و نگهداری

  • ابزارهای نوشتنی را با احتیاط اضافه کنید. ابزاری که داده را تغییر می‌دهد یا دستور اجرا می‌کند، باید ورودی محدود و در کلاینت تأیید انسانی داشته باشد.
  • هر ابزار با کمترین دسترسی: برای ابزارهای دیتابیس، کاربر فقط‌خواندنی بسازید.
  • ثبت فراخوانی‌ها: نام ابزار و ورودی هر فراخوانی را لاگ کنید.
  • نسخه SDK را ثابت کنید و پیش از به‌روزرسانی، تغییرات را بخوانید؛ مشخصات MCP همچنان در حال تکامل است.
  • توکن را دوره‌ای تغییر دهید و در صورت نشت، فوراً باطل کنید.

تهدیدهای خاص ایجنت‌ها، مثل Prompt Injection و Tool Poisoning، و راهکارهای آن‌ها در امنیت MCP Server و AI Agentها آمده است.

سوالات متداول

آیا می‌توان از راه دور به MCP Server وصل شد؟

بله. با روش Streamable HTTP، MCP Server به‌صورت سرویس شبکه اجرا می‌شود. آن را حتماً پشت HTTPS و احراز هویت قرار دهید. روش قدیمی‌تر HTTP+SSE هنوز در برخی کلاینت‌ها پشتیبانی می‌شود، اما برای سرورهای جدید Streamable HTTP توصیه می‌شود.

MCP Server چقدر منابع مصرف می‌کند؟

خود سرور بسیار سبک است و چند ده مگابایت RAM مصرف می‌کند. منابع واقعی به کاری که ابزارها انجام می‌دهند بستگی دارد. یک VPS کوچک برای چند MCP Server کافی است.

آیا می‌توانم MCP Server را با Docker اجرا کنم؟

بله، و برای ایزوله‌سازی بیشتر توصیه می‌شود. پورت کانتینر را فقط روی 127.0.0.1 منتشر کنید و کانتینر را با کاربر غیر root اجرا کنید. نکات آن در امنیت Docker.

ابزار من دیده می‌شود اما مدل از آن استفاده نمی‌کند. چرا؟

معمولاً توضیح ابزار به‌اندازه کافی روشن نیست یا مدل از Tool Calling به‌خوبی پشتیبانی نمی‌کند. در Docstring دقیقاً بنویسید ابزار چه کاری انجام می‌دهد و برای چه سوال‌هایی مناسب است.

سرور پایدار برای ابزارهای هوش مصنوعی

MCP Serverهای خود را روی سرورهای مجازی تراست هاست با IP ثابت اجرا کنید و با شبکه خصوصی به سرویس‌های داخلی وصل شوید.

سرور مجازی ابری تراست هاست

مشاوره تراست‌هاست​

با متخصصان و کارشناسان به صورت رایگان!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *