etxahun/ttlock-mcp
If you are the rightful owner of ttlock-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The TTLock MCP server facilitates access and management of TTLock data through MCP-compatible clients, supporting OAuth, lock management, IC card operations, and unlock record retrieval.
π TTLock MCP
An MCP (Model Context Protocol) server to access and manage TTLock data from MCP-compatible clients (VS Code, MCP Inspector, etc.).
It supports OAuth, lock management, IC card operations (add/delete/list, bulk), and reading unlock records.
π Table of Contents
- Architecture & Repository Layout
- Requirements
- Installation
- Configuration
- NPM Scripts
- Run & Test
- Tools Catalog (MCP)
- TTLock Integration Notes
- Troubleshooting
- Security & Best Practices
- Roadmap
- License
ποΈ Architecture & Repository Layout
ttlock-mcp/
ββ src/
β ββ env.ts # Loads/validates environment variables (.env) with zod
β ββ server.ts # MCP server (STDIO) + tool definitions (with auth guard)
β ββ ttlock.ts # TTLock HTTP client (OAuth + v3 endpoints)
ββ dist/ # Compiled output (tsc)
ββ .vscode/
β ββ mcp.json # VS Code config to launch the MCP server
ββ .env # Local environment variables (DO NOT commit)
ββ package.json
ββ tsconfig.json
ββ README.md # This document
Tech highlights
- Node.js 20+ with ESM (
moduleResolution: "NodeNext"
) - TypeScript
- @modelcontextprotocol/sdk (STDIO server)
- axios, qs, zod, dotenv
- (optional) dotenv-cli to load
.env
for the Inspector command
NodeNext/ESM note: use
.js
extension in relative imports even in.ts
files
(e.g.import { Env } from './env.js'
).
π Requirements
- Node.js >= 20
- TTLock Cloud credentials:
clientId
,clientSecret
- A TTLock gateway online for remote operations (unlock/lock and IC card add/delete)
π οΈ Installation
# 1) Install deps
npm install
# 2) (optional) Convenient for Inspector to auto-load .env
npm i -D dotenv-cli
# 3) Build once
npm run build
βοΈ Configuration
π .env
Create a .env
file at the repo root:
TTLOCK_CLIENT_ID=xxxxxxxx
TTLOCK_CLIENT_SECRET=xxxxxxxx
TTLOCK_API_BASE=https://api.sciener.com
MCP_SERVER_NAME=ttlock-mcp
# Optional: auto-login on first use
TTLOCK_USERNAME=your_ttat_account_or_email
TTLOCK_PASSWORD_MD5=32_char_lowercase_md5_of_your_password
Get MD5 on Linux:
echo -n 'your_password' | md5sum | awk '{print $1}'
π» VS Code (.vscode/mcp.json
)
Recommended workspace configuration:
{
"servers": {
"ttlock-mcp": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/dist/server.js"],
"envFile": "${workspaceFolder}/.env"
}
}
}
This lets VS Code start the server and load your .env
automatically.
π NPM Scripts
{
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"watch": "tsc -w",
"inspect": "dotenv -e .env -- npx @modelcontextprotocol/inspector node dist/server.js"
}
}
If you donβt use
dotenv-cli
, pass your variables via the Inspector UI or your shell environment.
π§ͺ Run & Test
π MCP Inspector
npm run build
npm run inspect
Inspector UI settings:
- Transport Type:
STDIO
- Command:
node
- Arguments:
dist/server.js
Quick tests:
- ping
{ "text": "hello" }
- auth.login (if you didnβt configure auto-login):
{ "username": "YOUR_EMAIL", "passwordMd5": "32_char_lowercase_md5" }
- locks.list
{ "pageNo": 1, "pageSize": 50 }
π» VS Code
- Open the project (WSL or local) with
code .
. - With the
mcp.json
above, open the Chat view (Copilot).
The ttlock-mcp server appears and tools are available. - Invoke tools directly (e.g., select
locks.list
or type#locks.list
).
π§ͺ Tools Catalog (MCP)
All handlers return
CallToolResult
({ content: [{ type: "text", text }] }
).
Tools marked with π require authentication (auto-login ifTTLOCK_USERNAME
andTTLOCK_PASSWORD_MD5
are present in.env
).
π Auth
auth.login
{ username: string, passwordMd5: string }
auth.refresh
{}
π Locks
- π
locks.list
{ pageNo?: number=1, pageSize?: number=50 }
- π
locks.detail
{ lockId: number }
- π
locks.unlock
{ lockId: number }
(requires gateway online) - π
locks.lock
{ lockId: number }
(requires gateway online)
πͺͺ IC Cards
- π
cards.list
{ lockId: number, pageNo?: number=1, pageSize?: number=50 }
- π
cards.add
{ lockId: number, cardNumber: string, cardName?: string, startDate?: ms, endDate?: ms }
IfstartDate
/endDate
are omitted (or0
), the card is permanent. - π
cards.bulkAdd
{ lockId: number, cards: Array<{cardNumber, cardName?, startDate?, endDate?}>, delayMs?: 0β5000, continueOnError?: boolean }
- π
cards.delete
{ lockId: number, cardId: number, deleteType?: 1|2|3=2 }
- π
cards.bulkDelete
{ lockId: number, cardIds: number[], deleteType?: 1|2|3=2, delayMs?: 0β5000, continueOnError?: boolean }
- π
cards.clear
{ lockId: number, confirm?: boolean=false }
β οΈ Deletes all cards on the lock.
cardId vs cardNumber: deleting requires
cardId
(fetch it viacards.list
).
deleteType
:2
= Gateway (remote) is most useful;1
= BLE;3
= NB-IoT (if applicable).
π Unlock Records (Access Logs)
- π
records.list
{ lockId: number, pageNo?: number=1, pageSize?: number=50, startDate?: ms, endDate?: ms }
Time format: startDate
/endDate
are epoch milliseconds (UTC).
Example (Madrid CEST, today 06:00β10:00): startDate=1756699200000
, endDate=1756713600000
.
π TTLock Integration Notes
- OAuth: login uses
username
+passwordMd5
(32 chars, lowercase). date
parameter (v3 APIs): each call sendsdate = Date.now()
. TTLock servers accept roughly Β±5 minutes.
If you seedate must be current time, in 5 minutes
, sync your system clock (NTP).
The client also supports a retry with server time offset (from HTTPDate
header) to mitigate small drifts.- Gateway: remote operations (unlock/lock, add/delete card) need a compatible gateway online.
- ESM: keep relative imports ending with
.js
.
π§― Troubleshooting
date must be current time, in 5 minutes
Your machine clock is off. Enable NTP:timedatectl set-ntp true sudo systemctl restart systemd-timesyncd
- Not authenticated
Runauth.login
or setTTLOCK_USERNAME
andTTLOCK_PASSWORD_MD5
in.env
. - Gateway offline / Not support
Ensure your lock/gateway supports the operation and is online. - Inspector βCommand not foundβ
Check Command =node
, Arguments =dist/server.js
, and that you built the project. - ESM import errors
Ensure relative imports end with.js
andtsconfig.json
usesmoduleResolution: "NodeNext"
.
πΊοΈ Roadmap
- Persist/rotate tokens on disk (cache).
- Webhook Lock Records Notify for real-time events.
- More management endpoints (rename card, change validity window, etc.).
- Tests and linting (Vitest/ESLint).
π License
This project is licensed under Apache-2.0.