NFC42 Developers
Company data API & MCP server · Okle42
What is it?
The NFC42 API / MCP add-on lets AI assistants and your company systems work with your company’s NFC42 data: look up stock, find low-stock items, missed patrols, tools that are lent out and equipment due for service, and record stock in/out, counts, lends, returns and services.
- MCP server for AI assistants (Claude, ChatGPT and other MCP clients):
https://nfc42-okle42.web.app/mcp - REST API for scripts, ERP and spreadsheets:
https://nfc42-okle42.web.app/api/v1/
Both use the same API keys, the same rules and the same daily limit. Changes appear in the app like any other record, marked with the key's name.
Get an API key
- The owner of the company opens the NFC42 app → Company → API / MCP.
- Subscribe to the API / MCP add-on (monthly or yearly, one per company). New companies can try it free for the first 7 days.
- Tap Create Key, give it a name (for example “Claude” or “ERP”) and choose Read or Read & Write.
- Copy the key. It starts with
nfc42_sk_and is shown only once. Up to 10 active keys per company.
Every request sends the key in the Authorization header: Authorization: Bearer nfc42_sk_…
Connect an AI assistant (MCP)
Server URL: https://nfc42-okle42.web.app/mcp · Transport: Streamable HTTP (stateless, JSON responses) · Auth: Bearer API key.
Claude Code
claude mcp add --transport http nfc42 https://nfc42-okle42.web.app/mcp --header "Authorization: Bearer <key>"
Claude Desktop
Open Settings → Developer → Edit Config and add this to claude_desktop_config.json (uses the mcp-remote bridge, which needs Node.js), then restart Claude Desktop:
{
"mcpServers": {
"nfc42": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://nfc42-okle42.web.app/mcp",
"--header", "Authorization:${NFC42_AUTH}"],
"env": { "NFC42_AUTH": "Bearer nfc42_sk_..." }
}
}
}
ChatGPT and the OpenAI API
ChatGPT's connector screen currently connects with OAuth or without authentication, so it cannot send an NFC42 key header. With the OpenAI Responses API you can pass the header directly:
"tools": [{
"type": "mcp",
"server_label": "nfc42",
"server_url": "https://nfc42-okle42.web.app/mcp",
"headers": { "Authorization": "Bearer nfc42_sk_..." },
"require_approval": "never"
}]
Any other MCP client that can send a custom header works the same way.
Tools
Keys with read scope see only the read tools; write keys see all of them. Items can be given by ID or by exact name (case-insensitive). If several items share a name, the call fails and lists their IDs.
| Tool | Scope | What it does |
|---|---|---|
summary | read | Inventory name and four counts: low stock, overdue patrol/cleaning, open lends, equipment overdue for service. |
list_items | read | Items with quantity and status. kind (stock, tool, checkpoint, cleaning, equipment, asset), query, limit ≤ 200. |
get_item | read | One item by id or name, with its 20 most recent records. |
low_stock | read | Stock items at or below their low-stock threshold. |
overdue | read | Patrol checkpoints and cleaning spots past their check-in interval. |
lent_out | read | Tools lent out and not yet returned (borrower, date, count). |
service_due | read | Equipment due for service within days (default 7) or overdue. |
recent_records | read | Newest records first. limit ≤ 200, since (ISO 8601), kind, item. |
reorder_suggestions | read | Stock items that are low or will run out within coverDays (default 14), with daily usage from the last lookbackDays (default 30), days left and a suggested order. |
patrol_report | read | Per checkpoint and cleaning spot over the last days (default 7): check-ins, expected, missed intervals, longest gap. |
attendance_today | read | Today's staff attendance counts: scheduled, clocked in, late, absent, not yet, off. Counts only. |
door_stays | read | Door-lock guest stay counts: active, starting / ending within 24 h, past end, ended in 7 days, per property. Counts only. |
company_cards | read | Staff with and without an NFC42 business card, and the public URL of each linked card. |
add_item | write | Create an item: name, kind, quantity, location, note, lowStock, patrolHours, serviceDays. |
stock_in | write | Add amount units (> 0). |
stock_out | write | Take out amount units; fails if not enough on hand. |
count | write | Set the counted quantity (≥ 0). |
record_service | write | Record a service for an equipment item. |
lend | write | Lend amount of a tool to a borrower. |
give_back | write | Return amount of a lent tool. |
REST API
Base URL https://nfc42-okle42.web.app/api/v1. JSON in, JSON out. {id} is an item ID (or a URL-encoded exact name).
| Method & path | Same as | Parameters |
|---|---|---|
GET /summary | summary | |
GET /items | list_items | query: kind, q, limit |
GET /items/{id} | get_item | |
GET /low-stock | low_stock | |
GET /overdue | overdue | |
GET /lent-out | lent_out | |
GET /service-due | service_due | query: days |
GET /records | recent_records | query: limit, since, kind, item |
GET /reorder | reorder_suggestions | query: lookbackDays, coverDays |
GET /patrol-report | patrol_report | query: days |
GET /attendance-today | attendance_today | |
GET /door-stays | door_stays | |
GET /cards | company_cards | |
POST /items | add_item | body: same fields as the tool |
POST /items/{id}/stock-in | stock_in | {"amount": 5, "note": "…"} |
POST /items/{id}/stock-out | stock_out | {"amount": 2} |
POST /items/{id}/count | count | {"quantity": 40} |
POST /items/{id}/service | record_service | {"note": "…"} |
POST /items/{id}/lend | lend | {"amount": 1, "borrower": "Ming"} |
POST /items/{id}/give-back | give_back | {"amount": 1} |
Examples
curl https://nfc42-okle42.web.app/api/v1/low-stock \
-H "Authorization: Bearer $NFC42_KEY"
curl -X POST https://nfc42-okle42.web.app/api/v1/items/$ITEM_ID/stock-out \
-H "Authorization: Bearer $NFC42_KEY" \
-H "Content-Type: application/json" \
-d '{"amount": 3, "note": "Order #1024"}'
Response:
{ "recordId": "4D471D77-B0B2-4C1B-B6E5-5B49BAF0ADE4",
"item": { "id": "…", "name": "Packing tape", "kind": "stock" },
"kind": "outbound", "delta": -3, "quantityBefore": 10, "quantity": 7 }
Errors
Errors return {"error": "code", "message": "…"}.
| HTTP | error | Meaning |
|---|---|---|
| 400 | invalid_argument | A parameter is missing or out of range. |
| 401 | invalid_api_key | Missing, wrong or revoked key. |
| 402 | api_plan_required | The API / MCP add-on is not active. |
| 403 | read_only_key, workspace_read_only, on_site_only | Key can't write; the Business plan ended; or the action must be done on site. |
| 404 | item_not_found | No such item (similar names are listed in candidates). |
| 409 | ambiguous_item, insufficient_stock, nothing_lent, duplicate_name, wrong_kind | The request conflicts with the current inventory. |
| 429 | quota_exceeded | Daily limit reached. |
In MCP, tool failures come back as a tool result with isError: true; the daily limit is a JSON-RPC error (code −32029).
Limits
- 2,000 calls per key per day (MCP tool calls and REST requests; resets at midnight Taiwan time).
initializeandtools/listdon't count. - Check-ins are not available through the API. Patrol check-ins, cleaning sign-offs and asset audits must be done on site by tapping the NFC tag in the app — that is what makes them trustworthy.
- Attendance and door locks are counts only. Staff names, clock times, guest names, card numbers and passcodes are never returned, and doors can't be unlocked or cards issued through the API.
- Scopes: read keys can only look; write keys can also add items and record stock, lends, returns and services. Neither can delete anything or change members.
- If the Business plan ends, the inventory becomes read-only: reads keep working while the add-on is active, writes are refused.
Security
- Treat a key like a password. Don't put it in web pages, mobile apps or public repositories; call the REST API from a server.
- Use a read key unless the integration really needs to write. Create one key per integration so you can revoke one without breaking the others.
- If a key leaks, revoke it in the app (Company → API / MCP). It stops working immediately.
- AI assistants act with the key's permissions. Review what a write-enabled assistant is about to do before you approve it.
- We store only a hash of each key; we can't show a lost key again — create a new one.
NFC42 開發者
公司資料 API 與 MCP 伺服器
這是什麼
API/MCP 加購讓 AI 助理與公司系統直接使用 NFC42 公司資料:查庫存、低庫存、漏巡、借出中的工具、快到期的保養,也能記錄入庫、出庫、盤點、借出、歸還與保養。
- MCP 伺服器(給 Claude、ChatGPT 等 AI 助理):
https://nfc42-okle42.web.app/mcp - REST API(給程式、ERP、試算表):
https://nfc42-okle42.web.app/api/v1/
兩者用同一組金鑰、同樣的規則與每日上限。寫入的記錄會像一般記錄一樣出現在 App,操作者顯示金鑰名稱。
取得金鑰
- 公司的老闆在 App 打開「公司 → API/MCP」。
- 訂閱 API/MCP 加購(月繳或年繳,每家公司一份)。新建立的公司前 7 天可免費試用。
- 點「產生金鑰」,取個名字(例如「Claude」「ERP」),選擇「唯讀」或「讀寫」。
- 拷貝金鑰。金鑰以
nfc42_sk_開頭,只會顯示這一次。每家公司最多 10 把有效金鑰。
每個請求都在標頭帶上:Authorization: Bearer nfc42_sk_…
連接 AI 助理(MCP)
伺服器網址 https://nfc42-okle42.web.app/mcp,傳輸方式 Streamable HTTP(無狀態、回 JSON),驗證用 Bearer 金鑰。設定範例見上方英文版:Claude Code 一行指令、Claude Desktop 的 claude_desktop_config.json(透過 mcp-remote,需要 Node.js)、OpenAI Responses API 的 headers。ChatGPT 的連接器畫面目前只支援 OAuth 或不驗證,沒辦法帶 NFC42 金鑰。
唯讀金鑰只看得到查詢類工具;讀寫金鑰看得到全部。品項可以用 ID 或完整名稱(不分大小寫)指定;有同名的品項會回錯誤並列出各自的 ID。
REST API
端點與參數見上方英文表格,回應都是 JSON。錯誤格式 {"error": "代碼", "message": "說明"}:401 金鑰無效或已撤銷、402 沒有啟用加購、403 唯讀金鑰/公司已唯讀/須現場操作、409 庫存不足或同名、429 超過每日上限。
限制
- 每把金鑰每天 2,000 次(MCP 工具呼叫與 REST 請求;台灣時間午夜歸零)。
- 打卡不開放 API。巡檢打卡、清潔簽到、資產盤點一定要到現場用 App 感應 NFC 標籤,紀錄才可信。
- 權限:唯讀金鑰只能查;讀寫金鑰可以新增品項、記錄出入庫、借還與保養。兩者都不能刪除資料或改成員。
- 商用版方案到期後公司資料變唯讀:加購有效期間仍可查詢,但不能寫入。
安全提醒
- 金鑰等同密碼,不要放進網頁、手機 App 或公開的程式庫;REST API 請從伺服器端呼叫。
- 不需要寫入就用唯讀金鑰;每個串接各用一把,撤銷一把不影響其他。
- 金鑰外流時到 App「公司 → API/MCP」撤銷,立即失效。
- AI 助理會以金鑰的權限操作;使用讀寫金鑰時,請先看清楚它要做什麼再同意。
- 伺服器只存金鑰的雜湊,遺失的金鑰無法再顯示,請重新產生。