Homebox MCP Server

Homebox MCP Server

An MCP server that exposes Homebox inventory management as tools for AI agents, enabling search, add, update, delete products, locations, tags, and maintenance entries.

Category
访问服务器

README

Homebox MCP Server

An MCP server that exposes Homebox inventory management as tools for AI agents.

What it does

This server lets an AI agent (Claude, Hermes, OpenClaw, or any MCP-compatible client) read and write your Homebox inventory: search, add, update, and delete products and locations, manage tags and maintenance entries — all through the unified Homebox v0.26+ entities API.

It runs in two transports:

  • stdio — for local agents that launch the server as a subprocess.
  • Streamable HTTP (/mcp) — for remote agents that talk HTTP. Per-request credentials are passed via request headers.

Key behaviors:

  • Targets Homebox v0.26.0+ (the entity-merge release) — items and locations share /api/v1/entities, with parentId denoting the parent entity. Older Homebox releases using /api/v1/items and /api/v1/locations are not supported.
  • search_products with only name splits the phrase into terms and queries each in parallel for broader recall.
  • add_product and update_product_by_id use grouped parameter objects (identity, location, identifiers, purchase, metadata, status) so large calls stay readable.
  • Maintenance tools (create_maintenance_entry_for_product, list_maintenance_entries, update_maintenance_entry, delete_maintenance_entry) operate against /api/v1/maintenance.
  • Multi-collection (tenant) support is exposed via the Homebox-native X-Tenant request header on the HTTP transport.

Installation

Requirements

Component Version
Homebox (server) v0.26.0 or newer (tested v0.26.2)
Python 3.10.13+
Dependencies Listed in pyproject.toml
uv (recommended) https://docs.astral.sh/uv/

Older Homebox releases that still expose /api/v1/items and /api/v1/locations are not supported — the server talks to /api/v1/entities exclusively.

Install the server

git clone <repo-url> homebox-mcp
cd homebox-mcp
uv sync                 # installs runtime + dev dependencies
cp .env.example .env   # then edit .env with your Homebox credentials

.env.example:

HOMEBOX_BASE_URL=https://your-homebox-instance.com
HOMEBOX_USERNAME=your_email@example.com
HOMEBOX_PASSWORD=your_password
# Optional HTTP server settings (server_http.py)
# FASTMCP_HOST=0.0.0.0
# FASTMCP_PORT=8000

Docker

docker build -t homebox-mcp .
docker run -p 8000:8000 \
  -e HOMEBOX_BASE_URL="https://your-homebox-instance.com" \
  -e HOMEBOX_USERNAME="your_email@example.com" \
  -e HOMEBOX_PASSWORD="your_password" \
  homebox-mcp

Run the server

just start         # stdio mode (default for local agents)
just start-http    # Streamable HTTP mode at http://0.0.0.0:8000/mcp

Or directly:

uv run main.py            # stdio
uv run server_http.py     # streamable HTTP

Install inside an agent

Pick the snippet that matches your agent and copy-paste it into the agent's MCP configuration. Replace the values in <…> with your own.

The examples assume stdio mode (local agent) with credentials read from environment / .env. Streamable HTTP mode exposes the same tools but takes credentials through request headers instead.

Claude Desktop / Claude Code (claude_desktop_config.json)

{
  "mcpServers": {
    "homebox": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/homebox-mcp", "run", "main.py"],
      "env": {
        "HOMEBOX_BASE_URL": "https://your-homebox-instance.com",
        "HOMEBOX_USERNAME": "your_email@example.com",
        "HOMEBOX_PASSWORD": "your_password"
      }
    }
  }
}

Hermes (stdio)

Add to your Hermes MCP servers configuration:

{
  "homebox": {
    "command": "uv",
    "args": ["--directory", "/absolute/path/to/homebox-mcp", "run", "main.py"],
    "env": {
      "HOMEBOX_BASE_URL": "https://your-homebox-instance.com",
      "HOMEBOX_USERNAME": "your_email@example.com",
      "HOMEBOX_PASSWORD": "your_password"
    }
  }
}

OpenClaw (stdio)

{
  "servers": {
    "homebox": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/homebox-mcp", "run", "main.py"],
      "env": {
        "HOMEBOX_BASE_URL": "https://your-homebox-instance.com",
        "HOMEBOX_USERNAME": "your_email@example.com",
        "HOMEBOX_PASSWORD": "your_password"
      }
    }
  }
}

Remote / Streamable HTTP

If you run the server with uv run server_http.py (or via the Docker image), any MCP-compatible HTTP client can reach it at http://host:8000/mcp and pass credentials via request headers:

