homebox-mcp
This MCP server lets an MCP client query and manage a Homebox home inventory in plain language through ~39 tools.
Search and read items, full item details, location trees/contents, tags, and warranty expirations.
Create/enrich items, bulk-import CSVs, create locations, duplicate items, and look up barcodes.
Edit item metadata, move items, set warranty/identity/custom fields/tags, and mark items sold.
Attach documents/photos from local paths or URLs; list, download, rename, and delete attachments.
Log, list, edit, and delete maintenance entries.
Report inventory totals/value by location/tag/time, export CSV, and inspect custom fields.
Generate printable QR labels and raw QR codes, finalize bulk photos, and build custom-field dedupe indexes.
Delete items, locations, tags, attachments, and maintenance entries with confirm-gated safety checks.
Click on "Deploy 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., "@homebox-mcp where is my impact driver"
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.
homebox-mcp
An MCP server over the
Homebox REST API, so an MCP client like Claude can
work with your home inventory in plain language: "where is my impact driver",
"what's in Tote B-3", "which warranties expire this year", "add this drill —
here's a photo of the receipt and the model number". It answers questions,
performs intake (create an item, attach the manual/receipt, tag and file it),
manages attachments, and prints QR labels for totes and shelves — no
hand-rolled curl.
Quickstart
You need a running Homebox instance (0.26+, see Requirements) and an API key from Profile → API Keys in the Homebox web UI.
Claude Code
claude mcp add homebox --scope user \
-e HOMEBOX_URL=https://homebox.example.com \
-e HOMEBOX_TOKEN=hb_xxxxxxxxxxxxxxxxxxxxxxxx \
-- uvx homebox-mcp
claude mcp get homebox # should show: Status ✔ Connected--scope user makes it available from any project. uvx fetches and runs the
published package in an ephemeral environment — nothing to install first.
Claude Desktop / generic MCP clients
Add to your client's MCP config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"homebox": {
"command": "uvx",
"args": ["homebox-mcp"],
"env": {
"HOMEBOX_URL": "https://homebox.example.com",
"HOMEBOX_TOKEN": "hb_xxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}From a clone (no PyPI)
The module carries PEP 723 inline
dependencies, so it also runs standalone with uv run --script — uv resolves
mcp, httpx, pillow, and pillow-heif into an ephemeral venv on first run.
Instead of env vars, drop credentials in a .env file next to the module:
git clone https://github.com/dgahagan/homebox-mcp
cd homebox-mcp
cp .env.example .env # .env is gitignored
chmod 600 .env
# edit .env: HOMEBOX_URL + HOMEBOX_TOKENThen register the absolute path to the module (or to server.py, a
compatibility shim kept for older registrations):
claude mcp add homebox --scope user -- \
uv run --script /path/to/homebox-mcp/homebox_mcp.pyThe server reads config from the environment, falling back to the sibling
.env (resolved relative to the script, so the absolute-path invocation still
finds it). The credential never enters the MCP config — it stays in the
gitignored .env.
Related MCP server: homekit-cli
Requirements
Homebox 0.26 or newer — the actively maintained sysadminsmedia fork at homebox.software. This server speaks the unified entities API introduced in 0.26. Older instances use a different API (
/items,/locations,/labels) and are rejected on the first tool call with a clear error rather than failing cryptically.An API key — Homebox Profile → API Keys (the token starts with
hb_).uv, or any Python ≥ 3.11 environment where you installhomebox-mcpyourself.MCP SDK 2.x (
mcp>=2,<3), pulled in automatically.uvx/pipxbuild an isolated environment, so this needs no action. If you are installing into an environment already pinned tomcp<2, stay onhomebox-mcp==1.0.1.
Configuration
All configuration is via environment variables (or the sibling .env for the
clone workflow):
Variable | Required | Purpose |
| yes | Base URL of your Homebox instance (no trailing slash). |
| yes | Homebox API key ( |
| no | Name of one custom field to treat as a stable item identifier — items can be resolved by it, summaries surface it, and |
| no | Where |
Tools
~39 tools. Reads accept a fuzzy identifier (assetId, alias field, exact
name, then first keyword match). Write tools require an exact identifier
(assetId, alias field, or exact name) — a typo or an ambiguous match is refused
rather than mutating the wrong item. An assetId must be in the full
000-012 form: a bare 12 is matched as a name or alias, never as asset
000-012. Locations are referenced by name or
/-separated path (e.g. Garage/Shelf 1) to disambiguate duplicate names.
Read / Q&A
Tool | Purpose |
| Search items by keyword and/or tag names (AND of both); returns each with assetId, location, and the alias field. |
| Full detail for one item: location path, identity, purchase, warranty, custom fields, tags, attachments. |
| The full location tree as an indented outline. |
| Items directly in a location plus its sub-location names; |
| All tag (label) names; |
| Items whose warranty expires in |
Create & intake
Tool | Purpose |
| Create and enrich an item in one call. |
| Bulk-create items and locations from a Homebox CSV in one multipart request. |
| Create a location (tote/bin/shelf) to bootstrap a new storage spot; |
| UPC/EAN → name/manufacturer/model (optional, for boxed goods). |
| Duplicate an item ("I bought a second one"). Copied custom fields include the alias field verbatim — give the copy its own value after. |
Edit
All write tools resolve by exact identifier and preserve everything you don't touch (a full-body PUT that echoes the rest of the item back — see gotchas).
Tool | Purpose |
| General item editor: rename, notes, quantity, purchase info, insured/archived flags, custom fields. Quantity-only edits use a partial PATCH. |
| Move an item into a location or into another item (e.g. a lens into |
| Set warranty end date, lifetime flag, and terms summary. |
| Set manufacturer / model / serial (e.g. after a nameplate photo reveals them). |
| Create or overwrite custom fields (upsert; typed by JSON value type). |
| Add / remove / replace tags on an item; unknown tag names are auto-created (partial PATCH). |
| Edit a tag's own metadata (rename, color, icon, parent tag for grouping) — not what's tagged on an item. Creates the tag if new. |
| General location editor: rename, move (or |
| Record a sale (price/buyer/date/notes) or |
Maintenance log
Tool | Purpose |
| Add an entry — "changed the mower oil today" (completed) or "sharpen blades in spring" (scheduled). |
| Entries for one item, or across the whole inventory ("what maintenance is due?"); |
| Edit an entry — e.g. mark a scheduled one completed by setting |
| Delete one entry ( |
Reporting
Tool | Purpose |
| Totals (counts, total value, warranty count), value by location or tag, or purchase-price over time — the cheap way to answer "what's my inventory worth?". |
| Export the whole inventory as a Homebox CSV (complement of |
| Discover the custom-field schema in use: all field names, or every distinct value of one field. |
Attachments
Tool | Purpose |
| Attach a file (local path or http(s) URL) to an item, or to a location by name as a fallback. |
| List an item's or location's attachments with their ids (the handle the other attachment tools need). |
| Download one attachment to a local path so its content (e.g. a manual) can be read. |
| Update an attachment's title, type, or primary flag. |
Uploads auto-convert HEIC/HEIF (iPhone photos) to JPEG so Homebox always stores a browser-renderable image, and sanitize
/in titles (Homebox treats a title as a path and would otherwise truncate it).
Deletes (confirm-gated)
Every delete requires confirm to equal the target's exact name and carries
the MCP destructiveHint annotation, so clients prompt before running them.
Tool | Purpose |
| Permanently delete an item and its attachments. No undo. |
| Delete a location. A non-empty one is refused unless |
| Delete a tag itself (removed from every tagged item; the items survive). |
| Delete one attachment ( |
Labels & finalize
Tool | Purpose |
| Save a printable label PNG (QR + readable name) for a |
| Save a raw QR JPEG for arbitrary data (prefer |
| Finalize after a bulk photo attach: set missing primary images, then generate missing thumbnails. |
|
|
How it works (and Homebox 0.26 gotchas)
The value of this server is as much in what it works around as in what it exposes. These are hard-won behaviors of the 0.26 entities API:
Items and locations are unified "entities" (
/v1/entities); a location is an entity whose entity-type hasisLocation=true. A new item with no entityTypeId lazily gets a defaultItemtype.GET /entitiesreturns non-location entities only. Location children never appear in/entitiesresults, even withparentIds— sub-locations come from the entity tree (/entities/tree).location_contentsmerges both sources, anddelete_location's emptiness check counts items and sub-locations.Deleting a non-empty location cascades sub-locations but orphans items. Force-deleting a location (
confirm_nonempty=True) deletes its sub-locations with it, but its items survive, re-parented to the top level. Move items out first if you don't want them loose.List/search responses are lightweight summaries — they omit
fieldsand have an emptyassetId. The server fetches full detail (GET /entities/{id}) before returning assetId/alias, sosearch_items/get_itemare accurate.qdoes not index custom fields. Resolving by an alias-field value uses a scan fallback (one detail fetch per item). Resolving by assetId (via/v1/assets/{id}) or name is cheaper — prefer assetId when you have it (e.g. the valuecreate_itemreturns).PUT clears omitted fields, including
assetId. Every write tool rebuilds a full body from a fresh GET (_preserve_item_body) and overrides only the targeted keys.create_itemassigns the asset ID after enrichment so it survives.Attachment titles are basenamed on
/. Homebox treats a title as path-like, so "front 3/4 view" silently stores as "4 view". The server sanitizes/→-in attach titles.Number custom fields are integer-typed. A float
numberValue(e.g.17000.0, which the MCP SDK produces from afloat-typed arg) makes the API 500 "Unknown Error". The server coerces number values toint; pass whole numbers.Custom-field values are type-keyed (
textValue/numberValue/booleanValue). The server rebuilds each field by its declared type — coercing everything totextValue(an earlier bug) silently wiped numeric/boolean fields on any PUT.Pagination. Entity listings over one page (200) were silently truncated; the server pages through to the reported
total, so search, dedupe, and warranty sweeps stay correct on large inventories.
Conventions (optional)
Homebox's built-in assetId is a stable numeric handle, but it isn't something
you'd type from memory. If you want a human-meaningful stable identifier —
useful for cross-referencing items with receipts, spreadsheets, or another
system — add a custom field (say item_id) holding a slug like
makita-xdt131 and point HOMEBOX_ALIAS_FIELD at it. Then:
items resolve by that slug in every read and write tool,
search_items/get_itemsummaries surface it, andfield_index()defaults to it, giving you a one-call dedupe map before a bulk import.
This is entirely optional — leave HOMEBOX_ALIAS_FIELD unset and items resolve
by assetId or name only. Nothing about the field name is special; any single
custom field works.
Companion scripts
Two standalone helper scripts ship in the repo (not MCP tools):
annotate_location_photos.pyturns one wide photo of a shelf bank into one boxed/labeled image per shelf (--rows N), and can upload each straight to its Homebox location with--upload. See its--help.heic2jpg.pyconverts HEIC/HEIF (iPhone photos) to JPEG for ad-hoc use (./heic2jpg.py FILE...). Note the attach tools already auto-convert HEIC on upload, so this is only needed to feed HEIC frames to a vision step before upload.
Both rely on pillow-heif, which bundles libheif — there's no system package to
install.
Security
API key handling. In the clone workflow the key lives in
.env, which is gitignored and should be mode600(chmod 600 .env). Never commit it. In theuvxworkflow it's passed through your MCP client's config — treat that file as a secret too.Key rotation. Rotating the Homebox
HBOX_AUTH_API_KEY_PEPPERinvalidates every issued key — mint a new one and update your config.Confirm-gated deletes. All four delete tools require
confirmto equal the target's exact name and carry the MCPdestructiveHintannotation, so a well-behaved client prompts before any destructive call.Use HTTPS for any remote Homebox instance — the API key is sent on every request in the
Authorizationheader.
Development
git clone https://github.com/dgahagan/homebox-mcp
cd homebox-mcp
# Run the test suite (httpx mocked with respx — no live instance needed)
uv run --with pytest --with respx --with . pytest
# Lint
uv run --with ruff ruff check .The server is a single module (homebox_mcp.py) with PEP 723 inline
dependencies. See CONTRIBUTING.md for setup and PR
expectations, and CHANGELOG.md for release notes.
License
MIT © Dan Gahagan
Available Tools
39 toolsattach_documentA
Attach a document to an item OR a location. source is a local file path
or an http(s) URL (downloaded then uploaded). doc_type is e.g. manual,
attachment, warranty, receipt, photo. identifier is assetId/alias/name
for an item, or a location name/path (tried as a fallback if no item
matches). Set primary=True to make a photo the entity's primary image —
e.g. a "this is the spot" wayfinding photo on a shelf/tote location
(doc_type="photo").
Inputs: title (required), source (required), identifier (required), primary, +1 more.
barcode_lookupARead-only
Look up a UPC/EAN barcode → name/manufacturer/model (optional path for boxed goods). Thin wrapper over GET /products/search-from-barcode.
Inputs: code (required).
create_itemA
Create an inventory item and enrich it in one call.
location is where the item goes, resolved as in move_item: a location
name or /-separated path (must exist; use list_locations), or a container
item, e.g. 'Camera Bag', 'Office/Camera Bag' or its assetId ('000-012').
A location wins over an item with the same name. tags are tag names (must already exist; use list_tags).
fields maps custom-field name -> value; each value's JSON type picks the
field type (string -> text, number -> number [integer-coerced],
true/false -> boolean). Returns the new assetId and id.
Inputs: name (required), tags, model, notes, +9 more.
create_locationA
Create a LOCATION entity (e.g. a new tote/bin/shelf) to bootstrap a
new storage spot. parent is an existing location name or /-separated
path (optional); description is optional free text, e.g. a contents
summary (≤1000 chars). Returns the new location id. For deep paths,
prefer import_csv's HB.location auto-create.
Inputs: name (required), parent, description.
delete_attachmentADestructive
PERMANENTLY delete one attachment from an item or location (see
list_attachments for ids). confirm must equal the attachment's exact
title.
Inputs: confirm (required), identifier (required), attachment_id (required).
delete_itemADestructive
PERMANENTLY delete an item (assetId / alias field / exact name),
including its attachments. confirm must equal the item's exact name.
There is no undo.
Inputs: confirm (required), identifier (required).
delete_locationADestructive
PERMANENTLY delete a location (name or /-separated path). confirm
must equal the location's exact name. A location that still contains items
or sub-locations is refused unless confirm_nonempty=True — sub-locations
are deleted with it, and its items are ORPHANED to the top level (not
deleted). There is no undo.
Inputs: confirm (required), location (required), confirm_nonempty.
delete_maintenanceADestructive
PERMANENTLY delete one maintenance entry (see list_maintenance for
ids). confirm must equal the entry's exact name.
Inputs: confirm (required), entry_id (required).
delete_tagADestructive
PERMANENTLY delete a tag itself (it is removed from every tagged item;
the items survive). confirm must equal the tag's exact name.
Inputs: name (required), confirm (required).
duplicate_itemA
Duplicate an existing item (assetId / alias field / exact name), e.g.
"I bought a second one". prefix is prepended to the new item's name.
Copies custom fields by default; attachments and maintenance log only on
request. NOTE: copied custom fields include the alias field verbatim — if
you use one, give the copy its own value via set_fields right after.
Returns the new item's id and assetId.
Inputs: identifier (required), prefix, copy_attachments, copy_maintenance, +1 more.
export_csvA
Export the whole inventory as a Homebox CSV (the complement of
import_csv; also a quick backup). Saves to save_to (file path or
directory; default: homebox-export.csv in the current directory) and
returns the path and row count.
Inputs: save_to.
field_indexARead-only
Return {field_value: assetId} for every entity that has the named
custom field — a one-pass index for DEDUPE before a bulk import (q does
not index custom fields, so this scans every entity). field_name
defaults to $HOMEBOX_ALIAS_FIELD. assetId may be empty for un-asset'd
rows. Deliberately uncapped: a truncated dedupe index causes duplicates,
so expect a large result on a large inventory.
Inputs: field_name.
finalize_photosAIdempotent
Finalize after a bulk photo attach: ensure every entity with photos has a primary image, then generate any missing thumbnails. (Wraps the set-primary-photos and create-missing-thumbnails actions, which are always run as a pair.)
Inputs: no named parameters.
generate_labelA
Save a printable Homebox label PNG (QR + readable name) for a location
or item, e.g. to stick on a tote/bin. kind is "location", "item", or
"asset". For location/item, identifier is a name or slug (resolved to an
id); for asset it's the assetId (e.g. 000-028). Saves to out_dir
(default: $HOMEBOX_LABEL_DIR, else the current directory). Returns the
saved file path.
Inputs: identifier (required), kind, out_dir.
get_attachmentA
Download one attachment (see list_attachments for ids) to a local path,
so its content — e.g. an attached manual or receipt — can be read.
save_to is a directory (keeps a name based on the title) or a full file
path.
Inputs: save_to (required), identifier (required), attachment_id (required).
get_itemARead-only
Get full detail for one item by assetId (e.g. 000-028), alias custom field, or name (fuzzy fallback: first keyword match). Includes location path, serial, model, purchase, warranty, custom fields, tags, and attachments.
Inputs: identifier (required).
import_csvA
Bulk-create items and locations from a Homebox CSV (multipart import).
This is the bulk creator for the photo-intake pipeline — one request imports everything, avoiding ~4 API calls per item. Recognized columns: HB.name, HB.location (path e.g. "Garage/Loft" — AUTO-CREATES the hierarchy), HB.tags (must already exist; see list_tags), HB.quantity, HB.serial_number, HB.model_number, HB.manufacturer, HB.notes, HB.purchase_price, HB.purchase_from, HB.purchase_time, HB.warranty_expires, HB.field. (custom fields). A location-only row (HB.location set, contents described elsewhere) creates just the location. After import, call finalize_photos if you attached photos. Returns the count of data rows submitted.
Inputs: csv_text (required).
inventory_statsARead-only
Inventory statistics — the cheap way to answer "what's my inventory
worth?" without scanning items. by is:
totals — counts (items/locations/tags/users), total purchase
price, items with warranty;
locations — total value per location;
tags — total value per tag;
purchase-price — value over time (optional YYYY-MM-DD start/end).
Inputs: by, end, start.
list_attachmentsARead-only
List an item's (or location's) attachments with their ids — the handle
needed by get_attachment / rename_attachment / delete_attachment.
identifier is assetId / alias field / name, or a location name/path.
Inputs: identifier (required). Returns: result
list_custom_fieldsARead-only
Discover the custom-field schema actually in use: with no arg, all
custom-field NAMES across the inventory; with field, the distinct
VALUES of that field ({"total", "values"}, capped at limit). Useful
before set_fields/field_index on an unfamiliar instance.
Inputs: field, limit.
list_locationsARead-only
Return the full location tree as an indented outline.
Inputs: no named parameters. Returns: result
list_maintenanceARead-only
List maintenance entries — for one item (assetId / alias field / name)
or, with no identifier, across the whole inventory ("what maintenance is
due?"). status is "scheduled" (upcoming), "completed", or "both".
Inputs: status, identifier. Returns: result
list_tagsARead-only
List all tag (label) names. Set detail=True to instead return full
tag objects (name, description, color, icon, parent tag name) for
auditing tag setup — pair with set_tag to edit any of these.
Inputs: detail.
location_contentsARead-only
List what is in a location (e.g. a tote or shelf), by location name.
Returns the items directly in that location plus any sub-locations (their
names only — not their contents). Set recursive=True to instead walk the
whole subtree and return every item nested under it, each tagged with its
full location path; use this when a location (e.g. Garage, Basement) has
sub-locations you also want the contents of, to avoid querying each one by
hand. location is a name or /-separated path (for duplicate names).
Inputs: location (required), max_items, recursive.
log_maintenanceA
Add a maintenance-log entry to an item (assetId / alias field / exact
name) — e.g. "changed the mower oil today" (completed_date) or "sharpen
blades in spring" (scheduled_date). Dates are YYYY-MM-DD; cost is a
number. Returns the new entry's id.
Inputs: name (required), identifier (required), cost, description, +2 more.
mark_soldAIdempotent
Record that an item was sold (assetId / alias field / exact name):
price, buyer, YYYY-MM-DD date, notes — only the args you pass are set.
clear=True instead erases all four sold fields (un-sells the item).
Other fields are preserved. Pair with set_item(archived=True) if the item
should also leave active inventory.
Inputs: identifier (required), clear, sold_to, sold_date, +2 more.
move_itemAIdempotent
Move an item into a location or into another item (assetId / alias field / exact name).
location is the destination's name or /-separated path — a location
(see list_locations) or a container item, e.g. a lens into 'Camera Bag'
or 'Office/Camera Bag' — or a container item's assetId ('000-012'). A
location wins over an item with the same name; reach the item with a
longer path or its assetId. A name that matches more than one location,
or more than one item, is refused. Uses a partial PATCH, so nothing else
on the item changes.
Inputs: location (required), identifier (required).
qrcodeA
Save a raw QR-code JPEG encoding arbitrary data (e.g. a deep link).
For tote labels prefer generate_label (adds the readable name). Saves to
out_dir (default: $HOMEBOX_LABEL_DIR, else the current directory).
Returns the saved file path.
Inputs: data (required), out_dir.
rename_attachmentAIdempotent
Update an attachment's title, type (manual/attachment/warranty/receipt/ photo), or primary flag (see list_attachments for ids). Only the args you pass change; the rest is re-sent as-is.
Inputs: identifier (required), attachment_id (required), title, primary, +1 more.
search_itemsARead-only
Search inventory items by name/keyword and/or by tag names (AND of both when both given — e.g. everything tagged "power-tool").
Returns items (not locations) with their immediate location, assetId, and the alias custom field (if $HOMEBOX_ALIAS_FIELD is configured). Use get_item for full detail on one result.
Inputs: tags, limit, query. Returns: result
set_fieldsAIdempotent
Create or update custom fields on an existing item (assetId / alias field / exact name).
fields maps custom-field name -> value; each value's JSON type picks the
field type (string -> text, number -> number [integer-coerced — the API
500s on float number values], true/false -> boolean). Upsert semantics:
named fields are created or overwritten; other fields are preserved.
Inputs: fields (required), identifier (required).
set_identityAIdempotent
Set manufacturer/model/serial on an existing item (assetId / alias field / exact name).
Only the args you pass change; other fields are preserved. Use when a nameplate/label photo reveals a serial number or a model-number correction after the item was created.
Inputs: identifier (required), manufacturer, model_number, serial_number.
set_itemAIdempotent
General item editor (assetId / alias field / exact name): rename, edit description/notes/quantity, purchase info, insured/archived flags, and custom fields in one call.
Only the args you pass are changed. Quantity-only changes go via a partial
PATCH; anything else uses a full-body PUT that preserves the rest of the
item (the 0.26 PUT-clears gotcha). fields maps custom-field name ->
value, typed by JSON type (see set_fields). To move an item use move_item;
for warranty/identity/tags see set_warranty/set_identity/set_tags.
Inputs: identifier (required), notes, fields, insured, +7 more.
set_locationAIdempotent
Edit a LOCATION's metadata (find it by current name or /-path): rename,
description (e.g. a contents manifest), notes, tags, custom fields
(values typed by JSON type). Only the args you pass change; other fields
are preserved. parent moves it under another location; clear_parent=True
moves it to the root. entity_type (e.g. "Item") converts a mis-created
entity — rare. asset_id overrides the auto-assigned assetId.
Inputs: location (required), tags, notes, fields, +7 more.
set_maintenanceAIdempotent
Edit a maintenance entry (see list_maintenance for ids) — e.g. mark a scheduled entry completed by setting completed_date. Only the args you pass change; the rest of the entry is re-sent as-is (the update is a full PUT).
Inputs: entry_id (required), cost, name, description, +2 more.
set_tagAIdempotent
Create or edit a tag's own metadata — NOT what's tagged on an item (see
set_tags for that). Matches name case-insensitively against list_tags;
creates the tag if it doesn't exist yet. Only the args you pass are
changed. parent nests this tag under another (existing) tag name, for
grouping related tags in the Homebox UI (e.g. several condition-* tags
under a "condition" parent); pass clear_parent=True to un-nest it.
Use list_tags(detail=True) to see current tag metadata first.
Inputs: name (required), icon, color, parent, +3 more.
set_tagsAIdempotent
Add, remove, or replace tags on an existing item (assetId / alias field / exact name).
mode is "add" (default — merges with the item's existing tags), "remove"
(drops just the named tags, keeps the rest), or "replace" (item ends up
with exactly these tags, nothing else). Tag names are matched
case-insensitively against list_tags and auto-created if they don't exist
yet. Everything else on the item is untouched (partial PATCH).
Inputs: tags (required), identifier (required), mode.
set_warrantyAIdempotent
Set warranty info on an existing item (assetId / alias field / exact name).
expires is a YYYY-MM-DD date (warranty end), lifetime flags a lifetime
warranty, details is a short terms summary (e.g. "limited lifetime,
test/measurement instruments excluded"). Only the args you pass change;
other fields are preserved.
Inputs: identifier (required), details, expires, lifetime.
warranties_expiringARead-only
List items whose warranty expires in a date window, or items with a lifetime warranty.
before/after are ISO dates (YYYY-MM-DD): returns items with
after <= warrantyExpires <= before. after defaults to TODAY, so
already-expired warranties are excluded unless you pass an earlier
after. Set lifetime=True to instead list items flagged as lifetime
warranty (before/after ignored). Useful for "which warranties expire
this year".
Inputs: after, before, lifetime. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 39 tools
The item-editing family overlaps substantially: set_item explicitly handles custom fields too, duplicating set_fields, and set_identity/set_warranty/set_tags/move_item/mark_sold all edit the same item with subtle boundaries. set_tag vs set_tags is also easily confused despite the explicit cross-reference. Descriptions steer an agent toward the right tool, but the boundaries are not crisp.
The dominant convention is verb_noun (set_location, delete_attachment, import_csv, list_maintenance), used consistently across most entities. A handful of noun-first outliers (field_index, barcode_lookup, warranties_expiring, qrcode, inventory_stats, location_contents) and singular/plural wobble (set_tag vs set_tags, get_attachment vs list_attachments) are minor deviations that don't hurt readability.
39 tools is heavy for an inventory server, well beyond the 15-tool sweet spot. The broad domain (items, locations, tags, attachments, maintenance, labels, CSV, stats) justifies many tools, but several granular item setters (set_fields, set_identity, set_warranty) could be folded into set_item, and utility tools like qrcode/finalize_photos inflate the surface.
Near-complete CRUD/lifecycle coverage exists for items (create/get/set/delete/duplicate/move/sold), locations, tags, attachments, and maintenance, plus CSV import/export, label generation, stats, and custom-field discovery. Minor gaps remain: no way to delete a custom-field definition, no plain list_items (only search_items), and no user management.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for searching Airweave collections with natural language queries.
Official Todoist MCP server. Manage tasks and projects. Hosted, no API key needed.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for managing Homebox inventory via AI assistants, enabling item management, location organization, and label categorization.4MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that provides tools for inspecting and controlling Apple HomeKit accessories, scenes, automations, and more via the HomeClaw app, enabling natural language interaction with your smart home.3 npmMIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives AI assistants real-time access to your homelab infrastructure. It enables querying node status, managing Docker containers, controlling Proxmox VMs, and inspecting OPNsense firewall state through natural conversation.2MIT
- FlicenseCqualityDmaintenanceAn MCP server that exposes Homebox inventory management as tools for AI agents, enabling search, add, update, delete products, locations, tags, and maintenance entries.172-