[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80926":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":12,"stars7d":15,"stars30d":16,"stars90d":14,"forks30d":14,"starsTrendScore":16,"compositeScore":17,"rankGlobal":9,"rankLanguage":9,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":37,"readmeContent":38,"aiSummary":39,"trendingCount":14,"starSnapshotCount":14,"syncStatus":12,"lastSyncTime":40,"discoverSource":41},80926,"dcp","device-context-protocol\u002Fdcp","device-context-protocol","Device Context Protocol — bridge LLM agents to physical devices. Sub-50-byte frames, 27.6KB flash \u002F 0.6KB RAM measured on ESP32, capability-scoped and safe by design. Complementary to MCP. Paper: arXiv:2605.26159",null,"Python",38,2,1,0,3,6,1.43,"MIT License",false,"main",[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"agent","arduino","bridge","cbor","device-control","embedded","esp32","hardware","iot","llm","mcp","microcontroller","model-context-protocol","protocol","uart","2026-06-12 02:04:08","# DCP — Device Context Protocol\n\n[![tests](https:\u002F\u002Fgithub.com\u002Fdevice-context-protocol\u002Fdcp\u002Factions\u002Fworkflows\u002Ftest.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fdevice-context-protocol\u002Fdcp\u002Factions\u002Fworkflows\u002Ftest.yml)\n[![license: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-blue.svg)](LICENSE)\n[![spec: v0.3 draft](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fspec-v0.3%20draft-orange)](SPEC.md)\n[![arXiv](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FarXiv-2605.26159-b31b1b.svg)](https:\u002F\u002Farxiv.org\u002Fabs\u002F2605.26159)\n\n**Status:** Draft v0.3 — May 2026 · Hardware-validated on ESP32-WROOM-32\n\n> A protocol that lets LLM agents safely control physical devices,\n> down to dollar-class microcontrollers.\n>\n> Intent-level, transport-agnostic, capability-scoped. Compact wire format\n> (sub-50-byte frames). Self-contained firmware: under 1 KB of RAM,\n> ~28 KB of flash.\n>\n> Complementary to [MCP](https:\u002F\u002Fmodelcontextprotocol.io) — a reference\n> Bridge translates DCP ↔ MCP so any MCP host (Claude Desktop, Claude Code,\n> IDE assistants) works zero-config.\n\n## Contents\n\n- [Why DCP?](#why-dcp)\n- [Design principles](#design-principles)\n- [Architecture](#architecture)\n- [Quickstart](#quickstart)\n- [Add a feature in 5 steps](docs\u002FADDING_FEATURES.md)\n- [Recipes — five ready-to-flash device skeletons](docs\u002FRECIPES.md)\n- [Wire format](#wire-format) · full [SPEC.md](SPEC.md)\n- [Manifest](#manifest)\n- [Roadmap](#roadmap)\n- **Design rationale:** [docs\u002FRATIONALE.md](docs\u002FRATIONALE.md) — why\n  not MCP-on-MCU, why not WoT, why not Matter.\n\n## Why DCP?\n\nMCP is excellent for SaaS tools, but assumes JSON-RPC over WebSocket and runtime\ntool discovery. On an MCU with 32 KB of RAM, that's a non-starter.\n\nDCP keeps MCP's mental model (manifest + tool calls) but:\n\n- compiles to a compact CBOR wire format\n- uses a static intent table (no runtime negotiation)\n- moves safety enforcement to a Bridge process\n\nA reference Bridge translates **DCP ↔ MCP**, so any MCP-compatible LLM works\nout of the box. DCP is the last mile to physical hardware.\n\n![Coverage of LLM-induced failure modes by each protocol's schema-level defenses](docs\u002Fpaper\u002Ffigures\u002Fhallucination.png)\n\n*Why this matters in one chart: the protocol's schema decides how many\nhallucinated or adversarial calls are stopped before any byte reaches a\ndevice. DCP catches all six categories at the wire layer; the others\ncatch what their existing schema happens to cover.*\n\n## Design principles\n\n1. **Intent, not register.** `set_brightness(50%)`, not `write_pwm(pin=5, duty=128)`.\n2. **Units in the protocol.** Every number declares a unit. No ambiguity.\n3. **Static intent table.** Manifest known at compile time; runtime is pure binary.\n4. **Safety lives in the Bridge.** Devices trust the Bridge; LLMs never see raw GPIO.\n5. **Idempotent by default.** Non-idempotent intents must declare themselves.\n6. **Transport-agnostic.** UART, BLE, MQTT, USB-CDC, WebSocket — one frame.\n\n## Architecture\n\n![DCP architecture](docs\u002Fpaper\u002Ffigures\u002Farch.png)\n\nThe Bridge is the sole trust boundary. On every call it issues and\nverifies capability tokens, enforces range\u002Ftype\u002Funit checks from the\nmanifest, and supports dry-run as a wire-format primitive. Devices\nremain simple enough to fit on commodity microcontrollers; everything\nthe LLM is allowed to do is enforced before any byte traverses the\ndevice boundary.\n\n## Validated on real hardware\n\nAs of v0.3 the reference firmware is **measured-validated on two\nphysical boards** — an ESP32-WROOM-32 dev board over CH340 USB-Serial,\nand an ESP32-S3 (LILYGO T-Panel S3) over the S3's native USB-Serial\u002FJTAG\n— both at 115 200 baud:\n\n- 13\u002F13 round-trip tests pass on each board (`tools\u002Ftest_uart_roundtrip.py`)\n- 88\u002F88 Python unit & conformance tests pass\n- Full lamp firmware: 295 KB flash, 22.7 KB globals on WROOM-32 — most\n  of which is the Arduino-ESP32 runtime + FreeRTOS, not DCP\n- **The DCP layer itself measures 27.6 KB of flash and 0.6 KB of RAM**\n  over a baseline empty sketch — reproduce with\n  `docs\u002Fpaper\u002Ffigures\u002Fmeasure_footprint.py`. The flash figure is over\n  the original `\u003C16 KB` design target (set before on-device HMAC was\n  added); the RAM figure is well under it.\n- The S3 run also exercises DCP over a native-USB CDC link rather\n  than a USB-UART bridge chip — same firmware, no transport-specific\n  code\n\n![Static RAM footprint: measured DCP layer vs IoT-MCP reported peak memory](docs\u002Fpaper\u002Ffigures\u002Ffootprint.png)\n\n*Static RAM is the scarce resource on an MCU. The DCP layer's measured\n0.6 KB of RAM sits two orders of magnitude under IoT-MCP's reported\n74 KB peak memory. DCP's flash cost (27.6 KB, measured) is not plotted\n— IoT-MCP does not report a comparable flash figure.*\n\nSee [docs\u002FRATIONALE.md §7](docs\u002FRATIONALE.md) for what the hardware\nvalidation does and does not prove.\n\n### Cross-compile clean across the ESP family (Xtensa + RISC-V + ESP8266)\n\nThe reference firmware is portable by design (Arduino `Stream` + a\nsoftware SHA-256, no SoC-specific code paths in `DCP.{h,cpp}`). It\ncross-compiles for every current ESP32 variant *and* for ESP8266;\ntwo of those targets are also runtime-validated on real boards, the\nrest are build-validated pending hardware on the bench:\n\n| Target            | ISA                   | Flash (lamp+blink) | Globals  | Status        |\n|-------------------|-----------------------|--------------------|----------|---------------|\n| ESP32-WROOM-32    | Xtensa LX6 (baseline) | 294 KB             | 22.7 KB  | runtime ✓     |\n| ESP32-S3 (T-Panel)| Xtensa LX7            | 322 KB             | 22.7 KB  | runtime ✓ (native USB) |\n| ESP32-C3          | RV32IMC               | 289 KB             | 13.4 KB  | builds ✓      |\n| ESP32-C6          | RV32IMAC + HW-crypto  | 266 KB             | 14.0 KB  | builds ✓      |\n| ESP32-H2          | RV32IMAC + 802.15.4   | 292 KB             | 14.0 KB  | builds ✓      |\n| ESP32-P4          | RV32IMAFC dual-core   | 326 KB             | 22.0 KB  | builds ✓      |\n| ESP8266 NodeMCU   | Xtensa LX106 (legacy) | 242 KB             | 28.9 KB  | builds ✓      |\n\nAll builds use Arduino-ESP32 core 3.3.8 \u002F Arduino-ESP8266 core 3.x\n+ the same `firmware\u002Fesp32\u002F` library. The sketch picks PWM API at\ncompile time (`ledcAttach`\u002F`ledcWrite` on ESP32, `analogWrite` on\nESP8266); the protocol layer itself has no `#ifdef`. Reproduce\nwith:\n\n```bash\narduino-cli compile --clean --fqbn esp32:esp32:esp32c3 \\\n    --library firmware\u002Fesp32 firmware\u002Fesp32\u002Fexamples\u002Flamp\narduino-cli compile --clean --fqbn esp8266:esp8266:nodemcuv2 \\\n    --library firmware\u002Fesp32 firmware\u002Fesp32\u002Fexamples\u002Flamp\n```\n\n## Manifest\n\n```yaml\ndcp: 0.3\ndevice:\n  id:     lamp-kitchen-01\n  model:  smart_lamp_v1\n  vendor: example.dev\n\nintents:\n  - name: set_brightness\n    params:\n      level: { type: float, unit: percent, range: [0, 100] }\n      fade:  { type: duration, unit: ms, default: 0 }\n    capability: lamp.write\n    idempotent: true\n    dry_run: true\n\n  - name: read_brightness\n    returns: { type: float, unit: percent }\n    capability: lamp.read\n\nevents:\n  - name: motion_detected\n    payload:\n      confidence: { type: float, unit: ratio, range: [0, 1] }\n    capability: lamp.read\n```\n\n`intent_id = crc16(name)` — manifests and firmware stay in sync without\ncoordination.\n\n## Wire format\n\n![DCP frame layout + on-wire size comparison](docs\u002Fpaper\u002Ffigures\u002Fwire_format.png)\n\nA frame is a 6-byte fixed header + CBOR payload + an optional 16-byte\ntruncated HMAC-SHA256. Header fields:\n\n| field       | meaning                                                          |\n|-------------|------------------------------------------------------------------|\n| `ver`       | 1 in v0.3                                                        |\n| `kind`      | 0x01 call · 0x02 reply · 0x03 event · 0x04 error · 0x81 dry-run |\n| `seq`       | client-chosen, echoed in reply                                   |\n| `intent_id` | CRC-16\u002FCCITT of intent name                                      |\n| `cbor`      | CBOR map: params \u002F return \u002F event payload \u002F error                |\n\nReply status codes: `ok`, `denied`, `range`, `busy`, `unknown_intent`, `capability_required`.\n\nA typical `set_brightness(50)` call is 19 bytes on the wire; the MCP\nJSON-RPC equivalent is approximately 180 bytes. The full normative spec\nlives at [SPEC.md](SPEC.md).\n\n## Adding a feature\n\nSee [docs\u002FADDING_FEATURES.md](docs\u002FADDING_FEATURES.md) for the full\n5-step loop with a worked `blink(times, period)` example. The short\nversion: edit the manifest, add a C++ handler + binding, recompile,\nflash, restart the MCP server — the LLM picks up the new tool\nautomatically. The Bridge needs no code change.\n\n## Quickstart\n\n```bash\n# As a user — install from PyPI:\npip install \"pydcp[mcp,serial]\"            # or [mcp,serial,mqtt,ble] for all transports\ndcp inspect examples\u002Flamp_manifest.yaml    # parsed manifest summary\ndcp serve   examples\u002Flamp_manifest.yaml --simulator\n```\n\n```bash\n# As a contributor — editable install from source:\ngit clone https:\u002F\u002Fgithub.com\u002Fdevice-context-protocol\u002Fdcp.git\ncd dcp\npip install -e \".[mcp,serial,mqtt,ble,dev]\"\npytest                                     # all 88 tests\npython examples\u002Flamp_demo.py               # in-process bridge ↔ fake lamp\n```\n\nThe PyPI package is named `pydcp` (the bare `dcp` is squatted by an\nunrelated package). The import name is `dcp`. The protocol name is DCP.\n\n### Run as an MCP server\n\nThe reference Bridge ships an MCP server that exposes each DCP intent as an\nMCP tool. With ``--simulator`` it spins up an in-process fake device, so you\ncan demo with no hardware.\n\n```bash\ndcp serve examples\u002Flamp_manifest.yaml --simulator               # no hardware\ndcp serve examples\u002Flamp_manifest.yaml --serial COM3             # real ESP32 over UART\ndcp serve examples\u002Flamp_manifest.yaml --mqtt broker.lan:1883 \\  # MQTT\n            --mqtt-prefix dcp\u002Flamp-kitchen\ndcp serve examples\u002Flamp_manifest.yaml --ble AA:BB:CC:DD:EE:FF \\ # BLE\n            --ble-service 12345678-1234-5678-1234-567812345678\n```\n\n### Capability tokens (HMAC-SHA256)\n\nFor multi-tenant or scoped access, mint short-lived HMAC tokens and pass them\nto the Bridge:\n\n```bash\nexport DCP_SECRET=$(dcp token keygen)\ndcp token mint --caps lamp.write,lamp.read --ttl 3600\n# eyJjYXBzIjpb...sig\n```\n\nTokens are verified by the Bridge on every call. The device sees only\nalready-authorized frames. Devices themselves do **not** verify signatures\nin v0.2 — that requires on-device HMAC, which is on the roadmap.\n\nTo wire it into **Claude Desktop**, add this to your\n``claude_desktop_config.json``:\n\n```json\n{\n  \"mcpServers\": {\n    \"smart-lamp\": {\n      \"command\": \"dcp\",\n      \"args\": [\n        \"serve\",\n        \"C:\u002Fpath\u002Fto\u002Fprotocol\u002Fexamples\u002Flamp_manifest.yaml\",\n        \"--simulator\"\n      ]\n    }\n  }\n}\n```\n\nThen ask Claude *\"set the lamp to 60% brightness\"*. The call flow:\n\n```\nClaude ─MCP─▶ dcp serve ─Bridge─▶ Loopback ─DCP wire─▶ GenericSimulator\n```\n\nFor production use, replace ``GenericSimulator`` with a real transport\n(UART \u002F MQTT \u002F BLE — coming next).\n\n## What's *not* in v0.3 (intentional)\n\n- Multi-device atomic transactions\n- Firmware OTA\n- Mesh routing (use Thread \u002F Zigbee underneath if you need it)\n- LLM-side authentication (delegated to the MCP host's session model)\n- Native CAN FD frames (ESP32-S3 TWAI is classic CAN; v0.4 ESP32-P4\n  port enables true CAN FD)\n\n## Cite\n\nIf you use DCP in academic work, please cite the arXiv preprint:\n\n```bibtex\n@misc{yang2026dcp,\n  title        = {Device Context Protocol: A Compact, Safety-First Architecture\n                  for LLM-Driven Control of Constrained Devices},\n  author       = {Yang, Dongxu},\n  year         = {2026},\n  eprint       = {2605.26159},\n  archivePrefix= {arXiv},\n  primaryClass = {cs.NI},\n  url          = {https:\u002F\u002Farxiv.org\u002Fabs\u002F2605.26159},\n}\n```\n\nA machine-readable [`CITATION.cff`](CITATION.cff) is also provided — GitHub\nrenders a \"Cite this repository\" button in the sidebar.\n\n## License\n\nMIT.\n\n## Roadmap\n\n- [x] Wire format + manifest parser\n- [x] Reference Python Bridge with loopback transport\n- [x] Lamp example\n- [x] MCP server wrapper + CLI (`dcp serve`)\n- [x] Generic in-process device simulator\n- [x] UART transport (COBS framing + CRC-16)\n- [x] ESP32 reference firmware (Arduino-compatible C++)\n- [x] Design rationale ([docs\u002FRATIONALE.md](docs\u002FRATIONALE.md))\n- [x] CI (GitHub Actions, Linux + Windows, py 3.11–3.13)\n- [x] MQTT transport\n- [x] HMAC-SHA256 capability tokens (Bridge-side enforcement)\n- [x] Manifest compiler: `dcp codegen` (YAML → C header)\n- [x] Compile-time `DCP_ID(name)` macro in firmware\n- [x] BLE GATT transport (bleak)\n- [x] Release prep: CONTRIBUTING \u002F CHANGELOG \u002F CoC \u002F SECURITY \u002F issue templates\n- [x] On-device HMAC verification (per-frame signatures, ESP32 firmware)\n- [x] ESP32 BLE peripheral example (NimBLE-Arduino)\n- [x] Conformance test suite (golden frames, language-neutral YAML)\n- [x] Codegen `--stubs`: emits handler signatures + binding table\n- [x] Quickstart video script ([docs\u002FQUICKSTART_VIDEO.md](docs\u002FQUICKSTART_VIDEO.md))\n- [x] Real-hardware validation on two boards (ESP32-WROOM-32 over\n  CH340, ESP32-S3 \u002F T-Panel over native USB), 13\u002F13 round-trips each\n- [x] Cross-compile clean on ESP32 RISC-V family (C3, C6, H2, P4) and ESP8266\n- [x] Public repo at `device-context-protocol\u002Fdcp` (v0.3.0 released)\n- [x] PyPI release (`pip install pydcp`, latest v0.3.1)\n- [x] LLM-driven hallucination-rejection benchmark: 675 tool calls\n  across 5 LLMs \u002F 4 vendors, prompt-injection category instantiated\n  from AgentDojo's attack templates. DCP catches 100% of capability-\n  escalation and 78% of prompt-injection attempts vs 0–1% for MCP\u002F\n  IoT-MCP. See `tools\u002Fgen_llm_corpus.py` + `tools\u002Fbench_hallucination_empirical.py`.\n- [x] DCP vs IoT-MCP wire-latency A\u002FB on identical ESP32-S3 hardware:\n  15.60 ms vs 15.59 ms median, within 5 µs. See\n  `firmware\u002Fesp32\u002Fexamples\u002Fiotmcp_echo\u002F` + `tools\u002Fbench_latency_iotmcp.py`.\n- [x] arXiv preprint published: [arXiv:2605.26159](https:\u002F\u002Farxiv.org\u002Fabs\u002F2605.26159)\n  (v0.3.1). Source bundle and rendered PDF also mirrored on the v0.3.1\n  [release page](https:\u002F\u002Fgithub.com\u002Fdevice-context-protocol\u002Fdcp\u002Freleases\u002Ftag\u002Fv0.3.1).\n- [ ] T-Panel S3 + CAN bus demo (firmware ready, awaiting hardware)\n- [ ] ESP32-P4 port for native CAN FD\n- [ ] Multi-MCU footprint matrix (nRF52840, Cortex-M0+, RP2040)\n","Device Context Protocol (DCP) 是一个旨在将大型语言模型（LLM）代理安全地连接到物理设备的协议。它支持低于50字节的数据帧，针对ESP32等微控制器进行了优化，仅需约28KB闪存和小于1KB的RAM。DCP的核心功能包括意图级、传输无关性和能力范围控制，通过CBOR编码实现紧凑的线格式，并且设计上确保了安全性，主要通过桥接器来执行安全检查。适用于需要低成本、低功耗但又要求高安全性的物联网项目或任何希望利用LLM增强硬件互动性的场景中。作为Model Context Protocol (MCP)的补充，DCP能够无缝集成现有的MCP主机环境，无需额外配置即可工作。","2026-06-11 04:02:53","CREATED_QUERY"]