Skip to main content
Glama
ruanderson1

inventory-mcp

by ruanderson1

inventory-mcp

Demonstration MCP server for inventory queries, developed in Python with FastMCP. The project supports the study of the main concepts of the Model Context Protocol (MCP), with separation between transport, MCP interface, business rules, validation, and data.

The current scope is intentionally read-only: the server allows querying products and stock quantities, with no creation, modification, or deletion operations.

Technologies

  • Python 3.11+

  • FastMCP

  • Pydantic

  • pytest

  • Ruff

Related MCP server: vanam-erp-mcp

Architecture

  • app/server.py: creates the FastMCP server, registers the tools, and starts the stdio or SSE transport.

  • app/client.py: demonstrative client that lists and calls the tools via stdio or SSE.

  • app/tools/: MCP interface; validates inputs, delegates to the service, and transforms expected errors into stable responses.

  • app/services/: inventory query and loading rules.

  • app/schemas/: Pydantic models that define and validate the product and stock contracts.

  • app/data/: local data source, currently the inventory.json file.

  • tests/: automated tests for the service, tools, and server configuration.

Client → MCP Server → Tool → InventoryService → inventory.json

The tools do not access the file directly. They delegate business rules to InventoryService.

MCP Tools

get_product

  • Purpose: consult the complete data of a product by name.

  • Input: name (non-empty string).

  • Output on success: object with name, quantity, and price.

  • Output for non-existent product: object with error: "product_not_found" and a descriptive message.

  • MCP Description: Use this tool to retrieve the complete data of a product by name, including its price and stock quantity.

  • Classification: read-only.

{
  "name": "Mouse",
  "quantity": 25,
  "price": 89.9
}

get_stock

  • Purpose: query only the current quantity of a product by name.

  • Input: name (non-empty string).

  • Output on success: object with quantity.

  • Output for non-existent product: object with error: "product_not_found" and a descriptive message.

  • MCP Description: Use this tool to retrieve only the current stock quantity of a product by name.

  • Classification: read-only.

{
  "quantity": 25
}

Input Validation

The tools require name to be a non-empty string. Names that are empty or made up only of spaces are rejected before the query. The service applies strip() to remove leading and trailing spaces and casefold() to compare names without case sensitivity.

Pydantic validates the records loaded from the JSON and the output models. A product must have a non-empty name, a non-negative integer quantity, and a non-negative numeric price. Empty query names are rejected by _validate_product_name(). Invalid records stop loading with an explicit error.

Error Handling

InventoryService throws ProductNotFoundError when it does not find the requested product. The tools catch this expected error and return a predictable payload:

{
  "error": "product_not_found",
  "message": "Product not found: Monitor"
}

Input errors, such as an empty name or a value that is not a string, are not hidden: they are reported as errors from the tool call.

MCP Transports

  • stdio: communicates through standard input and output. In this project, the client starts the FastMCP server as a subprocess, performs the calls, and terminates the process when finished.

  • SSE: communicates through an HTTP endpoint using Server-Sent Events. Server and client run in separate processes; by default, the server listens at http://127.0.0.1:8000/sse.

How to Run

The commands below use PowerShell and must be run from the project root.

Create and activate the virtual environment

python -m venv .venv
.\.venv\Scripts\Activate.ps1

Install dependencies

python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

Run via stdio

The client uses stdio by default and starts the server as a subprocess:

.\.venv\Scripts\python.exe -m app.client

To start only the server directly:

.\.venv\Scripts\python.exe -m app.server --transport stdio

Run via SSE

Start the server in a terminal (sse is the server's default transport):

.\.venv\Scripts\python.exe -m app.server

The equivalent explicit command is python -m app.server --transport sse. In another terminal, connect the client:

.\.venv\Scripts\python.exe -m app.client --transport sse

The client accepts another endpoint via --url.

Run the tests

.\.venv\Scripts\pytest.exe

Run Ruff

.\.venv\Scripts\ruff.exe check .
.\.venv\Scripts\ruff.exe format --check .

Tool Risk Assessment

The current tools are read-only and cannot create, modify, or delete data. This decision reduces the risk surface, but does not eliminate possible impacts on confidentiality and availability.

Tool

Data accessed

Operation

Current risk

Possible impact of misuse

get_product

Name, price, and quantity

Read

Low

Exposure or enumeration of inventory information

get_stock

Available quantity

Read

Low

Stock enumeration and excessive tracking of availability

Large-volume calls can still consume server resources. Future changes to the tools or to the returned data should be accompanied by a new risk assessment.

Trust Boundary

Arguments received from an MCP client are treated as untrusted input.

MCP Client
    ↓
MCP Server
    ↓
Tool
    ↓
InventoryService
    ↓
inventory.json

Validation happens before the arguments are used by the service layer. The server does not assume that data sent by the client is valid simply because it arrived through the MCP protocol. The records in inventory.json are also treated as external input and validated by Pydantic during loading.

MCP Tool Annotations

The tools are semantically classified according to their behavior. The two current operations declare:

readOnlyHint=true
openWorldHint=false

readOnlyHint=true informs the MCP client that the operation does not intend to modify state.

openWorldHint=false indicates that the tool works on a closed and known domain — in this case, the local inventory — instead of querying external systems or open sources.

These annotations act as metadata and hints for MCP clients, not as security mechanisms. A client should not rely on them as a substitute for validation, authorization, or other real controls.

Risk of write tools

A future operation such as:

update_stock(name, quantity)

would have significantly higher risk because it would modify the persistent state of the system.

An incorrect or malicious call could change the wrong product, record invalid values, or allow unauthorized changes. A future tool like update_stock would require rigorous validation, authentication, authorization, auditing, and tracing. Destructive operations would also require confirmation or approval when applicable.

Risk by transport

In stdio, the server is started locally as a subprocess of the client, reducing network exposure. In SSE, server and client are separate processes and communication uses an HTTP endpoint. Eventually publishing this endpoint outside the local host would require additional access and availability controls.

Tests

The current suite validates:

  • loading, search, normalization, and errors of InventoryService;

  • tool return values and conversion of a non-existent product into a predictable error;

  • rejection of empty names and values that are not strings;

  • rejection of invalid inventory records by Pydantic;

  • registration of the tools in the server;

  • selection and configuration of SSE and stdio transports;

  • real integration via stdio, including list_tools(), a get_stock call, and reading the MCP annotations.

The scenarios include existing and non-existent products, leading/trailing spaces, case differences, and invalid inputs. In the end-to-end test, a real FastMCP client starts the server as a subprocess, validates readOnlyHint and openWorldHint, queries the stock loaded from the local JSON, and closes the connection via the context manager.

Code Quality

The project uses type hints, separates responsibilities between MCP, services, schemas, and data, and keeps dependencies minimal. pytest covers the implemented behaviors, while Ruff checks linting, imports, Python 3.11 compatibility, and formatting.

Current Limitations

  • Data is loaded from a local JSON file.

  • There is no database.

  • There is no AI or LLM integration.

  • There are no write tools.

  • There is no authentication or authorization.

Possible Evolutions

  • tracing and structured logging, kept out of the current scope to preserve the project's didactic focus;

  • support for Streamable HTTP;

  • database persistence;

  • authentication and authorization;

  • write tools with safeguards;

  • future integration with LLM.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    A
    quality
    B
    maintenance
    MCP server for querying inventory items and stock levels via internal API, enabling AI chatbots to look up product codes and current quantities.
    2
  • A
    license
    -
    quality
    C
    maintenance
    A 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.
    10
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    A 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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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