Skip to main content
Glama
JohnGilligan2

mcp-exports

mcp-exports

Общий одноразовый хостинг загрузок для внутренних MCP-серверов.

https://exports.example.com · порт хоста 8114 · без входа для клиента

MCP server  --POST /put  (service token)-->  mcp-exports  -->  download URL
customer    --GET  /d/{token} (no auth)  -->  mcp-exports  -->  the file, once

Зачем он существует

Инструмент, который возвращает неделю записей звонков инлайн, расходует ~530 000 токенов; те же данные в виде CSV — это 1 МБ, и они собираются за 1,6 секунды. Поэтому экспорт возвращает ссылку. Первая версия отдавала эту ссылку с самого MCP-сервера, и это ломалось тремя способами:

  1. MCP-хосты стоят за IP-allow-list только для Anthropic, но скачивает файл браузер клиента на произвольном адресе. Отдельное имя хоста позволяет двум политикам доступа не конфликтовать, а не вырезать исключение в конфиге прокси, где живут ещё и настройки стриминга для MCP.

  2. MCP-контейнеры пересоздаются на каждом пуше, и in-memory-хранилище умирало вместе с ними — инвалидируя живые ссылки посреди разговора.

  3. Хранилище принадлежало одному процессу, поэтому второй воркер случайным образом получал 404.

Related MCP server: agent-secret

Модель безопасности, простыми словами

URL загрузки — это capability: у кого он есть, тот получает файл, никакой вход не требуется. Это та же логика, по которой мы уже выдаём URL записей NetSapiens и PDF портала Odoo, и именно она позволяет ссылке работать при клике из окна чата. Это не аутентификация, и слабости реальны: ссылку можно переслать, её может залогировать прокси, а может она вечно лежать в истории беседы.

Поэтому дизайн опирается на то, что на самом деле помогает:

Управление

Почему

Одноразовое использование (по умолчанию max_downloads=1)

Файл удаляется сразу после получения, поэтому ссылка, утёкшая позже, уже мертва. Это самый сильный контроль из доступных, потому что capability-ссылку нельзя сделать неразделяемой.

Короткий TTL — 1 час данных, 15 минут финансов

Сжимает окно. Деньги получают меньше.

256-битные токены secrets.token_urlsafe

Не подбираются и не перечисляются

Одинаковый 404 для пропущих / некорректных / истёкших / использованных

По разнице нечему научиться

Content-Disposition: attachment всегда

HTML- или SVG-экспорт не должен никогда отрисовываться на нашем origin — иначе хост станет вектором stored-XSS

no-store, noindex, nosniff, no-referrer

Не кэшируется, не индексируется, не утекает referrer

Лог доступа только с префиксом токена

Достаточно для связи загрузки↔скачивания; недостаточно, чтобы по логу, который читают больше людей, чем сам файл, воссоздать рабочую ссылку

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

API

POST /put?filename=x.csv&sensitivity=data|financial&customer=Acme%20Movers
     &ttl=3600&max_downloads=1
     Authorization: Bearer <server token>
  -> 201 {download_url, filename, size, expires_in_seconds, expires_at,
          max_downloads, single_use}

GET  /d/{token}   -> 200 the file (then it is gone), or 404
GET  /healthz     -> counters + bytes held

ttl зажимается, а не выполняется — попросите неделю — получите MCP_EXPORTS_TTL_MAX, и ответ покажет вам, что по факту вы получили.

Использование с MCP-сервера

Скопируйте client/export_client.py на сервер и задайте MCP_EXPORTS_URL + MCP_EXPORTS_TOKEN. ExportClient.from_env() возвращает None без настроек, поэтому сервер может предлагать инструменты экспорта только там, где хост реально подключён, а не рекламировать инструмент, который всегда падает. Он бросает исключение, а не откатывается к инлайн-строкам: если хост недоступен, безопасного ухудшения не существует, потому что вернуть строки — это и есть тот сбой, ради предотвращения которого экспорт вообще существует.

Развёртывание

Portainer → Stacks → Repository, refs/heads/main, порт 8114. Для каждого MCP-сервера сгенерируйте токен:

python -c "import secrets; print(secrets.token_urlsafe(32))"

NPM: exports.example.com10.0.0.10:8114, без Access List (в этом весь смысл), WebSocket выключены, стандартные таймауты.

Тесты

python -m pytest tests -q

47 тестов, без сети. Они охватывают именно свойства безопасности: одноразовость действительно удаляет файл; любая форма плохого токена неотличима; имена файлов не могут сбежать или подставить заголовки; финансовый TTL короче; а Dockerfile делает chown точки монтирования тома до сброса прав root — без этого именованный том окажется принадлежащим root, и любая загрузка падает скаложенным EACCES.

Note: my final line "любая загрузка падает с" perhaps "неудачей EACCES". In the original: "every upload fails EACCES." So "каждая загрузка падает с "EACCES"". Let's fix: "и каждая загрузка упадает с EACCES."

Let me ensure all spacing and blank lines. I'll craft clean final.

However, I need make sure Russian stray from source: "CP" etc. Since this is translation, I can improve style.

Let me produce final output, with the exact text.

One concern: "двум политике" is typo: should be "двум политикам". Correct in final.

Also "сильное" numbers: "530,000 tokens" original ~530,000. In Russian maybe "530 000". I used "530 000".

Also "Нет, Safe" I'll handle.

Now, the final output# mcp-exports

Общий одноразовый хостинг загрузок для внутренних MCP-серверов.

