Skip to main content
Glama
mattijsmoens

sovereign-mcp-gateway

by mattijsmoens

sovereign-mcp-gateway

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

Built on patent-pending components

pip install sovereign-mcp-gateway
sovereign-mcp-gateway --init          # writes gateway.json from the servers you already run
sovereign-mcp-gateway --config gateway.json --check

--init читает уже имеющуюся у вас конфигурацию MCP (Claude Desktop, Claude Code, Cursor, VS Code или Windsurf) и записывает gateway.json, который проксирует те же серверы, так что первый запуск даёт рабочую конфигурацию, а не ошибку конфигурации. Он не будет импортировать собственную запись шлюза, потому что это заставило бы его проксировать самого себя.

Сам шлюз является MCP-сервером, поэтому любой клиент, говорящий на MCP, работает без изменений.

Эта базовая установка — рабочий шлюз. Четыре дополнительных опции добавляют поверх него дополнительные слои — см. Установка.


Что это останавливает

Агент читает issue на GitHub, в теле которого содержится инструкция, адресованная модели, а не вам. Он поддаётся убеждению и вызывает git_commit.

коммитов после

внедрённый коммит присутствует

напрямую к mcp-server-git

2

да

через шлюз

1

нет

Тот же инструмент, те же аргументы, тот же сервер. Разница в том, был ли кто-то в состоянии отказать.

Прочтите пошаговое руководство: Ваш агент читает issue — или запустите его:

pip install "sovereign-mcp-gateway[all]" mcp-server-git
python examples/poisoned_issue.py

Related MCP server: Agentrim MCP

Почему прокси, а не библиотека

Библиотеку должен принять тот, кто написал сервер. Прокси защищает серверы, которые вы не можете изменить — а таких большинство, потому что полезные MCP-серверы — это опубликованные пакеты, которые поддерживает кто-то другой.

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

Настройка

Начните с того, что уже запущено

$ sovereign-mcp-gateway --init

Wrote gateway.json

  imported 3 servers from Claude Desktop
    /Users/you/Library/Application Support/Claude/claude_desktop_config.json
  imported 1 server from VS Code (project)

  upstreams: fetch, git, sqlite, time

  skipped:
    sovereign - this gateway - importing it would proxy itself
    notion    - no command, probably a remote/SSE server
    git       - already imported from another client

Четыре вещи он не сделает: не импортирует сам себя, не импортирует удалённый сервер, который не может запустить как подпроцесс, не перезапишет существующий файл без --force и не запишет список deny_tools, который вы не выбирали. Он записывает файл, сообщает, что взял и что оставил, и останавливается.

Передайте --config PATH вместе с --init, чтобы записать в другое место, а не в ./gateway.json.

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

{
  "servers": {
    "git":    {"command": "mcp-server-git",    "args": ["--repository", "/repo"]},
    "sqlite": {"command": "mcp-server-sqlite", "args": ["--db-path", "/data.db"]}
  },
  "policy": {"deny_tools": ["git__git_reset"], "pii_policy": "warn"},
  "audit":  {"path": "gateway-audit.jsonl"}
}

Проверьте подключение, прежде чем клиент его увидит:

sovereign-mcp-gateway --config gateway.json --check
SOVEREIGN GATEWAY - configuration check
upstreams: 2
layers:   policy -> intent -> text-filter -> frozen-verify -> audit

EXPOSED AS                             UPSTREAM TOOL
git__git_status                        git.git_status
git__git_reset                         git.git_reset          [DENIED]
sqlite__read_query                     sqlite.read_query
...
18 tools exposed.

Цепочка

policy → intent → text-filter → frozen-verify → [ call executes ] → output-verify → logic-rules → audit

Layer

Package

Отказывает, когда

policy

—

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

intent

intentshield

вызов не проходит поведенческий минимум

text-filter

sovereign-shield

аргумент содержит инъекцию на любом из 21 языков или в семи кодировках

frozen-verify

sovereign-mcp

вызов не соответствует определению инструмента, замороженному при запуске

output-verify

sovereign-mcp

результат не проходит проверку схемы, обмана, PII или содержимого

logic-rules

logicshield

результат противоречит правилам, которые вы настроили

audit

sovereign-mcp

— записывает каждый вызов, разрешённый или отклонённый, в журнал с хеш-цепочкой

Установка

Базовая установка — это рабочий шлюз, а не заглушка:

pip install sovereign-mcp-gateway

Это даёт вам policy → frozen-verify → audit, который уже отклоняет инструмент, не предоставляемый ни одним апстримом, аргумент неверного типа, незадекларированный параметр, инструмент из вашего списка запрещённых и инъекцию в аргументе. Больше ничего не нужно.