HOMEBOX_USERNAME: your_email@example.com
HOMEBOX_PASSWORD: your_password
X-Tenant: 00000000-0000-0000-0000-000000000000   # optional, multi-collection

HOMEBOX_BASE_URL is read only from the runtime environment of the server process; it cannot be overridden per request.

Finding the X-Tenant value

Open Homebox, log in, then in DevTools → Network find the request GET /api/v1/users/self and copy the X-Tenant request header. Pass it on every MCP request via the X-Tenant header.

Available tools

17 tools are exposed. Grouped parameter objects accept both snake_case and camelCase keys.

Products (entities)

search_products

Search products via Homebox query plus local filters. Provide at least one filter; name is split into per-term queries when no other strict filter is provided.

  • name (Optional[str]) — product name (or phrase) query
  • item_id (Optional[str]) — exact product UUID
  • asset_id (Optional[str]) — asset ID filter
  • serial_number (Optional[str])
  • model_number (Optional[str])
  • manufacturer (Optional[str])
  • query (Optional[str]) — generic full-text query

Returns: list of matching product dicts, or an error string.

add_product

Create a new product or subitem with grouped parameters. If both location and parent_item are provided, parent_item wins (subitem creation).

  • identity (dict, required): {"name", "description", "asset_id"}
  • location (Optional[dict]): {"id"} or {"name"} — for standalone products
  • parent_item (Optional[dict]): {"id"} or {"name"} — for subitems
  • identifiers (Optional[dict]): {"serial_number", "model_number", "manufacturer"}
  • purchase (Optional[dict]): {"price", "seller", "date", "warranty_expires"}
  • metadata (Optional[dict]): {"notes", "quantity", "tag_ids", "tag_names", "custom_fields"}
  • status (Optional[dict]): {"archived", "insured", "lifetime_warranty"}

Returns: created product dict (after optional update pass), or error string.

update_product_by_id

Update an existing product. Pass IDs (item_id, location.id) — names are only resolved through list_locations outside this tool.

  • item_id (str, required) — UUID of the item to update
  • identity (Optional[dict]): {"new_name", "description", "asset_id"}
  • location (Optional[dict]): {"id"} or {"name"}
  • identifiers (Optional[dict]): {"serial_number", "model_number", "manufacturer"}
  • purchase (Optional[dict]): {"price", "seller", "date", "warranty_expires"}
  • metadata (Optional[dict]): {"notes", "quantity", "tag_ids", "tag_names", "custom_fields"}
  • status (Optional[dict]): {"archived", "insured", "lifetime_warranty"}

Returns: updated product dict, or error string.

add_bulk_products

Add multiple products in one call. Each entry uses the grouped shape from add_product.

  • items (list[dict], required) — each item must contain an identity.name
  • Returns: list (one result per input item).

delete_product_by_id

Delete a single product by ID.

  • item_id (str, required) — UUID of the item
  • product_name (str, required) — used for the success/error message only

Returns: success message, or error string.

delete_bulk_products

Delete multiple products. Delegates to delete_product_by_id for each entry.

  • items (list[dict], required) — each entry {item_id, product_name}
  • Returns: list (one result message per input item).

Locations

list_locations

Return Homebox's location tree (GET /api/v1/entities/tree).

  • No parameters.
  • Returns: list of top-level tree nodes (each with nested children).

create_location

Create a new location (entity with isLocation implied by being parent-less).

  • name (str, required)
  • description (Optional[str])
  • parent_id (Optional[str]) — UUID of a parent location

Returns: created location dict, or error string.

update_location_by_id

Update a location's editable fields. Fetches the current state first to preserve omitted fields.

  • location_id (str, required) — UUID of the location
  • new_name (Optional[str])
  • new_description (Optional[str])
  • new_parent_id (Optional[str]) — pass empty string "" to detach from parent

Returns: updated location dict, or error string.

delete_location_by_id

Delete a single location.

  • location_id (str, required) — UUID of the location
  • Returns: success message, or error string.

list_items_by_location

List direct child items of a location (uses ?parentIds=…).

  • location_id (str, required) — UUID of the location
  • Returns: list of {"id", "name"} items, or error string.

Tags

list_tags

Return all tags from /api/v1/tags.

  • No parameters.
  • Returns: list of {"id", "name"} tags, or error string.

create_tag

Create a tag if it does not already exist (case-folded de-dupe).

  • name (str, required)
  • Returns: created or pre-existing tag dict, or error string.

Maintenance

create_maintenance_entry_for_product

