diff --git a/AGENTS.md b/AGENTS.md
index f315b52..05a0e32 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -59,9 +59,13 @@ Use the smallest relevant check while iterating. Before a broad PR, run
- This repo is a reimplementation. A few upstream service addresses are load-bearing
and are deliberately kept, each with a whitelist entry in
`scripts/harness-check.mjs`: the global-agent relay (`api.hermes-studio.ai`), the
- OpenRouter referer, and the ESP32 purchase link. Do not "clean them up" as legacy
+ OpenRouter referer, and the sidebar website link. Do not "clean them up" as legacy
brand text — removing them breaks those features. Do not read the relay address as
project identity: this deployment is not affiliated with the upstream operator.
+- The upstream ESP32 / MCU device feature was removed on purpose (no UI entry, no REST
+ routes, no store, no locale strings). Do not reintroduce it. Its "purchase" affordance
+ was the only part that merely advertised the upstream site; the rest was real device
+ management, and the whole thing is gone because the hardware is out of scope here.
- The online-update channel (`runtime-version-manager.ts`) has no default URL. It reads
`HERMES_WEB_UI_VERSION_MANIFEST_URL` / `HERMES_WEB_UI_DOWNLOAD_BASE_URL` /
`HERMES_WEB_UI_GITHUB_REPO` and degrades with a named error when unset. Do not
diff --git a/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md b/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md
new file mode 100644
index 0000000..f7aa815
--- /dev/null
+++ b/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md
@@ -0,0 +1,40 @@
+---
+date: 2026-10-17
+pr: pending
+feature: Remove the upstream ESP32/MCU device panel from the chat sidebars
+impact: Sidebar-only deletion. Both files lose one child component (SettingsCircuitBadge) and its import from the settings row at the bottom of the page sidebar. No chat store, no message rendering, no /chat-run payload, no streaming, and no tool-call path is touched. Nothing in the chat chain gains or loses a capability.
+---
+
+## What changed
+
+`ChatPanel.vue` and `GroupChatPanel.vue` each rendered ``
+next to the settings button in `.page-sidebar-bottom`. Both now omit it.
+
+## Why
+
+The badge opened an ESP32/MCU device management dialog. Its only outbound call to
+the upstream operator was the "purchase" button inside that dialog, but the rest was
+real functionality (add device, LAN status, remote connect/disconnect, rename,
+delete) backed by six REST routes and the `mcu_devices` table. The hardware is out
+of scope for this deployment, so the whole feature is gone rather than hidden.
+
+## Removal scope
+
+- `SettingsCircuitBadge.vue`, `api/hermes/mcu-devices.ts`
+- server `routes/mcu-devices.ts`, `controllers/mcu-devices.ts`,
+ `db/hermes/mcu-devices-store.ts`, the `routes/index.ts` registration, and the
+ `mcu_devices` entry in `schemas.ts`
+- `GlobalAgentServer.hasMcuDeviceCode()`, which only existed to answer the panel's
+ LAN-status column
+- `mcuDevices.*` locale keys in both `zh.ts` and `en.ts`
+- the corresponding harness and `no-legacy-brand` whitelist entries
+
+## Deliberately kept
+
+- `DevicesView.vue` and the `hermes.devices` route. That is LAN device discovery
+ backed by `@/api/hermes/devices`, a separate feature from MCU device management.
+- `packages/server/src/services/global-agent/server.ts` itself. Only the one
+ now-unused method was removed; the relay is load-bearing for other features.
+- Existing `mcu_devices` tables in already-provisioned databases. The table
+ creation was dropped but no `DROP TABLE` was added, so an old deployment keeps
+ its rows as harmless orphans instead of losing data on upgrade.
diff --git a/docs/known-issues.md b/docs/known-issues.md
index a4eae5b..edb66e8 100644
--- a/docs/known-issues.md
+++ b/docs/known-issues.md
@@ -45,13 +45,7 @@
- **位置**:`packages/client/src/views/hermes/WorkflowView.vue`,`showWorkflowBatchDeleteConfirm`
- **证据**:naive 的 `NPopconfirm v-model:show` 需要它;Arco 的 `a-popconfirm` 无 `show` prop 后它失去读取方,只剩写。关闭改由 `@ok`/`@cancel` 驱动
-### 6. 两个弹窗共用一个 saving ref
-
-- **现象**:新增设备弹窗与改名弹窗同时存在时,按钮的 loading/disabled 会互相干扰
-- **位置**:`packages/client/src/components/layout/SettingsCircuitBadge.vue`
-- **证据**:两个 modal 共用 `saving`。迁移前就是这样
-
-### 7. ProfileCreateModal 有两个重复的 style 块
+### 6. ProfileCreateModal 有两个重复的 style 块
- **现象**:无功能影响
- **位置**:`packages/client/src/components/hermes/profiles/ProfileCreateModal.vue`
@@ -154,7 +148,7 @@
### 表格列的省略与 tooltip
-- **文件**:`SettingsCircuitBadge.vue`、`UserManagementSettings.vue`
+- **文件**:`UserManagementSettings.vue`
- **备注**:naive 的 `ellipsis: { tooltip: true }` → Arco 的 `ellipsis: true` + 列顶层 `tooltip: true`
- **需确认**:长文本省略后悬浮能显示完整内容
@@ -167,7 +161,7 @@
### 弹窗的遮罩/ESC 行为
- **风险**:Arco 默认 `maskClosable` 和 `escToClose` 都是 `true`。用户填了一半的表单按 ESC 或点遮罩会**直接丢弃且不重置**
-- **涉及**:`VoiceApiFormModal.vue`、`VoiceApiConfigurator.vue`、`SettingsCircuitBadge.vue` 的设备面板
+- **涉及**:`VoiceApiFormModal.vue`、`VoiceApiConfigurator.vue`
- **需确认**:是否应该设 `:mask-closable="false"` / `:esc-to-close="false"`
### 模型选择弹窗(ProviderFormModal)
diff --git a/packages/client/src/api/hermes/mcu-devices.ts b/packages/client/src/api/hermes/mcu-devices.ts
deleted file mode 100644
index 2e85dbf..0000000
--- a/packages/client/src/api/hermes/mcu-devices.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { request } from '../client'
-
-export interface McuDevice {
- id: number
- name: string
- device_code: string
- is_official: boolean
- created_at: number
- lan_connected?: boolean
- remote_connected?: boolean
-}
-
-export interface McuDeviceListResponse {
- devices: McuDevice[]
-}
-
-export async function fetchMcuDevices(): Promise {
- return request('/api/mcu-devices')
-}
-
-export async function createMcuDevice(input: {
- name: string
- device_code: string
-}): Promise {
- return request('/api/mcu-devices', {
- method: 'POST',
- body: JSON.stringify(input),
- })
-}
-
-export async function updateMcuDeviceName(id: number, name: string): Promise {
- return request(`/api/mcu-devices/${encodeURIComponent(String(id))}`, {
- method: 'PATCH',
- body: JSON.stringify({ name }),
- })
-}
-
-export async function deleteMcuDevice(id: number): Promise {
- return request(`/api/mcu-devices/${encodeURIComponent(String(id))}`, {
- method: 'DELETE',
- })
-}
-
-export async function connectMcuDeviceRemote(id: number): Promise {
- return request(`/api/mcu-devices/${encodeURIComponent(String(id))}/remote-connect`, {
- method: 'POST',
- })
-}
-
-export async function disconnectMcuDeviceRemote(id: number): Promise {
- return request(`/api/mcu-devices/${encodeURIComponent(String(id))}/remote-disconnect`, {
- method: 'POST',
- })
-}
diff --git a/packages/client/src/components/hermes/chat/ChatPanel.vue b/packages/client/src/components/hermes/chat/ChatPanel.vue
index 21bf176..5380ad1 100644
--- a/packages/client/src/components/hermes/chat/ChatPanel.vue
+++ b/packages/client/src/components/hermes/chat/ChatPanel.vue
@@ -19,7 +19,6 @@ import OutlinePanel from "./OutlinePanel.vue";
import FilesPanel from "./FilesPanel.vue";
import TerminalPanel from "./TerminalPanel.vue";
import PageSidebarNav from "@/components/layout/PageSidebarNav.vue";
-import SettingsCircuitBadge from "@/components/layout/SettingsCircuitBadge.vue";
import { isStoredSuperAdmin } from "@/api/client";
import { useDefaultWorkspace } from "@/composables/useDefaultWorkspace";
@@ -1289,7 +1288,6 @@ async function handleSessionModelCustomSubmit() {
{{ t("sidebar.settings") }}
-
diff --git a/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue b/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue
index c72a3b9..34163dd 100644
--- a/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue
+++ b/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue
@@ -11,7 +11,6 @@ import GroupChatInput from './GroupChatInput.vue'
import FolderPicker from '@/components/hermes/chat/FolderPicker.vue'
import ProfileAvatar from '@/components/hermes/profiles/ProfileAvatar.vue'
import PageSidebarNav from '@/components/layout/PageSidebarNav.vue'
-import SettingsCircuitBadge from '@/components/layout/SettingsCircuitBadge.vue'
import { copyToClipboard } from '@/utils/clipboard'
import type { Attachment } from '@/stores/hermes/chat'
import type { RoomAgent, RoomInfo } from '@/api/hermes/group-chat'
@@ -512,7 +511,6 @@ async function handleApproval(choice: 'once' | 'session' | 'always' | 'deny') {
{{ t('sidebar.settings') }}
-
diff --git a/packages/client/src/components/layout/PageSidebarFooter.vue b/packages/client/src/components/layout/PageSidebarFooter.vue
index 802cd64..b21b940 100644
--- a/packages/client/src/components/layout/PageSidebarFooter.vue
+++ b/packages/client/src/components/layout/PageSidebarFooter.vue
@@ -1,7 +1,6 @@
@@ -124,21 +119,6 @@ function openApiRelay() {
{{ historyButtonLabel }}
-