跳到主要内容

Hands-On: Give Your Hardware a Brain — Build MCP Skills That Let AI Control Real Devices

Imagine telling your oven "Preheat to 200 degrees and bake for 25 minutes" — and it just... does it. No app, no buttons, no menu diving. Just natural language, understood by an AI agent, executed on real hardware.

This guide shows you exactly how that works, using a Smart Oven project built with TuyaOpen. By the end, you'll know how to create your own hardware MCP skills for any device.


What You'll Build

An AI-powered Smart Oven where a chat agent can:

CommandWhat the Agent Does
"Turn on the oven"Calls oven.start → sets the power DP
"Preheat to 200°C"Calls oven.set_temperature(200) → writes the temp DP
"Bake for 25 minutes"Calls oven.set_timer(1500) → sets countdown DP
"Is it still on?"Calls oven.get_state() → reads all DPs, returns JSON
"Run the pizza recipe"Calls oven.run_recipe("pizza") → sets temp + timer + starts
"Take a photo and check if the cake is done"Calls device.camera_shot() → captures a JPEG the AI can see

The magic glue? MCP Function Call — the protocol that turns hardware operations into tools an AI agent can discover and invoke.


How It Works: The Architecture

The key insight: Every hardware capability (set temperature, read state, capture image) is registered as an MCP tool — a named function with typed parameters and a callback. The AI agent sees these tools, decides which to call based on user intent, and the callback drives the real hardware.


Step 1: Create the Cloud Product

Before writing any firmware code, you need a product on the Tuya cloud platform. The product defines your device's data model (DPs), AI agent, and cloud capabilities. Everything downstream — firmware, MCP tools, the app — depends on this.

1a. Create the product

  1. Log in to the Tuya Developer PlatformAI Product > DevelopmentCreate
  2. Select Custom to create a custom product from scratch (instead of picking a preset category)
  3. Complete the creation wizard — you'll get a PID (Product ID)
提示

The fastest way: use the /tuya-iot-platform vibe coding skill in TuyaOpen IDE. Just describe your device in natural language and the Agent creates the product, defines DPs, and configures the AI Agent for you.

1b. Define Data Points (DPs)

Data Points (DPs) are the digital twin of your hardware. Each DP maps to a controllable or readable feature. In the Function Definition tab, click Add to create these custom DPs (IDs 101–199):

DP IDCodeTypeRangeDescription
101switchBoolPower on/off
102temp_setValue50–250Target temperature (°C)
103temp_currentValue0–300Current temperature (°C)
104timerValue0–3600Countdown timer (seconds)
备注

Standard DPs (ID < 100) are pre-defined by Tuya. Custom DPs (ID 101–199) are yours to define. For the oven, all four are custom.

1c. Add AI Agent & MCP capabilities

In the Function Definition tab → Product AI CapabilitiesAdd Agent:

  1. Model ConfigurationSkills Configuration → select Plugin → add Device Control · Bound Only (this enables MCP tool calls to your device DPs)
  2. Prompt Development → write a system prompt that describes the oven's capabilities so the AI knows when to call each tool

This creates the cloud-side Agent that will discover and invoke the MCP tools you register in firmware.

1d. Generate the DP header for firmware

Once DPs are defined on the cloud, generate the C header your firmware will include:

tuyaopen dp generate --target embedded

This produces tuya_dp_profile.h — the contract between cloud and device:

// tuya_dp_profile.h — auto-generated by `tuyaopen dp generate`
#define DPID_SWITCH 101
#define DPID_TEMP_SET 102
#define DPID_TEMP_CURRENT 103
#define DPID_TIMER 104

#define DPID_TEMP_SET_MIN 50
#define DPID_TEMP_SET_MAX 250
#define DPID_TIMER_MIN 0
#define DPID_TIMER_MAX 3600
提示

The full product creation flow is documented in Create Your Product & Agent. For the oven demo, you can also let the AI Agent generate the product and DPs for you using the /tuya-iot-platform skill in TuyaOpen IDE.


Step 2: Implement the Mock Hardware Layer

Before wiring up MCP tools, you need functions that simulate (or drive) the actual hardware. This keeps your tool callbacks clean:

// app_oven.h
typedef struct {
bool switch_on;
int temp_set;
int temp_current;
int timer_remaining;
} oven_state_t;

OPERATE_RET app_oven_set_switch(bool on);
OPERATE_RET app_oven_set_temp(int temp_c);
OPERATE_RET app_oven_set_timer(int seconds);
OPERATE_RET app_oven_add_timer(int seconds);
oven_state_t app_oven_get_state(void);
// app_oven.c — each setter reports DPs to the cloud + updates the LCD
static oven_state_t g_oven_state = {
.switch_on = false,
.temp_set = 180,
.temp_current = 25,
.timer_remaining = 0
};

