npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

the-real-snipeit-mcp

v0.1.7

Published

MCP server for the Snipe-IT REST API — 100% endpoint coverage (read + write), hand-wrappers + OpenAPI codegen, stdio transport.

Readme

the-real-snipeit-mcp

npm version CI License: MIT Node MCP

Talk to Snipe-IT from Claude. Ask "show me all overdue audits", "check out laptop A-42 to manuel", "which licenses expire in the next 90 days" — and the LLM picks the right API call out of 183 tools. Read-and-write, with a safety gate for destructive operations and an envelope-aware client that never mistakes a Snipe-IT error for success.

A Model Context Protocol (MCP) server that exposes the entire Snipe-IT REST API to Claude (Desktop, Code, Agent SDK) over stdio. Built for IT asset managers who'd rather describe what they want than navigate a dashboard.

Three tool layers:

  • 38 hand-wrappers (snipeit_*) — friendlier UX for common workflows (checkout/checkin, audits, by-tag/by-serial lookup, bulk checkout)
  • ~145 auto-generated tools (snipeit_gen_*) — full coverage of every operation in the OpenAPI 3.1 spec
  • snipeit_raw_request — escape hatch for any method/path

Plus 3 resources (current user, settings, asset summary) and 3 prompts (inventory audit, user onboarding, license health).


Quick start

Prerequisites: Node ≥ 20, a Snipe-IT instance you can reach (self-hosted or cloud), and an API token from User menu → Manage API Keys (docs).

Option A — Install from npm

npm install -g the-real-snipeit-mcp

Option B — From source

git clone https://github.com/mguttmann/the-real-snipeit-mcp.git
cd the-real-snipeit-mcp
npm install
cp .env.example .env
# edit .env: set SNIPEIT_API_TOKEN and SNIPEIT_API_BASE for your instance
npm run build
npm start    # ← stdio: this blocks; that's normal — your MCP client speaks JSON-RPC over stdin/stdout

Verify with the MCP Inspector (separate terminal):

npm run inspector

⚠️ The SNIPEIT_API_BASE default https://snipe-it.example.com/api/v1 is an RFC 2606 reserved placeholder — it does not resolve. Set your own URL before running.

Configuration

| Variable | Default | Description | |---|---|---| | SNIPEIT_API_TOKEN | (required) | Snipe-IT Personal API Token (JWT) | | SNIPEIT_API_BASE | https://snipe-it.example.com/api/v1 | API base URL | | SNIPEIT_CONFIRM_WRITES | false | If true, destructive tools require confirm: "YES" | | SNIPEIT_TIMEOUT_MS | 30000 | Per-request timeout | | SNIPEIT_LOG_LEVEL | info | debug | info | warn | error |

Claude Desktop config

{
  "mcpServers": {
    "snipeit": {
      "command": "node",
      "args": [
        "--env-file=/absolute/path/to/the-real-snipeit-mcp/.env",
        "/absolute/path/to/the-real-snipeit-mcp/dist/index.js"
      ]
    }
  }
}

Tool reference

Hand-wrappers (38 tools)

Identity (1)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_me | GET /users/me | readOnly |

Hardware / Assets (13)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_list_hardware | GET /hardware (paginated, common filters) | readOnly | | snipeit_search_hardware | GET /hardware?search={query} (convenience) | readOnly | | snipeit_get_hardware_by_id | GET /hardware/{id} | readOnly | | snipeit_get_hardware_by_tag | GET /hardware/bytag/{tag} | readOnly | | snipeit_get_hardware_by_serial | GET /hardware/byserial/{serial} | readOnly | | snipeit_create_hardware | POST /hardware | writeOnce | | snipeit_update_hardware | PATCH /hardware/{id} | writeIdempotent | | snipeit_delete_hardware | DELETE /hardware/{id} | writeIdempotent | | snipeit_checkout_hardware | POST /hardware/{id}/checkout (user/location/asset) | writeOnce | | snipeit_checkin_hardware | POST /hardware/{id}/checkin | writeOnce | | snipeit_audit_hardware | POST /hardware/audit | writeOnce | | snipeit_list_audit_due | GET /hardware/audit/due | readOnly | | snipeit_list_audit_overdue | GET /hardware/audit/overdue | readOnly |

Users (5)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_list_users | GET /users | readOnly | | snipeit_get_user | GET /users/{id} | readOnly | | snipeit_get_user_assets | GET /users/{id}/assets | readOnly | | snipeit_get_user_accessories | GET /users/{id}/accessories | readOnly | | snipeit_get_user_licenses | GET /users/{id}/licenses | readOnly |

Licenses (3)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_list_licenses | GET /licenses | readOnly | | snipeit_get_license_seats | GET /licenses/{id}/seats | readOnly | | snipeit_checkout_license_seat | PUT /licenses/{license_id}/seats/{seat_id} | writeIdempotent |

Accessories / Consumables / Components (8)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_list_accessories | GET /accessories | readOnly | | snipeit_checkout_accessory | POST /accessories/{id}/checkout | writeOnce | | snipeit_checkin_accessory | POST /accessories/{id}/checkin (pivot-id) | writeOnce | | snipeit_list_consumables | GET /consumables | readOnly | | snipeit_checkout_consumable | POST /consumables/{id}/checkout | writeOnce | | snipeit_list_components | GET /components | readOnly | | snipeit_checkout_component | POST /components/{id}/checkout (to asset) | writeOnce | | snipeit_checkin_component | POST /components/{id}/checkin (pivot-id) | writeOnce |

