Skip to main content
Glama
PNX89

QUENCHZ

by PNX89

QUENCHZ

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

CI Python TypeScript client License: MIT Data: ECB

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

{
  "observations": [
    ["2026-03-30", 1.1484],
    ["2026-03-31", 1.1498],
    ["2026-04-01", 1.1605],
    ["2026-04-02", 1.1525],
    ["2026-04-07", 1.1557],
    ["2026-04-08", 1.1706],
    ["2026-04-09", 1.1685],
    ["2026-04-10", 1.1711]
  ],
  "coverage": {
    "requested_from": "2026-03-30",
    "requested_to": "2026-04-10",
    "requested_calendar_days": 12,
    "expected_observations": 8,
    "delivered_observations": 8,
    "delivered_from": "2026-03-30",
    "delivered_to": "2026-04-10",
    "absent": {
      "target_closed": 4,
      "not_yet_published": 0,
      "no_such_observation": 0,
      "before_the_series": 0
    },
    "window_still_open": false,
    "body_completed_at": "2026-08-26T12:00:00Z",
    "source": "ECB statistics."
  },
  "source": "ECB statistics."
}

Было запрошено двенадцать календарных дней, а вернулось восемь, и ответ полон. Страстная пятница, Пасхальный понедельник и выходные — это закрытия, а не пропуски, и полезная нагрузка вендора не говорит о них ничего. Чтобы отличить одно от другого, нужны календарь публикаций и настенные часы, и именно этим занимается блок coverage: [src/quenchz/coverage.py].

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

Источник: статистика ECB.

Двенадцать дней запрошено, восемь доставлено

Сертификат выше — не сводка, написанная рядом с данными. Это обязательное поле в ответе, восстановленное из календаря публикаций, а не прочитанное из ответа, потому что ответ его не содержит.

поле

на какой вопрос отвечает

requested_calendar_days

что запросил вызывающий

expected_observations

что, по календарю, вообще причиталось

delivered_observations

что пришло

absent.target_closed

рынок был закрыт

absent.not_yet_published

срок — сегодня, а данных ещё нет

absent.no_such_observation

оно причиталось, оно опаздывает, и кто-то должен знать

absent.before_the_series

ничего никогда не причиталось, потому что ряд ещё не начался

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

Related MCP server: OPNsense MCP

Действительный токен, который ничего не достигает

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

Эту проверку приходится писать вручную. SDK несёт поле resource из RFC 8707 в AccessToken и никогда ни с чем его не сравнивает: BearerAuthBackend проверяет префикс Bearer, истинность и срок действия, а затем передаёт resource нетронутым. SDK действительно говорит эмитенту ограничивать аудиторию выпускаемого им токена, но ничего не говорит о том, чтобы сервер ресурсов проверял, что это было сделано. Два теста утверждают, что SDK по-прежнему ведёт себя так, поэтому если релиз начнёт применять это, данное утверждение громко сломается, а не тихо перестанет быть истинным.

Токен, чья аудитория — список, тоже отклоняется, хотя PyJWT принял бы его. RFC 7519 рассматривает аудиторию как проверку членства, поэтому токен, выписанный на этот ресурс и на другой, проходит через библиотеку. Здесь он не проходит: токен, действительный ещё где-то, — это токен, который где-то ещё могут предъявить у этой двери, и именно эту ситуацию призван избегать RFC 8707.

Вызывающий не может узнать и о том, чем ему не разрешено пользоваться. Инструмент вне предоставленной ему области действия отсутствует в его списке, а запрос к нему всё равно возвращает байты, идентичные запросу к имени, которого никогда не существовало. У этого есть реальная цена: тот, кто действительно опечатался в области действия, получает менее полезное сообщение, чем мог бы получить. Но это того стоит, потому что собственный отказ SDK по области действия отвечает Required scope: <name>, что подтверждает существование инструмента и называет разрешение, которое сработало бы, а сотня догадок, опирающихся на этот ответ, — это карта поверхности, нарисованная сервером для вызывающего, которому никогда не разрешали её видеть.

Запуск сервера

uv sync --dev
uv run pytest

Сервер, с внутрипроцессным эмитентом, который выпускает собственные токены в файл:

uv run python -m quenchz.interop_server --port 8931 --tokens-file tokens.json

Ключ подписи генерируется в памяти и никогда не касается диска. Каждое имя хоста использует зарезервированный TLD .invalid из RFC 2606 и никогда не может быть разрешено.

Два вызывающих и один бюджет, который не видит ни один

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

Наивная схема сохранена в исходном коде, так что разница — это измерение, а не утверждение. Один и тот же характер поступления запросов, обе схемы:

схема

жадный: допущено

тихий затем: допущено

одно общее ведро