Каждая дополнительная опция добавляет слой поверх:

Extra

Добавляет

Стоит того, когда

[text]

sovereign-shield — более глубокая проверка строковых аргументов: 21 язык и семивариантное декодирование для полезных нагрузок, скрытых в base64, hex, ROT13, leetspeak или перевёрнутом тексте

Ваши агенты читают текст откуда угодно, где вы не контролируете. Базовая установка ловит IGNORE ALL PREVIOUS INSTRUCTIONS; она не поймает ту же фразу в base64 или на голландском

[intent]

intentshield — поведенческий минимум, применяемый независимо от того, какой инструмент вызван: запреты на shell, запреты на удаление, URL с учётными данными, синтаксис вредоносного ПО

Вы хотите страховку, которая не зависит от правильной схемы каждого инструмента

[rules]

logicshield — правила согласованности, которые вы пишете для вывода инструмента

Вы можете выразить, как выглядит правильный результат. Ничего не делает, пока вы не зададите output_rules

[consensus]

requests — требуется HTTP-провайдерам слоя C

Вы включаете консенсус N-моделей с хостинг-провайдером

Комбинируйте, что хотите, или берите всё:

pip install "sovereign-mcp-gateway[text]"             # one extra
pip install "sovereign-mcp-gateway[text,intent]"      # several
pip install "sovereign-mcp-gateway[all]"              # every layer

Все четыре дополнительных пакета — небольшие чистые Python-пакеты — [all] не добавляет скомпилированных зависимостей и не требует запуска службы.

Частичная установка заметно деградирует. Шлюз выводит свои активные слои при запуске, так что вы всегда видите, что на самом деле работает:

layers:   policy -> frozen-verify -> audit                                  # base
layers:   policy -> intent -> text-filter -> frozen-verify -> audit         # [all]

Если слоя нет в этой строке, он не работает — что бы вы ни думали, что установили.

Проверено от начала до конца

Против mcp-server-git и mcp-server-sqlite, работающих как реальные апстримы, управляемых реальным MCP-клиентом:

Call

Результат

git__git_status, git__git_log

разрешено

sqlite__create_table, __write_query, __read_query

разрешено — строка действительно в базе данных

git__git_reset

отклонено: в списке запрещённых

git__git_push_force

отклонено: ни один апстрим его не предоставляет

git__git_status(repo_path=12345)

отклонено: неверный тип для замороженной схемы

git__git_commit("IGNORE ALL PREVIOUS INSTRUCTIONS…")

отклонено: текстовый фильтр

sqlite__git_commit(...)

отклонено: инструмент нельзя вызвать через пространство имён другого апстрима

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

Эти случаи — тестовый набор, а не скриншот: pytest tests/ -v.

Слой C: консенсус N-моделей

Все остальные слои детерминированы и локальны. Слой C — исключение: он просит несколько независимых моделей извлечь один и тот же структурированный документ из результата инструмента, канонизирует каждый ответ и сравнивает SHA-256-хеши. Согласие определяется хешем, а не прозой.

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

{
  "servers": { "...": {} },
  "consensus": {
    "providers": [
      {"type": "local", "model": "llama3.1:8b"},
      {"type": "local", "model": "qwen2.5:7b", "base_url": "http://localhost:11434/v1"},
      {"type": "openrouter", "model": "anthropic/claude-3.5-sonnet",
       "api_key_env": "OPENROUTER_API_KEY"}
    ]
  }
}