Locations / Status-Labels / Maintenances (6)

| Tool | Endpoint | Annotations | |---|---|---| | snipeit_list_locations | GET /locations | readOnly | | snipeit_get_location | GET /locations/{id} | readOnly | | snipeit_list_statuslabels | GET /statuslabels | readOnly | | snipeit_get_statuslabel_assets | GET /statuslabels/{id}/assetlist | readOnly | | snipeit_list_maintenances | GET /maintenances | readOnly | | snipeit_create_maintenance | POST /maintenances | writeOnce |

Bulk & Escape (2)

| Tool | Behavior | Annotations | |---|---|---| | snipeit_bulk_checkout | Serially checks out N assets, returns per-item success/error summary | writeOnce | | snipeit_raw_request | Any method/path against SNIPEIT_API_BASE — escape hatch | writeOnce (writeIdempotent for GET) |

List tools (snipeit_list_*) accept limit?, offset?, and all?: boolean. With all: true, the tool auto-paginates up to 10 000 rows.

Auto-generated tools (snipeit_gen_*)

All 77 paths × every method in the Snipe-IT OpenAPI 3.1 spec are exposed as snipeit_gen_<snake_operation_id> — roughly 145 tools. Use these when the hand-wrapper layer doesn't cover what you need. Read tools have readOnlyHint: true; writes have destructiveHint: true. Regenerate with npm run codegen after npm run refresh-spec.

snipeit_raw_request

Escape hatch for anything else:

{ method: "PATCH", path: "/locations/4", body: { name: "HQ" } }

GET requests bypass the destructive-write guard; other methods honor SNIPEIT_CONFIRM_WRITES.


Resources

| URI | Description | |---|---| | snipeit://me | Current authenticated user (GET /users/me) | | snipeit://settings | Server settings (GET /settings) | | snipeit://hardware/summary | {total, by_status_label, by_category} — aggregated counts |

Prompts

| Prompt | Args | Purpose | |---|---|---| | snipeit-inventory-audit | – | Lists overdue/due audits + unassigned assets, then summarizes | | snipeit-user-onboarding | user_id, optional kit | Suggests a checkout sequence for a new user | | snipeit-license-health | – | Seat usage + licenses expiring within 90 days |


Workflows / Recipes

Onboard a new user with a laptop

  1. Confirm the user: snipeit_get_user(id: 42)
  2. Find an available laptop: snipeit_list_hardware(category_id: 3, status_id: 5) (ready-to-deploy)
  3. Checkout: snipeit_checkout_hardware(id: 100, checkout_to_type: "user", assigned_user: 42, note: "Onboarding 2026-05-25")

Bulk-checkout a kit to one user

{
  "items": [
    { "asset_id": 100, "checkout_to_type": "user", "assigned_user": 42 },
    { "asset_id": 101, "checkout_to_type": "user", "assigned_user": 42 },
    { "asset_id": 102, "checkout_to_type": "user", "assigned_user": 42 }
  ]
}

Continues on per-item errors. Returns {summary: {total, ok, errors}, results: [...]}.

Audit overdue cleanup

  1. snipeit_list_audit_overdue(all: true) — full list, auto-paginated
  2. For each: snipeit_audit_hardware(asset_tag: "...", location_id: 1, next_audit_date: "2027-05-25")

Find an asset by tag or serial

  • By asset tag: snipeit_get_hardware_by_tag(tag: "A-42") (handles URL encoding)
  • By serial: snipeit_get_hardware_by_serial(serial: "SN12345")

Discover what an LLM can do

Browse the MCP Inspector:

npm run build && npm run inspector

Write safety

By default, destructive tools execute directly. Set SNIPEIT_CONFIRM_WRITES=true and any write tool returns a redacted preview instead — re-invoke with confirm: "YES" to actually execute. Preview includes the full URL (apiBase + path) and a redacted body (password/secret/token/api_key fields replaced with (redacted)).

Snipe-IT API quirk

Snipe-IT often returns HTTP 200 with {"status":"error","messages":…} for validation errors. This server detects that envelope and surfaces the messages as a tool error (with isError: true), so callers never accidentally treat a Snipe-IT error as success. Successful envelopes ({"status":"success","payload":…}) are unwrapped automatically so tool data is the inner payload, not the outer wrapper.


Develop

npm run dev               # tsx watch
npm test                  # unit + integration if env present
npm run test:unit         # unit only (CI-safe)
npm run test:integration  # live; requires SNIPEIT_API_TOKEN in .env
npm run lint
npm run typecheck
npm run codegen           # regenerate src/tools/generated from vendor/snipe-it-rest-api.json
npm run refresh-spec      # pull latest OpenAPI spec from snipe-it.readme.io
npm run inspector         # MCP Inspector

Security

  • API token is read from SNIPEIT_API_TOKEN env only. Never hard-coded. .env is git-ignored.
  • The logger redacts known secret patterns (Bearer tokens, JWTs, api_token fields, Authorization header) before any output.
  • All MCP stdio output goes to stderr only — stdout is reserved for the protocol.
  • If your token has ever been pasted into a chat or commit, rotate it.

License

MIT.