60

0 из 60

резерв каждому плюс общий запас

45

15 из 60, ровно его резерв

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

Доказательство извне Python

[clients/typescript/src/prove.ts] управляет работающим сервером с помощью официального MCP TypeScript SDK в собственном задании CI. Он не разделяет код с тем, что тестирует, и это важно: набор тестов на Python и сервер на Python могут согласиться друг с другом в чём-то, что не соответствует протоколу.

Шестнадцать проверок. Токен для этого ресурса допускается с кодом 200; токен для другого ресурса, для двух ресурсов или ни для одного отклоняется с кодом 401 и вызовом Bearer. Непредоставленный инструмент и несуществующий отказывают идентичными байтами. Вызывающий, работающий всплесками, останавливается там, где, согласно арифметике, и должен, а тихий по-прежнему получает ровно свой резерв.

У этого доказательства был собственный недостаток, который стоит зафиксировать. Его первая версия проверяла, бросил ли connect() исключение, и считала любое исключение отказом, поэтому когда намеренно сломанная сборка заставляла верификатор упасть, а сервер отвечать 500, доказательство сообщало об успехе. Сервер, отвечающий 500 на всё, удовлетворил бы каждую проверку аудитории на этой странице. Теперь оно читает код состояния.

Что вендор записывает и чего нет в полезной нагрузке

Здесь три момента времени, и клиенту видны только два из них.

время

что это

где это находится

около 14:10 CET

согласование между центральными банками

в прозе вендора

14:15 CET

момент, к которому курс относится

в полезной нагрузке, как TITLE_COMPL

около 16:00 CET

когда курс фактически публикуется

только в прозе вендора

Клиент, который читает собственные метаданные полезной нагрузки и заключает, что курс доступен в 14:15, ошибается почти на два часа и каждый день после полудня будет называть ещё не опубликованный день настоящим пропуском. Полезная нагрузка не просто опускает ограничение. Она несёт другое время, которое выглядит авторитетным, и использовать его неправильно.

Кодирование отсутствия тоже изменилось, и это обнаружилось, когда написали клиента, считающего строки, и получили число на 62 больше, чем у клиента, считавшего значения. Полный ряд — это 7,140 строк, содержащих 7,078 значений и 62 заполнителя: до мая 2012 года закрытый день приходил как строка с пустым значением и OBS_STATUS со значением H, а после — вообще без строки. Один и тот же календарь, две кодировки, и только подсчёт значений корректен в обе эпохи.

Четыре решения и цена каждого

Аудитория — это ворота, а не подпись. Цена: токен, действительный где-то ещё, здесь отклоняется, поэтому вызывающий с токеном широкой области действия должен вернуться к своему эмитенту за более узким.

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

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

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

Ограничения

  • Эмитент локальный и внутрипроцессный. Никаких заявлений о каком-либо реальном поставщике удостоверений не делается, и ничто здесь не было рядом с таковым.

  • Бюджет установлен самостоятельно. Он не соответствует никакому лимиту, публикуемому вендором, потому что вендор не публикует никаких.

  • Сертификат восстанавливает четыре названные причины. Пятая, о которой он не подумал, считается настоящим пропуском — это безопасное направление, но это не то же самое, что полнота.

  • Справочные курсы ECB — это ежедневно публикуемый справочный показатель, а не торгуемая цена, и ничто здесь не относится к ним как к таковой. Здесь нет книги заявок, нет механизма сопоставления и нет пути исполнения.

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

  • Ничто здесь не одобрено ECB и не связано с ним.

Разработка

uv run pytest
uv run python scripts/readme_block.py

Каждое число и каждый блок на этой странице проверяются tests/test_readme.py на соответствие тому, что они описывают. Тело ответа выше сгенерировано, а не переписано вручную.

Лицензия

MIT. См. LICENSE.

Данные используются повторно в соответствии с политикой ESCB по повторному использованию статистики, которая разрешает это бесплатно при трёх условиях: указан источник, статистика и метаданные не изменяются и отсутствуют сторонние данные. Все три условия — это тесты в [tests/test_licence.py], а не обещания. Источник: статистика ECB.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enforces fine-grained, context-aware access control on MCP tool calls, with a tamper-evident, replayable audit log that records denials and verifies every decision.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables remote agents to securely read firewall and NAT rules, inspect routing tables and logs, and execute safety-gated mutation plans through a bearer-authenticated MCP endpoint.
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables policy-governed MCP interactions with deterministic authorization, tenant isolation, minimized PII exposure, and human approval gates for sensitive mutations, while producing structured audit events.
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to govern downstream tool servers by enforcing default-deny authority and attestation on every tool call, with live monitoring, approval, and mid-session revocation.
    3
    Apache 2.0