Conversation
This isn’t fully baked yet - it would touch way too much main code to flip it over just yet
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| UnusedCode | 10 medium |
| Comprehensibility | 1 minor |
| CodeStyle | 52 minor |
| Complexity | 11 medium |
🟢 Metrics 2029 complexity
Metric Results Complexity 2029
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I'm still massaging these prompts and such, specifically checking permissions and notifications/logging, but if anybody wants to test it, please do :) I'm also trying to find a way to refactor the validation so it's not duplicating a lot of the code that we already have in form requests and model validation so we're not repeating ourselves and potentially introducing inconsistencies.
While I'm not personally a huge fan of AI in my workflows, I know some people are, so it sort of makes sense to provide support for that natively. This (right now) isn't really meant to replace everything in the system, just common tasks that one might want to use AI with. Again, I don't really use it though, so if I've missed a use-case or workflow, please do let me know.
I'd also be curious if folks would need/want a setting to disable the MCP entirely. I can't think of a reason why you would, but it's possible. You need an account to be able to use these tools anyway, but in the same way we let folks disable API access, I could see folks wanting to disable this too.
I tried to make the prompts at least as localized as possible, since we do have loads of people who don't use Snipe-IT in English, but there are some spots where it just sorta junks up the code too much and makes it unreadable. Hopefully folks can have their AI figure that part out :)
I included this readme in the
app/Mcpdirectory, and if we do end up merging this, it will go into the normal docs as well:Snipe-IT MCP Server
This directory contains the Model Context Protocol (MCP) server implementation for Snipe-IT. It exposes the Snipe-IT asset management database to AI assistants through a standard interface, allowing them to look up assets, manage users, process checkouts and check-ins, and run common IT workflows — all in plain language.
Table of Contents
Connecting to an AI Service
The MCP server is available at:
It uses OAuth 2.0 for authentication (see Authentication below). Any MCP-compatible client that supports OAuth and the Streamable HTTP transport can connect to it.
Claude Desktop
Add the server to your
claude_desktop_config.json:{ "mcpServers": { "snipe-it": { "url": "https://your-snipeit-domain/mcp/snipe-it" } } }Claude Desktop will initiate the OAuth flow on first connection. Once authorised, you can use tools and prompts directly in conversation:
MCP Inspector
The MCP Inspector is useful for exploring and testing tools before
integrating with a client:
php artisan mcp:inspector SnipeITMcpServerin your terminalCursor / VS Code / Other MCP Clients
Any client that supports the MCP Streamable HTTP transport and OAuth can connect using the same URL. Refer to your client's documentation for how to add a remote MCP server.
Authentication
The server uses OAuth 2.0 with dynamic client registration. Clients that support OAuth will handle this automatically. On first connection:
/.well-known/oauth-authorization-server/oauth/registerThe authenticated user's Snipe-IT permissions apply — a user without
delete assetspermission cannot calldelete_asset, for example.Prompts
Prompts are pre-built conversation starters for common multi-step workflows. In clients that support them (such as Claude Desktop), prompts appear in a slash-command menu or prompt picker. Select a prompt, fill in any arguments, and the AI will walk through the workflow using the available tools automatically.
onboard_employeeGuide through creating a new employee account and assigning appropriate equipment and licenses.
Creates the user account, finds available assets suitable for their role, checks equipment out to them, and assigns any relevant license seats.
first_namelast_namedepartmentlocationtitleExample usage in Claude:
offboard_employeeCheck in all equipment and licenses from a departing employee and deactivate their account.
Looks up everything assigned to the user, checks in all assets and accessories, revokes license seats, and deactivates the account.
usernameExample usage in Claude:
audit_locationReview all assets at a location, flag overdue audits and status anomalies.
Lists all assets at the location, identifies overdue audit dates, flags unexpected statuses, and produces a summary with recommended actions.
locationExample usage in Claude:
find_available_assetFind an undeployed asset by category or model and optionally check it out to a user.
Searches for Ready-to-Deploy assets matching the criteria, lists options if multiple are available, and can check out the selected asset immediately.
categorymodelassign_toExample usage in Claude:
expiring_licensesReview license seat usage and flag licenses expiring within a given number of days.
Lists all licenses, identifies those expiring soon, flags over-deployed and under-used licenses, and produces a prioritised action list.
daysExample usage in Claude:
end_of_life_reviewIdentify assets that have passed their EOL date or are fully depreciated, and recommend disposition actions.
Can be scoped to a department or category. Groups findings and recommends retirement, redeployment, repair, or archival.
departmentcategoryExample usage in Claude:
warranty_expiringList assets whose warranty expires within a given number of days.
Groups findings by urgency (within 30 days, 31–60, 61–N), flags assets in critical roles, and recommends extensions or replacements.
daysExample usage in Claude:
inventory_summaryProduce a high-level inventory count by category, broken down by deployment status.
Can be scoped to a location or department. Shows deployed vs. available counts, top models, total value, and stock-out risks.
locationdepartmentExample usage in Claude:
user_inventoryList everything currently assigned to a specific user across all asset types.
Shows assets, accessories, license seats, and consumables assigned to the user, plus total assigned value if cost data is available.
usernameExample usage in Claude:
Tools Reference
Tools are individual actions the AI can call directly. They can also be combined freely in conversation without using a prompt — just describe what you want in plain language.
Assets
show_assetLook up a single asset by asset tag, serial number, or numeric ID.
asset_tagserialidlist_assetsSearch and list assets with optional filters.
searchstatus_typeRTD,Deployed,Archived,Pending, orUndeployablecompany_idlocation_idcategory_idmodel_idmanufacturer_idlimitoffsetcreate_assetCreate a new asset.
model_idstatus_idasset_tagnameserialcompany_idlocation_idrtd_location_idsupplier_idpurchase_datepurchase_costorder_numberwarranty_monthsrequestablenotesupdate_assetUpdate fields on an asset. Identify it by
asset_tag,serial, orid.asset_tagserialidnamenew_asset_tagnew_serialstatus_idmodel_idnotesorder_numberpurchase_datepurchase_costwarranty_monthslocation_idrtd_location_idsupplier_idrequestablebyodasset_eol_dateexpected_checkinnext_audit_datedelete_assetSoft-delete an asset. If checked out, it will be checked in first.
asset_tagserialidrestore_assetRestore a soft-deleted asset.
idcheckout_assetCheck out an asset to a user, location, or another asset.
asset_tagidcheckout_to_typeuser,location, orassetassigned_userassigned_locationassigned_assetnotecheckout_atexpected_checkincheckin_assetCheck a currently checked-out asset back in.
asset_tagidnoteaudit_assetRecord an audit for an asset, updating the last audit date and optionally the location.
asset_tagserialidnotelocation_idnext_audit_dateadd_asset_noteAdd a manual note to an asset. The note is recorded in the asset's activity log.
asset_tagserialidnoteUsers
list_usersSearch and list users.
searchcompany_iddepartment_idlocation_idactivatedlimitoffsetshow_userLook up a single user by numeric ID, username, or email address.
idusernameemailcreate_userCreate a new user account.
first_nameusernamelast_nameemailpasswordemployee_numjobtitlephonecompany_iddepartment_idlocation_idmanager_idactivatednotesstart_dateend_datevipremoteaddresscitystatecountryzipupdate_userUpdate fields on a user. Identify by
id,username, oremail. Usenew_usernameornew_emailto change those values.idusernameemailnew_usernamenew_emailfirst_namelast_namepasswordemployee_numjobtitlephonecompany_iddepartment_idlocation_idmanager_idactivatednotesstart_dateend_datevipremotedelete_userSoft-delete a user. The user must have no assets, licenses, accessories, or consumables assigned.
idusernameemailrestore_userRestore a soft-deleted user.
idget_current_userReturn information about the currently authenticated user. No parameters.
update_profileUpdate the authenticated user's own profile. Fields protected by the
self.profilegate (first_name,last_name,phone,website,gravatar) require profile editing to be enabled in Snipe-IT settings.location_idrequires theself.edit_locationpermission.first_namelast_namephonewebsitegravatarlocaleen-US)two_factor_optinself.two_factorpermission and 2FA enabled in settings)location_idself.edit_locationpermission)get_user_assetsReturn all assets currently checked out to a user.
idreset_2faReset two-factor authentication for a user (requires admin permission).
idAccessories
create_accessorynamecategory_idqtymodel_numbermanufacturer_idsupplier_idlocation_idcompany_idorder_numberpurchase_costpurchase_datemin_amtrequestablenotesupdate_accessoryIdentify by
idorname. Usenew_nameto rename.delete_accessoryThe accessory must have no units currently checked out. Identify by
idorname.checkout_accessoryidnamecheckout_to_typeuser,location, orassetassigned_userassigned_locationassigned_assetnotecheckin_accessorycheckout_idnoteComponents
create_componentnamecategory_idqtyserialmodel_numbermanufacturer_idsupplier_idlocation_idcompany_idorder_numberpurchase_costpurchase_datemin_amtnotesupdate_componentIdentify by
idorname. Usenew_nameto rename.delete_componentThe component must have no units checked out to assets. Identify by
idorname.checkout_componentidnameasset_idassigned_qtynotecheckin_componentcomponent_asset_idcheckin_qtynoteConsumables
list_consumablessearchcompany_idcategory_idmanufacturer_idlocation_idlimitoffsetshow_consumableLook up by
idorname.create_consumablenameqtycategory_idcompany_idlocation_idmanufacturer_idsupplier_iditem_noorder_numbermodel_numberpurchase_costpurchase_datemin_amtrequestablenotesupdate_consumableIdentify by
idorname. Usenew_nameto rename.delete_consumableThe consumable must have no units currently checked out. Identify by
idorname.checkout_consumableidnameassigned_tonoteLicenses
list_licensessearchcompany_idcategory_idmanufacturer_idsupplier_idlimitoffsetshow_licenseLook up by
idorname. Returns seat counts.create_licensenameseatscategory_idserialmanufacturer_idsupplier_idcompany_idpurchase_datepurchase_costexpiration_datelicense_namelicense_emailmaintainedreassignablenotesmin_amtupdate_licenseIdentify by
idorname. Usenew_nameto rename.delete_licenseThe license must have no seats currently assigned. Identify by
idorname.checkout_licenseidnameassigned_toasset_idnotecheckin_licenseseat_idnoteDepartments
create_departmentnamelocation_idcompany_idmanager_idphonefaxnotesupdate_departmentIdentify by
idorname. Usenew_nameto rename.delete_departmentThe department must have no users assigned. Identify by
idorname.Companies
list_companiesSearch with optional
search,limit,offset.show_companyLook up by
idorname.create_companynamephonefaxemailnotesupdate_companyIdentify by
idorname. Usenew_nameto rename.delete_companyIdentify by
idorname.Categories
list_categoriessearchcategory_typeasset,accessory,consumable,component, orlicenselimitoffsetshow_categoryLook up by
idorname.create_categorynamecategory_typeasset,accessory,consumable,component, orlicensecheckin_emailrequire_acceptanceuse_default_eulanotesupdate_categoryIdentify by
idorname. Usenew_nameto rename.delete_categoryThe category must have no items assigned. Identify by
idorname.Manufacturers
list_manufacturersSearch with optional
search,limit,offset.show_manufacturerLook up by
idorname.create_manufacturernameurlsupport_urlsupport_emailsupport_phonewarranty_lookup_urlnotesupdate_manufacturerIdentify by
idorname. Usenew_nameto rename.delete_manufacturerIdentify by
idorname.Suppliers
list_suppliersSearch with optional
search,limit,offset.show_supplierLook up by
idorname.create_suppliernameaddressaddress2citystatecountryzipphonefaxemailurlcontactnotesupdate_supplierIdentify by
idorname. Usenew_nameto rename.delete_supplierIdentify by
idorname.Status Labels
list_status_labelssearchstatus_typedeployable,pending,archived, orundeployablelimitoffsetshow_status_labelLook up by
idorname.create_status_labelnametypedeployable,pending,archived, orundeployablecolor#RRGGBBformatnotesdefault_labelshow_in_navupdate_status_labelIdentify by
idorname. Usenew_nameto rename.delete_status_labelIdentify by
idorname.Locations
list_locationssearchparent_idlimitoffsetshow_locationLook up by
idorname.create_locationnameaddressaddress2citystatecountryzipphonefaxcurrencyparent_idmanager_idupdate_locationIdentify by
idorname. Usenew_nameto rename.delete_locationIdentify by
idorname.Asset Models
list_asset_modelssearchcategory_idmanufacturer_idlimitoffsetshow_asset_modelLook up by
idorname.create_asset_modelnamecategory_idmodel_numbermanufacturer_iddepreciation_ideolmin_amtnotesrequestablerequire_serialupdate_asset_modelIdentify by
idorname. Usenew_nameto rename.delete_asset_modelIdentify by
idorname.Depreciations
list_depreciationsSearch with optional
search,limit,offset.show_depreciationLook up by
idorname.create_depreciationnamemonthsupdate_depreciationIdentify by
idorname. Usenew_nameto rename,monthsto change the period.delete_depreciationIdentify by
idorname.Groups
list_groupsSearch with optional
search,limit,offset.show_groupLook up by
idorname.create_groupnamenotesupdate_groupIdentify by
idorname. Usenew_nameto rename.delete_groupThe group must have no users assigned. Identify by
idorname.Maintenance
list_maintenancesasset_idlimitoffsetcreate_maintenanceasset_idtitleasset_maintenance_typemaintenance,repair,upgrade)supplier_idis_warrantycoststart_datecompletion_datenotesuser_idActivity Log
get_activity_logitem_typeApp\Models\Asset)item_iduser_idaction_typecheckout,checkin,update)limitoffset