OPERATE_RET app_oven_set_temp(int temp_c) {
if (temp_c < DPID_TEMP_SET_MIN || temp_c > DPID_TEMP_SET_MAX)
return OPRT_INVALID_PARM;
g_oven_state.temp_set = temp_c;
__oven_report_dp(); // sync to cloud + LCD
return OPRT_OK;
}

Step 3: Register MCP Tools (The Core Step)

This is where the AI agent gets its "hands" on your hardware. Each tool is registered with:

  • Name — what the AI sees (use dot-notation: oven.set_temperature)
  • Description — LLM-friendly text explaining when/how to call it
  • Parameters — typed input properties with ranges
  • Callback — the function that runs when the AI calls this tool

The Registration Pattern

#include "ai_mcp_server.h"
#include "tal_event_info.h"

// Called once when MQTT connects (deferred registration)
static OPERATE_RET __oven_mcp_on_mqtt_connected(void *data) {
(void)data;

// Tool 1: Start the oven
TUYA_CALL_ERR_GOTO(AI_MCP_TOOL_ADD(
"oven.start",
"Turn on the oven. Use when the user wants to start cooking, "
"preheat, or begin baking.\nParameters: none\nReturns: bool",
__oven_start_cb, NULL
));

// Tool 2: Set temperature
TUYA_CALL_ERR_GOTO(AI_MCP_TOOL_ADD(
"oven.set_temperature",
"Set the oven target temperature in Celsius (50-250).\n"
"Parameters: temperature (int)\nReturns: int (applied temp)",
__oven_set_temp_cb, NULL,
MCP_PROP_INT_RANGE("temperature", "Target temperature in °C (50-250).",
DPID_TEMP_SET_MIN, DPID_TEMP_SET_MAX),
MCP_PROP_END
));

// Tool 3: Get full state
TUYA_CALL_ERR_GOTO(AI_MCP_TOOL_ADD(
"oven.get_state",
"Get the current oven state: power, target temp, current temp, "
"timer remaining.\nParameters: none\nReturns: JSON object",
__oven_get_state_cb, NULL
));

// ... more tools
return OPRT_OK;
}

OPERATE_RET app_oven_mcp_init(void) {
return tal_event_subscribe(
EVENT_MQTT_CONNECTED, "oven_mcp_tools",
__oven_mcp_on_mqtt_connected, SUBSCRIBE_TYPE_ONETIME);
}

The Callback Pattern

Each callback reads AI-supplied arguments from properties, calls the hardware function, and returns a result:

static OPERATE_RET __oven_set_temp_cb(const MCP_PROPERTY_LIST_T *properties,
MCP_RETURN_VALUE_T *ret_val,
void *user_data) {
// 1. Read the AI-supplied parameter
int temp = properties->properties[0]->value.int_val;

// 2. Call the hardware function
OPERATE_RET rt = app_oven_set_temp(temp);

// 3. Return the result to the AI
ai_mcp_return_value_set_int(ret_val,
(rt == OPRT_OK) ? temp : -1);
return OPRT_OK;
}

For JSON returns (like get_state):

static OPERATE_RET __oven_get_state_cb(const MCP_PROPERTY_LIST_T *properties,
MCP_RETURN_VALUE_T *ret_val,
void *user_data) {
oven_state_t s = app_oven_get_state();
cJSON *json = cJSON_CreateObject();
cJSON_AddBoolToObject(json, "switch_on", s.switch_on);
cJSON_AddNumberToObject(json, "temp_set", s.temp_set);
cJSON_AddNumberToObject(json, "temp_current", s.temp_current);
cJSON_AddNumberToObject(json, "timer_remaining", s.timer_remaining);
ai_mcp_return_value_set_json(ret_val, json);
return OPRT_OK;
}

Step 4: Wire It Into the Boot Sequence

In your app_chat_bot.c, call your MCP init right after ai_mcp_init():

#if defined(ENABLE_COMP_AI_MCP) && (ENABLE_COMP_AI_MCP == 1)
TUYA_CALL_ERR_RETURN(ai_mcp_init());
TUYA_CALL_ERR_RETURN(app_oven_mcp_init()); // ← your tools
#endif

Tools register automatically when MQTT connects. That's it.


Step 5: Build and Test

cd source/embedded
tos.py build

Verify the tool appears in the agent's tool list, then try these interactions:

You SayAgent CallsResult
"Preheat to 200 and bake for 25 minutes"oven.set_temperature(200)oven.set_timer(1500)oven.start()Oven heats up, timer counts down
"Roast a chicken"oven.run_recipe("roast")200°C, 40 min, auto-start
"Is it still on? How hot?"oven.get_state()Returns {switch_on: true, temp_set: 200, ...}
"Take a photo and check if the cake is done"device.camera_shot()AI receives a JPEG and can visually inspect

