Skip to main content
Glama

inventory-mcp

MCP server for Inventory (whereiput.it) — search your stuff, do full CRUD, and run the AI photo-assist flow from Claude Desktop, Claude Code, Codex, or any MCP-compatible client.

This is software you run yourself, against your own Inventory server. There is no hosted MCP endpoint and no default API URL — you point it at the /api/v1/inventory/* token API of your own whereiput.it instance (running on your machine, your LAN, or your droplet) and run it next to your MCP client. Nothing here phones home.

It is a thin scope-enforced proxy over the Inventory token API (/api/v1/inventory/*). It makes no auth decision: it forwards your inv_ bearer unchanged as an Authorization: Bearer header, and the API's 403/404 is the real boundary. The token is never placed in a URL and never logged.

Two distinct URLs — don't conflate them.

  • The MCP endpoint is what you configure into your client: either a node dist/stdio.js command (stdio) or an http://YOUR_HOST:3100/mcp URL (HTTP transport).

  • INVENTORY_API_URL is what this server proxies to — your Inventory API host. It is required, has no default, and the server exits immediately if it is unset.

Get a token

Mint a personal API token in the SPA of your own instance at {YOUR_WHEREIPUT_APEX}/settings?tab=integrations (name + scopes read/write/ai) — replace {YOUR_WHEREIPUT_APEX} with your instance's address, e.g. http://localhost:8088 or https://inventory.yourdomain. The raw inv_… secret is shown once — copy it into the installer.

Tool visibility is gated by the token's scopes: a read-only token never sees write/ai tools.

Related MCP server: Homebox MCP Server

Setup

npm install
npm run build   # compiles dist/ AND regenerates the host-agnostic install.sh

stdio (zero infra — the default path)

stdio runs on the same machine as your MCP client with no port, no TLS, and no process manager — the client launches node dist/stdio.js on demand. This is the recommended path.

Claude Desktop config (claude_desktop_config.json). Pick the INVENTORY_API_URL that matches your server topology (Phase 17): single-origin (API + SPA on one host) or split api-host (the /api/v1/inventory/* routes served by the Laravel backend on a separate api. host):

{
  "mcpServers": {
    "inventory": {
      "command": "node",
      "args": ["/path/to/inventory-mcp/dist/stdio.js"],
      "env": {
        // Single-origin (API + SPA together):
        "INVENTORY_API_URL": "http://localhost:8088",
        // Split api-host (uncomment instead — the backend serves /api/v1/inventory on api.):
        // "INVENTORY_API_URL": "https://api.yourdomain",
        "INVENTORY_API_TOKEN": "inv_your_token_here"
      }
    }
  }
}

Here the command + args (node dist/stdio.js) are the MCP endpoint; INVENTORY_API_URL is the separate server-side proxy target. http is fine for a local/private API; use https if your API is publicly reachable.

HTTP transport (LAN / droplet)

Run the HTTP transport when you want to share one MCP server across devices — e.g. on your local network next to Home Assistant, or on the same droplet that runs your whereiput.it instance:

INVENTORY_API_URL=http://localhost:8088 node dist/http.js   # or https://api.yourdomain

It listens on INVENTORY_MCP_PORT (default 3100) and accepts the inv_ bearer per request (no INVENTORY_API_TOKEN on the server). http is allowed only for local/private networks; if you expose the transport publicly, https is REQUIRED — the Node process speaks plain HTTP, so TLS-terminate it yourself behind a reverse proxy you control.

Wire it into a client:

# Claude Code
claude mcp add inventory --transport http http://YOUR_HOST:3100/mcp -H "Authorization: Bearer inv_…"
# Codex (~/.codex/config.toml)
[mcp_servers.inventory]
url = "http://YOUR_HOST:3100/mcp"
bearer_token_env_var = "INVENTORY_TOKEN"
export INVENTORY_TOKEN="inv_your_token_here"   # fish: set -gx INVENTORY_TOKEN inv_your_token_here
// Generic HTTP client
{ "type": "http", "url": "http://YOUR_HOST:3100/mcp", "headers": { "Authorization": "Bearer inv_…" } }

Self-host install helper

When the HTTP transport is running, its / route serves a host-agnostic install.sh that advertises its own address (derived from the request) and prompts for token + client + INVENTORY_API_URL:

curl -fsSL http://YOUR_HOST:3100 | bash
# non-interactive (token, client, api-url positional):
curl -fsSL http://YOUR_HOST:3100 | bash -s -- inv_your_token_here codex http://localhost:8088

The same install.sh is generated on disk by npm run build, so you can also run ./install.sh directly from the clone. It gates on the inv_ prefix and configures Claude Code (claude mcp add) and/or Codex (codex mcp add + an idempotent managed-block shell export) — never embedding the token in a URL.

Optional: Docker

A multi-stage node:22-alpine Dockerfile (running the HTTP transport) ships in this repo. It bakes no INVENTORY_API_URL — you supply it at run time:

docker build -t inventory-mcp .
docker run -e INVENTORY_API_URL=http://host.docker.internal:8088 -p 3100:3100 inventory-mcp

An optional, opt-in compose snippet (explicitly not part of the main self-host docker-compose.yml and not wired behind the edge proxy) is documented in docs/SELF-HOSTING.md under Optional: Inventory MCP server.

Environment variables

Variable

Default

Purpose

INVENTORY_API_URL

Required — no default

Your Inventory token API base URL. Single-origin http://localhost:8088 or split api-host https://api.yourdomain. The server exits with a fail-fast message if unset. Never a hosted default.

INVENTORY_API_TOKEN

The inv_ bearer (stdio only; the HTTP transport takes it per-request).

INVENTORY_MCP_PORT

3100

HTTP transport listen port.

Tools

Tool

Scope

API call

list_areas, get_area

read

GET areas[/{id}]

list_locations, get_location

read

GET areas/{id}/locations, locations/{id}

search_items, get_item

read

GET items/search?q=, items/{id}

create_area / update_area / delete_area

write

POST/PUT/DELETE areas

create_location / update_location / delete_location

write

POST areas/{id}/locations, PUT/DELETE locations/{id}

create_item / update_item / delete_item

write

POST locations/{id}/items, PUT/DELETE items/{id}

create_category, create_tag

write

POST categories / tags

recognize_photo

ai

POST items/recognize

save_recognized

ai

POST locations/{id}/items/bulk

A user-invoked catalog_from_photo prompt walks the recognize → review → save flow.

AI photo-assist caveat (Phase 7 follow-up)

recognize_photo passes text-friendly args (image_base64 + mime + area_id). The Phase 7 recognize endpoint is multipart-only today. For the remote HTTP transport, the recognize endpoint likely needs a base64/JSON input-adapter branch (an input adapter only — no logic change). The ai tools + client methods ship now; the live end-to-end recognize call lights up once that input adapter lands. This is a documented sequencing acceptance, not a blocker.

Development

npm run dev        # HTTP transport with tsx (no build step)
npm run dev:stdio  # stdio transport with tsx
npm test           # vitest
F
license - not found
-
quality - not tested
B
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.

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/golem15com/inventory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server