https://exports.example.com · порт хоста 8114 · без входа для клиента

MCP server  --POST /put  (service token)-->  mcp-exports  -->  download URL
customer    --GET  /d/{token} (no auth)  -->  mcp-exports  -->  the file, once

Зачем он существует

Инструмент, который возвращает неделю записей звонков инлайн, обходится в ~530 000 токенов; те же данные в виде CSV — это 1 МБ, и они собираются за 1,6 секунды. Поэтому экспорт возвращает ссылку. Первая версия отдавала эту ссылку с самого MCP-сервера, и это ломалось тремя способами:

  1. MCP-хосты стоят за позволёным только для Anthropic IP-allow-list, но скачивает файл браузер клиента с произвольного адреса. Отдельное имя хоста позволяет двум политикам доступа не конфликтовать, а не вырезать исключение в конфиге прокси, в котором также живут настройки стриминга, необходимые MCP.

  2. MCP-контейнеры пересоздаются на каждом пуше, и in-memory-хранилище умирало вместе с ними — инвалидируя живые ссылки посреди разговора.

  3. Хранилище принадлежало одному процессу, поэтому второй воркер случайно получал 404.

Модель безопасности, простыми словами

URL загрузки — это capability: у кого он есть, тот и получает файл, безо всякого входа. Та же сделка, что и с запросами NetSafe или Odoo PDF, которые мы и так раздаём; именно это позволяет ссылке работать при клике из окна чата. Это не аутентификация, и слабости реальны: ссылку могут переслать, прокси может её залогировать, а она может остаться в истории сообщений навсегда.

Поэтому конструкция опирается на то, что действительно помогает:

Управление

Почему

Одноразовое использование (по умолчанию max_downloads=1)

Байты удаляются после получения, поэтому ссылка, утёкшая после, уже мертва. Самый сильный контроль из возможных: capability-ссылку нельзя отобрать.

Короткий TTL — 1 час данных, 15 минут финансовых

Сжимает окно. Финансовое получает меньше.

256-битные токены secrets.token_urlsafe

Не угадываются и не перебираются

Одинаковый 404 для отсутствующего / некорректного / истёкшего / использованного

По разнице нечему не научиться

Content-Disposition: attachment всегда

HTML- или SVG-экспорт не должен никогда открываться на нашем origin — это сделало бы этот хост источником stored-XSS

no-store, noindex, nosniff, no-referrer

Не кэшируется, не индексируется, не утекает реферер

Лог доступа только с префиксом токена

Достаточно, чтобы связать загрузку и скачивание; недостаточно, чтобы по журналу, доступному большему, чем сам файл, собрать рабочий URL

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

API

POST /put?filename=x.csv&sensitivity=data|financial&customer=Acme%20Movers
     &ttl=3600&max_downloads=1
     Authorization: Bearer <server token>
  -> 201 {download_url, filename, size, expires_in_seconds, expires_at,
          max_downloads, single_use}

GET  /d/{token}   -> 200 the file (then it is gone), or 404
GET  /healthz     -> counters + bytes held

ttl ограничивается сверху, а не выполняется — запросите неделю, а получите MCP_EXPORTS_TTL_MAX, и ответ подскажет, что вам выдано на самом деле.

Использование с MCP-сервера

Скопируйте client/export_client.py на сервер и задайте MCP_EXPORTS_URL + MCP_EXPORTS_TOKEN. ExportClient.from_env() вернёт None, когда конфигурации нет, поэтому сервер может включать экспортные инструменты только туда, где хост действительно подключён, а не показывать инструмент, который всегда падает. Он выбрает исключение, а не отступает к инлайн-строкам: если хост недоступен, безопасной работы в старом режиме нет, потому что возвращать строки — это именно тот сбой, который экспорт и должен предотвратить.

Развёртывание

Portainer → Stacks → Repository, refs/heads/main, порт 8114. Для каждого MCP-сервера сгенерируйте персональный токен:

python -c "import secrets; print(secrets.token_urlsafe(32))"

NPM: exports.example.com10.0.0.10:8114, no Access List (в этом и смысл), Websockets off, стандартные таймауты.

Тесты

python -m pytest tests -q

7 тестов, без сети. Они покрывают именно security-части:

  • одиночное использование реально удаляет байты;

  • каждый некорректный вид токена неразличим;

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

  • финансовый TTL короче;

  • а Dockerfile выполняет chown для точки монтирования тома до сбрасывания привилегий root — иначе именованный том приходит с владельцем root, и любая загрузка заканчивается с EACCES.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Provides secure OAuth2-based credential management for MCP servers, allowing agents to obtain short-lived token references without exposing raw secrets.
    7
    18
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for one-time secret sharing, enabling AI agents to securely claim and store secrets (e.g., API keys) via claim codes without exposing them in chat transcripts.
    3
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables sharing self-contained HTML files via public or access-key-protected private links. Provides MCP tools to create shares, retrieve public share metadata, and describe the service.
    2
  • F
    license
    Not graded
    quality
    B
    maintenance
    MCP server for end-to-end encrypted secret storage and retrieval, enabling LLM agents to fetch secrets by name via one-time URLs while keeping plaintext out of model context and logs.
    1

View all related MCP servers

Related MCP Connectors

  • An authenticated remote MCP server for user-owned devices and one-shot capability invocation.

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • Remote MCP for C2PA intake verifier MCP, structured receipts, audit logs, and reviewer-ready evidenc

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JohnGilligan2/mcp-exports'

If you have feedback or need assistance with the MCP directory API, please join our Discord server