inventory-mcp
inventory-mcp
Демонстрационный MCP-сервер для запросов инвентаря, разработанный на Python с использованием FastMCP. Проект поддерживает изучение основных концепций Model Context Protocol (MCP), с разделением на транспорт, MCP-интерфейс, бизнес-правила, валидацию и данные.
Текущая область намеренно предназначена только для чтения: сервер позволяет запрашивать товары и количество на складе без операций создания, изменения или удаления.
Технологии
Python 3.11+
FastMCP
Pydantic
pytest
Ruff
Related MCP server: vanam-erp-mcp
Архитектура
app/server.py: создаёт сервер FastMCP, регистрирует инструменты и запускает транспортstdioили SSE.app/client.py: демонстрационный клиент, который перечисляет и вызывает инструменты черезstdioили SSE.app/tools/: MCP-интерфейс; проверяет входные данные, делегирует сервису и преобразует ожидаемые ошибки в стабильные ответы.app/services/: правила запросов и загрузки инвентаря.app/schemas/: Pydantic-модели, которые определяют и проверяют контракты товара и запасов.app/data/: локальный источник данных, в настоящее время файлinventory.json.tests/: автоматические тесты сервиса, инструментов и конфигурации сервера.
Client → MCP Server → Tool → InventoryService → inventory.jsonИнструменты не обращаются к файлу напрямую. Они делегируют бизнес-правила в InventoryService.
MCP-инструменты
get_product
Назначение: запросить полные данные товара по имени.
Вход:
name(stringне пустая).Вывод в случае успеха: объект с
name,quantityиprice.Вывод для несуществующего товара: объект с
error: "product_not_found"и описательнымmessage.Описание MCP:
Use this tool to retrieve the complete data of a product by name, including its price and stock quantity.Классификация: только чтение.
{
"name": "Mouse",
"quantity": 25,
"price": 89.9
}get_stock
Назначение: запросить только текущее количество товара по имени.
Вход:
name(stringне пустая).Вывод в случае успеха: объект с
quantity.Вывод для несуществующего товара: объект с
error: "product_not_found"и описательнымmessage.Описание MCP:
Use this tool to retrieve only the current stock quantity of a product by name.Классификация: только чтение.
{
"quantity": 25
}Проверка входных данных
Инструменты требуют, чтобы name была строкой с содержимым. Пустые имена или имена, состоящие только из пробелов, отклоняются до запроса. Сервис применяет strip() для удаления пробелов по краям и casefold() для сравнения имён без учёта регистра.
Pydantic проверяет записи, загруженные из JSON, и выходные модели. Товар должен иметь непустое имя, целое неотрицательное количество и неотрицательное числовое значение цены. Отклонение пустых имён запросов выполняется через _validate_product_name(). Недействительные записи прерывают загрузку с явной ошибкой.
Обработка ошибок
InventoryService вызывает ProductNotFoundError, когда не находит запрошенный товар. Инструменты перехватывают эту ожидаемую ошибку и возвращают предсказуемую полезную нагрузку:
{
"error": "product_not_found",
"message": "Product not found: Monitor"
}Ошибки ввода, такие как пустое имя или значение, не являющееся строкой, не скрываются: они сообщаются как ошибки вызова инструмента.
Транспорты MCP
stdio: общается через стандартный ввод и вывод. В этом проекте клиент запускает сервер FastMCP как подпроцесс, выполняет вызовы и завершает процесс по окончании.SSE: общается через HTTP-эндпоинт с Server-Sent Events. Сервер и клиент работают в отдельных процессах; по умолчанию сервер принимает запросы на
http://127.0.0.1:8000/sse.
Как выполнить
Приведённые ниже команды используют PowerShell и должны выполняться в корне проекта.
Создание и активация виртуального окружения
python -m venv .venv
.\.venv\Scripts\Activate.ps1Установка зависимостей
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"Запуск через stdio
Клиент использует stdio по умолчанию и запускает сервер как подпроцесс:
.\.venv\Scripts\python.exe -m app.clientЧтобы запустить только сервер напрямую:
.\.venv\Scripts\python.exe -m app.server --transport stdioЗапуск через SSE
Запустите сервер в терминале (sse — транспорт по умолчанию для сервера):
.\.venv\Scripts\python.exe -m app.serverЭквивалентная явная команда — python -m app.server --transport sse. В другом терминале подключите клиент:
.\.venv\Scripts\python.exe -m app.client --transport sseКлиент принимает другой endpoint через --url.
Запуск тестов
.\.venv\Scripts\pytest.exeЗапуск Ruff
.\.venv\Scripts\ruff.exe check .
.\.venv\Scripts\ruff.exe format --check .Оценка риска инструментов
Текущие инструменты предназначены только для чтения и не могут создавать, изменять или удалять данные. Это решение снижает поверхность риска, но не устраняет возможные последствия для конфиденциальности и доступности.
Инструмент | Доступные данные | Операция | Текущий риск | Возможное последствие неправомерного использования |
| Имя, цена и количество | Чтение | Низкий | Раскрытие или перечисление информации об инвентаре |
| Доступное количество | Чтение | Низкий | Перечисление запасов и чрезмерное отслеживание доступности |
Вызовы в больших объёмах по-прежнему могут потреблять ресурсы сервера. Будущие изменения в инструментах или возвращаемых данных должны сопровождаться новой оценкой риска.
Граница доверия
Аргументы, полученные от MCP-клиента, рассматриваются как ненадёжные входные данные.
MCP Client
↓
MCP Server
↓
Tool
↓
InventoryService
↓
inventory.jsonПроверка происходит до того, как аргументы будут использованы сервисным слоем. Сервер не считает данные, отправленные клиентом, действительными только потому, что они пришли по протоколу MCP. Записи из inventory.json также рассматриваются как внешние входные данные и проверяются с помощью Pydantic во время загрузки.
Аннотации MCP-инструментов
Инструменты классифицируются семантически в соответствии с их поведением. Текущие две операции объявляют:
readOnlyHint=true
openWorldHint=falsereadOnlyHint=true сообщает MCP-клиенту, что операция не предназначена для изменения состояния.
openWorldHint=false указывает, что инструмент работает в закрытой и известной области — в данном случае в локальном инвентаре — вместо обращения к внешним системам или открытым источникам.
Эти аннотации работают как метаданные и подсказки для MCP-клиентов, не как механизмы безопасности. Клиент не должен полагаться на них как на замену валидации, авторизации или других реальных контролей.
Риск инструментов записи
Будущая операция, например:
update_stock(name, quantity)будет иметь значительно больший риск, поскольку изменит постоянное состояние системы.
Некорректный или вредоносный вызов может изменить не тот товар, записать недействительные значения или допустить несанкционированные изменения. Будущий инструмент, такой как update_stock, потребовал бы строгой валидации, аутентификации, авторизации, аудита и трассировки. Деструктивные операции также потребовали бы подтверждения или одобрения, когда это применимо.
Риск по транспорту
При stdio сервер запускается локально как подпроцесс клиента, что снижает сетевую экспозицию. При SSE сервер и клиент являются отдельными процессами, и взаимодействие использует HTTP-эндпоинт. Возможная публикация этого эндпоинта за пределами локального хоста потребовала бы дополнительных мер контроля доступа и доступности.
Тесты
Текущий набор тестов проверяет:
загрузка, поиск, нормализация и ошибки
InventoryService;возвраты инструментов и преобразование несуществующего товара в предсказуемую ошибку;
отклонение пустых имён и значений, не являющихся строками;
отклонение недействительных записей инвентаря Pydantic;
регистрация инструментов на сервере;
выбор и настройка транспортов SSE и
stdio;реальная интеграция через
stdio, включаяlist_tools(), вызовget_stockи чтение аннотаций MCP.
Сценарии включают существующие и несуществующие товары, пробелы по краям, различия между прописными и строчными буквами и недействительные входные данные. В сквозном тесте реальный FastMCP-клиент запускает сервер как подпроцесс, проверяет readOnlyHint и openWorldHint, запрашивает запас, загруженный из локального JSON, и закрывает соединение через контекстный менеджер.
Качество кода
Проект использует аннотации типов, разделяет обязанности между MCP, сервисами, схемами и данными и сохраняет минимальные зависимости. pytest покрывает реализованное поведение, а Ruff проверяет линтинг, импорты, совместимость с Python 3.11 и форматирование.
Текущие ограничения
Данные загружаются из локального JSON-файла.
Нет базы данных.
Нет интеграции с ИИ или LLM.
Нет инструментов записи.
Нет аутентификации или авторизации.
Возможные направления развития
трассировка и структурированное логирование, оставленные за пределами текущей области для сохранения учебной направленности проекта;
поддержка Streamable HTTP;
сохранение в базе данных;
аутентификация и авторизация;
инструменты записи с защитными механизмами;
будущая интеграция с LLM.
This server cannot be installed
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
- AlicenseAqualityCmaintenanceRead-only MCP server for IKEA product search and in-store stock lookup.9301MIT
- FlicenseAqualityBmaintenanceMCP server for querying inventory items and stock levels via internal API, enabling AI chatbots to look up product codes and current quantities.2
- Alicense-qualityCmaintenanceA lightweight, local inventory-intelligence MCP server that enables querying structured inventory schemas with read-only, zero-config tools for stock levels, velocity metrics, and purchase orders.10MIT
- FlicenseAqualityCmaintenanceA local MCP server that enables querying Amazon Selling Partner API for profitability analysis (revenue, fees, COGS, net margin) and inventory alerts (FBA stock levels and low-stock warnings) using read-only operations.9
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
Read-only MCP server for searching Japan government procurement bid information from the KKJ portal.
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/ruanderson1/YAITECHUB-MCP-Server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server