tinymcp: Mở khóa Thế giới Vật lý cho LLM với MCP và Vi điều khiển
Hôm nay chúng tôi chính thức ra mắt tinymcp, một máy chủ và framework Model Context Protocol (MCP) giúp bất kỳ thiết bị kết nối nào cũng có thể cung cấp chức năng từ xa cho các mô hình ngôn ngữ lớn (LLMs). Trong khi nhiều máy chủ MCP mở rộng khả năng của LLM, chỉ một số ít có thể tương tác trực tiếp với thế giới vật lý. tinymcp tận dụng dịch vụ đám mây tối ưu của Golioth và firmware SDK để cho phép LLM tương tác với những thiết bị hạn chế nhất.
tinymcp là một dự án thử nghiệm và sẽ phát triển nhanh chóng với những thay đổi lớn. Cần thận trọng khi giao quyền điều khiển vật lý cho hệ thống AI.
Thông tin nền tảng
Nhiều công ty đang chạy đua để xây dựng các máy chủ MCP cho phép LLM tương tác với API nhằm đáp ứng yêu cầu người dùng. Mục đích chính của MCP là cung cấp thêm bối cảnh cho LLM, giúp trả về các phản hồi hữu ích hơn bằng cách truy cập dữ liệu bên ngoài. Ví dụ, một máy chủ MCP của Golioth có thể cho phép người dùng khai thác LLM để phân tích dữ liệu tổng quan về đội thiết bị thông qua Golioth Management API.
Đây là một trường hợp sử dụng hấp dẫn và chắc chắn sẽ được hỗ trợ trong tương lai, nhưng không phải là điều mới lạ. tinymcp hướng tới việc cho phép người dùng tự chạy máy chủ MCP trên các thiết bị nhúng và phơi bày chức năng từ xa dễ dàng, dựa trên nền tảng Golioth hiện có như LightDB State và Remote Procedure Call (RPC). Nó tận dụng khả năng gọi công cụ của MCP, giúp phơi bày chức năng tùy ý trên thiết bị tới LLM. Máy chủ tinymcp hoạt động như một proxy, chuyển đổi các cuộc gọi API JSON-RPC từ client MCP thành các cuộc gọi RPC của Golioth gửi đến thiết bị.
Cách hoạt động
Bởi vì tinymcp tận dụng tính năng hiện có của Golioth, bạn có thể dùng các phiên bản hiện tại hoặc cũ của Golioth Firmware SDK để triển khai máy chủ MCP trên thiết bị. Các thiết bị đã chạy firmware đăng ký RPC có thể phơi bày chức năng qua MCP mà không cần thay đổi firmware. Mọi nền tảng và phần cứng mà SDK hỗ trợ đều có thể được nhắm đến.
Ví dụ trong ví dụ blinky, một ứng dụng firmware đơn giản sử dụng Zephyr phơi bày khả năng bật tắt đèn LED qua các cuộc gọi công cụ MCP.
#include <zephyr/logging/log.h> LOG_MODULE_REGISTER(blinky, LOG_LEVEL_DBG); #include <golioth/client.h> #include <golioth/rpc.h> #include <samples/common/sample_credentials.h> #include <samples/common/net_connect.h> #include <string.h> #include <zephyr/kernel.h> #include <zephyr/drivers/gpio.h> #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); static K_SEM_DEFINE(connected, 0, 1); static enum golioth_rpc_status on_light_on(zcbor_state_t *request_params_array, zcbor_state_t *response_detail_map, void *callback_arg) { gpio_pin_set_dt(&led, 1); LOG_DBG("light on"); return GOLIOTH_RPC_OK; } static enum golioth_rpc_status on_light_off(zcbor_state_t *request_params_array, zcbor_state_t *response_detail_map, void *callback_arg) { gpio_pin_set_dt(&led, 0); LOG_DBG("light off"); return GOLIOTH_RPC_OK; } static void on_client_event(struct golioth_client *client, enum golioth_client_event event, void *arg) { bool is_connected = (event == GOLIOTH_CLIENT_EVENT_CONNECTED); if (is_connected) { k_sem_give(&connected); } LOG_INF("Golioth client %s", is_connected ? "connected" : "disconnected"); } int main(void) { LOG_DBG("Start tinymcp blinky"); int err; if (!device_is_ready(led.port)) { return -EIO; } err = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); if (err < 0) { return -EIO; } net_connect(); /* Lưu ý: Trong sản xuất, credentials nên được lưu trữ an toàn. Ở đây đơn giản sử dụng lưu dưới dạng plaintext. */ const struct golioth_client_config *client_config = golioth_sample_credentials_get(); struct golioth_client *client = golioth_client_create(client_config); struct golioth_rpc *rpc = golioth_rpc_init(client); golioth_client_register_event_callback(client, on_client_event, NULL); k_sem_take(&connected, K_FOREVER); err = golioth_rpc_register(rpc, "light_on", on_light_on, NULL); if (err) { LOG_ERR("Failed to register light_on RPC: %d", err); } err = golioth_rpc_register(rpc, "light_off", on_light_off, NULL); if (err) { LOG_ERR("Failed to register light_off RPC: %d", err); } while (true) { k_sleep(K_SECONDS(5)); } return 0; }
Thiết bị chạy ứng dụng firmware này sẽ kết nối với Golioth và chờ lệnh RPC đến. Máy chủ tinymcp kết nối với Golioth, truy vấn dữ liệu LightDB State của thiết bị để xác định các “công cụ” được phơi bày. Ví dụ, trạng thái sau đây phơi bày hai RPC đã đăng ký trong ví dụ blinky:
{ "mcp": { "tools": { "schema": [ { "name": "light_on" }, { "name": "light_off" } ] } } }
Cả người dùng lẫn thiết bị đều có thể ghi vào LightDB State, do đó lược đồ này có thể được tải lên qua console hoặc API quản lý để phơi bày các RPC hiện có, hoặc firmware thiết bị có thể cập nhật để gửi lược đồ này lên LightDB State khi khởi động nhằm tạo thành một giải pháp tự chứa hơn.
Máy chủ tinymcp có thể đăng ký với bất kỳ client MCP nào, ví dụ như Claude Code, Cursor, hoặc Gemini CLI. Sau đó ngôn ngữ tự nhiên có thể được dùng để tương tác với thiết bị, ví dụ như ra lệnh LLM “tắt đèn”.
Hướng phát triển tiếp theo
Cung cấp quyền truy cập thế giới vật lý cho LLM mở ra rất nhiều trường hợp sử dụng mới. Dù việc giao quyền cho AI cần được thực hiện cẩn trọng, chúng tôi rất mong chờ cộng đồng Golioth sáng tạo khai thác tính năng này. Ngoài ra còn có nhiều ý tưởng để cải tiến tinymcp như hỗ trợ nhắm mục tiêu nhiều thiết bị, xử lý công cụ ngoài, v.v. Hãy