Skip to main content
Glama
billy-yoyo

React MCP SPA

by billy-yoyo

React MCP SPA

Минималистичное одностраничное приложение (SPA) на React, упакованное в один HTML-файл и обслуживаемое сервером MCP Apps. SPA не использует маршрутизацию по URL-путям — оно выбирает, какую страницу отобразить, считывая имя текущего инструмента из контекста хоста MCP.

Структура

  • packages/ui/ — SPA на React + Vite, собираемое в единый HTML-файл с помощью vite-plugin-singlefile.

  • packages/mcp/ — MCP-сервер, использующий @modelcontextprotocol/ext-apps/server. Регистрирует инструменты (show-home, show-counter, show-profile), которые указывают на один и тот же ресурс ui://.

  • packages/playground/ — инструмент для разработки, который отображает SPA внутри имитации чата с JSON-вводами для hostContext и toolResult, чтобы страницы можно было тестировать без MCP-хоста.

Related MCP server: @businessmaps/mcp

Установка

Требуется Node.js версии ≥ 20 и pnpm версии ≥ 9.

pnpm install

Разработка UI в изоляции

pnpm run dev:ui

Откройте указанный URL (например, http://localhost:5173). SPA обнаружит отсутствие MCP-хоста и покажет выбор маршрута, чтобы вы могли просмотреть каждую страницу.

Playground — тестирование рендеринга без MCP

pnpm run dev:playground

Открывается по адресу http://localhost:5174. Playground повторно использует реальный рендерер маршрутов SPA (RouteRenderer из packages/ui/src/Router.tsx) и оборачивает его в имитацию чата. В заголовке есть два текстовых поля JSON — одно для hostContext (определяет, какая страница отображается через toolInfo.tool.name), и другое для toolResult, передаваемого на страницу. Кнопки пресетов загружают готовые пары контекст+результат для каждого зарегистрированного инструмента; изменения в любом из текстовых полей обновляют вывод инструмента помощника в реальном времени.

Сборка и запуск MCP-сервера

pnpm run build       # builds packages/ui → dist/index.html, then packages/mcp
pnpm run serve:mcp   # starts Streamable HTTP server on http://localhost:3001/mcp

Для транспорта stdio:

pnpm --filter @react-mcp-spa/mcp run serve:stdio

Публикация сервера через cloudflared

Некоторые MCP-клиенты (включая облачные) не могут получить доступ к localhost. Используйте cloudflared, чтобы открыть быстрый туннель, который присваивает публичный HTTPS URL.

Установите cloudflared через менеджер пакетов вашей ОС:

# macOS (Homebrew)
brew install cloudflared

# Linux (Debian/Ubuntu)
# See https://pkg.cloudflare.com/ for the apt repo, or grab the .deb from
# https://github.com/cloudflare/cloudflared/releases

# Windows (winget)
winget install --id Cloudflare.cloudflared

Запустите сервер локально:

pnpm run serve:mcp

В другом терминале выполните:

cloudflared tunnel --url http://localhost:3001
# or: pnpm run tunnel

cloudflared выведет URL вида https://<random>.trycloudflare.com. Добавьте /mcp и используйте его как URL вашего MCP-сервера:

https://<random>.trycloudflare.com/mcp

Туннель остается активным, пока вы не завершите работу cloudflared. Для получения стабильного имени хоста настройте именованный туннель Cloudflare вместо быстрого туннеля.

Упаковка в качестве расширения Claude Desktop (.mcpb)

В репозитории есть упаковщик, который создает устанавливаемый MCP Bundle для Claude Desktop. Расширение запускает сервер через stdio — туннель не требуется.

pnpm run pack:mcpb

Эта команда собирает оба пакета, подготавливает скомпилированный сервер + UI HTML + рабочие node_modules в папке build/mcpb-staging/ и вызывает mcpb pack для создания:

build/react-mcp-spa.mcpb

Чтобы установить его, дважды щелкните файл .mcpb в Finder/Explorer (или перетащите его в Claude Desktop). Claude проверит манифест и зарегистрирует сервер; после установки три инструмента (show-home, show-counter, show-profile) станут доступны, и каждый из них будет отображать свою страницу как встроенный React UI.

Манифест пакета находится в mcpb/manifest.json — обновляйте там version (а также в packages/mcp/package.json) при выпуске новой версии расширения.

Как работает маршрутизация

SPA никогда не считывает window.location. Вместо этого packages/ui/src/App.tsx использует useApp() из @modelcontextprotocol/ext-apps/react и:

  1. Считывает app.getHostContext().toolInfo.tool.name, чтобы узнать, какой инструмент вызвал хост — это и есть "маршрут".

  2. Подписывается на app.ontoolresult, чтобы получить CallToolResult от сервера и передать его на страницу в качестве данных.

  3. Отслеживает app.onhostcontextchanged, чтобы обновления темы, безопасных областей (safe-area) или локали корректно перерисовывались.

Добавление новой страницы — это двухэтапный процесс:

  1. Зарегистрируйте инструмент в packages/mcp/src/server.ts с _meta.ui.resourceUri, указывающим на общий ресурс ui://react-mcp-spa/app.html.

  2. Добавьте case для имени инструмента в renderRoute() внутри packages/ui/src/App.tsx.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server built with the mcp-framework for developing and managing custom tools. It provides a structured foundation for building and integrating modular components like data processors and API clients into Claude Desktop.
    11 npm
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP bridge server that allows AI tools to call functions and execute code directly within a web browser tab. It enables developers to register custom browser-side tools with full access to the DOM, web APIs, and local application state.
    14 npm
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    A minimal todo app MCP server for ChatGPT that exposes tools for managing tasks and provides an interactive HTML widget interface. It demonstrates how to build MCP servers with React-based UIs and includes development OAuth for ChatGPT connector setup.
    -