The Complete Tool Set

Here's the full set of MCP tools for the Smart Oven:

ToolParametersReturnsPurpose
oven.startboolPower on
oven.stopboolPower off
oven.set_temperaturetemperature (int, 50–250)intSet target temp
oven.set_timerseconds (int, 0–3600)intSet countdown
oven.add_timeseconds (int)intAdd time to timer
oven.get_stateJSONRead all DPs
oven.list_recipesJSON arrayList preset programs
oven.run_reciperecipe (string)JSONApply recipe + start
device.camera_shotimage/jpegCapture a photo

Built-in Recipes

RecipeTempTimeBest For
bake180°C30 minCakes, bread, casseroles
roast200°C40 minMeat and vegetables
broil230°C10 minQuick browning
pizza220°C15 minHigh-heat pizza
grill250°C8 minIntense grilling
reheat120°C5 minLeftovers
warm80°C30 minKeep food warm

AI Coding Prompts: Tips for Developers

When using AI coding assistants (Cursor, Claude Code, Copilot) to build hardware MCP skills, these prompt patterns will accelerate your development:

Prompt Pattern 0: Generate the Full Cloud Product from a Description

/tuya-iot-platform
Create a new AI product for a smart oven with these capabilities:
- Power on/off (bool)
- Temperature setting 50-250°C (value)
- Current temperature readback 0-300°C (value, read-only)
- Countdown timer 0-3600 seconds (value)

Add an AI Agent with device control MCP plugin.
Generate the DP definitions and the embedded DP header.

Why it works: The /tuya-iot-platform skill creates the cloud product, defines DPs, configures the AI Agent, and generates the firmware DP header — all from a natural-language device description. This is the fastest way to go from idea to code.

Prompt Pattern 1: Describe the Device, Not the Code

I have a smart oven with these features:
- Power on/off
- Temperature control (50-250°C)
- Timer (0-3600 seconds)
- Current temperature sensor
- Camera for visual inspection

Create MCP tool registrations for each feature.
Use the AI_MCP_TOOL_ADD macro pattern from the otto_robot example.

Why it works: The AI maps your device description directly to tool names, descriptions, and parameters.

Prompt Pattern 2: Specify the DP Mapping

My oven DPs are:
- DP 101: switch (bool, rw)
- DP 102: temp_set (value, 50-250, rw)
- DP 103: temp_current (value, 0-300, ro)
- DP 104: timer (value, 0-3600, rw)

Generate the tuya_dp_profile.h header and the MCP tool callbacks
that read/write these DPs.

Why it works: Explicit DP definitions eliminate ambiguity about parameter types and ranges.

Prompt Pattern 3: Request LLM-Friendly Descriptions

For each MCP tool, write descriptions that help an LLM understand:
1. WHEN to use this tool (what user intent triggers it)
2. WHAT parameters it takes (with units and ranges)
3. WHAT it returns (type and meaning)

Example: "Set the oven target temperature in Celsius (50-250).
Use when the user says 'preheat', 'set temp', or 'bake at X degrees'."

Why it works: Good tool descriptions are the #1 factor in the AI picking the right tool.

Prompt Pattern 4: Ask for Error Handling

Add input validation to each MCP tool callback:
- Clamp temperature to the DP range (50-250)
- Return -1 on invalid parameters
- For run_recipe, return {ok: false, available: [...]} on unknown recipe names

Why it works: The AI can self-correct when it gets structured error responses.

Prompt Pattern 5: Generate the Full Stack at Once

/tuyaopen-dev-loop
Create a complete Smart Oven project:
1. Cloud product with DPs (switch, temp_set, temp_current, timer)
2. Embedded firmware with mock hardware (app_oven.c)
3. MCP tools for all oven features (app_oven_mcp.c)
4. LVGL UI showing oven state on the T5-AI board display
5. Wire everything in app_chat_bot.c

Why it works: The /tuyaopen-dev-loop skill orchestrates the full cloud-to-device workflow.


Key Takeaways

  1. Start with the cloud product — Create the product, define DPs, and add the AI Agent on the cloud platform before touching firmware. The product is the foundation.
  2. DPs are the contract — Define them on the cloud, generate the header, and everything else follows.
  3. Tool descriptions matter — Write them for LLMs: when to use, what params, what returns.
  4. Defer registration to MQTT connect — Use tal_event_subscribe(EVENT_MQTT_CONNECTED, ..., SUBSCRIBE_TYPE_ONETIME) so tools register when the cloud link is ready.
  5. Keep hardware separate from MCP — Your app_oven.c handles hardware; app_oven_mcp.c handles tool registration. Clean separation.
  6. Return structured data — JSON responses with ok: false + available options let the AI self-correct.

Next Steps