inventree-mcp-plugin
Click on "Install 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., "@inventree-mcp-pluginlist all parts in the Electronics category"
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.
inventree-mcp-plugin
MCP (Model Context Protocol) server plugin for InvenTree. Exposes InvenTree inventory data through standardized MCP tools, allowing AI assistants like Claude to interact with your inventory.
Features
Parts: List, search, create, and update parts
Stock: List, adjust, and transfer stock items
Locations: Browse stock location hierarchy
Categories: Browse part category hierarchy
Orders: View purchase and sales orders
BOM: View bill of materials for assemblies
Builds: View build orders
Tags: List and search part tags
Related MCP server: Klipper MCP Server
Installation
pip install inventree-mcp-pluginOr with uv:
uv pip install inventree-mcp-pluginConfiguration
Enable the plugin in InvenTree Admin under Settings > Plugin Settings
Configure plugin settings:
Require Authentication: Whether the MCP endpoint requires authentication (default:
true)
The MCP endpoint is available at: /plugin/inventree-mcp/mcp/
Authentication
When Require Authentication is enabled (the default), every request to the MCP endpoint must include a valid credential. The plugin accepts the same auth methods as the InvenTree API:
Method | Header |
API Token |
|
Bearer |
|
Basic |
|
Session | Cookie-based (browser sessions) |
To obtain an API token, either use the InvenTree web UI (Settings > API Tokens) or request one programmatically:
curl -s http://your-inventree-instance/api/user/token/ \
-H "Authorization: Basic $(echo -n admin:inventree | base64)"
# Returns: {"token": "inv-..."}Unauthenticated requests receive a JSON-RPC error response with HTTP 401.
User Setup and Permissions
The plugin accesses InvenTree data through the Django ORM using the permissions of the authenticated user. InvenTree uses a role-based permission system: users belong to groups, and each group has rule sets that grant view, add, change, and delete permissions across 9 role categories.
Important: The plugin currently bypasses InvenTree's RolePermission checks because it uses the ORM directly rather than the REST API. This means any authenticated user can access all tools regardless of their role assignments. For production use, create a dedicated service account with appropriate group membership to establish a clear permission boundary.
Recommended user profiles
Create these groups and users via the InvenTree Admin Center (Settings > Admin Center > Groups):
Read-only MCP user — for AI assistants that only need to query data:
Role | view | add | change | delete |
Part | yes | |||
Part Category | yes | |||
Stock Item | yes | |||
Stock Location | yes | |||
Build | yes | |||
Purchase Order | yes | |||
Sales Order | yes |
Read-write MCP user — for AI assistants that also create/modify data:
Role | view | add | change | delete |
Part | yes | yes | yes | |
Part Category | yes | |||
Stock Item | yes | yes | ||
Stock Location | yes | |||
Build | yes | |||
Purchase Order | yes | |||
Sales Order | yes |
Creating the service account
Go to Admin Center > Groups and create a group (e.g.
mcp-readonlyormcp-readwrite)Set the role permissions as shown above
Go to Admin Center > Users and create a new user (e.g.
mcp-service)Assign the user to the group
Generate an API token for the user at Settings > API Tokens
Or via the API (requires an admin account):
# 1. Create a group (admin token required)
curl -X POST http://your-inventree-instance/api/user/group/ \
-H "Authorization: Token <admin-token>" \
-H "Content-Type: application/json" \
-d '{"name": "mcp-readonly"}'
# 2. Create a user assigned to that group
curl -X POST http://your-inventree-instance/api/user/ \
-H "Authorization: Token <admin-token>" \
-H "Content-Type: application/json" \
-d '{"username": "mcp-service", "password": "a-strong-password", "group_ids": [<group-id>]}'
# 3. Get a token for the new user
curl -s http://your-inventree-instance/api/user/token/ \
-H "Authorization: Basic $(echo -n mcp-service:a-strong-password | base64)"Tool permission reference
Simple tools
Tool | InvenTree Role(s) | Minimum Permission |
| Part | view |
| Part, Part Category | add (part), view (category) |
| Part | change |
| Stock Item | view |
| Stock Item | change |
| Stock Item, Stock Location | change (stock), view (location) |
| Stock Location | view |
| Part Category | view |
| Purchase Order | view |
| Sales Order | view |
| Part | view |
| Build | view |
| — | view |
Combinatory tools
Tool | InvenTree Role(s) | Minimum Permission |
| Part | delete |
| Stock Item, Part Category, Stock Location | view |
| Stock Item, Part Category, Stock Location | view |
Usage with MCP Clients
The plugin uses the Streamable HTTP transport. The endpoint is:
http://your-inventree-instance/plugin/inventree-mcp/mcp/Every request must include an Authorization header with an InvenTree API token (see Authentication).
Claude Code
Add the server with the claude mcp add command. Use --scope project to store the config in .mcp.json (checked into the repo) or omit it for local-only config.
claude mcp add --transport http inventree \
--header "Authorization: Token YOUR_INVENTREE_TOKEN" \
http://your-inventree-instance/plugin/inventree-mcp/mcp/To avoid storing the token in plain text, use an environment variable:
claude mcp add --transport http inventree \
--header "Authorization: Token ${INVENTREE_TOKEN}" \
http://your-inventree-instance/plugin/inventree-mcp/mcp/Or add the config manually to .mcp.json (project scope) or ~/.claude.json (user scope):
{
"mcpServers": {
"inventree": {
"type": "http",
"url": "http://your-inventree-instance/plugin/inventree-mcp/mcp/",
"headers": {
"Authorization": "Token YOUR_INVENTREE_TOKEN"
}
}
}
}Claude Desktop
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"inventree": {
"type": "http",
"url": "http://your-inventree-instance/plugin/inventree-mcp/mcp/",
"headers": {
"Authorization": "Token YOUR_INVENTREE_TOKEN"
}
}
}
}Restart Claude Desktop after editing the config file.
Gemini CLI
Google's Gemini CLI supports MCP servers. Add the server via the settings file at ~/.gemini/settings.json:
{
"mcpServers": {
"inventree": {
"httpUrl": "http://your-inventree-instance/plugin/inventree-mcp/mcp/",
"headers": {
"Authorization": "Token YOUR_INVENTREE_TOKEN"
}
}
}
}ChatGPT Desktop
ChatGPT Desktop supports MCP in Developer Mode (requires ChatGPT Plus, Pro, Business, or Enterprise). Enable Developer Mode under Settings > Advanced, then add the server via Settings > Connectors.
When adding a custom connector, provide:
URL:
http://your-inventree-instance/plugin/inventree-mcp/mcp/Authentication: Token — value:
YOUR_INVENTREE_TOKEN
Use Cases
Common prompts to use once the MCP is connected to your AI assistant. Paste them as-is — your AI will use the InvenTree MCP tools automatically rather than making raw HTTP requests.
Exploring inventory
Show me the top-level part categories and how many subcategories each one has.
List all parts in the "Passives" category. Group them by subcategory and tell me which ones are currently inactive.
Search for anything related to "motor driver" across part names and descriptions.
Give me the full category tree so I can understand how the inventory is organised.
Stock levels
Which parts have zero stock right now? List their names, IDs and categories.
Show me all stock items stored in the "Main Warehouse" location and its sub-locations.
I need to transfer 50 units of part #142 from "Shelf A" to "Shelf B". Do it and confirm.
Adjust stock for part #88 — add 200 units to reflect a new delivery.
Parts and BOMs
Get the full bill of materials for part #210 and estimate the total component count needed to build 25 units.
What sub-assemblies does part #305 depend on? Show the BOM tree.
Create a new part called "Schottky Diode 40V 1A" in category #12 with IPN "D-SS14" and mark it as purchaseable.
Find all parts tagged "obsolete" and deactivate them. Show me the list before making any changes.
Orders and builds
List all open purchase orders and summarise what's being ordered and from which suppliers.
What's the status of current build orders? Are any overdue or blocked?
Show me the line items for purchase order #34 and tell me which parts haven't been received yet.
Which sales orders have been placed in the last 30 days and what's their status?
Cleanup and maintenance
Find all parts that are inactive and have no stock. Delete them after confirming the list with me.
List all tags currently in use and tell me which ones are applied to fewer than 3 parts — those might be duplicates or typos.
Show me all parts that are marked as assemblies but have an empty BOM.
Available Tools
Simple — single-resource CRUD
Parts
Tool | Description |
| List parts with optional category/active filters |
| Get detailed part information |
| Search parts by name or description |
| Create a new part |
| Update an existing part |
Stock
Tool | Description |
| List stock items with optional filters |
| Get detailed stock item information |
| Add or remove stock quantity |
| Transfer stock to a different location |
Locations
Tool | Description |
| List stock locations |
| Get location details |
| Get hierarchical location tree |
Categories
Tool | Description |
| List part categories |
| Get category details |
| Get hierarchical category tree |
Orders
Tool | Description |
| List purchase orders |
| Get purchase order with line items |
| List sales orders |
| Get sales order with line items |
BOM & Builds
Tool | Description |
| List BOM items |
| Get full BOM for a part |
| List build orders |
| Get build order details |
Tags
Tool | Description |
| List all tags |
| Search tags by name |
Combinatory — multi-resource operations
Tool | Description |
| Delete multiple parts by ID (with safety checks) |
| Stock quantity pivot by category and location |
| Stock quantity pivot with full category/location hierarchy paths |
Development
Prerequisites
Install prek and set up git hooks:
prek install# Clone the repository
git clone https://github.com/eljefedelrodeodeljefe/inventree-mcp-plugin.git
cd inventree-mcp-plugin
# Install dependencies
uv sync --dev
# Run linting
uv run ruff check .
uv run ruff format --check .
# Run unit tests (mocked, no InvenTree required)
uv run pytest -vIntegration Testing
A docker-compose.dev.yml is included to spin up a disposable InvenTree instance with PostgreSQL, Redis, and the plugin volume-mounted. All state lives in Docker volumes that are destroyed on teardown.
Integration Prerequisites
Docker and Docker Compose v2+
Quick start
# Start InvenTree and seed the demo dataset
./scripts/integration-test.sh up
# MCP endpoint is now live at:
# http://localhost:8000/plugin/inventree-mcp/mcp/
# Get an admin API token (useful for curl/httpie testing)
./scripts/integration-test.sh tokenTest accounts
The up command seeds InvenTree's demo dataset and creates dedicated MCP service accounts:
Username | Password | Purpose |
|
| Superuser — full access, use for admin tasks |
|
| MCP service account — assign roles via Admin Center |
|
| No roles — use to verify permission denials |
|
| Demo user — full permissions |
|
| Demo user — view only |
After up, configure the mcp-readwrite group's role permissions via the Admin Center (Admin Center > Groups > mcp-readwrite > Rule Sets). See User Setup and Permissions for the recommended role matrix.
Get tokens for different users:
./scripts/integration-test.sh token # mcp-service (default)
./scripts/integration-test.sh token admin # admin superuser
./scripts/integration-test.sh token readonly # mcp-readonly (no roles)Resetting state
# Wipe all data and re-seed (keeps containers running)
./scripts/integration-test.sh resetThis runs invoke dev.delete-data followed by invoke dev.setup-test -i, giving you a clean slate without rebuilding containers.
Teardown
# Stop containers and delete all volumes
./scripts/integration-test.sh downSmoke tests
The script includes an authenticated smoke test suite that verifies the MCP endpoint end-to-end:
./scripts/integration-test.sh smokeThis automatically obtains a token and tests:
Unauthenticated requests are rejected (401)
Authenticated
initializesucceedsAuthenticated
tools/listreturns registered toolsAuthenticated
tools/callforlist_partssucceeds
Manual MCP testing
With the stack running, obtain a token first then test the endpoint:
# Get a token
TOKEN=$(./scripts/integration-test.sh token)
# Initialize the MCP session
curl -X POST http://localhost:8000/plugin/inventree-mcp/mcp/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Token ${TOKEN}" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": { "name": "test", "version": "0.1.0" }
}
}'
# List available tools
curl -X POST http://localhost:8000/plugin/inventree-mcp/mcp/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Token ${TOKEN}" \
-d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'
# Call a tool
curl -X POST http://localhost:8000/plugin/inventree-mcp/mcp/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Token ${TOKEN}" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": { "name": "list_parts", "arguments": { "limit": 5 } }
}'Script reference
./scripts/integration-test.sh up # Start stack, seed data, create MCP users
./scripts/integration-test.sh reset # Wipe data, re-seed, re-create MCP users
./scripts/integration-test.sh token # Print mcp-service API token
./scripts/integration-test.sh token admin # Print admin API token
./scripts/integration-test.sh token readonly # Print mcp-readonly API token
./scripts/integration-test.sh smoke # Run authenticated smoke tests
./scripts/integration-test.sh status # Check if InvenTree is healthy
./scripts/integration-test.sh down # Tear down + delete volumesReleasing
Releases are automated with python-semantic-release. It parses Conventional Commit messages since the last tag, determines the next version bump (patch, minor, or major), updates the version in pyproject.toml, generates CHANGELOG.md, creates a git tag, and publishes a GitHub release.
The workflow requires manual trigger to avoid creating releases on every merge to main.
From the GitHub UI
Go to Actions → Release
Click Run workflow
Select the
mainbranch and confirm
From the command line
gh workflow run release.yml --ref mainTo watch the run until it completes:
gh workflow run release.yml --ref main && gh run watch --exit-statusLocal dry-run
Preview what the next version would be without making any changes:
uv run semantic-release version --printLicense
MIT
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.
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/eljefedelrodeodeljefe/inventree-mcp-plugin'
If you have feedback or need assistance with the MCP directory API, please join our Discord server