MCP server for CEC IoT platform integration, providing tools to query areas, devices, cameras, and control IoT devices through remote APIs
This MCP server provides 8 tools for IoT device management with a fastmcp framework. Tools are explicitly registered with @mcp.tool() decorators, but definitions have significant gaps. Most tool descriptions are present but verbose and contain implementation details rather than LLM-optimized guidance. Parameter schemas are visible in code (area_ids, name, sn, etc.) with basic type declarations, but many lack proper JSON Schema structure and validation constraints. Output schemas are not formally documented. Error handling is minimal, most tools either return raw API results or catch exceptions generically. The server accepts credentials as constructor parameters (app_key, app_secret) which is a security red flag, though these appear to be configuration-time rather than request-time. Tool naming follows verb_noun pattern (get_area_info, list_device_base_info, add_camera, etc.) which is good, but some names are overly specific or redundant (get_asset_model_tool, control_device_tool, get_collect_data_by_id_codes_tool all end in '_tool'). Composition shows some dependency awareness (e.g., descriptions instruct to call get_area_info before list_device_base_info), but this is documentation-only, not enforced by the interface. Parameter defaults are used but some are empty strings which could cause silent failures.
新增摄像头 ## 调用示例,查询19楼前台新增一个摄像头: 1. 先判断用户输入是否带有区域 2. 如果有,则通过"查询全量区域列表"tool,获取全量区域信息,并获取出和"19楼前台"相关的区域code。 3. 将区域code,作为area_code 入参 ### 入参 1. name 摄像头名称,非必填,如果用户没指定,则不需要填 2. sn 摄像头序列号,非必填,如果用户没指定,则不需要填 3. area_code 区域编码,非必填,如果用户没有输入区域信息,则不需要填 ### 返回GB/T - 28181配置 1. 新增摄像头成功后,返回GB/T - 28181配置。 2. 如果返回结果不是GB/T - 28181配置,则判定新增异常。 3. 返回结果以可读性较好的markdown形式呈现给用户, 4. 提示用户去摄像头管理后台录入GB/T - 28181信息。
批量控制设备 入参说明: 入参格式:[{"assetId":"设备id","code":"属性编码","value":"控制属性值"}], 入参格式的数据来源场景示例: 关闭19楼的所有灯,(1). 通过`获取设备基本信息`Tool 获取到设备列表,(2). 获取设备列表的brandModelId列表,(3). 通过`获取品牌型号物模型信息`Tool 获取物模型属性信息,(4). 组装入参指令 返回说明 将结果转化为可读的markdown形式
## 查询全量区域列表 以下场景需要调用此函数 1. 当用户提出获取区域信息的需求时,使用工具获取所有区域信息。 2. 分析获取到的 areaName,梳理出区域的上下级关系。 返回数据 将区域信息以 markdown 表格的形式展示,表格应包含区域名称、上级区域等必要信息。
获取品牌型号物模型信息,获取设备的属性信息,属性信息用于控制以及当前采集值查询 ### 参数说明 brand_model_ids:品牌型号id列表,可以通过`list_device_base_info` 工具查询符合条件的品牌型号ID ### 返回格式 [{"brandModelId":"","code":"","alias":"","choseEnums":[{"enumCode": "1", "enumName": "开"}, {"enumCode": "0", "enumName": "关"}]}]
获取摄像头当前截图地址 ### 参数说明 - area_ids:区域ID列表,可以通过"查询全量区域列表"tool,获取全量区域信息,并获取出区域id列表。 ### 实例 查询19楼摄像头当前图像:先查询出19楼,19楼-房间1,19楼-房间2 区域id列表,再查询播放地址 ### 返回结果需要转成markdown表格
Redundant '_tool' suffix in 4 tool names (get_asset_model_tool, control_device_tool, get_collect_data_by_id_codes_tool). Naming convention is inconsistent (some tools omit '_tool').
Descriptions are verbose, procedural, and include implementation examples ('先判断用户输入...', '关闭19楼的所有灯') instead of declarative LLM-optimized guidance. Average description length ~250 chars, but content is low-signal (implementation steps rather than 'what/when/why').
Parameter validation is absent. Many parameters default to empty strings (name='', sn='', area_code='') with no validation. array parameters (area_ids, brand_model_ids) have no length constraints, allowing zero or unbounded values.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 46 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 51 | - | v1 |
获取设备的采集值(不包含在离线), 入参说明: device_ids:设备id列表,通过`获取设备基本信息`Tool 获取到设备id列表, codes:属性编码列表,参数来源:(1).通过`获取设备基本信息`Tool 获取到设备列表,(2). 获取设备列表的brandModelId列表,(3). 通过`获取品牌型号物模型信息`Tool 获取物模型属性信息 示例: 19楼有几个灯开着:(1).通过`获取设备基本信息`Tool 获取到19楼的所有灯的设备,并获取ids,brandModelIds。(2). 通过`获取品牌型号物模型信息`Tool 获取包含了`开`枚举值的属性编码列表 返回说明: 将获取到的设备采集值结果转化为易读的Markdown形式
获取摄像头实时流播放地址(HLS/RTMP格式) ### 参数说明 - area_ids:区域ID列表,可以通过"查询全量区域列表"tool,获取全量区域信息,并获取出区域id列表。 ### 示例 查询19楼摄像头播放地址:先查询出19楼,19楼-房间1,19楼-房间2 区域id列表,再查询播放地址 ### 返回结果需要转成markdown表格
## 查询设备基本信息(id、名称、序列号、区域、在离线) ### 入参 1. area_ids 区域id列表,非必填,需要通过"查询全量区域列表"tool获取到目标区域列表 2. name 设备名称 ## 调用示例,查询19楼的所有设备: 1. 先判断用户输入是否带有区域 2. 如果有,则通过"查询全量区域列表"tool,获取全量区域信息,并获取出和"19楼"相关的区域id列表,包含19楼-房间1、19楼-房间2。 3. 将区域id列表,作为area_ids 入参 ### 返回数据 [{"id":"设备id","name":"设备名称","brandModelId":"品牌型号id","sn":"序列号","areaId":"区域id","areaName":"区域名称","status":"在离线枚举值","statusName":"在离线状态描述"}]
Output schemas are not formally documented. Tool descriptions mention return format informally ('markdown表格', list of dicts) but no structured schema definitions are visible. LLMs cannot plan downstream calls without knowing return fields.
Error handling is minimal and non-actionable. Most tools either return raw API responses or catch exceptions as strings ('Error occurred: {str(e)}'). No guidance for LLM on recovery steps or retry logic.
control_device_tool (add_camera) is a WRITE/DESTRUCTIVE operation but description does not warn of irreversibility or side effects. No dry-run, confirmation, or rollback pattern offered. Agents may destroy state without safeguards.
Credentials (app_key, app_secret) are passed as constructor parameters to the serve() function. While not exposed as tool parameters, this pattern risks leaking secrets in logs or server startup traces. Should use environment variables or secure vaults.
No pagination support in tools that could return large result sets (list_device_base_info, get_asset_model_tool, get_collect_data_by_id_codes_tool). No limit, offset, or next_cursor parameters. Risk of context window exhaustion if thousands of items returned.
Tool descriptions include example values and implementation steps (e.g., '19楼', 'GB/T-28181') which LLMs may reuse literally instead of adapting to context. Replace with formal constraints and enum declarations.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present in code. control_device_tool and add_camera are clearly destructive but unmarked. Agents cannot automatically determine safety without reading descriptions.