MCP App Proxyfier
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP App Proxyfiersearch for running shoes under $100"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP App Proxyfier
MCP-сервер, который отдаёт в чат с моделью интерактивные MCP Apps (официальное UI-расширение MCP, рендерится в песочнице-iframe хоста). Вместо текстовой обёртки над запросами зритель получает нативный UI прямо в диалоге.
Реализован один вылизанный флоу на настоящих данных: Megamarket — поиск товаров → грид → детальная страница → корзина → оформление.
Данные статические: каталог собран из сохранённых снапшотов реальных страниц
megamarket.ru (pages/) скриптом pnpm update:data. Сеть и браузер на демо не нужны —
сервер стартует мгновенно и отвечает одинаково при любом Wi-Fi в зале.
Сценарий живого демо (без MCP → MCP без UI → MCP с UI → MCP с UI и скиллом) — в
DEMO.md.
Структура
packages/
ui/ React + Vite; собирается в самодостаточные HTML (по одному на приложение)
server/ MCP-сервер, отдаёт UI как ui:// ресурсы + инструменты
pages/ HAR/HTML-снапшоты megamarket.ru — сырьё для pnpm update:dataUI собирается в два самодостаточных HTML-бандла — index (каркасный ping) и
megamarket; все JS/CSS встроены, внешних ссылок нет (требование песочницы-iframe).
Сервер на старте читает эти HTML и регистрирует как ui:// ресурсы.
Related MCP server: FakeStore MCP
Инструменты
Инструмент | Вход | UI | Назначение |
|
|
| Каркасная проверка рендера iframe |
|
| — | Поиск товаров, результат только текстом (список позиций) |
|
|
| Тот же поиск + грид карточек виджетом |
|
|
| Тот же поиск + виджет; описание обязывает прочитать |
|
|
| Карточка товара: галерея, таблица «О товаре», описание |
| — | — | Сегодня/завтра + ближайшие 7 дней с днями недели |
|
|
| Добавляет товар в корзину |
| — |
| Текущее состояние корзины |
| — |
| Оформляет заказ по корзине, возвращает подтверждение и очищает её |
filters — ценовой коридор priceMin / priceMax и срок доставки deliveryBy
(YYYY-MM-DD; оставляет только то, что приедет не позже).
get_delivery_calendar существует потому, что у модели нет часов: «до пятницы» она сама
в число не превратит — либо выдумает, либо отсчитает от даты обучения. Скилл обязывает
вызвать календарь до поиска, отсюда и порядок вызовов в демо.
Три варианта поиска — это ступени живого демо (без UI → с UI → с UI и методичкой). Они
существуют одновременно на одном подключении, переключение идёт формулировкой запроса, без
перезапуска сервера. Почему их три, а не один с параметром: привязка UI живёт в
_meta.ui.resourceUri на регистрации инструмента и уезжает клиенту в tools/list —
результат вызова её изменить не может.
Корзина — in-memory, одна на процесс сервера: перезапуск её обнуляет.
Ресурсы ui://
MCP Apps: самодостаточный HTML, который хост рендерит в песочнице-iframe и кормит
structuredContent результата инструмента через мост. MIME — text/html;profile=mcp-app.
URI | Собирается из | Кто рендерит |
|
|
|
|
| все инструменты Megamarket |
Приложение Megamarket — мини-SPA: выдача → деталка → корзина → подтверждение. Какой вид
показать, оно решает по форме пришедшего structuredContent: products — выдача,
product — деталка, cart — корзина.
Виджет интерактивный, а не картинка:
чипы фильтров над гридом (бренд, шумоподавление) — фильтруют внутри iframe, без вызова инструмента и без нового пузыря в чате;
клик по карточке открывает деталку (
get_productчерез мост), «Назад» возвращает в тот же отфильтрованный список — состояние фильтров переживает переход;деталка открывается и голосом («покажи подробнее вот эти») — вид тот же самый;
«В корзину» на карточке и на деталке — app-initiated
add_to_cart(id); ответ несёт актуальную корзину, поэтому бейдж обновляется без отдельногоview_cart.
Фильтры виджета сознательно не трогают доставку: срок задаёт агент через
filters.deliveryBy на сервере. Иначе виджет молча показывал бы то, что агент уже отсёк.
Ресурсы skill://
Методички для агента. В отличие от ui:// это не MCP Apps — рендерить нечего, это
обычный текст, который агент читает перед вызовом инструмента.
URI | MIME | Назначение |
|
| Индекс скиллов — точка входа, по которой агент находит остальные |
|
| Подбор товара: уточнить бюджет и сценарий, перевести бюджет в |
Индекс и сами методички собираются из одного SkillDefinition
(packages/server/src/skills/skill-registry.ts), поэтому имя и описание в индексе не могут
разъехаться с ресурсом.
Данные
Каталог — packages/server/data/market.json (70 товаров, у всех есть детальная карточка).
Пересобирается из снапшотов:
pnpm update:data # разбирает pages/ → packages/server/data/market.json
pnpm update:data -- --dry-run # только показать, что распарсилось, ничего не писатьСкрипт идемпотентен: повторный прогон просто перезаписывает файл. Сеть не трогает.
Выдача поиска ограничена девятью позициями (SEARCH_RESULT_LIMIT) — грид 3×3 в узком
чат-iframe.
Сроки доставки — синтетические
packages/server/data/delivery.json не собирается из снапшотов: настоящий срок
(calculatedDeliveryDate в SSR-стейте страниц) есть ровно у одного товара каталога из 70, а
на выдаче Мегамаркет его не отдаёт вовсе. Формат подписей при этом взят у сайта: он пишет
только «Сегодня», «Завтра» и дату вида «15 июля» — «Послезавтра» у него нет.
В файле лежат дни, а не даты: дата считается в рантайме от сегодня, поэтому «Завтра» остаётся завтрашним и через месяц. Товары, которых в файле нет, получают детерминированный срок по хешу id — одинаковый между запусками, чтобы выдача не «дышала».
Флаг anc (активное шумоподавление) поднимается в «плоский» DTO из характеристик, чтобы
виджет фильтровал грид без запроса деталки на каждый товар. null означает «характеристики
нет в снапшоте», а не «шумоподавления нет».
Требования
Node.js 22+ (рекомендуется 24)
pnpm 11+
Сборка
pnpm install
pnpm build # сначала собирает HTML-бандлы UI, затем серверpnpm build сначала собирает UI (самодостаточные HTML со встроенными JS/CSS — без внешних
источников, как требует песочница-iframe), затем компилирует сервер, который на старте
читает эти HTML и регистрирует как ui:// ресурсы.
Превью виджета в браузере
Посмотреть виджет без Claude Desktop:
pnpm --filter @mcp-app-proxyfier/ui exec vite
# → http://localhost:5173/preview.htmlРендерит те же компоненты вью, что и боевое приложение, на настоящем ответе сервера.
Работают чипы фильтров, заход в карточку и возврат в отфильтрованный список. Кейс
открывается ссылкой: ?case=friday, ?case=detail, ?case=cart.
Фикстуры пересобираются с живого сервера, руками их править не надо:
pnpm build # превью читает ответы собранного сервера
pnpm update:fixtures # → packages/ui/src/preview/fixtures.jsonДаты доставки в фикстуре заморожены на момент снятия (превью — про вёрстку, не про
календарь). Протухли подписи вроде «Завтра» — просто перезапустите update:fixtures.
Чего в превью нет: postMessage-моста и вызовов инструментов — «Подробнее» берёт деталку из
фикстуры, а не дёргает get_product; «В корзину» показывает снимок корзины, а не вызывает
add_to_cart. Мост и рендер iframe проверяются только вживую, в Claude Desktop (см.
«Ручная проверка рендера» ниже). В продакшен-сборку превью не попадает: pnpm build:ui
собирает только index и megamarket.
Тесты
pnpm test # typecheck (включая тесты) + прогонТесты проверяют внешнее поведение через швы: инструменты MCP как чёрные ящики (поднимается
настоящий McpServer на in-memory транспорте), загрузку статического каталога (включая
деградацию товара без богатой детали), сроки доставки, реестр скиллов и выбор транспорта.
Рендер iframe проверяется вручную (см. ниже) — в CI его нет.
Тесты тайпчекаются вместе с кодом: гоняет их tsx, который типы не проверяет, поэтому
раньше tsc молча зеленел на тестах, ссылающихся на удалённые модули. Сборка идёт отдельным
конфигом (tsconfig.build.json), чтобы тесты не попадали в dist/.
Запуск / регистрация в Claude Desktop
Сервер говорит по MCP через stdio: Claude Desktop запускает его как дочерний процесс.
После pnpm build пропишите его в конфиг Claude Desktop.
Расположение файла конфигурации:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Добавьте (замените путь на абсолютный путь к этому репозиторию):
{
"mcpServers": {
"mcp-app-proxyfier": {
"command": "node",
"args": ["/absolute/path/to/mcp-app-proxyfier/packages/server/dist/index.js"]
}
}
}Затем полностью закройте и заново откройте Claude Desktop.
Ручная проверка рендера (главный риск демо)
Главный риск — баг рендера iframe на хосте (ext-apps #671): клиент согласует UI-возможность и тянет ресурс, но не рисует iframe. Поэтому его проверяют глазами на боевой сборке.
В чате Claude Desktop попросите модель вызвать инструмент ping (например, «вызови
инструмент ping с echo hello»). Убедитесь визуально:
В чате нарисован интерактивный iframe (карточка с заголовком «MCP App Proxyfier»), а не только текстовый результат.
Карточка показывает
message: pong,echo: helloи таймстамп — то естьstructuredContentинструмента дошёл до UI через мост.
Если виден только текст и iframe не рисуется — баг #671 воспроизведён: зафиксируйте версию Claude Desktop и держите наготове запасной текстовый сценарий для демо.
Абстракция транспорта
Сервер не зависит от транспорта. Инструменты и ресурсы регистрируются на McpServer без
знания о канале. Транспорт выбирается за швом ServerTransportProvider
(packages/server/src/transport/): stdio (по умолчанию) и http (Streamable HTTP). Оба
провайдера регистрируют ровно те же инструменты и ui:// ресурсы — добавление HTTP не
потребовало правок кода инструментов или ресурсов.
Транспорт выбирается флагом или переменной окружения (флаг приоритетнее):
Параметр | Флаг | Env | По умолчанию |
Транспорт |
|
|
|
Интерфейс прослушивания |
|
|
|
Порт |
|
|
|
Путь эндпоинта |
|
|
|
Bearer-токен |
|
| (выкл.) |
Флаги понимают обе формы: --port 3000 и --port=3000.
Удалённый коннектор (Streamable HTTP)
Для демо, где владелец подключает коннектор сам (custom connector в claude.ai), а не Claude Desktop запускает его локально. Это альтернативный канал к тому же серверу — stdio-демо он не блокирует.
Соберите и запустите сервер по HTTP (слушает на
127.0.0.1:3000/mcp). Туннель делает порт публичным, поэтому задайтеMCP_HTTP_TOKEN— запросы безAuthorization: Bearer <token>отклоняются с401:pnpm build MCP_TRANSPORT=http MCP_HTTP_TOKEN="$(openssl rand -hex 16)" pnpm start # токен выкл. (только локально, без туннеля): pnpm start -- --transport httpОткройте публичный HTTPS-туннель к этому локальному порту:
cloudflared tunnel --url http://127.0.0.1:3000 # → печатает https://<random>.trycloudflare.com # альтернатива ngrok: # ngrok http 3000 → https://<random>.ngrok-free.appURL коннектора — это origin туннеля плюс путь эндпоинта, например
https://<random>.trycloudflare.com/mcp.В claude.ai → Settings → Connectors → Add custom connector вставьте этот URL (и Bearer-токен в поле авторизации коннектора, если вы его задали). Claude инициализирует сессию Streamable HTTP и показывает те же инструменты и
ui://приложения, что и stdio.
Ручная проверка (рендер iframe на хосте, ext-apps #671). Как и для stdio, убедитесь визуально, что результат инструмента рисует интерактивный iframe в чате claude.ai, а не только текст. Баг рендера #671 — клиентский и не связан с транспортом, но его нужно перепроверить на claude.ai: сборка хоста отличается от Claude Desktop.
Замечания:
Один запущенный процесс держит одну сессию Streamable HTTP — одного докладчика за туннелем.
Реконнект = перезапуск. При чистом отключении claude.ai шлёт завершение сессии и повторное подключение работает; после грязного обрыва (туннель умер) проще всего
Ctrl-Cи заново--transport http, если коннектор потерял сессию.Прослушивание остаётся на localhost намеренно; не слушайте
0.0.0.0— доступ к серверу только через туннель. Защита от DNS-rebinding выключена намеренно (host туннеля динамический); доступ охраняет Bearer-токенMCP_HTTP_TOKEN.После демо погасите туннель — URL является секретом.
Maintenance
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
- FlicenseAqualityDmaintenanceAn MCP server that connects AI assistants to SearchAgora, enabling users to search for, discover, and purchase products across the web through natural language conversations.62
- Flicense-qualityDmaintenanceA Model Context Protocol server that enables AI assistants to interact with a complete e-commerce application, providing authentication, product browsing, and shopping cart management through standardized MCP tools.
- Alicense-qualityDmaintenanceMCP server that connects Carrefour Drive to Claude and other MCP clients, enabling product search with real prices, nutriscore, availability, and natural language cart management.MIT
- Alicense-qualityBmaintenanceAI customer support MCP server with order status lookup and RAG-powered knowledge base search for e-commerce stores.MIT
Related MCP Connectors
Connect e-commerce and marketing data to AI assistants via MCP.
Remote MCP for Universal Cart merchant readiness MCP, structured receipts, audit logs, and reviewer-
Agent Commerce MCP — agent-native A2A storefront. Discovery, Stripe checkout, affiliate program.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/DreamShaded/MCP-Apps-data-proxyfier'
If you have feedback or need assistance with the MCP directory API, please join our Discord server