Главная / Статьи

Построение масштабируемых безсостоянийных серверов MCP 2026 (технический разбор)

Пошаговое руководство по созданию масштабируемых серверов MCP 2026 без состояния (технический разбор): контракты, проверки и готовые блоки кода для команд, использующих эту архитектурную схему.

Издатель: REACTAPP.TOP11 мин чтения2446 слов

Источники: Stateless Model Context Protocol: Building Scalable MCP 2026 Specification Servers (Technical Deepdive)

Используйте это как переработанную версию идей из документа «Stateless Model Context Protocol: Building Scalable MCP 2026 Specification Servers (Technical Deepdive)», ориентированную на операторов: четкие этапы, упорядоченные блоки кода и записи о восстановлении, сохраняющиеся при передаче задач. Этап Обзора работает наилучшим образом, если рассматриваться как измеримая основа. Сначала зафиксируйте один идеальный пример работы, один случай сбоя и записи о возврате к предыдущему состоянию, прежде чем расширять объем работ. Записывайте временные показатели, а также стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости на ранних этапах предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам.

Проблема состояний: почему MCP до 2026 года сталкивалась с трудностями при масштабировании

На этапе «Проблема состояний» необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг, исходя из известной точки контроля, без необходимости угадывать скрытое состояние. Конфигурацию следует хранить отдельно от кода приложения. Файлы среды, хранилища конфиденциальных данных и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь кодовый граф. При следующем шаге, представляющем собой код или вызов инструмента, следует предпочитать структурированные выходные данные с проверкой схемы вместо свободного текста.

+--------------------------------------------------------------------------+
|                       Pre-2026 Stateful Architecture                     |
|                                                                          |
|   +--------------+      WebSocket / SSE      +-----------------------+   |
|   | Client Agent | <=======================> | MCP Server Pod A      |   |
|   +--------------+    (Session Pinned)       | (In-Memory Session)   |   |
|                                              +-----------------------+   |
|                                                          |               |
|                                                    State Lookup          |
|                                                          v               |
|                                              +-----------------------+   |
|                                              | Central Redis Cache   |   |
|                                              +-----------------------+   |
+--------------------------------------------------------------------------+

Препятствия, связанные с аффинностью сессий

Для этапа «The Friction of Session» необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо одновременно задокументировать успешный сценарий выполнения и сценарий восстановления. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не этапом последующей доработки. При следующем шаге, представляющем собой код или вызов инструмента, следует отдавать предпочтение структурированным выводам с проверкой по схеме перед свободным текстовым описанием.

Внутренние механизмы MCP 2026–07–28: маршрутизация заголовков и самоописывающиеся RPC

Для этапа «Под капотом» необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Лучше использовать небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной функцией, а не с запутанной цепочкой операций. При следующем шаге, представляющем собой код или вызов инструмента, лучше использовать структурированные выводы с проверкой схемы вместо свободного текста. Для этапа «Под капотом» необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Регистрируйте время выполнения, а также стоимость токенов или запросов вместе с функциональными результатами. Отображение стоимости на раннем этапе предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам.

+--------------------------------------------------------------------------+
|                     MCP 2026-07-28 Stateless Architecture                |
|                                                                          |
|   +--------------+    HTTP POST (Self-Describing)    +---------------+   |
|   | Client Agent | --------------------------------> | Round-Robin   |   |
|   +--------------+   Headers: Mcp-Method, Mcp-Name   | Load Balancer |   |
|                                                      +---------------+   |
|                                                              |           |
|                                           Any Worker Pod     |           |
|                                       +----------------------+--------+  |
|                                       |                      |        |  |
|                                       v                      v        v  |
|                                  +--------+              +--------+ +---+|
|                                  | Pod 1  |              | Pod 2  | |...||
|                                  +--------+              +--------+ +---+|
+--------------------------------------------------------------------------+

Самоописывающийся JSON-RPC 2.0 с использованием _meta