Create a maintenance entry for an existing product. Provide scheduled_date, completed_date, or both; if neither, both default to today.

  • product_id (Optional[str]) — preferred if known
  • product_name (Optional[str]) — resolved to a product ID if product_id is missing
  • name (str, required) — title/summary of the task
  • description (Optional[str])
  • cost (Optional[float])
  • scheduled_date (Optional[str]) — YYYY-MM-DD
  • completed_date (Optional[str]) — YYYY-MM-DD

Returns: created maintenance entry dict, or error string.

list_maintenance_entries

List maintenance entries from Homebox. The global /api/v1/maintenance endpoint is broken on Homebox v0.26+; this tool falls back to enumerating per-entity maintenance lists and aggregating them.

  • product_id (Optional[str]) — restrict to entries for one product
  • product_name (Optional[str]) — used to resolve the entity when product_id is missing
  • Returns: list of maintenance entry dicts, or error string.

update_maintenance_entry

Update an existing maintenance entry. Homebox v0.26+ exposes maintenance only per-entity, so the owning product must be supplied.

  • entry_id (str, required) — UUID of the entry
  • product_id (Optional[str]) — UUID of the owning entity (preferred)
  • product_name (Optional[str]) — resolved to an entity when product_id is missing
  • name (Optional[str])
  • description (Optional[str])
  • cost (Optional[float])
  • scheduled_date (Optional[str]) — YYYY-MM-DD
  • completed_date (Optional[str]) — YYYY-MM-DD

Returns: updated maintenance entry dict, or error string.

delete_maintenance_entry

Delete a maintenance entry.

  • entry_id (str, required) — UUID of the entry
  • Returns: success message, or error string.

Testing

The project ships unit tests and end-to-end tests.

Unit tests (no Docker required)

just test
# or: uv run pytest tests/ -v -k "not e2e"

End-to-end tests (requires Docker)

The E2E suite spins up a pinned Homebox v0.26.2 container, builds the MCP server image, registers a test user, and exercises all 17 tools through the Streamable HTTP transport. Each tool's effect is then verified against the real Homebox API (not just the MCP response envelope).

just test-e2e

What it does:

  1. docker compose -f docker-compose.e2e.yml up -d — start Homebox v0.26.2 on port 31745 and the MCP server on port 31746.
  2. Wait for the Homebox healthcheck.
  3. Register a test user (idempotent).
  4. Run pytest tests/e2e/ -m e2e.
  5. Tear down all containers.

See docker-compose.e2e.yml for the pinned image and tests/e2e/ for the suite. The suite covers every tool:

Category Tools tested
Locations list_locations, create_location, update_location_by_id, list_items_by_location, delete_location_by_id
Products search_products, add_product, update_product_by_id, add_bulk_products, delete_product_by_id, delete_bulk_products
Tags list_tags, create_tag
Maintenance create_maintenance_entry_for_product, list_maintenance_entries, update_maintenance_entry, delete_maintenance_entry

Recommended workflow for adding items

  1. Find a location for a standalone product — call list_locations to get a location UUID.
  2. Find a parent for a subitem — call search_products(name=...) to resolve the parent item UUID.
  3. Create or update — use add_product (new) or update_product_by_id (existing). If both location and parent_item are passed to add_product, parent_item is used and location is ignored for the creation target.

Justfile commands

just --list           # Show all commands
just start            # Start MCP server in stdio mode
just start-http       # Start MCP server in Streamable HTTP mode
just stop             # Stop running HTTP servers
just lint-format      # Run linting checks
just lint-fix         # Run linting and auto-fix issues
just test             # Run unit tests
just test-e2e         # Run E2E tests (requires Docker)
just wipe             # Clean cache/build artifacts
just docker-build     # Build Docker image
just docker-run       # Run Docker container

Repository layout

homebox-mcp/
├── main.py                          # FastMCP server, all 17 tools, helpers
├── models.py                        # Grouped dataclasses for tool inputs
├── server_http.py                   # Streamable HTTP transport entrypoint
├── request_config_middleware.py     # Per-request credential/tenant scoping
├── Dockerfile                       # HTTP server image
├── docker-compose.e2e.yml           # Pinned Homebox + MCP server stack
├── justfile                         # Dev/test commands
├── scripts/e2e-setup.sh             # Test user registration helper
├── tests/
│   ├── test_main.py                 # Unit tests (mocked HTTP)
│   ├── test_request_config_middleware.py
│   ├── test_transport_servers.py
│   └── e2e/                         # E2E tests against real Homebox v0.26.2
└── pyproject.toml

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选