Table of Contents (Click to expand)
(Click for detailed information on prerequisites, download and installation/configuration/run steps)
To run the Hbntory platform, Docker and Docker Compose are the only core system requirements. Because all services (Backoffice API, External Products API, MCP Server, AI Service, and Frontend) are fully containerized, you do not need to install Python, MySQL, or Node.js locally on your host system.
Note however that if you want to run our integrated test suite locally or just want to run components without the whole Docker abstraction you'll need Python3 installed (you can refer to this third-party tutorial) along with all the libraries listed in the individual requirements (to have a list quickly, from a shell like Bash opened in project root you can run find . -type f -name "requirements.txt" -exec cat {} + | tr -d '\r' | grep -v '^#' | sort -u). Then just install them with pip.
- Git: To clone the project repository.
- Modern Web Browser: Chrome, Firefox, Edge, or Safari to access the Backoffice Web UI and AI Client.
- Download and install Docker Desktop for Windows.
- During installation, make sure the Use WSL 2 instead of Hyper-V option is checked.
- Restart your computer after installation completes.
- Install Docker Desktop on Windows (as described above).
- Open Docker Desktop, navigate to Settings > Resources > WSL Integration.
- Toggle the switch to enable integration for your installed Linux distribution (e.g., Ubuntu).
- Open your WSL terminal;
dockeranddocker composewill now be available directly.
Run the following commands in your terminal:
sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
# Note: Log out and log back in for the group membership change to take effect.sudo pacman -Syu docker docker-compose
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
# Note: Log out and log back in for the group membership change to take effect.
Hbntory uses Docker Compose to orchestrate all microservices. Configuration is driven entirely through environment variables defined in a .env file at the root of the repository.
If you have Git it is very quick and easy: open a shell like Bash where you want project to sit then type those commands.
git clone https://github.com/llacote-holberton/holberton_inventory.git
cd holberton_inventory
Alternatively you can just download the latest release zip and extract it in your favorite file explorer then open the holberton_inventory.
Copy the provided .env.example file to create your local .env configuration:
cp .env.example .env
# If you want to edit in command line with vim
vim .envOpen with your favorite GUI text editor and adjusted the required values.
Before launching the stack, you must update the following placeholder values in your .env file:
- DB_ROOT_PASSWORD & DB_HBNTORY_USER_PWD: change these from the default placeholders to secure passwords.
- INTERNAL_API_KEY: security key used by the MCP Server to communicate with the Backoffice API.
You can generate a secure random string using Python if you have it installed:
python3 -c "import secrets; print(secrets.token_urlsafe(32))" - JWT_SECRET: used by the Backoffice API to sign authentication tokens. Generate a unique secret string using the same command above.
- LLA_MODEL_NAME: provide here a "machine name" for the desired model. NOTE that by default the model is Nvidia's minmax3, which will require you to create a (free) access and related API Key. Confer https://platform.minimax.io/docs/guides/quickstart-preparation.
- LLM_MODEL_API_KEY: provide your API key for the configured LLM provider
For more information on LLM configuration specifically, please confer the Annex 1: choosing your LLM model.
NOTE: all the following commands expect you to run them from the project's root so the 'compose' command automatically finds the related docker-compose.yml file. Otherwise you will need to specify the path to the compose file.
To build all container images and start all microservices, run:
docker compose up -d --build
IMPORTANT as project uses community provided images AND a public Github repository for one service (products-api), a working network connexion allowing access to internet is required whenever you use the option --build (and a decent bandwith like >=1.5Mo sec is recommended).
What does it do?
- docker: name of the "containarization tool" which allows you to create and run apps and operating systems in a total isolation.
- compose: one of the first level commands of docker: instructs it to find file(s) with specific name(s) in current filetree and parse them to get a series of instructions to create several "containers" lumped together. Here it will automatically target the "docker-compose.yml"
- '--build': forces the composition process to double-check the files which define how each container should be created, and (re)create them if need be.
- '-d': means "detached mode", aka the compose process will tell you about what it is doing on the terminal while working but when finished will "give terminal back to you". Without this option, the terminal would be "locked" to show runtime information. Which is a mode usually kept for debugging.
You can check the status of all running containers at any time with:
docker compose ps (ps standing for "process status")
You can also check the logs of the containers by doing the following command, with or without a service name as parameter.
docker compose logs <optional:name-of-service-as-defined-in-compose-file>
Finally, you can monitor the live real-time memory and CPU consumption of all running containers across your Hbntory stack by executing:
docker compose stats
Or just a snapshot of it at given time with --no-stream option added (docker stats --no-stream).
To stop the stack without losing any information, just run this.
docker compose down.
If you want to completely and cleanly uninstall this project (or just restart it from scratch), you can simply do docker compose down -v. The -v option means "Volume deletion" and implies that the persistent storage for database will be deleted from your machine.
Considering you fulfilled all preparation steps (confer above section) just this is enough, at project's root: docker compose up --build -d.
This command starts all the containers: the MariaDB database, the external product API, the BackOffice, the FrontOffice, and the AI Service.
Once the containers are running, the application is accessible via:
- the BackOffice HTML interface, for internal users (admin / managers) (by default at url http://localhost:8000)
- the FrontOffice interface, for anonymous customers, which triggers the AI agent when the submit button is clicked (by default at http://localhost:8080)
On the Frontoffice side, the customer submits a request through the FrontOffice; it is forwarded to the AI Service, which relies on an agent (MiniMax 3) querying an MCP server to fetch produc t/stock information from the BackOffice and the external product API, then returns a response to the customer.
For concrete examples, see Examples of use.
On the BackOffice side, internal users manage stock (CRUD) via the HTML interface or the dedicated REST API, with real-time updates pushed to other sessions via Serve r-Sent Events.
As the interface is pretty much self-explanatory, examples are not provided, discover and enjoy it by yourself! Just note two important limitations: per business requirements users and branches cannot be deleted from interface, you'll need someone who knows how to write SQL instructions through mariadb utility.
As this project was built under tight time constraints and with a pedagogical focus first, it remains intentionally simple in scope.
Functional features overview:
- Per-branch stock management (viewing, updating) with a non-negative quantity constraint
- Real-time stock updates on the BackOffice side via Server-Sent Events
- Internal user authentication with two roles:
adminandmanager - Product lookup by an AI agent (MiniMax 3) via a dedicated MCP server
- Product catalog lookup via a containerized external API
- Branch-Specific Stock Tracking: Manage and inspect stock quantities independently per physical or virtual store branch.
- Atomic Stock Adjustments: Fast and secure addition and removal of stock items with built-in validation (e.g., preventing negative inventory balances).
- Product Catalog Integration: Seamless integration with external product reference APIs, supporting instant lookups by numeric Product ID or alphanumeric SKU.
- Discontinued Item Protection: Automatic validation preventing stock additions for phased-out catalog items while preserving existing inventory records.
- Live UI Updates: Pub/Sub architecture built with Python
asyncio.Queuestreaming stock modifications live via Server-Sent Events (SSE). - Zero-Polling Reactivity: Connected Manager dashboards dynamically update quantities and alert visual states across open browser sessions in real-time without full page refreshes.
- JWT Authentication: Stateless authentication issuing signed JSON Web Tokens (
/login,/whoami). - Strict Role Isolation:
- Admin: Full access to global user management (create, activate/deactivate, reset passwords), global branch listing, and manager assignments.
- Manager: Strict scope isolation enforcing access exclusively to their assigned branch's stock data.
- Inter-Service Authentication: Protected internal API communication secured with static API key headers (
X-API-KEY) between the MCP Server and Backoffice.
- Natural Language Inventory Queries: Chat-based AI assistant capable of answering complex inventory questions and executing stock checks using natural language.
- FastMCP Integration: Custom MCP server exposing structured Tools (
get_stock,list_branches,get_all_branch_stocks) and Resources (inventory://catalog-summary) directly to the LLM agent. - Multi-LLM Provider Support: Powered by LiteLLM / Google ADK, allowing seamlessly swapping between 100+ LLMs (OpenAI, Google Gemini, Anthropic, NVIDIA NIM, Groq, local Ollama, etc.) via simple environment configuration.
- Fully Orchestrated Stack: 6-container Docker Compose setup (
stocks-db,products-api,internal-api,backoffice,mcp-server,ai-service,web-client). - Database Abstraction: MariaDB relational backend for persistent production storage paired with SQLAlchemy ORM for test portability.
As Hbntory was designed and built within tight time constraints as a pedagogical proof-of-concept, certain trade-offs and architectural compromises were made.
- Stateless Chat Session: The AI agent currently operates statelessly—each request is processed independently without conversational memory. Complex multi-turn follow-up queries (e.g., "Which computers are in Toulouse?" followed by "What about Paris?") are not supported natively yet.
- Partial Entity Enrichment in Bulk Queries: Large-scale summary queries (like fetching the full multi-branch catalog) rely heavily on raw database IDs. The AI agent may return list outputs containing Product IDs without automatically cross-referencing names and supplier details for every single item.
- Model-Dependent Performance: AI response latency, reasoning quality, and tool-calling execution accuracy are strictly bound to the capabilities of the selected LLM (e.g., lightweight local models vs. commercial frontier models).
- Single-Node Pub/Sub Scope: The real-time SSE engine relies on Python's in-memory
asyncio.Queuewithin a single process. It does not support horizontal scaling across multiple Backoffice API instances (which would require a distributed broker like Redis Pub/Sub or RabbitMQ). - Resource Footprint: Running 6 microservice containers simultaneously requires a moderately powerful host machine (recommended: at least 4GB of free RAM and multi-core CPU).
- Proof-of-Concept Security Model: While basic JWT authentication, RBAC, and API keys are implemented, the overall system has not undergone security audits. Potential production vulnerabilities remain open (e.g., unencrypted HTTP between internal container networks, lack of request rate-limiting/throttling, and basic CORS policies).
- Database Schema Lifecycle: Database initialization relies on raw static
.sqlscripts. There is currently no database migration tool integrated (such as Alembic) to handle dynamic schema evolution.
- Incomplete Backend Test Suite: Endpoints and features developed in later phases (e.g., recent user management and stock assignment endpoints) currently lack full unit and integration test coverage.
- Absence of Front-End Automation: The HTML5/Vanilla JS frontend has no automated end-to-end (E2E) or component testing suite (e.g., Cypress, Playwright, or Jest).
- No Automated LLM Benchmarking: Evaluation of AI tool-calling reliability and response safety is currently done through manual prompt testing.
(Click to expand)
Question: Donne moi les détails du produit 3 | Donne moi les détails du produit HB-MON-2101
Answer:
Voici les détails du produit 3 | HB-MON-2101:
- **Nom** : 27 inch Lab Monitor
- **SKU** : HB-MON-2101
- **Catégorie** : Displays
- **Marque** : LabForge
- **Prix unitaire** : 229,50 USD
- **Description** : Training catalog item for HBntory integration: 27 inch lab monitor.
- **Tags** : display, lab, hdmi
- **Arrêté** : Non
Question: Give me all informations about HB-MON-2101
Answer:
Here are all the details for **HB-MON-2101**:
- **Name:** 27 inch Lab Monitor
- **Description:** Training catalog item for HBntory integration: 27 inch lab monitor.
- **Category:** Displays
- **Brand:** LabForge
- **Unit Price:** $229.50 USD
- **Discontinued:** No
- **Tags:** display, lab, hdmi
- **Product ID:** 3
Question: Gib mir alle Informationen zu HB-MON-2101.
Answer:
- **Name:** 27 inch Lab Monitor
- **SKU:** HB-MON-2101
- **Kategorie:** Displays
- **Marke:** LabForge
- **Preis:** 229,50 USD
- **Beschreibung:** Training catalog item for HBntory integration: 27 inch lab monitor.
- **Tags:** display, lab, hdmi
- **Eingestellt:** Nein`
NOTE: only western languages are correctly supported. Questions made in other languages like arabic or asian ones (ex HB-MON-2101に関するすべての情報を教えてください) have a high probability of ending up with answers in agent's default language aka French.
Question: Give me all products available in Toulouse Esquirol branch
Anwser:
Here are the products available in the **Toulouse Esquirol** branch:
| SKU | Product | Quantity | Unit Price |
|---|---|---|---|
| HB-MON-2102 | 24 inch Compact Monitor (LabForge) | 15 | $169.99 |
| *(unknown)* | Product ID 666 | 45 | — |
Note: The product with ID 666 could not be retrieved from the catalog (it appears to be missing or invalid), so its details are unavailable.
Question: Give me all stocks availability across all branches for HB-MON-2102
Answer
Here are the stock availability details for **HB-MON-2102** (24 inch Compact Monitor):
| Branch ID | Quantity |
|-----------|----------|
| 1 | 15 |
| 2 | 8 |
| 5 | 24 |
| **Total** | **47** |
Question: Give me all stocks everywhere
Answer:
Here are all the stocks across the network:
**Caussade (branch 4)**
- Produit #2: 777
- Produit #6: 0
**Paris La Défense (branch 5)**
- Produit #1: 10,013
- Produit #3: 1
- Produit #4: 24
- Produit #7: 888
- Produit #18: 29
- Produit #32: 2
- Produit #35: 65
- Produit #666: 1
**Rodez (branch 3)**
- (no stock)
**Toulouse Carmes (branch 2)**
- Produit #4: 8
**Toulouse Esquirol (branch 1)**
- Produit #4: 15
- Produit #666: 45
Question: If I want to buy 3 HB-MON-2102 and as many HB-KBD-4102, which branches should I visit?
Answer: To buy 3 units of HB-MON-2102 and as many HB-KBD-4102 as possible, you should visit **branch 5**, which has 24 monitors and 888 keyboards in stock — more than enough for both items in one stop.
The AI Agent is configured to only process questions directly related to stocks and products. Anything beyond will result in a polite refuse or plain incapability to give pertinent answers.
Couple of use-cases which are not supported.
What is the current weather in Toulouse?
Give me the winning numbers on the next French National Lottery.
-> I'm having trouble understanding your question, could you clarify please?
This section only present the high-level information. For more details on technical choices and in-depth explanations please confer our dedicated Architecture page.
The project relies on following core principles.
1/ Business data is split in two parts: a catalog of products provided by a third party, exposed through an API; and a database managed by identified humans to affect stocks of products available for selling in various stores (named "branches").
2/ The "end-user" part only exposes an Agent dedicated to answering questions about products and stocks by relying on a middleware "preparing answers" for it (no global data access). This way the manipulations of actual business data is strictly gated, limiting security risks at least from that channel.
3/ The custom components are all made in Python to simplify the maintenance and evolution of the project.
4/ As this application as a whole requires several components to run on a group of ports, it provides a Docker composition file to provide a quick & easy way to set up all services in a cohesive way.
The project is built around three main components:
- BackOffice — the sole source of truth for product and stock knowledge, for both internal users (HTML interface) and the AI agent. Relies on an ORM interface for CRUD operations, an HTTP client to the external product API, and an HTTP server exposing HTML pages, REST endpoints, and an SSE stream.
- FrontOffice — the sole entry point for anonymous visitors; it never talks directly to the BackOffice, only through the AI Service.
- AI Service — the bridge between the FrontOffice and the BackOffice, combining an AI agent (MiniMax 3) and an MCP server that provides the tools needed to query product/stock information.
Python and related libraries (SQLAlchemy, LiteLLM, Google ADK, Fast MCP, Fast API): for creating the micro-services exposing each component on network. MariaDB: to manage data in a SQL-based relational database. Docker: to define each micro-service as a self-sufficient app and coordinate their uses and inter-communications.
flowchart TB
Client["Web client<br/>Anonymous users"] -->|REST / SSE| IA["AI Query Service<br/>MiniMax 3 agent + MCP client"]
Internal["Internal users<br/>Admin, managers"] -->|Authenticated HTTP| BO["Backoffice<br/>Auth, stock management"]
IA -->|"MCP (streamable-http)"| MCP["Product MCP server<br/>Bridge to the product API"]
BO -->|SQLAlchemy| DB["Database<br/>Users, branches, stock"]
MCP -->|"GET /api/stock (read-only)"| BO
MCP -->|"HTTP (list / details)"| API["External product API<br/>Catalog, Docker container"]
sequenceDiagram
participant C as Web client
participant FO as FrontOffice
participant IA as AI Service (MiniMax 3 agent)
participant MCP as Product MCP server
participant BO as Backoffice
participant API as External product API
C->>FO: Submits a request
FO->>IA: Calls the AI endpoint
IA->>MCP: Tool request (MCP)
MCP->>API: Catalog lookup
MCP->>BO: GET /api/stock (read-only)
BO-->>MCP: Stock data
API-->>MCP: Product data
MCP-->>IA: Aggregated result
IA-->>FO: Generated response
FO-->>C: Response displayed
For detailed examples of sequence diagrams, please confer the "Sequence Diagram" section in the Architecture document.
1/ Users must first authenticate through a localhost:BACKOFFICE_PORT/login with a check of their username/password tuple against the bcrypt hash in db. 2/ Then they can access the interface. 3/ Interface buttons are each associated with a specific Backoffice API endpoint, called on click. Operations send back a JSON message to confirm the success of failure.
Anyone can access the Client User Interface and input a question. On submit, it is sent to AI agent which can retrieve context-specific information through the tools and resources exposed by MCP before formulating an answer.
Here is what you can expect on a somewhat modern machine (snapshot taken on a AMD Ryzen 7 6800HS with 16 GB of basic DDR5 RAM) with all services running idle.
| CONTAINER ID | NAME | CPU % | MEM USAGE / LIMIT | MEM % | NET I/O | BLOCK I/O | PIDS |
|---|---|---|---|---|---|---|---|
| 1dfd230ddd19 | hbntory-web-client | 0.18% | 44.79MiB / 14.86GiB | 0.29% | 1.44kB / 126B | 17MB / 897kB | 6 |
| ca5a9c35cb7d | hbntory-ai-service | 0.17% | 149.3MiB / 14.86GiB | 0.98% | 1.52kB / 126B | 51.7MB / 1.15MB | 6 |
| 45c0156a4325 | hbntory-mcp-server | 0.20% | 61MiB / 14.86GiB | 0.40% | 1.69kB / 126B | 22.4MB / 909kB | 1 |
| 9ba4063fd0ab | hbntory-internal-api | 0.19% | 74.81MiB / 14.86GiB | 0.49% | 1.73kB / 126B | 31.3MB / 938kB | 6 |
| 5e1de8ca3f1e | hbntory-backoffice | 0.18% | 77.83MiB / 14.86GiB | 0.51% | 1.77kB / 126B | 33.6MB / 958kB | 6 |
| 6627f200a4dc | hbntory-stocks-db | 0.01% | 166.6MiB / 14.86GiB | 1.10% | 1.82kB / 126B | 48.9MB / 32.8kB | 10 |
| 4d50f7256afe | hbntory-products-api | 0.01% | 26.06MiB / 14.86GiB | 0.17% | 2.08kB / 126B | 16.4MB / 0B | 1 |
You can expect an overhead of roughly 200Mo additional memory when one "natural language request" is submitted to the AI agent, with most of it being consumed by that service itself.
For now the only parts of the app covered by automated tests is the backoffice part. Tests cover roughly 80% of all use-cases across CRUD operations on base (Stocks, Users, Branches) and API calls (Internal API used by MCP server, Backoffice API used by authenticated users's interfaces).
To run the whole test suite, please from the project's root use this chain of commands.
cd backoffice && pytest
This is enough to automatically run all "sub-test-suite files" located in backoffice/tests each covering one functional aspect.
For detailed instructions on how to run partial tests and the currently covered use-cases, please refer to our Testing Guide.
This project has been realized in compliance with all business specifications and technical constraints detailed in the Project context
Confer PROJECT.md
To share a common vision and limit conflicts when pushing code, we applied a few simple rules throughout the project:
- Starting with an architecture flowchart to understand the overall structure and identify potential challenges early on.
- From the start of coding, never pushing directly to
dev: every feature went through a Pull Request from a personal branch, reviewed and approved by the other teammate — allowing a fresh set of eyes on the code and a natural understanding of each other's work. - Testing features as they were coded.
- Regularly reintegrating changes pushed to
devback into the personal branch, to keep the history as linear as possible and avoid conflicts down the road. - Occasional use of GitHub Issues and Wiki, which turned out to be unnecessary once our collaboration workflow was running smoothly.
- Main tools: Git and Visual Studio Code / Kate for writing and sharing code; various LLM for digging topics and writing tests against our code.
- Holberton School for the project guidelines
- All peer reviewers and testers: Barat Erwan, Lacôte Laurent, Lages Yoann
Plus Nvidia's MiniMax LLM (by default) and Python libraries: FastAPI, FastMCP, HttpX(2), SQLAlchemy, Pytest along with their own dependencies.
This project is part of the Holberton School curriculum and is made available under the General Public License v3.0, confer License text for details.