При работе с механизмом самоописывающегося JSON-RPC 2.0 сначала запишите условия использования: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список поможет избежать ошибок при последующих изменениях кода. Храните конфигурацию вне кода приложения. Файлы с настройками окружения, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять без необходимости просматривать весь код. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных является распространенной причиной ресурсозатрат.

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "query_database",
    "arguments": {
      "query": "SELECT count(*) FROM users WHERE status = 'active';"
    }
  },
  "id": "req-98421",
  "_meta": {
    "protocolVersion": "2026-07-28",
    "clientInfo": {
      "name": "AutonomousAgentWorker",
      "version": "4.1.0"
    },
    "progressToken": "tok_998122",
    "traceContext": {
      "traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
    }
  }
}

Обязательные заголовки маршрутизации HTTP уровня 7

При работе над этапом обязательной маршрутизации HTTP на уровне 7 сначала запишите описание функционала: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Документируйте одновременно успешный сценарий работы и сценарий восстановления. Повторные попытки, проверки со стороны оператора и обработка некорректных сообщений являются частью продукта, а не элементами последующей доработки. Храните в кэше стабильные инструкции системы и схемы инструментов. Пересылка одинаковых заголовков — распространенная причина избыточных ресурсов.

Обнаружение серверов и интеллектуальный кэширование

При работе над этапами обнаружения серверов и интеллектуальной обработки сначала запишите условия взаимодействия: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые модули большим скриптам. Если какой-то шаг не сработает, причина должна быть связана с конкретной функцией, а не с запутанной цепочкой операций. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных — распространенная причина избыточных затрат. При работе над этапами обнаружения серверов и интеллектуальной обработки сначала запишите условия взаимодействия: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Регистрируйте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам.

{
  "jsonrpc": "2.0",
  "result": {
    "protocolVersion": "2026-07-28",
    "capabilities": {
      "tools": { "listChanged": false }
    },
    "serverInfo": {
      "name": "Scalable-Stateless-MCP-Server",
      "version": "2.0.0"
    },
    "cacheControl": {
      "ttlMs": 3600000,
      "cacheScope": "public"
    }
  },
  "id": "disc-001"
}

Создание производственного сервера без состояния: FastAPI, FastMCP 2.0 и OAuth 2.1

Этап создания производственного сервера без состояния работает наилучшим образом, если рассматривать его как измеримую основу. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код. Установите лимиты на количество токенов за одну операцию и за сессию. Инструменты-агенты активно расширяют объём контекста; жесткие ограничения предотвращают появление неожиданных счетов.

+-----------------------------------------------------------------------------+
|                       Stateless Request Dispatching                         |
|                                                                             |
|   Client Request w/ Bearer JWT                                              |
|   + Header: Mcp-Method: tools/call                                          |
|   + Header: Mcp-Name: query_database                                        |
|                                                                             |
|         │                                                                   |
|         ▼                                                                   |
|   +------------------------------------+                                    |
|   | OAuth 2.1 Bearer Validation        |  ---> (401 Unauthorized if invalid)|
|   | verify_token()                     |                                    |
|   +------------------------------------+                                    |
|         │                                                                   |
|         ▼ Decoded Claims (user_info)                                        |
|   +------------------------------------+                                    |
|   | Header-Based Route Dispatcher      |                                    |
|   | extract Mcp-Method / Mcp-Name      |                                    |
|   +------------------------------------+                                    |
|         │                                                                   |
|         ├──────────────────────────────┐                                    |
|         ▼                              ▼                                    |
|   [ tools/call ]               [ server/discover ]                          |
|   Execute tool handler          Return cached capability                    |
|   Scoped to user_info['sub']    manifest & protocol specs                   |
+-----------------------------------------------------------------------------+
from fastapi import FastAPI, Depends, HTTPException, Header, Security
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel
from typing import Dict, Any, Optional
import jwt


