@nexalware/mcp
OfficialClick on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@nexalware/mcp turn on the back porch light"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@nexalware/mcp
Nexalware as an MCP server, over stdio. Point any MCP-aware host (Claude Desktop, Claude Code, Cursor, etc.) at it, and your device control tools show up automatically, the host's own model decides when to call them. It's a thin wrapper around the TypeScript SDK, same operations, same permissions, just discoverable instead of hand-coded.
Building your own agent instead of using a pre-built host? Use the SDK directly, in TypeScript or Python. It's one function call away in code you already control, no subprocess or protocol discovery needed.
Get an API key
Create one on the dashboard (API Keys), scoped with a DeviceGrant to only the device(s) this agent should touch. This key ends up sitting in a local config file, least privilege matters more here than for a typical server-side integration.
Related MCP server: CLI Anything
Claude Code
claude mcp add nexalware -e NEXALWARE_API_KEY=nxw_live_sk_your_key_here -- npx -y @nexalware/mcpClaude Desktop, or any host using a mcpServers config file
Add this block to the host's MCP config (Claude Desktop: Settings -> Developer -> Edit Config):
{
"mcpServers": {
"nexalware": {
"command": "npx",
"args": ["-y", "@nexalware/mcp"],
"env": {
"NEXALWARE_API_KEY": "nxw_live_sk_your_key_here"
}
}
}
}Restart the host afterward, tools only load at startup.
Environment variables
Variable | Required | Meaning |
| yes | The key from the step above. The server exits immediately with an error if this is missing. |
| no | Override for a self-hosted or staging deployment. Defaults to the production API. |
Using npx -y @nexalware/mcp (not a pinned version) means every launch runs the latest published release, no separate update step.
Troubleshooting
Invalid API key — either a placeholder was never replaced (nxw_live_sk_your_key_here sent as-is fails exactly like this, not with a clearer error), or a server process from before you changed the key is still running. Fully restart the host after any key/command change (for VS Code: File → Exit, then reopen) — claude mcp list can show Connected while an already-open session is still talking to a stale process holding the old key.
Windows PowerShell 5.1 drops a bare --, so claude mcp add fails with error: unknown option '-y'. Quote it:
claude mcp add nexalware --scope user -e "NEXALWARE_API_KEY=nxw_live_sk_your_key_here" '--' npx -y '@nexalware/mcp'If the server times out or keeps disconnecting, npx -y contacts the npm registry on every start, which can exceed the client's startup timeout on a slow connection. Install the package once and run it with node directly instead:
npm install -g @nexalware/mcp
claude mcp remove nexalware --scope user
claude mcp add nexalware --scope user -e "NEXALWARE_API_KEY=nxw_live_sk_your_key_here" '--' node "$(npm config get prefix)\node_modules\@nexalware\mcp\dist\bin\nexalware-mcp.js"Run npm install -g @nexalware/mcp again whenever you want to update, since this method skips the auto-latest behavior described above.
Tools
Every tool takes and returns the same shape as its equivalent TypeScript SDK method, a failed call comes back as a normal MCP tool error with the same message the API itself returns, not a crash. The model reads each tool's parameter descriptions straight from its schema at call time, the breakdown below is the same information, written out for a human deciding what to wire up or debugging what the agent just did.
list_devices
The devices this key can actually act on, only what its own DeviceGrant(s) cover, never the rest of the account. The natural first call, an agent that doesn't already know a deviceId starts here instead of guessing one.
projectId(string, optional) — Narrow the list to one project. Leave it out to list every device this key can reach.
get_device_commands
The command catalog a device accepts, so the agent knows what cmd values are actually valid before calling send_command.
deviceId(string, required) — From a priorlist_devicescall, shaped likedev_a1b2c3.
send_command
The general-purpose way to make a device do something.
deviceId(string, required) — Which device to command.cmd(string, required) — Must match anamefromget_device_commands, case-sensitive.params(object, optional) — Only if that command's catalog entry declares aparamsSchema, shape depends entirely on the specific command.
turn_device_on / turn_device_off
Shorthand for the ON/OFF command.
deviceId(string, required) — Which device to turn on/off.
get_device_telemetry
Historical telemetry readings, newest first.
deviceId(string, required) — Which device's history to read.metric(string, optional) — Only this metric name, e.g.power_draw. Omit to get every metric.limit(number, optional) — Max rows, 1-1000, defaults to 100.since(number, optional) — Unix milliseconds, only readings at or after this time.
get_latest_telemetry
Current state plus the most recent reading per metric, in one call.
deviceId(string, required) — Which device to snapshot.
list_sub_devices
Physical devices connected locally behind this one, if it's acting as a master. Empty until the master's own firmware reports one.
deviceId(string, required) — The master device's id, not a sub-device id.
get_sub_device
One sub-device's current state and capabilities.
deviceId(string, required) — The master device's id.subDeviceId(string, required) — From a priorlist_sub_devicescall, shaped likesub_x1y2z3.
get_sub_device_telemetry
Same idea as get_device_telemetry, scoped to one sub-device.
deviceId(string, required) — The master device's id.subDeviceId(string, required) — Which sub-device's history to read.metric/limit/since(optional) — Same meaning as inget_device_telemetry.
send_sub_device_command
Send a command to one sub-device behind a master, instead of the master itself.
deviceId(string, required) — The master device's id.subDeviceId(string, required) — Which sub-device to target.cmd(string, required) — Whatever command name the sub-device itself declared it accepts (its own vocabulary, not a Nexalware-defined catalog).params(object, optional) — Arguments for that command, if it needs any.
list_schedules
A device's active (PENDING or ACTIVE) schedules.
deviceId(string, required) — Which device's schedules to list.
get_schedule_context
The commands available to schedule for a device, same catalog as get_device_commands.
deviceId(string, required) — Which device to check.
create_schedule
Create or replace one of a device's 5 schedule slots, firing onCommand at onTs and offCommand at offTs. Calling this again with the same slot overwrites what was there.
deviceId(string, required) — Which device to schedule.slot(number, required) — Which of the 5 fixed slots to use, an integer 0 to 4.onTs(number, required) — Unix seconds to fireonCommand.offTs(number, required) — Unix seconds to fireoffCommand.label(string, optional) — Shown on the dashboard, max 7 characters.enabled(boolean, optional) — Omit to default enabled;falsecreates it disabled.onCommand(object, optional) —{ command, params? }. Defaults to{ command: "ON" }if omitted.offCommand(object, optional) — Same shape, defaults to{ command: "OFF" }.
update_schedule
Update an existing schedule slot, only the fields provided are changed.
deviceId(string, required) — Which device's schedule to update.slot(number, required) — Which slot (0-4), must already exist.onTs/offTs/label/enabled/onCommand/offCommand(all optional) — Same meaning as increate_schedule, include only what's changing.
delete_schedule
Cancel a schedule slot.
deviceId(string, required) — Which device's schedule to cancel.slot(number, required) — Which slot (0-4) to cancel.
get_schedule_history
A device's completed or cancelled schedules, most recent first.
deviceId(string, required) — Which device to check.
What it can't do
Nothing outside the calling key's own DeviceGrant. There's no tool to create a grant, register a device, or manage API keys, those stay dashboard-only, an MCP tool call is only ever as capable as the key you gave it, never able to expand its own access.
create_schedule/update_schedule fire existing commands from a device's catalog, they can't invent new ones. Defining, editing, or deleting a command definition itself stays a dashboard-only action.
Links
SDK Reference (TypeScript) / SDK Reference (Python) - the same operations, called directly from your own code.
Device Orchestration - what
list_sub_devices/send_sub_device_commandactually operate on.
License
MIT
Available Tools
17 toolscreate_scheduleA
Create or replace one of a device's schedule slots (0-4), firing onCommand at onTs and offCommand at offTs. Rejected if the calling key has no permission for either command.
Inputs: onTs (required), slot (required), offTs (required), deviceId (required), +4 more.
delete_scheduleC
Cancel a schedule slot.
Inputs: slot (required), deviceId (required).
get_device_commandsA
List the commands a device accepts: name, label, and the params each one expects.
Inputs: deviceId (required).
get_device_telemetryA
Read a device's telemetry history, newest first.
Inputs: deviceId (required), limit, since, metric.
get_latest_telemetryB
Read a device's current state plus the most recent reading per telemetry metric.
Inputs: deviceId (required).
get_schedule_contextA
List the commands available to schedule for a device, same catalog as get_device_commands.
Inputs: deviceId (required).
get_schedule_historyA
List a device's completed or cancelled schedules, most recent first.
Inputs: deviceId (required).
get_sub_deviceC
Read one sub-device's current state and capabilities.
Inputs: deviceId (required), subDeviceId (required).
get_sub_device_telemetryA
Read one sub-device's telemetry history, newest first.
Inputs: deviceId (required), subDeviceId (required), limit, since, +1 more.
list_devicesA
List the devices this API key can actually act on - only what its own DeviceGrant(s) cover, never the rest of the account. Call this first to discover valid deviceId values instead of guessing or asking the user to paste one in.
Inputs: projectId.
list_schedulesB
List a device's active (pending or currently running) schedules.
Inputs: deviceId (required).
list_sub_devicesA
List the physical sub-devices connected locally behind this device, if it's acting as a master. Empty until the master actually reports one, this never includes software agents.
Inputs: deviceId (required).
send_commandA
Send a command to a device. Check get_device_commands first for valid cmd names and expected params. Rejected if the calling key has no permission for this device/command.
Inputs: cmd (required), deviceId (required), params.
send_sub_device_commandA
Send a command to one specific sub-device behind a master, instead of the master itself. Not validated against a catalog, Nexalware relays it opaquely, the master and sub-device interpret it.
Inputs: cmd (required), deviceId (required), subDeviceId (required), params.
turn_device_offB
Shorthand for sending the OFF command to a device.
Inputs: deviceId (required).
turn_device_onB
Shorthand for sending the ON command to a device.
Inputs: deviceId (required).
update_scheduleC
Update an existing schedule slot, only the fields provided are changed.
Inputs: slot (required), deviceId (required), onTs, label, +4 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Tools are largely distinct by resource (device vs sub-device) and action (telemetry, command, schedule). Minor overlap exists between turn_device_on/off and send_command, and between get_device_commands and get_schedule_context, but descriptions clarify the boundaries.
All tool names use a consistent snake_case verb_noun pattern (get_, list_, send_, turn_, create_, update_, delete_). The only slight deviation is turn_device_on/off, but it remains readable and consistent with the overall style.
17 tools is slightly above the ideal range but justified by the need to cover devices, sub-devices, telemetry, commands, and schedules. Each tool appears to serve a distinct purpose with no redundant operations.
The surface covers device discovery, command catalog, sending commands, telemetry (latest and history), sub-device operations, and full schedule lifecycle (create/update/delete/list/history/context). Minor gaps exist, such as no device metadata update or sub-device command catalog, but core workflows are complete.
Maintenance
Related MCP Connectors
Discover, plan and run tools across your connected business systems through one OAuth MCP endpoint
Single-connection MCP gateway discovering and executing 490+ verified MCP & A2A tools.
Host any HTTP API as MCP tools with a tamper-evident cross-agent settlement ledger.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to discover and invoke backend tools over MCP JSON-RPC while enforcing 3-legged OAuth 2.0 identity propagation, role-based access control, and protocol transcoding to REST APIs.1Apache 2.0
- AlicenseNot gradedqualityCmaintenanceExposes approved application capabilities as stable MCP tools, enabling agents to discover and execute read-only operations by default, with optional write or destructive authority for a session.MIT
- AlicenseNot gradedqualityAmaintenanceEnables MCP clients to discover and connect over MQTT, list and invoke tools, and read resources in browser and Node.js environments.4 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to discover and invoke versioned external tools through an MCP or REST gateway with authentication, authorization, mutation safety, reliability controls, audit logging, and replay.Apache 2.0