MCP 接入说明
让 Claude、Cursor 等 AI 助手直接查询你名下的设备:位置、轨迹、里程、报警事件,也能帮你设置电子围栏和报警开关。
| 服务地址 | https://xcslink.com/api/mcp |
|---|---|
| 传输方式 | Streamable HTTP(仅 POST,不提供 SSE 流) |
| 鉴权 | 请求头 Authorization: Bearer 你的令牌 |
| 权限范围 | 令牌所属账号能看到的设备,与小程序一致 |
推荐方式:一键授权
不用复制任何东西。在支持远程 MCP 的客户端里填上面的服务地址,客户端会自动打开授权页,你用数联在线账号登录、勾选要给的权限、点“允许”就连上了。Claude 桌面版、Claude.ai、ChatGPT、Cursor、VS Code、Gemini CLI 都走这条路。
授权页上有三项权限,可以只勾一部分:
| 权限 | 能做什么 |
|---|---|
gps.read | 查看设备与位置、历史轨迹与里程、报警记录、电子围栏与报警设置 |
gps.write | 新增、修改、删除电子围栏,修改报警设置,创建位置分享链接 |
gps.command | 向真实设备发送远程指令 |
授权后访问令牌 1 小时过期,客户端会自动续期,你不用管。
随时撤销
网页端右上角自己的名称 → “对接令牌(MCP)”,弹窗下半部分列出所有已连接的 AI 客户端,可以单个撤销或全部撤销。撤销后该客户端立刻失去访问权限。
备选方式:长期令牌
客户端不支持一键授权,或者你在写脚本、做接口对接时用这条。已经在用长期令牌的客户端不受任何影响,继续用即可。
第一步:获取令牌
两个地方都能拿到同一类令牌,用哪个都行,取决于你平时用哪端。
网页端(推荐给没有微信小程序的用户)
- 用浏览器打开 https://xcslink.com/ 并登录。
- 点右上角自己的名称,展开菜单。
- 选“对接令牌(MCP)”,在弹窗里点“复制”。
微信小程序
- 打开本平台的微信小程序并登录。
- 点首页底部的“设置”,进入“我的”页面。
- 在顶部卡片里点“对接令牌(MCP) ****** 复制”,确认提示后,令牌就复制到了剪贴板。
第二步:配置 AI 客户端
Claude Code
在终端执行(加 -s user 表示所有项目都可用):
claude mcp add --transport http -s user ulzx https://xcslink.com/api/mcp --header "Authorization: Bearer {{TOKEN}}"
执行 claude mcp list,看到 ulzx ... ✔ Connected 即配置成功。更换令牌时先执行 claude mcp remove ulzx -s user 再重新添加。
Cursor
编辑 ~/.cursor/mcp.json(全局)或项目下的 .cursor/mcp.json,写入:
{
"mcpServers": {
"ulzx": {
"url": "https://xcslink.com/api/mcp",
"headers": {
"Authorization": "Bearer {{TOKEN}}"
}
}
}
}
保存后在 Cursor 设置的 MCP 页面确认 ulzx 已启用。其他支持在配置文件里写 url 与 headers 的客户端,格式相同。
Claude 桌面版(以及只支持本地命令的客户端)
这类客户端不能直接填写请求头,需要借助开源工具 mcp-remote 转接。电脑上需先安装 Node.js 18 或更高版本。
打开配置文件:Claude 桌面版菜单“设置 → 开发者 → 编辑配置”,或直接编辑
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
写入以下内容后,完全退出并重新打开 Claude 桌面版:
{
"mcpServers": {
"ulzx": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://xcslink.com/api/mcp",
"--header", "Authorization:${AUTH_HEADER}",
"--transport", "http-only"
],
"env": {
"AUTH_HEADER": "Bearer {{TOKEN}}"
}
}
}
}
令牌放在 env 里、args 中不留空格,是为了避开 Windows 下参数里空格被拆开的问题。
其他支持远程 MCP 的客户端
在客户端的 MCP 服务器设置里按下表填写:
| 名称 | ulzx(可自定义) |
|---|---|
| 类型 | Streamable HTTP(有的客户端叫“可流式传输的 HTTP”或 streamableHttp);不要选 SSE |
| 地址 | https://xcslink.com/api/mcp |
| 请求头 | 名 Authorization,值 Bearer 你的令牌 |
如果客户端只能填写本地命令,按“Claude 桌面版”页签的方式用 mcp-remote 转接。
第三步:试一试
配置好后,直接用自然语言提问,AI 会自动调用合适的工具:
- 我有哪些设备?现在都在哪?
- “大宝贝”今天跑了多少公里,从哪到哪?
- 昨天下午 2 点到 5 点这辆车的轨迹是什么样的?
- 最近一周有没有超速、断电或者进出围栏?
- 看看我的车设了哪些围栏和报警。
- 在我现在的位置设一个 300 米的围栏,名字叫“家”,离开时报警。
- 把这辆车的超速报警打开,阈值改成 100 公里每小时。
- 生成一个 3 小时有效的位置分享链接。
- 哪些设备快到期了?
涉及“今天、昨天”等说法时,AI 会先调用 get_time_context 获取服务器时间,时间一律按北京时间理解。
工具一览
| 工具 | 类型 | 说明 |
|---|---|---|
get_time_context | 查询 | 服务器当前时间,以及今天、昨天、本周起点的时间戳 |
list_devices | 查询 | 账号下的设备列表 |
get_latest_info | 查询 | 多台设备的最新位置、速度、电量、今日里程,可解析地址 |
device_latest_status | 查询 | 单台设备最近通信与定位状态 |
get_history | 查询 | 历史轨迹,单次最长 24 小时,点多时自动抽样 |
get_total_km | 查询 | 一段时间内的行驶里程,单次最长 31 天 |
get_track_summary | 查询 | 行程摘要:起终点、里程、最高速度 |
overview | 查询 | 按日、月、年的统计:里程、使用时长、各类事件次数 |
event_stay | 查询 | 停留记录 |
event_fence | 查询 | 进出围栏记录 |
event_overspeed | 查询 | 超速记录 |
event_acc | 查询 | ACC 状态切换记录 |
event_power_off | 查询 | 断电、接电记录 |
event_low_power | 查询 | 低电量记录 |
event_vibration | 查询 | 震动记录 |
list_fences | 查询 | 设备已设置的电子围栏及数量上限 |
get_alert_settings | 查询 | 报警开关与超速阈值 |
list_expiring_devices | 查询 | 即将到期或已到期的设备 |
list_device_commands | 查询 | 某型号设备可用的远程指令 |
set_fence | 设置 | 新增或修改圆形、多边形围栏 |
delete_fence | 设置 | 删除围栏 |
set_alert_settings | 设置 | 修改报警开关或超速阈值,只改你提到的项 |
create_share_link | 设置 | 生成实时位置分享链接 |
send_device_command | 设置 | 向设备下发低危指令,例如改定位频率、立即定位一次 |
prepare_device_command | 设备控制 | 高危指令的第一步:回报设备名称、指令含义、可能影响,并给出一次性确认凭据 |
confirm_device_command | 设备控制 | 高危指令的第二步:凭确认凭据真正下发 |
建议在 AI 客户端里保持“调用设置类工具前需确认”的默认行为。
注意事项
- 设置围栏或报警后,设备会自动重连一次以加载新配置,属正常现象,与在小程序里保存效果相同。
- 生成分享链接后,这台设备之前分享出去的链接会失效。
- 频率限制:同一网络出口最多 10 个请求同时处理,每秒 20 次。正常使用不会碰到;超出时返回 HTTP 503,稍等重试即可。
- 设备不在线时下发指令:指令会排队,设备下次联网时自动执行,不需要重复下发。
- 高危指令要两步:断开油电、恢复出厂、重启设备、远程监听、定时关机这类操作,AI 不能一次调用就执行。它必须先取得确认凭据,把设备名称、指令含义和可能影响告诉你,你同意后才会真正下发。凭据 5 分钟有效、只能用一次,且绑定了账号、设备和指令。改定位频率、立即定位一次这类低危指令不受影响,仍然一步完成。
- 坐标系:默认返回 WGS84。在高德、腾讯地图上使用请让 AI 用 GCJ02,百度地图用 BD09。
- 单位:里程为公里,速度为公里每小时,围栏半径为米。
常见问题
提示 invalid session 或 401
令牌无效。通常是在复制它的那一端重新登录或退出过,请重新复制令牌并更新客户端配置。网页端、小程序、App 三种令牌都能用。
提示 insufficient_scope 或 403
授权时没勾这项权限。在网页端“对接令牌(MCP)”里撤销该客户端,然后在客户端中重新连接一次,勾上需要的权限即可。
客户端显示连接失败
确认地址是 https://xcslink.com/api/mcp(带 /api),类型选 Streamable HTTP 而不是 SSE,请求头的值以 Bearer 开头(后面有一个空格)。
偶尔出现 503
触发了频率限制,稍后重试即可。如果频繁出现,让 AI 逐个调用工具,不要一次并行很多个。
查不到轨迹
设备在该时间段内没有上报定位,或时间跨度超过 24 小时。可以先用 device_latest_status 看设备最后一次上报时间。
开发者:直接调用
协议为 JSON-RPC 2.0。工具业务错误在 result.isError=true 中返回,原因见 result.content[0].text。
curl -X POST https://xcslink.com/api/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{TOKEN}}" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_devices","arguments":{}}}'
curl -X POST https://xcslink.com/api/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
tools/list 无需令牌,返回每个工具的完整参数说明。
OAuth 端点
按 MCP 授权规范实现,Authorization Code 加 PKCE,code_challenge_method 只接受 S256。未带凭证时 MCP 入口返回 HTTP 401 与 WWW-Authenticate,客户端据此自动发现下面这些地址。
| 用途 | 地址 |
|---|---|
| 受保护资源元数据 | /.well-known/oauth-protected-resource/api/mcp |
| 授权服务器元数据 | /.well-known/oauth-authorization-server |
| 动态客户端注册 | POST /oauth/register |
| 授权 | GET /oauth/authorize |
| 换取令牌与刷新 | POST /oauth/token |
| 撤销 | POST /oauth/revoke |
同时支持动态客户端注册与 CIMD 两种免预注册方式。授权响应会带 iss,resource 参数按规范做 audience 校验。访问令牌 1 小时,刷新令牌 30 天且每次刷新滚动更新。
错误码
| 状态 | 含义 | 怎么处理 |
|---|---|---|
| HTTP 401 | 没带凭证,或 OAuth 令牌无效、已过期、已撤销 | 按 WWW-Authenticate 里的地址走授权流程,或用刷新令牌续期 |
| HTTP 403 | scope 不足,挑战头里的 scope 指明缺哪一项 | 重新授权并勾上该权限 |
| HTTP 503 | 触发限流 | 稍后重试,减少并行 |
| JSON-RPC 401 | 长期令牌无效 | 重新复制令牌 |
| JSON-RPC -32602 | 工具名不存在 | 先调 tools/list |
result.isError=true | 工具业务错误 | 原因见 result.content[0].text |
MCP Integration Guide
Ask Claude, Cursor or any other MCP-capable assistant about your devices in plain language: where they are, where they have been, how far they drove, what alerts fired. They can also set geofences and alert switches for you.
| Endpoint | https://xcslink.com/api/mcp |
|---|---|
| Transport | Streamable HTTP (POST only, no SSE stream) |
| Auth | Header Authorization: Bearer YOUR_TOKEN |
| Scope | Exactly the devices the token's account can see in the mini program |
Recommended: one-click authorization
Nothing to copy. Put the endpoint above into any client that supports remote MCP, and the client opens an authorization page: sign in with your ShuLian Online account, tick the permissions you want to grant, press Allow. Claude Desktop, Claude.ai, ChatGPT, Cursor, VS Code and Gemini CLI all work this way.
The page offers three permissions and you may grant only some of them:
| Scope | What it allows |
|---|---|
gps.read | View devices and positions, history tracks and mileage, alert records, geofences and alert settings |
gps.write | Create, modify and delete geofences, change alert settings, create location share links |
gps.command | Send remote commands to real devices |
Access tokens expire after an hour and the client refreshes them for you.
Revoke at any time
In the web console click your name in the top-right corner, then “对接令牌(MCP)”. The lower half of the dialog lists every connected AI client; revoke one or all of them. Access stops immediately.
Alternative: long-lived token
Use this when your client has no one-click authorization, or when you are scripting against the API. Clients already using a long-lived token are unaffected and keep working.
Step 1: Get your token
Either place gives you the same kind of token; use whichever client you normally work in.
Web console (use this one if you do not have the WeChat mini program)
- Open https://xcslink.com/ in a browser and log in.
- Click your name in the top-right corner to open the menu.
- Choose “对接令牌(MCP)” (Integration Token) and click Copy in the dialog.
WeChat mini program
- Open our WeChat mini program and log in.
- Tap “设置” (Settings) at the bottom of the home page to open the “我的” (Me) page.
- In the top card, tap “对接令牌(MCP) ****** 复制” (integration token, copy) and confirm; the token is now on your clipboard.
Step 2: Configure your AI client
Claude Code
Run this in a terminal (-s user makes the server available in every project):
claude mcp add --transport http -s user ulzx https://xcslink.com/api/mcp --header "Authorization: Bearer {{TOKEN}}"
Then run claude mcp list. Seeing ulzx ... ✔ Connected means you are done. To swap in a new token, remove the server with claude mcp remove ulzx -s user and add it again.
Cursor
Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json in a project:
{
"mcpServers": {
"ulzx": {
"url": "https://xcslink.com/api/mcp",
"headers": {
"Authorization": "Bearer {{TOKEN}}"
}
}
}
}
Save the file, then check that ulzx is enabled on Cursor's MCP settings page. Any other client that takes url and headers in a config file uses the same shape.
Claude Desktop (and clients that only run local commands)
These clients cannot send a custom request header, so put the open-source bridge mcp-remote in front. It needs Node.js 18 or later.
Open the config file via “Settings → Developer → Edit Config” in Claude Desktop, or edit it directly:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add the block below, then quit Claude Desktop completely and reopen it:
{
"mcpServers": {
"ulzx": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://xcslink.com/api/mcp",
"--header", "Authorization:${AUTH_HEADER}",
"--transport", "http-only"
],
"env": {
"AUTH_HEADER": "Bearer {{TOKEN}}"
}
}
}
}
The token sits in env and no argument contains a space, which keeps Windows from splitting the header apart.
Other clients with remote MCP support
Fill in the client's MCP server form like this:
| Name | ulzx (any name) |
|---|---|
| Type | Streamable HTTP (sometimes shown as streamableHttp); do not choose SSE |
| URL | https://xcslink.com/api/mcp |
| Header | Name Authorization, value Bearer YOUR_TOKEN |
If the client only takes a local command, bridge it with mcp-remote as shown in the Claude Desktop tab.
Step 3: Try it
Ask in plain language; the assistant picks the tools it needs:
- What devices do I have, and where are they now?
- How far did my car drive today, and from where to where?
- Show me this car's track between 2 pm and 5 pm yesterday.
- Any speeding, power cuts or geofence entries/exits in the past week?
- What geofences and alarms are set on my car?
- Create a 300 m geofence named “Home” at my current location and alert me when the car leaves.
- Turn on the overspeed alarm for this car and set the limit to 100 km/h.
- Create a location sharing link valid for 3 hours.
- Which devices are about to expire?
For “today”, “yesterday” and the like, the assistant first calls get_time_context to get server time. Everything is Beijing time (UTC+8).
Tools
| Tool | Access | What it does |
|---|---|---|
get_time_context | Read | Current server time and timestamps for today, yesterday and this week |
list_devices | Read | Devices under the account |
get_latest_info | Read | Latest position, speed, battery and today's mileage of several devices, with optional address |
device_latest_status | Read | Latest communication and positioning status of one device |
get_history | Read | Track points, up to 24 hours per call, sampled when there are many |
get_total_km | Read | Mileage over a period, up to 31 days per call |
get_track_summary | Read | Trip summary: start, end, distance, top speed |
overview | Read | Daily, monthly or yearly statistics: mileage, usage time, event counts |
event_stay | Read | Stops |
event_fence | Read | Geofence entries and exits |
event_overspeed | Read | Speeding |
event_acc | Read | ACC state changes |
event_power_off | Read | Power cut and restore |
event_low_power | Read | Low battery |
event_vibration | Read | Vibration |
list_fences | Read | Geofences on a device and the allowed maximum |
get_alert_settings | Read | Alarm switches and overspeed limit |
list_expiring_devices | Read | Devices expiring soon or already expired |
list_device_commands | Read | Remote commands available for a device model |
set_fence | Write | Create or modify a circular or polygon geofence |
delete_fence | Write | Delete a geofence |
set_alert_settings | Write | Change alarm switches or the overspeed limit; only what you mention |
create_share_link | Write | Create a live location sharing link |
send_device_command | Write | Send a low-risk command, such as changing the tracking interval or requesting one fix |
prepare_device_command | Device control | First step for a high-risk command: reports the device name, what the command does and its impact, and returns a single-use confirmation id |
confirm_device_command | Device control | Second step: sends the command, and only with a valid confirmation id |
Keep your client's default of asking for confirmation before it runs anything in the Write group.
Notes
- After a geofence or alert change, the device reconnects once to pick up the new settings. That is expected, and it is exactly what saving in the mini program does.
- Creating a share link invalidates any link shared earlier for that device.
- Rate limit: up to 10 requests in flight per network address and 20 per second. Normal use stays well below that; anything over gets HTTP 503, so just retry.
- Commands to an offline device are queued and run the next time the device connects, so there is no need to send them again.
- High-risk commands take two steps. Cutting fuel or power, factory reset, restarting the device, remote listening and scheduled shutdown cannot be executed in a single call. The assistant must first obtain a confirmation id and tell you the device name, what the command does and its impact; only then can it send it. The id is valid for five minutes, works once, and is bound to your account, the device and the exact command. Low-risk commands such as changing the tracking interval still take one step.
- Coordinates: WGS84 by default. Ask for GCJ02 if you plot on AMap or Tencent Maps, BD09 for Baidu Maps.
- Units: mileage in km, speed in km/h, geofence radius in meters.
FAQ
“invalid session” or 401
The token is no longer valid, almost always because you logged in again or logged out in the client you copied it from. Copy the new token and update your client. Tokens from the web console, the mini program and the app all work.
“insufficient_scope” or 403
That permission was not granted. Revoke the client under “对接令牌(MCP)” in the web console, connect again from the client and tick the permission you need.
The client cannot connect
Check three things: the URL is https://xcslink.com/api/mcp (note the /api), the type is Streamable HTTP and not SSE, and the header value starts with Bearer followed by a space.
Occasional 503
You hit the rate limit. Retry in a moment; if it keeps happening, ask the AI to call tools one at a time instead of firing many in parallel.
No track data
Either the device reported no positions in that window, or the window is longer than 24 hours. Check the last report time with device_latest_status first.
Developers: raw calls
The protocol is JSON-RPC 2.0. Tool-level errors come back as result.isError=true, with the reason in result.content[0].text.
curl -X POST https://xcslink.com/api/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{TOKEN}}" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_devices","arguments":{}}}'
curl -X POST https://xcslink.com/api/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
tools/list needs no token and returns the full parameter schema of every tool. The tool descriptions themselves are in Chinese; mainstream models read them without trouble and will still answer you in English.
OAuth endpoints
Implemented per the MCP authorization spec: Authorization Code with PKCE, and code_challenge_method must be S256. Without credentials the MCP endpoint answers HTTP 401 with a WWW-Authenticate challenge, which is how clients discover the addresses below.
| Purpose | Address |
|---|---|
| Protected resource metadata | /.well-known/oauth-protected-resource/api/mcp |
| Authorization server metadata | /.well-known/oauth-authorization-server |
| Dynamic client registration | POST /oauth/register |
| Authorization | GET /oauth/authorize |
| Token and refresh | POST /oauth/token |
| Revocation | POST /oauth/revoke |
Both dynamic client registration and client ID metadata documents are supported, so no manual pre-registration is required. Authorization responses carry iss, and the resource parameter is validated as the token audience. Access tokens last one hour; refresh tokens last 30 days and rotate on every use.
Error codes
| Status | Meaning | What to do |
|---|---|---|
| HTTP 401 | No credentials, or the OAuth token is invalid, expired or revoked | Follow the address in WWW-Authenticate to authorize, or refresh the token |
| HTTP 403 | Insufficient scope; the challenge names the missing one | Authorize again and grant that permission |
| HTTP 503 | Rate limited | Retry shortly and reduce parallelism |
| JSON-RPC 401 | The long-lived token is not valid | Copy a fresh token |
| JSON-RPC -32602 | Unknown tool name | Call tools/list first |
result.isError=true | Tool-level error | Reason is in result.content[0].text |