app = FastAPI(title="Stateless MCP 2026 Server")
security = HTTPBearer()
JWT_SECRET = "production_secret_key"
JWT_ALGORITHM = "HS256"
def verify_token(credentials: HTTPAuthorizationCredentials = Security(security)) -> Dict[str, Any]:
    """
    Validates incoming OAuth 2.1 Bearer JWT tokens.
    Converts the MCP server into a standard OAuth Resource Server.
    """
    try:
        payload = jwt.decode(credentials.credentials, JWT_SECRET, algorithms=[JWT_ALGORITHM])
        return payload
    except Exception:
        raise HTTPException(status_code=401, detail="Invalid Bearer token")
class JsonRpcRequest(BaseModel):
    jsonrpc: str = "2.0"
    method: str
    params: Optional[Dict[str, Any]] = None
    id: Any
    _meta: Optional[Dict[str, Any]] = None
@app.post("/mcp")
async def handle_mcp_request(
    request: JsonRpcRequest,
    mcp_method: Optional[str] = Header(None, alias="Mcp-Method"),
    mcp_name: Optional[str] = Header(None, alias="Mcp-Name"),
    user_info: Dict[str, Any] = Depends(verify_token)
):
    """
    Stateless MCP Request Handler conforming to the 2026-07-28 specification.
    Prefers Mcp-Method and Mcp-Name headers for fast execution dispatch.
    """
    effective_method = mcp_method or request.method
    # Route: Tool Execution
    if effective_method == "tools/call":
        tool_name = mcp_name or (request.params.get("name") if request.params else None)
        arguments = request.params.get("arguments", {}) if request.params else {}

        if tool_name == "query_database":
            query = arguments.get("query")
            user_id = user_info.get("sub", "anonymous")

            # Context is scoped directly to the authenticated token claims
            return {
                "jsonrpc": "2.0",
                "result": {
                    "content": [
                        {
                            "type": "text",
                            "text": f"Executed query '{query}' for user {user_id}"
                        }
                    ]
                },
                "id": request.id
            }

        # Standard JSON-RPC Method Not Found (-32601)
        return {
            "jsonrpc": "2.0",
            "error": {
                "code": -32601,
                "message": f"Tool '{tool_name}' not found"
            },
            "id": request.id
        }
    # Route: Server Discovery
    elif effective_method == "server/discover":
        return {
            "jsonrpc": "2.0",
            "result": {
                "protocolVersion": "2026-07-28",
                "capabilities": {
                    "tools": {"listChanged": False}
                },
                "serverInfo": {
                    "name": "Scalable-Stateless-MCP-Server",
                    "version": "2.0.0"
                }
            },
            "id": request.id
        }
    # Unsupported Protocol Method
    return {
        "jsonrpc": "2.0",
        "error": {
            "code": -32601,
            "message": f"Method '{effective_method}' unsupported"
        },
        "id": request.id
    }

Управление трафиком с нулевой обработкой на уровне 7: конфигурация Envoy и Gateway

Этап управления трафиком с нулевой обработкой на уровне 7 работает наилучшим образом, когда рассматривается как измеримая среда. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Документируйте одновременно успешный и восстановительный пути работы. Повторные попытки, проверка оператором и обработка некорректных сообщений являются частью продукта, а не последующими доработками. Установите лимиты на количество токенов за одну операцию и за сессию. Инструменты с агентным подходом активно расширяют объем данных; жесткие ограничения предотвращают появление неожиданных счетов при демонстрации функций.

routes:
  - match:
      prefix: "/mcp"
      headers:
        - name: "Mcp-Method"
          exact_match: "tools/call"
        - name: "Mcp-Name"
          exact_match: "query_database"
    route:
      cluster: mcp_database_tools_cluster
  - match:
      prefix: "/mcp"
    route:
      cluster: mcp_general_cluster

Управление состоянием без сессий: многократные запросы и связанные с ними компромиссы

