Developers

MCP connector

Give an AI client read access to one organisation's register. The server URL for this environment is https://qr-inventory.com/mcp/inventory.

Connecting

QR Inventory speaks the Model Context Protocol over HTTP. Point the client at the server URL. The client posts JSON-RPC messages. A GET request to the same URL is rejected.

https://qr-inventory.com/mcp/inventory

This is not the REST API. A Sanctum API key from User Management will not authenticate an MCP client. The connector signs the user in with OAuth, and every tool is limited to that user's organisation. Requests are limited to 120 a minute for that user.

In a client such as Claude, add a custom connector and paste the server URL. The client discovers the OAuth endpoints, registers itself, and sends the user to QR Inventory to approve access. After approval, the client can call tools. The register tools are read-only. picture-board-tool is the exception: it creates a PDF and returns a download link.

A tool call looks like this:

POST https://qr-inventory.com/mcp/inventory
Authorization: Bearer {oauth-access-token}
Accept: application/json
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search-assets-tool",
    "arguments": { "query": "hairdryer" }
  }
}

OAuth

The server uses OAuth 2.1 with the authorisation-code grant and PKCE (S256). The only scope is mcp:use. Clients are public: they register without a client secret.

Step Endpoint What it returns
Protected resource GET /.well-known/oauth-protected-resource The resource URL, the authorisation server, and the mcp:use scope.
Authorisation server GET /.well-known/oauth-authorization-server The authorise, token, and registration endpoints, and the S256 challenge method.
Register a client POST /oauth/register A client_id for the redirect URI. Send JSON. redirect_uris is required.
Authorise GET /oauth/authorize The QR Inventory sign-in and approval screen. The user must already have an account.
Token POST /oauth/token An access token and a refresh token. Send the access token as Authorization: Bearer.
POST https://qr-inventory.com/oauth/register
Content-Type: application/json

{
  "client_name": "Claude",
  "redirect_uris": ["https://claude.ai/api/mcp/auth_callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_method": "none"
}

A machine-readable copy of the tool list is at https://qr-inventory.com/mcp/docs.json.

Tools

Call list-filter-options-tool before filtering if you do not know the exact category, location, or group name. Names are matched exactly, ignoring letter case. Locations and groups include what sits beneath them unless you turn that off. Items packed in a container are listed in that container's notes: search for the item, then answer with the container and its location.

TOOL list-assets-tool

List assets and return register counts.

Returns totals by status, category, subcategory and location, plus inspection and warranty rollups. The asset list is included unless include_assets is false. Read-only, and limited to the signed-in organisation.

Argument Required Description
category No Category name or numeric id.
subcategory No Subcategory name or numeric id. If the name matches more than one row, also pass category or use the id.
location No Location name or numeric id. Locations beneath it are included unless include_sublocations is false.
include_sublocations No Include locations beneath the location filter. Defaults to true.
group No Group name or numeric id. Groups beneath it are included unless include_subgroups is false.
include_subgroups No Include groups beneath the group filter. Defaults to true.
status No active, retired, or any. Defaults to any.
include_assets No Include the asset list as well as the counts. Defaults to true.
limit No Assets to return in the list. 1 to 200. Defaults to 100.
offset No Assets to skip. Defaults to 0.

TOOL search-assets-tool

Find assets by words.

Every word must match the label, notes, sub-location, QR sticker code, serial, manufacturer, or manufacturer code. Container contents are stored in the container notes, so a match there means the item is inside that container. Read-only.

Argument Required Description
query Yes The words to search for.
limit No Maximum matches. 1 to 50. Defaults to 20.
category No Category name or numeric id.
subcategory No Subcategory name or numeric id. If the name matches more than one row, also pass category or use the id.
location No Location name or numeric id. Locations beneath it are included unless include_sublocations is false.
include_sublocations No Include locations beneath the location filter. Defaults to true.
group No Group name or numeric id. Groups beneath it are included unless include_subgroups is false.
include_subgroups No Include groups beneath the group filter. Defaults to true.
status No active, retired, or any. Defaults to any.

TOOL get-asset-tool

Fetch one asset.

Looks up a single asset by QR sticker code, serial number, or numeric id. Includes location, supplier, maintainer, and inspection dates. Use this for a container when you need its full contents. Read-only.

Argument Required Description
identifier Yes QR sticker code, serial number, or numeric id.

TOOL upcoming-inspections-tool

List inspections that are due or overdue.

Overdue assets are always included. The window looks ahead the given number of days. Read-only.

Argument Required Description
within_days No How far ahead to look, in days. 1 to 365. Defaults to 30.
limit No Maximum assets to return. 1 to 100. Defaults to 50.

TOOL list-filter-options-tool

List the names you can filter by.

Returns the organisation's categories, subcategories, locations, and groups, each with a direct asset count. Call this before filtering when the exact name is unknown. Read-only.

This tool takes no arguments.

TOOL picture-board-tool

Build a PDF picture board.

One card per asset, with photo, label, QR code, and location. Retired assets are excluded. The result is a download link that anyone with the link can open for 24 hours. The board is refused when the filter matches more than 250 assets.

Argument Required Description
category No Category name or numeric id.
subcategory No Subcategory name or numeric id. If the name matches more than one row, also pass category or use the id.
location No Location name or numeric id. Locations beneath it are included unless include_sublocations is false.
include_sublocations No Include locations beneath the location filter. Defaults to true.
group No Group name or numeric id. Groups beneath it are included unless include_subgroups is false.
include_subgroups No Include groups beneath the group filter. Defaults to true.
per_page No Cards per page: 4, 8, or 12. Defaults to 8.
include_contents No Add an appendix of notes for assets that have them. Defaults to true.
title No Title shown instead of the filter label. Maximum 80 characters.