mcp-coffee
Click on "Deploy 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-coffeeorder two cappuccinos"
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 Coffee — учебный проект по Model Context Protocol
Telegram-бот кофейни, который принимает заказы в свободной форме («два капучино и латте»), записывает их в Excel и сообщает время готовности. Главная цель проекта — разобраться, как устроен MCP изнутри: и сервер, и клиент написаны вручную, tool use реализован ручной петлёй поверх OpenAI, без готовых агентских врапперов.
Что демонстрирует проект
MCP-сервер на TypeScript — три инструмента, транспорт Streamable HTTP, сессии по заголовку
mcp-session-id.MCP-клиент — подключение,
tools/list,tools/call.Ручная петля tool use — модель сама извлекает структуру заказа из текста; мы перехватываем вызовы инструментов, исполняем их через MCP и возвращаем результат в диалог, пока модель не ответит текстом.
Разделение слоёв — хранение (Excel) отделено от бизнес-логики (инструменты) и от «мозга» (бот).
Related MCP server: cafe-mcp-server
Архитектура
Система состоит из трёх независимых частей:
Часть | Файл | Ответственность |
MCP-сервер |
| 3 инструмента + Express/Streamable HTTP на |
Слой хранения |
| Чтение |
MCP-клиент |
|
|
Бот |
| Telegram + OpenAI + ручная петля tool use. |
Ключевой принцип: сервер не знает про OpenAI, а OpenAI не знает про Excel. Бот посередине — переводчик между ними.
Поток данных
Пользователь в Telegram: "два капучино"
│
▼
[bot.ts] получает текст
│
▼
[bot.ts] → OpenAI: сообщение + список инструментов (function calling)
│
▼
OpenAI решает вызвать create_order({items:[{drink:"капучино",qty:2}]})
│
▼
[bot.ts] перехватывает вызов ← РУЧНАЯ ПЕТЛЯ
│
▼
[mcpClient] → [index.ts] tools/call create_order(...)
│
▼
[index.ts] читает menu.xlsx (время), пишет строку в orders.xlsx
│
▼
результат {id, totalMinutes} → обратно в OpenAI
│
▼
OpenAI формулирует ответ: "Заказ №7 принят, готовность ~8 мин"
│
▼
[bot.ts] → TelegramИнструменты MCP
Инструмент | Аргументы | Возвращает |
| — | список напитков |
|
| напитки, у которых ключевое слово есть в составе/названии |
|
|
|
|
|
|
Описания инструментов и схемы аргументов — на английском: это контракт для модели, по которому она выбирает инструмент и заполняет аргументы.
Технологии
TypeScript · @modelcontextprotocol/sdk · Express · OpenAI SDK ·
Telegraf · ExcelJS · zod · Node.js 24
Запуск
npm install
cp .env.example .env # впиши OPENAI_API_KEY и TELEGRAM_BOT_TOKEN.env:
OPENAI_API_KEY=sk-...
TELEGRAM_BOT_TOKEN=123456:ABC-...
OPENAI_MODEL=gpt-4o-mini
MCP_URL=http://localhost:3000/mcpДва терминала:
npm run dev # 1-й: MCP-сервер на :3000
npm run dev:bot # 2-й: Telegram-ботДальше пиши боту: «два капучино и латте» → получишь номер и время; «когда готов заказ 3?» → остаток минут до готовности.
Команды
Команда | Что делает |
| MCP-сервер (tsx watch) |
| Telegram-бот (tsx watch) |
| сборка в |
| запуск собранного сервера |
| юнит-тесты (встроенный |
Структура
src/
├── index.ts точка входа: MCP-сервер (инструменты + HTTP-транспорт)
├── bot.ts точка входа: Telegram + OpenAI + ручная петля tool use
├── config.ts настройки в одном месте (модель, порт, лимиты)
├── domain/ ЧИСТАЯ логика без I/O (тестируется без запуска сервера)
│ ├── search.ts поиск по составу
│ ├── orders.ts расчёт заказа: проверка меню, время
│ └── history.ts обрезка окна контекста
├── infra/ адаптеры к внешнему миру
│ ├── excel.ts слой хранения (ExcelJS)
│ └── mcpClient.ts MCP-клиент (с авто-переподключением)
└── tests/ юнит-тесты к чистой логике
data/
└── menu.xlsx меню (напиток | цена | время_приготовления_мин | состав)
orders.xlsx создаётся при первом заказеАрхитектура: точки входа наверху, чистое ядро (domain/) отделено от
адаптеров к внешнему миру (infra/). Благодаря этому логику можно
тестировать, не запуская сервер и бота.
Принятые решения и почему
Этот раздел — самое важное в проекте: он показывает понимание, а не только код.
Ручная петля tool use вместо готового агента. Цель — увидеть механику: как модель возвращает
tool_calls, как результат с рольюtoolиtool_call_idпривязывается к конкретному вызову, как цикл повторяется. Это понимание дороже, чем «подключил библиотеку».Поиск по составу — это retrieval, а не исправление опечаток. Нормализацию текста («КАПУЧино», «капуччино») делает сама LLM — дублировать её на сервере бессмысленно. А вот состав напитков лежит в Excel, и в контексте модели его нет: по названию «Розовая волна» не угадать, что там арбузный сироп. Поэтому
search_menuоправдан: LLM извлекает ключевое слово («арбуз»), а сервер находит напитки по данным, которых у модели нет. Это тот же паттерн, что и поиск по большому каталогу, который не помещается в окно контекста.Расчёт времени — в инструменте, не в слое хранения. Чтобы посчитать общее время, нужно сопоставить заказ с меню — это та же операция, что и валидация «существует ли напиток». Логично держать в одном месте.
excel.tsостаётся тупым хранилищем: поменяем формулу — слой хранения не трогаем.Общее время = сумма
время × количество. Сознательное упрощение для модели «один бариста по очереди». Легко заменить на максимум (параллельная готовка) — правка в одном месте, в обработчикеcreate_order.Описания инструментов на английском, общение — на русском. Описания и
.describe()— контракт для модели (выбор инструмента, заполнение аргументов): на английском надёжнее для function calling и экономнее по токенам. Тексты ошибок — на русском: они возвращаются модели как данные, и она пересказывает их пользователю.Язык ответа задан в системном промпте.
gpt-4o-miniиногда вставляет иноязычные слова. Явное требование «отвечай только по-русски» в системном промпте убирает большинство таких сбоев; при необходимости можно дополнительно понизитьtemperature.Сессии MCP по
mcp-session-id. Один разговор клиента с сервером = одна сессия со своим транспортом; так несколько клиентов не мешают друг другу.Автопереподключение к MCP. Сессии живут в памяти сервера: после его рестарта
mcp-session-idбота протухает, и сервер отвечает 400. Чтобы бот не падал на каждом сообщении до перезапуска,McpClientпри ошибке запроса один раз переподключается (новая сессия) и повторяет вызов.Управление окном контекста — обрезка по границам ходов. История растёт с каждым сообщением и упёрлась бы в лимит токенов. Обрезаем до
MAX_TURNSпоследних ходов, но не как попало: у tool-use есть инвариант —assistantсtool_callsобязан сопровождатьсяtool-ответами с теми жеtool_call_id. Поэтому окно всегда начинается с сообщенияuserи системное сообщение сохраняется — иначе «осиротевший»toolдал бы ошибку 400.
Известные ограничения
История диалога хранится в памяти процесса — перезапуск бота её обнуляет.
Обрезка контекста — по числу ходов (
MAX_TURNS), а не по токенам. Точнее было бы считать токены (tiktoken), но для учебного проекта порога по ходам достаточно.Юнит-тесты на чистую логику гоняются в CI (GitHub Actions) на каждый push.
This server cannot be deployed
Maintenance
Related MCP Connectors
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Appreciate teammates, celebrate milestones, and run workspace ops from MCP clients via OAuth.
- MaShop MCPOAuthapp.mashop
Build, deploy and manage MaShop e-commerce projects from Claude, Cursor or any MCP client.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for Starbucks — let AI agents search the menu, customize drinks, find stores, place mobile pickup orders, and manage Starbucks Rewards.1639 npm1MIT
- FlicenseAqualityBmaintenanceMCP server that recommends coffee based on preferences (mood, milk, caffeine, temperature) from a static menu; includes tools for listing menu, recommending, and explaining recommendations.3-
- FlicenseNot gradedqualityCmaintenanceEnables natural language interaction with a coffee shop's inventory and order system, allowing users to check menu items, place orders, and track order status via MCP tools.-
- FlicenseNot gradedqualityCmaintenanceEnables interaction with a Web Shop backend API through MCP, allowing users to browse products, create and view orders, and admins to manage all orders and users.-