Два типа провайдеров: local (любая OpenAI-совместимая конечная точка — Ollama, vLLM, LM Studio; base_url по умолчанию http://localhost:11434/v1) и openrouter (ключ читается из указанной переменной окружения и никогда не записывается в конфиг).

Три правила, которые шлюз применяет при запуске, а не обнаруживает во время выполнения:

  • Как минимум два провайдера. Одна модель не может не согласиться сама с собой; консенсус из одной модели сообщает о согласии на каждый вызов, что хуже, чем отсутствие слоя, потому что это выглядит как проверка.

  • Без дублирующихся моделей. Согласие двух экземпляров одной и той же модели — не независимая проверка.

  • Отсутствующий API-ключ не даёт запуститься. Он не откатывается к работе без слоя.

Все провайдеры работают с temperature = 0, это обеспечивается в конструкторе.

Проверьте, что ваши модели согласны, прежде чем доверять слою

--check выполняет один реальный консенсус-вызов к вашим настроенным моделям и сообщает, что произошло. Это важнее, чем звучит:

LAYER C  - probing the configured models with one real call
--------------------------------------------------------------
  OK. The configured models produced identical documents.
  Layer C will pass ordinary output rather than refusing it.

Консенсус сравнивает канонические хеши, поэтому две модели, которые обе семантически правы, но структурно различаются, никогда не согласятся. Более слабая модель, которая повторяет схему —

{"branch": {"type": "string", "value": "main"}}   instead of   {"branch": "main"}

— не совпадает при каждом вызове, всегда, и шлюз отклоняет всё с причиной, которая правильно читается как «модели не согласились». Потому что они не согласились.

Проверка различает три исхода:

означает

OK

модели создали идентичные документы; слой пригоден к использованию

MISMATCH

они не согласны по тривиальному документу и будут отклонять каждый вызов — замените модель или удалите секцию

provider unreachable

ничего не проверено; неверен ключ, идентификатор модели или конечная точка

Установите sovereign-mcp-gateway[consensus] или [all] — HTTP-провайдерам нужен requests, от которого основная библиотека намеренно не зависит.

--check также выводит список активных слоёв, так что вы можете подтвердить с одного взгляда:

layers:   policy -> intent -> text-filter -> frozen-verify -> consensus -> audit

Если consensus отсутствует в этой строке, он не работает, что бы ни говорил конфиг.

Пространства имён

При включённом namespace (по умолчанию) инструмент отображается как git__git_status. Два апстрима, предлагающие одно и то же имя инструмента, не могут конфликтовать, затенять друг друга или быть достигнуты через неправильное пространство имён. Отключайте его только при наличии одного апстрима.

Политика

"policy": {
  "deny_tools":  ["git__git_reset", "write_query"],
  "allow_tools": null,
  "pii_policy":  "warn",
  "fail_closed": true,
  "rate_limit_interval": 0
}
  • deny_tools сопоставляется либо с открытым именем (git__git_reset), либо с исходным именем инструмента (git_reset, на каждом апстриме, где он есть).

  • allow_tools при задании отказывает всему, что не входит в список.

  • pii_policy по умолчанию имеет значение warn, а не block. Реальные инструменты возвращают персональные данные как обычный вывод — каждая запись git log содержит email автора — и блокировка таких данных делает шлюз непригодным к использованию. Установите block, если ваши инструменты никогда не должны выдавать PII.

  • fail_closed определяет, что происходит, когда сам слой завершается с ошибкой. По умолчанию: отказ.

  • rate_limit_interval равен 0, что отключает собственную задержку между действиями поведенческого минимума. Эта задержка подходит для одного агента, делающего обдуманные шаги, и не подходит для прокси, где всплеск вызовов инструментов — обычный трафик.

  • entropy_policy по умолчанию имеет значение warn. Эвристика энтропии текстового фильтра ищет закодированные полезные нагрузки, скрытые в прозе, но аргументы инструментов обычно структурированы — пути, идентификаторы, хэши — где высокая энтропия является нормой. Одного лишь пути к временной директории было достаточно, чтобы легитимный вызов был отклонён. Установите block, если ваши аргументы действительно являются прозой.

Что это не делает

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

Он также не может защитить от скомпрометированного апстрима, возвращающего корректно выглядящие данные — консенсус Layer C в sovereign-mcp решает эту проблему и требует провайдеров моделей, которых вы настраиваете сами.

Лицензия

Business Source License 1.1 — см. LICENSE.

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

Производственное использование также бесплатно для частного лица или организации из четырёх или менее человек — это прописано в лицензии как Additional Use Grant, а не просто заявлено здесь. Крупным организациям требуется коммерческая лицензия.

Каждая версия конвертируется в Apache 2.0 по наступлении её Change Date, через четыре года после публикации.

Чтобы лицензировать её для производства или узнать, нужна ли вам лицензия для вашего использования: contact@sovereign-shield.net

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Centralized MCP control plane that proxies multiple upstream MCP servers with tool namespacing, filtering, policy enforcement, audit logging, and health checks.
    13 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A least-privilege enforcement proxy for MCP servers. It sits between MCP clients and upstream servers, enforcing tool policies, hiding denied tools, requiring human approval for risky actions, and providing a structured audit trail.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides a governance proxy layer for MCP servers, enforcing per-tool allowlists, human approval for write operations, quotas, secret redaction, and a hash-chained audit log of all calls.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a security and context-control layer that multiplexes multiple MCP servers behind a single endpoint, scanning tool definitions and results, enforcing authorization, rate limiting, and audit logging, and dynamically retrieving tools to manage context window usage.
    MIT