Skip to content

feat: MCP tool profiles & parameter validation hardening#45

Merged
chenliuyun merged 8 commits into
mainfrom
feat/mcp-tool-profiles
May 15, 2026
Merged

feat: MCP tool profiles & parameter validation hardening#45
chenliuyun merged 8 commits into
mainfrom
feat/mcp-tool-profiles

Conversation

@chenliuyun
Copy link
Copy Markdown
Collaborator

Summary

  • Add --tools flag to mcp serve/mcp tools with three profiles: readonly (10 tools), default (13), all (24) for safe AI agent delegation
  • Expand client-side parameter validation to 15+ device families (humidifier, air purifier, vacuums, fans, thermostat, keypad, TV, roller shade)
  • Fix type coercion bypass (Number(true) → 1, Number("") → 0) with isNumericish guard
  • Canonicalize device aliases before validation so cached alias names get full validation
  • Sync expand path with raw validators (device-aware brightness range, blind tilt even-angle check)
  • Extract parseParameterForWire for consistent JSON parameter serialization in MCP

Test plan

  • npm run typecheck passes
  • npx vitest run — 2370 tests pass
  • switchbot mcp tools --tools readonly shows 10 tools
  • switchbot mcp tools --tools all shows 24 tools
  • switchbot mcp serve --tools readonly only registers read-only tools
  • switchbot devices expand <floorLampId> setBrightness --brightness 0 accepted
  • switchbot devices command <blindId> setPosition "up;51" rejected (odd angle)

🤖 Generated with Claude Code

chenliuyun added 8 commits May 15, 2026 16:39
Add --tools flag to mcp serve/tools with readonly/default/all profiles
for safe AI agent delegation. Expand device catalog and param-validator
coverage. Fix: reject malformed JSON field types before Number() coercion,
block waterLevel for all combo vacuum aliases, correct Strip Light 3
brightness range, add missing devices to isColorTemperatureDevice.
Keep parameter range as 0-100 but change exampleParams from '0' to '1'
so expand users don't hit the hardcoded min=1 client-side check.
- buildBrightnessSet now accepts deviceType and uses brightnessRange()
  so 0-100 devices (Floor Lamp, RGBIC, etc.) allow --brightness 0
- buildBlindTiltSetPosition rejects odd angles (must be multiple of 2)
- Restore catalog exampleParams to '0' since expand now supports it
validateParameter now resolves aliases (e.g. "Evaporative Humidifier"
→ "Humidifier2") via canonicalizeDeviceType before matching, so cached
alias strings get the same validation as canonical type names.
Prevents Number("") coercing to 0 and silently passing range checks.
Prevents expand from rejecting valid lighting commands when the cached
device type is an alias (e.g. "Ceiling Light Pro").
The default profile excludes admin tools; smoke test calls policy_new.
@chenliuyun chenliuyun merged commit fa8bc62 into main May 15, 2026
11 checks passed
@chenliuyun chenliuyun deleted the feat/mcp-tool-profiles branch May 15, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant