公司買了一台筆電給新同事,三年後這個同事離職。這時候 IT 要回答幾個問題:
- 他手上有哪些公司的東西要收回來?
- 他用的軟體授權,收回來之後可以給誰?
- 這台筆電的保固還有多久,要不要汰換?
員工少的時候,一張試算表就夠了。人多了之後,試算表會跟現實對不起來:有人換了電腦沒登記、有人離職沒還、授權買了 50 套卻不知道有幾套還在用。
IT 資產管理系統要解的就是這件事:公司的每一樣東西,現在在誰手上。
核心的東西:資產、授權、借出紀錄
以 open source 的 Snipe-IT(AGPL-3.0)為例,它管的東西可以分成三類:
- 資產:有序號、一個一個管的東西,例如筆電、螢幕、手機。每一台有自己的資產編號、購買日期、保固期。
- 授權:軟體的使用席次。例如買了 5 套辦公軟體,就是 5 個席次,每個席次可以指派給一個人。
- 借出與歸還:資產或席次交給某個人,叫借出(checkout);收回來,叫歸還(checkin)。每一次都會留下紀錄。
核心的流程只有一條:入庫 → 借出 → 歸還 → 再借出,直到報廢。 資產的狀態跟著流程走:待部署、已借出、封存。
這跟 ERP 那篇講的是同一個想法:每一個動作都留下紀錄,狀態從紀錄長出來,而不是另外記一本帳。
在本機跑起來
我用官方 image 加 docker compose,在本機跑了 Snipe-IT 8.8.0。三個容器(網站、資料庫、收信用的 Mailpit)合計大約 200 MB 記憶體。
架設時有兩件事值得記下來:
- 官方範例的加密金鑰要自己產生。 官方的
.env.docker裡寫死了一組APP_KEY,照抄的話,每個照著範例架站的人金鑰都一樣。 - 第一次啟動會導到網頁的設定精靈。 精靈做兩件事:建第一個管理員、建一筆系統設定。兩件都可以用指令完成,適合要自動化部署的情況。
接著灌了一批假資料:5 位員工、7 台筆電(購買日期和保固期各不相同)、1 套 5 個席次的軟體授權,部分借給員工。
為什麼要自己寫 MCP
2026-10 查證時,Snipe-IT 沒有官方的 MCP server,社群版本最多 32 顆星,而且沒有標示授權。它的 API 本身很完整,有 OpenAPI 文件。
這是一個典型的情況:系統有 API,但沒有好用的 MCP。 想讓 AI 查資產,就要自己包一層。
我寫了一個最小的 MCP server,不用任何套件,直接實作 MCP 的 JSON-RPC 協定,大約 130 行。它有三個工具:
| 工具 | 回答的問題 |
|---|---|
find_assets | 哪些資產在誰手上、哪些可以借、哪些保固快到期 |
license_usage | 每套授權用了幾個席次、還剩幾個、在誰手上 |
prepare_offboarding | 某位員工離職時,要收回哪些東西 |
原則一:MCP 用唯讀帳號
MCP server 不用管理員的金鑰。我建了一個帳號,只給「檢視資產、檢視授權、檢視員工」的權限,再用它產生 API 金鑰。
實測結果:
- 讀資產、讀員工:200
- 借出資產:403
- 刪除資產:403
就算 AI 被誘導去呼叫寫入的 API,這個帳號也做不到。權限在 Snipe-IT 這一層擋住,不是靠 MCP server 的程式碼自律。
過程中還踩到一個小坑:建帳號時如果設成「未啟用」,連讀取都會回 401。API 帳號也是帳號,要啟用才能用。
原則二:會改資料的事,只產生清單
離職是最適合 AI 幫忙的情境之一:把一個人名下的資產、授權全部列出來,比在畫面上一頁一頁點快得多。
但「歸還」是寫入的動作。所以 prepare_offboarding 只產生清單,並且明講下一步:
{
"username": "zhihao",
"assets": [
{ "tag": "IT-0004", "name": "lab-laptop-04", "holder": "zhihao", "warranty_expires": "2027-03-15" },
{ "tag": "IT-0005", "name": "lab-laptop-05", "holder": "zhihao", "warranty_expires": "2028-01-10" }
],
"licenses": ["Office Suite"],
"next_step": "A person with checkout rights must check these in. This tool does not write."
}東西實際收回來了,才由有權限的人在系統裡按歸還。AI 列清單,人做確認,這跟 ERP 那篇「提交單據要人按」是同一條規則。
原則三:MCP 要把格式統一
這是寫 MCP 時最意外的發現。
第一版跑出來,授權的持有人清單是空的,離職清單裡的持有人是 null。查原始回應才發現,同一個概念「誰拿著它」,在三個 API 端點有三種格式:
- 資產列表:持有人的資料裡有帳號名稱。
- 授權席次:持有人有編號、姓名、email,沒有帳號名稱。
- 某位員工名下的資產:持有人欄位是空的,因為「這個人」已經在網址裡了。
每一種單獨看都合理,合在一起就不一致。如果 MCP 直接把原始回應丟給 AI,AI 會看到三種格式,很容易答錯。
解法是在 MCP server 裡統一:先取一次員工清單,用員工編號對照出帳號名稱,所有工具都回同一種格式。這也是 MCP 存在的價值之一:它不只是把 API 包成工具,還要把系統的不一致擋在 AI 前面。
還有兩個細節:
- Snipe-IT 的驗證錯誤回 HTTP 200。 例如名稱重複,HTTP 狀態碼是 200,錯誤寫在回應的
status欄位。MCP server 只看狀態碼,就會把錯誤當成功。 - 每個結果都附上查詢時間。 AI 回答時可以說「資料截至幾點幾分」,見怎麼觀察資料有沒有正常進來。
原則四:只回答問題需要的欄位
Snipe-IT 的員工資料有 email、電話、職稱、地址。回答「誰拿著這台筆電」只需要帳號名稱。
所以 MCP server 每個工具都只回固定的幾個欄位:資產編號、名稱、序號、型號、狀態、持有人、保固到期日。email 和電話不回。這跟 CRM 那篇講的「個資欄位要分級」是同一件事。
這次沒有驗證的事
我用一支測試腳本扮演 MCP host,逐一呼叫三個工具,確認回應正確。寫這篇時,我還沒有把它接到真的 AI 上測試,所以不知道 AI 會不會選對工具、看不看得懂參數。
後來的實測補上了這一段:四個問題,AI 都選對了工具和參數;要求它歸還筆電時,它明確回答「做不到,狀態沒有變」。
想看實作,可以讀這幾套
| 系統 | 授權 | 特色 | AI/MCP 現況(2026-10) |
|---|---|---|---|
| Snipe-IT | AGPL-3.0 | 專注資產和授權,API 完整 | 沒有官方 MCP,社群版本最多 32 顆星且未標授權 |
| GLPI | GPL-3.0 | 資產加上服務台工單,功能較廣 | 沒有官方 MCP,社群版本最多 4 顆星 |
相關主題
- ERP 在管什麼:每個動作留紀錄,狀態從紀錄長出來
- CRM 會碰到哪些資料:個資欄位分級
- 會員資料怎麼進 CRM:串接用專用帳號、權限照角色縮