Этап управления состоянием без сессий работает наилучшим образом, когда его рассматривают как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объема работ. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Когда какой-то шаг сбивается, причина сбоя должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Установите лимиты на количество токенов за один ход и за сессию. Инструменты агентов активно расширяют объем контекста; жесткие ограничения предотвращают появление неожиданных счетов. Этап управления состоянием без сессий работает наилучшим образом, когда его рассматривают как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объема работ. Записывайте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные счета при переходе от демо-версии к общим средам.

Интерактивный цикл многократных запросов (MRTR)

Для этапа MRTR с несколькими итерациями необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Конфигурацию следует хранить отдельно от кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код. При следующем шаге, представляющем собой выполнение кода или вызов инструмента, предпочтительнее использовать структурированные выходные данные с проверкой схемы вместо свободного текста.

Анализ архитектурных компромиссов

На этапе анализа архитектурных компромиссов необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо задокументировать как успешный, так и восстановительный сценарии работы. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не этапом последующей доработки. При следующем шаге, представляющем собой код или вызов инструмента, следует отдавать предпочтение структурированным выводам с проверкой по схеме перед свободным текстовым описанием.

Развертывание в облаке: масштабирование MCP на Kubernetes и Serverless

Для этапа MCP масштабирования в облачной среде необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не пытаясь угадать скрытое состояние системы. Лучше использовать небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной функцией, а не с запутанной структурой всего процесса. При следующем шаге, представляющем собой код или вызов инструмента, целесообразно использовать структурированные выходные данные с проверкой соответствия шаблону вместо свободного текста.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mcp-tool-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mcp-tool-server
  minReplicas: 3
  maxReplicas: 50
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: External
      external:
        metric:
          name: nginx_ingress_controller_requests
        target:
          type: Value
          averageValue: 1000m

Заключение и следующие шаги

На этапе «Заключение и следующие шаги» необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Укажите названия результатов работы, определите критерии успеха и не допускайте молчаливого частичного завершения задачи. При следующем шаге, представляющем собой код или вызов инструмента, отдавайте предпочтение структурированным выходным данным с проверкой по шаблону перед произвольными текстовыми описаниями.

Ресурсы с дополнительной информацией

На этапе подготовки ресурсов для получения дополнительной информации необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг, исходя из известной точки контроля, без необходимости угадывать скрытое состояние. Рядом с функциональными результатами следует записывать время выполнения и стоимость токенов или запросов. Отображение стоимости заранее помогает избежать неожиданных счетов при переходе от демо-среды к общедоступным средам. При следующем шаге, представляющем собой код или вызов инструмента, следует отдавать предпочтение структурированным выводам с проверкой схемы перед свободным текстом.

Чек-лист операций

При работе над чек-листом операций сначала необходимо зафиксировать условия работы: требуемые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист обеспечивает прозрачность последующих изменений в коде.

Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия элементам, определите критерии успешности и не соглашайтесь на молчаливое частичное выполнение задачи.

Храните в кэше стабильные инструкции системы и схемы инструментов. Пересылка одинакового входного данных является распространенной причиной ошибок.

Обеспечьте доступ к инструментам с узкими схемами и четкими метками о побочных эффектах. Хостам необходимо знать, какие вызовы изменяют состояние, прежде чем они автоматически одобрят операцию.

При наличии бюджета добавляйте тесты для проверки критического пути в процессе CI с использованием фикстчеров, а не реальных платных API.

Документируйте как успешный, так и восстановительный пути выполнения. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не этапом последующей доработки.

Перед тем как запускать стек в продакшн, заморозьте версии, сделайте «золотой» отчет для критического пути и уточните шаги возврата к предыдущей версии. В совместных средах необходимы ограничения на частоту запросов, проверки принадлежности пользователя и четко определенный ответственный за обновление секретов. Лучше выбирать надежность, чем креативные одноразовые демонстрации.

Примечание для ecba7bb3b9c6: не храните ключи поставщика в репозитории, установите лимит токенов на сессию и сохраняйте отчеты рядом с фикстурами для оценки, чтобы последующие замены моделей оставались сопоставимыми.