About
AI assistant for appointments in Telegram (cousework)
README
Телеграм-бот, который принимает записи к специалистам на естественном языке. Пользователь пишет «Хочу к стоматологу в Казани на завтра утром», а LLM-агент сам находит врача, проверяет свободные слоты в расписании и создаёт запись — без кнопок, меню и пошаговых форм.
Ключевая идея проекта: бизнес-логика живёт в обычном REST API, а языковая модель получает к ней доступ через MCP (Model Context Protocol) — как к набору инструментов. Модель не знает про базу данных и не пишет SQL; она вызывает те же операции, которые доступны любому другому клиенту API.
Стек: Python 3.11 · aiogram 3 · LangChain + Ollama (qwen3:8b, локальная LLM) · MCP (mcp, mcp-use) · Django 4.2 + Django REST Framework · SQLite · Docker Compose
Что бот умеет
- Найти специалиста по специализации, городу или категории услуг
- Показать свободные слоты врача на конкретную дату (сетка по 30 минут, с учётом графика работы и уже занятых часов)
- Записать на приём — время окончания рассчитывается автоматически из длительности услуги
- Подтвердить, отменить или закрыть запись (
pending → confirmed → completed/cancelled) - Ответить на вопросы об услугах, ценах, расписании и категориях
- Держится в рамках роли: системный промпт ограничивает агента темой медцентра и записей
Каталог, расписания и записи параллельно доступны через админку Django и Swagger UI.
Как это устроено
flowchart LR
subgraph bot["telegram_bot/"]
BOT["bot.py<br/>aiogram, polling"]
AGENT["MCPAgent<br/>до 30 шагов"]
MCP["mcp_server.py<br/>6 tools + 12 resources"]
BOT <--> AGENT
AGENT <-->|"MCP / stdio"| MCP
end
subgraph api["api/"]
DRF["Django REST API<br/>6 ViewSet'ов, бизнес-правила"]
DB[("SQLite")]
DRF <--> DB
end
TG(["Telegram"]) <--> BOT
AGENT <-->|"промпт / ответ"| OLLAMA["Ollama<br/>qwen3:8b"]
MCP <-->|"REST / JSON"| DRF
Полный цикл одного запроса:
sequenceDiagram
actor U as Пользователь
participant B as bot.py
participant A as MCPAgent
participant M as MCP-сервер
participant D as Django API
U->>B: «Запиши к стоматологу на завтра в 11:00»
B->>A: текст + Telegram ID отправителя
A->>M: search_specialists(specialization, city)
M->>D: GET /api/specialists/?search=...
D-->>M: список специалистов
M-->>A: результат
A->>M: get_available_slots(specialist_id, date)
M->>D: GET /api/specialists/{id}/available_slots/
D-->>M: свободные слоты
M-->>A: результат
A->>M: create_appointment(...)
M->>D: GET /api/services/{id}/ — длительность, расчёт end_time
M->>D: POST /api/appointments/
Note over D: validate(): пересечения<br/>и график работы
D-->>M: созданная запись
M-->>A: результат
A-->>B: текст ответа
B->>U: «Записал: завтра 11:00–11:30»
1. Бот (telegram_bot/bot.py) — тонкий слой. Принимает сообщение, добавляет к нему Telegram ID отправителя (чтобы агент мог связать собеседника с клиентом в базе), отдаёт MCPAgent. Ответ модели чистится от блока рассуждений <think>...</think>, которые генерирует qwen3, и уходит пользователю.
2. Агент — MCPAgent из mcp-use поверх ChatOllama. До 30 шагов цикла «рассуждение → вызов инструмента → анализ результата». Модель работает локально в Ollama: данные пациентов не уходят во внешние API.
3. MCP-сервер (telegram_bot/mcp_server.py) — мост между моделью и API, запускается через stdio.
- 6 tools (действия):
search_specialists,get_available_slots,create_appointment,confirm_appointment,cancel_appointment,complete_appointment - 12 resources (чтение): специалисты, их услуги и расписания, услуги, категории, записи, клиенты
- Docstring каждого инструмента — это и есть его спецификация для модели: по ним LLM понимает, что принимает аргумент
dateв форматеYYYY-MM-DD, аstart_time—HH:MM. - Самая содержательная логика здесь —
create_appointment: инструмент сам подтягивает длительность услуги и вычисляетend_time, чтобы модели не приходилось считать время.
4. Django REST API (api/) — источник правды и место, где живут инварианты.
- Модели:
ServiceCategory,Specialist,SpecialistSchedule,Service,Client,Appointment GET /api/specialists/{id}/available_slots/?date=...— генерация слотов: берётся график на нужный день недели, режется на интервалы по 30 минут, из них вычитаются пересечения с активными записямиAppointmentSerializer.validate()— двойная защита: запись не создастся, если время пересекается с существующей (pending/confirmed) или выходит за пределы графика работы специалиста. Даже если модель ошибётся, API её остановит.- Swagger/ReDoc через
drf-yasg
Почему MCP, а не function calling напрямую. Инструменты описаны один раз на стороне сервера и не привязаны ни к боту, ни к конкретной модели. Тот же mcp_server.py можно подключить к другому клиенту (Claude Desktop, IDE, веб-чат), а модель в боте заменить одной строкой — контракт не меняется.
Схема данных
| Модель | Назначение |
|---|---|
ServiceCategory |
Категории услуг (Красота, Здоровье, Фитнес) |
Specialist |
Врач/мастер: специализация, город, фото, привязка к User |
SpecialistSchedule |
График по дням недели (unique_together на специалиста и день) |
Service |
Услуга: цена, длительность в минутах, специалист, категория |
Client |
Клиент: телефон, email, город, telegram_id |
Appointment |
Запись: клиент, услуга, специалист, дата, интервал, статус |
Запуск
Требования
- Docker и Docker Compose
- Ollama с загруженной моделью:
ollama pull qwen3:8b - Бот в Telegram, созданный через @BotFather
1. Переменные окружения
Создайте .env в корне проекта:
BOT_TOKEN=<токен от BotFather>
OLLAMA_URL=http://host.docker.internal:11434
host.docker.internal позволяет контейнеру достучаться до Ollama, запущенной на хосте (macOS/Windows). На Linux используйте http://172.17.0.1:11434 или запустите Ollama в той же Docker-сети.
2. Поднять сервисы
docker compose up --build
3. Применить миграции и наполнить базу
docker compose exec api python manage.py migrate
docker compose exec api python manage.py create_test_data
Команда create_test_data создаёт категории, специалистов с расписаниями, услуги и тестовых клиентов, а также администратора admin / admin.
4. Проверить
- Swagger: http://localhost:8000/swagger/
- Админка: http://localhost:8000/admin/
- Бот: напишите ему
/startв Telegram
Локальный запуск без Docker
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# терминал 1 — API
cd api && python manage.py migrate && python manage.py create_test_data
python manage.py runserver 8000
# терминал 2 — бот (MCP-сервер поднимается им автоматически через stdio)
cd telegram_bot && python bot.py
Примеры диалога
👤 Есть стоматологи в Казани?
🤖 Да, принимает Иванов Пётр Сергеевич — стоматолог, Казань.
Услуги: консультация (30 мин, 1500 ₽), лечение кариеса (60 мин, 4500 ₽).
👤 Какие есть окна на 15 июня?
🤖 Свободно: 09:00–09:30, 09:30–10:00, 11:00–11:30, 14:00–14:30.
👤 Запиши на консультацию в 11:00
🤖 Записал: 15 июня, 11:00–11:30, консультация у Иванова П. С.
Статус — ожидает подтверждения.
Технические решения и компромиссы
Что сделано осознанно:
- Локальная LLM. Медицинские данные не покидают инфраструктуру — для домена это не опция, а требование.
- Валидация на стороне API, а не промпта. LLM недетерминирована; пересечения слотов и выход за график ловятся в сериализаторе, где ошибиться нельзя.
- Расчёт
end_timeвнутри MCP-инструмента. Арифметика со временем — плохая задача для модели, поэтому она отдана коду. - Разделение tools и resources. Действия, меняющие состояние, отделены от чтения — модель не может «случайно» что-то создать, читая справочник.
Что осталось за рамками текущей версии:
- Аутентификация:
permission_classes = [AllowAny]и placeholder-токен в MCP-сервере — рабочая конфигурация для демо, но перед продакшеном нужен реальный Token/JWT-слой. mcp_server.pyходит наhttp://localhost:8000— при запуске в Docker Compose адрес нужно поменять наhttp://api:8000(или вынести в переменную окружения).- SQLite и
runserver— dev-конфигурация; для боевого контура нужны PostgreSQL и ASGI-сервер. telegram_idесть в моделиClient, но не попал вClientSerializer— связка «Telegram-пользователь ↔ клиент в базе» пока делается через передачу ID в промпте.- Нет истории диалога между сообщениями: каждый запрос обрабатывается независимо.
Структура проекта
.
├── api/ # Django REST API
│ ├── boba/ # settings, urls, swagger
│ └── booking/
│ ├── models.py # 6 моделей предметной области
│ ├── serializers.py # валидация пересечений и графика
│ ├── views.py # ViewSet'ы, генерация слотов, экшены статусов
│ └── management/commands/create_test_data.py
├── telegram_bot/
│ ├── bot.py # aiogram + MCPAgent + Ollama
│ └── mcp_server.py # 6 tools + 12 resources поверх REST API
└── docker-compose.yaml
Installing Telegram Agent
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/om1ji/telegram-agentFAQ
Is Telegram Agent MCP free?
Yes, Telegram Agent MCP is free — one-click install via Unyly at no cost.
Does Telegram Agent need an API key?
No, Telegram Agent runs without API keys or environment variables.
Is Telegram Agent hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Telegram Agent in Claude Desktop, Claude Code or Cursor?
Open Telegram Agent on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Gmail
Read, send and search emails from Claude
by GoogleSlack
Send, search and summarize Slack messages
by SlackRunbear
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
Discord Server
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)
Klavis AI
Open Source MCP Infra. Hosted MCP servers and MCP clients on Slack and Discord.
Work90210/APIFold
Turn any REST API into a hosted MCP server. 18 free public servers (GitHub, Stripe, Slack, OpenAI, Notion, and more) — no setup required, bring your own API key
by Work90210arikusi/deepseek-mcp-server
MCP server for DeepSeek AI with chat, reasoning, multi-turn sessions, function calling, thinking mode, and cost tracking.
by arikusihashgraph-online/hashnet-mcp-js
MCP server for the Registry Broker. Discover, register, and chat with AI agents on the Hashgraph network.
by hashgraph-onlineprofullstack/mcp-server
A comprehensive MCP server aggregating 20+ tools including SEO optimization, document conversion, domain lookup, email validation, QR generation, weather data,
by profullstackWayStation-ai/mcp
Seamlessly and securely connect Claude Desktop and other MCP hosts to your favorite apps (Notion, Slack, Monday, Airtable, etc.). Takes less than 90 secs.
by waystation-aiCompare Telegram Agent with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All communication MCPs
