[{"element_type":"markdown","content":"\u003cp\u003e\u003cem\u003eA tutorial on a full AI agent workflow with CircuitPython Online IDE\u003c/em\u003e\u003c/p\u003e\n","metadata":{"markdown":"*A tutorial on a full AI agent workflow with CircuitPython Online IDE*"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/521/original/image-10.png?1783572605","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003e\u003cem\u003eDisclosure: The author of this post is the developer of CircuitPython Online IDE.\u003c/em\u003e\u003c/p\u003e\n\n\u003ch2\u003eBackground: Current State of AI Agent workflow for CircuitPython\u003c/h2\u003e\n\n\u003cp\u003eThe trend of AI-assisted coding is already affecting how we code for microcontrollers. \u003ca href=\"https://medium.com/@gene.arnold/%EF%B8%8F-building-a-simon-says-game-with-chatgpt-and-a-raspberry-pi-pico-1806f3314e8b\"\u003eIt is easy to ask LLM (Large Language Model) chatbots questions about CircuitPython and copy the code snippets to the microcontroller.\u003c/a\u003e And if there are any errors, we naturally paste the error message from the REPL back to the chatbot. \u003ca href=\"https://adafruit-playground.com/u/dexter_starboard/pages/circuitpython-and-chatgpt-code-interpreter\"\u003eSome chat environments went one step further and can interpret CircuitPython code\u003c/a\u003e, but they are still blind to real hardware such as sensors and motors.\u003c/p\u003e\n\n\u003cp\u003eAI coding \u003cstrong\u003eagents\u003c/strong\u003e, on the other hand, have changed how software gets written. As CircuitPython lead developer Scott Shawcroft put it in his \u003ca href=\"https://blog.adafruit.com/2026/01/14/scotts-circuitpython2026\"\u003e#CircuitPython2026 post\u003c/a\u003e, LLMs used by a client-side agent that \"can run commands and relay back the result in a loop\" are game changing. He then envisioned the upcoming trend for the CircuitPython workflow: \"we need to create the 'agentic' feedback loop for best results. We let the LLM auto-load code and give it the serial output back. We should also give it context about recent CircuitPython changes and API references so it can correct its knowledge.\"\u003c/p\u003e\n\n\u003cp\u003eThe \u003cstrong\u003efull agent workflow\u003c/strong\u003e Scott described isn't new. Experts have been giving agents real hardware access for a while (\u003ca href=\"https://www.reddit.com/r/circuitpython/comments/1ollo56/comment/o1pzbz0/\"\u003eohararp-g's Reddit post\u003c/a\u003e is one example), typically through the Model Context Protocol (MCP). But that power comes with setup work: installing and configuring MCP servers for code, the REPL, libraries, and more. That's a fine trade for a professional dev environment. It's a steep ask for learners and hobbyists.\u003c/p\u003e\n\n\u003cp\u003eWhat people have been asking for is an easy way to get access to the coding agent for CircuitPython in seconds. That's the gap closed by the AI Agent Bridge feature of CircuitPython Online IDE (\u003ca href=\"https://circuitpy.dev\"\u003ehttps://circuitpy.dev\u003c/a\u003e).\u003c/p\u003e\n\n\u003ch2\u003eWhat is AI Agent Bridge?\u003c/h2\u003e\n\n\u003cp\u003eTo be clear, the IDE itself doesn't contain any AI. Instead, it exposes a set of tools, implemented as JavaScript functions, that an AI agent can call. These functions serve as the bridge between the IDE and the agent.\u003c/p\u003e\n\n\u003cp\u003eThis means the agent also needs to live inside the browser. The agent we're going to use is Claude in Chrome.\u003c/p\u003e\n\n\u003ch2\u003ePrerequisites\u003c/h2\u003e\n\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eGoogle Chrome\u003c/strong\u003e with the \u003ca href=\"https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn\"\u003eClaude in Chrome extension\u003c/a\u003e installed.\u003c/li\u003e\n\u003cli\u003eA \u003cstrong\u003eClaude subscription\u003c/strong\u003e that includes Claude in Chrome.\u003c/li\u003e\n\u003cli\u003eA CircuitPython-compatible board.\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003eNote that everything runs in the browser, so there is nothing to install or configure on your local computer.\u003c/p\u003e\n\n\u003ch2\u003eExample 1: Night Light on Breadboard\u003c/h2\u003e\n\n\u003cp\u003eIn this example, I'm going to show how to use the AI Agent Bridge feature from start to finish to build a simple night light project.\u003c/p\u003e\n","metadata":{"markdown":"*Disclosure: The author of this post is the developer of CircuitPython Online IDE.*\n\n## Background: Current State of AI Agent workflow for CircuitPython\n\nThe trend of AI-assisted coding is already affecting how we code for microcontrollers. [It is easy to ask LLM (Large Language Model) chatbots questions about CircuitPython and copy the code snippets to the microcontroller.](https://medium.com/@gene.arnold/%EF%B8%8F-building-a-simon-says-game-with-chatgpt-and-a-raspberry-pi-pico-1806f3314e8b) And if there are any errors, we naturally paste the error message from the REPL back to the chatbot. [Some chat environments went one step further and can interpret CircuitPython code](https://adafruit-playground.com/u/dexter_starboard/pages/circuitpython-and-chatgpt-code-interpreter), but they are still blind to real hardware such as sensors and motors.\n\nAI coding **agents**, on the other hand, have changed how software gets written. As CircuitPython lead developer Scott Shawcroft put it in his [#CircuitPython2026 post](https://blog.adafruit.com/2026/01/14/scotts-circuitpython2026), LLMs used by a client-side agent that \"can run commands and relay back the result in a loop\" are game changing. He then envisioned the upcoming trend for the CircuitPython workflow: \"we need to create the 'agentic' feedback loop for best results. We let the LLM auto-load code and give it the serial output back. We should also give it context about recent CircuitPython changes and API references so it can correct its knowledge.\"\n\nThe **full agent workflow** Scott described isn't new. Experts have been giving agents real hardware access for a while ([ohararp-g's Reddit post](https://www.reddit.com/r/circuitpython/comments/1ollo56/comment/o1pzbz0/) is one example), typically through the Model Context Protocol (MCP). But that power comes with setup work: installing and configuring MCP servers for code, the REPL, libraries, and more. That's a fine trade for a professional dev environment. It's a steep ask for learners and hobbyists.\n\nWhat people have been asking for is an easy way to get access to the coding agent for CircuitPython in seconds. That's the gap closed by the AI Agent Bridge feature of CircuitPython Online IDE (https://circuitpy.dev).\n\n## What is AI Agent Bridge?\n\nTo be clear, the IDE itself doesn't contain any AI. Instead, it exposes a set of tools, implemented as JavaScript functions, that an AI agent can call. These functions serve as the bridge between the IDE and the agent.\n\nThis means the agent also needs to live inside the browser. The agent we're going to use is Claude in Chrome.\n\n## Prerequisites\n\n- **Google Chrome** with the [Claude in Chrome extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) installed.\n- A **Claude subscription** that includes Claude in Chrome.\n- A CircuitPython-compatible board.\n\nNote that everything runs in the browser, so there is nothing to install or configure on your local computer.\n\n## Example 1: Night Light on Breadboard\n\nIn this example, I'm going to show how to use the AI Agent Bridge feature from start to finish to build a simple night light project.\n"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/522/original/image-9.png?1783572641","metadata":{}},{"element_type":"markdown","content":"\u003ch3\u003eStep 1: Set Up the IDE\u003c/h3\u003e\n\n\u003cp\u003eWith the Claude in Chrome extension already installed, we first open \u003ca href=\"https://circuitpy.dev\"\u003ehttps://circuitpy.dev\u003c/a\u003e in Chrome. This loads the CircuitPython Online IDE as a website.\u003c/p\u003e\n\n\u003cp\u003eNext, we follow the instructions in the navigation tab. The first step is to connect the CircuitPy drive, which is the microcontroller's mass storage. The second step is to connect the serial console, after which you will see a greeting message. These are the same setup steps every time you use the Online IDE.\u003c/p\u003e\n","metadata":{"markdown":"### Step 1: Set Up the IDE\n\nWith the Claude in Chrome extension already installed, we first open https://circuitpy.dev in Chrome. This loads the CircuitPython Online IDE as a website.\n\nNext, we follow the instructions in the navigation tab. The first step is to connect the CircuitPy drive, which is the microcontroller's mass storage. The second step is to connect the serial console, after which you will see a greeting message. These are the same setup steps every time you use the Online IDE."}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/523/original/image.png?1783572674","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eTo use the AI Agent Bridge, open Tools -\u0026gt; AI Agent Bridge and click the button to turn it on. An indicator will appear in the bottom right corner showing that the Agent Bridge is on.\u003c/p\u003e\n\n\u003cp\u003eThe final step is to open the Claude in Chrome extension, which brings up the chat interface on the right side.\u003c/p\u003e\n","metadata":{"markdown":"To use the AI Agent Bridge, open Tools -\u0026gt; AI Agent Bridge and click the button to turn it on. An indicator will appear in the bottom right corner showing that the Agent Bridge is on.\n\nThe final step is to open the Claude in Chrome extension, which brings up the chat interface on the right side."}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/524/original/image-2.png?1783572696","metadata":{}},{"element_type":"markdown","content":"\u003ch3\u003eStep 2: Document the pin connections\u003c/h3\u003e\n\n\u003cp\u003eClaude in Chrome is a general-purpose agent, so it doesn't know what hardware we are working with. We need to tell it how the circuit is connected. Since the circuit rarely changes, the best place to document it is a markdown file stored on the microcontroller itself.\u003c/p\u003e\n\n\u003cp\u003eIn this project, the breadboard holds a microcontroller, a photoresistor, and an LED.\u003c/p\u003e\n\n\u003cp\u003eLet's create a file called \u003ccode class=\"inline\"\u003eCIRCUIT.md\u003c/code\u003e in the board's root:\u003c/p\u003e\n\u003ccode class=\"markdown\"\u003e\u003cpre\u003eHere is the circuit connection:\n\nConnection involves a Photoresistor:\n1. Ground to photoresistor\n2. Photoresistor to a reference resistor\n3. Reference resistor to VCC\n4. The shared node between the photoresistor and the reference resistor is connected to the microcontroller at D0.\n\nConnection involves an LED:\n1. From the microcontroller, it is connected to the LED on microcontroller pin D7.\n2. After the LED, there is a resistor, which is then connected to ground.\n\u003c/pre\u003e\u003c/code\u003e","metadata":{"markdown":"### Step 2: Document the pin connections\n\nClaude in Chrome is a general-purpose agent, so it doesn't know what hardware we are working with. We need to tell it how the circuit is connected. Since the circuit rarely changes, the best place to document it is a markdown file stored on the microcontroller itself.\n\nIn this project, the breadboard holds a microcontroller, a photoresistor, and an LED.\n\nLet's create a file called `CIRCUIT.md` in the board's root:\n\n```markdown\nHere is the circuit connection:\n\nConnection involves a Photoresistor:\n1. Ground to photoresistor\n2. Photoresistor to a reference resistor\n3. Reference resistor to VCC\n4. The shared node between the photoresistor and the reference resistor is connected to the microcontroller at D0.\n\nConnection involves an LED:\n1. From the microcontroller, it is connected to the LED on microcontroller pin D7.\n2. After the LED, there is a resistor, which is then connected to ground.\n```"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/525/original/image-1.png?1783572718","metadata":{}},{"element_type":"markdown","content":"\u003ch3\u003eStep 3: Copy and run the system prompt\u003c/h3\u003e\n\n\u003cp\u003eBesides the circuit, the agent also needs to know what kind of project we are working on (CircuitPython): how to call the IDE's tools, to check its connection first, to experiment in the REPL before writing files, to install libraries from the board's CircuitPython bundle, and to read the plotting guide before drawing plots. This information is the same every time you work with the AI Agent Bridge, so I have already written a system prompt for you to copy.\u003c/p\u003e\n\n\u003cp\u003eClick \u003cstrong\u003eCopy System Prompt\u003c/strong\u003e in the Agent Bridge tab, and paste it into the Claude side panel in Chrome. You only do this once per conversation.\u003c/p\u003e\n\n\u003cp\u003eAfter it reads this system prompt, the agent will confirm your setup and ask what you'd like to build.\u003c/p\u003e\n","metadata":{"markdown":"### Step 3: Copy and run the system prompt\n\nBesides the circuit, the agent also needs to know what kind of project we are working on (CircuitPython): how to call the IDE's tools, to check its connection first, to experiment in the REPL before writing files, to install libraries from the board's CircuitPython bundle, and to read the plotting guide before drawing plots. This information is the same every time you work with the AI Agent Bridge, so I have already written a system prompt for you to copy.\n\nClick **Copy System Prompt** in the Agent Bridge tab, and paste it into the Claude side panel in Chrome. You only do this once per conversation.\n\nAfter it reads this system prompt, the agent will confirm your setup and ask what you'd like to build.\n"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/527/original/image-3.png?1783572816","metadata":{}},{"element_type":"markdown","content":"\u003ch3\u003eStep 4: Build the night light\u003c/h3\u003e\n\n\u003cp\u003eTime to build something real: \u003cstrong\u003ea night light\u003c/strong\u003e. \u003c/p\u003e\n\n\u003cp\u003ePrompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eBuild a nightlight that will turn on the LED when the photoresistor is in the dark. Turn it off when it is bright.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003eThe agent then started running experiments in the REPL. It tested the LED connection and checked what the photoresistor reading looks like at normal room brightness.\u003c/p\u003e\n\u003ccode class=\"text\"\u003e\u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"import board, analogio, digitalio\\nprint(hasattr(board,'D0'), hasattr(board,'D7'))\"\"\")\nTrue True\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"sensor = analogio.AnalogIn(board.D0)\\nled = digitalio.DigitalInOut(board.D7)\\nled.direction = digitalio.Direction.OUTPUT\\nprint('setup done')\"\"\")\nsetup done\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"led.value = True\\nprint('LED ON', sensor.value)\"\"\")\nLED ON 54989\n\u003c/pre\u003e\u003c/code\u003e\n\u003cp\u003eThen it asked me to cover the photoresistor so it could measure the reading in the dark.\u003c/p\u003e\n","metadata":{"markdown":"### Step 4: Build the night light\n\nTime to build something real: **a night light**. \n\nPrompt:\n\u0026gt; Build a nightlight that will turn on the LED when the photoresistor is in the dark. Turn it off when it is bright.\n\nThe agent then started running experiments in the REPL. It tested the LED connection and checked what the photoresistor reading looks like at normal room brightness.\n\n```text\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"import board, analogio, digitalio\\nprint(hasattr(board,'D0'), hasattr(board,'D7'))\"\"\")\nTrue True\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"sensor = analogio.AnalogIn(board.D0)\\nled = digitalio.DigitalInOut(board.D7)\\nled.direction = digitalio.Direction.OUTPUT\\nprint('setup done')\"\"\")\nsetup done\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"led.value = True\\nprint('LED ON', sensor.value)\"\"\")\nLED ON 54989\n```\n\nThen it asked me to cover the photoresistor so it could measure the reading in the dark.\n"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/528/original/image-4.png?1783572838","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eI covered the photoresistor and gave it another prompt.\u003c/p\u003e\n\n\u003cp\u003eFollow-up prompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eThe photoresistor is covered. Can you read it again?\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003eIt ran the experiment again:\u003c/p\u003e\n\u003ccode class=\"\"\u003e\u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"print('dark reading', sensor.value)\"\"\")\ndark reading 62436\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"led.value = False\\nprint('led off')\"\"\")\nled off\n\u003c/pre\u003e\u003c/code\u003e\n\u003cp\u003eThen it asked me to help gather more data so it could set the thresholds.\u003c/p\u003e\n","metadata":{"markdown":"I covered the photoresistor and gave it another prompt.\n\nFollow-up prompt:\n\u0026gt; The photoresistor is covered. Can you read it again?\n\nIt ran the experiment again:\n\n```\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"print('dark reading', sensor.value)\"\"\")\ndark reading 62436\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"led.value = False\\nprint('led off')\"\"\")\nled off\n```\n\nThen it asked me to help gather more data so it could set the thresholds."}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/529/original/image-5.png?1783572862","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eFollow-up prompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eIt is uncovered now.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ccode class=\"\"\u003e\u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"for i in range(5):\\n    print('bright reading', sensor.value)\"\"\")\nbright reading 50859\nbright reading 51037\nbright reading 50720\nbright reading 50164\nbright reading 49886\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"import time\\nDARK_ON = 58000\\nBRIGHT_OFF = 55000\\nstate = False\\nfor i in range(20):\\n    v = sensor.value\\n    if v \u0026gt; DARK_ON:\\n        state = True\\n    elif v \u0026lt; BRIGHT_OFF:\\n        state = False\\n    led.value = state\\n    print(v, state)\\n    time.sleep(0.5)\"\"\")\n50739 False\n51276 False\n50819 False\n50064 False\n49866 False\n49687 False\n50303 False\n51018 False\n50938 False\n50958 False\n50183 False\n49786 False\n49866 False\n50461 False\n51315 False\n62258 True\n62337 True\n49032 False\n48634 False\n48773 False\n\u0026gt;\u0026gt;\u0026gt; \nsoft reboot\n\nAuto-reload is on. Simply save files over USB to run them or enter REPL to disable.\ncode.py output:\n\u003c/pre\u003e\u003c/code\u003e\n\u003cp\u003eAfter gathering enough data points, it confidently wrote code.py and ran the final code. It then asked me to confirm that the code was working.\u003c/p\u003e\n","metadata":{"markdown":"Follow-up prompt:\n\u0026gt; It is uncovered now.\n\n```\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"for i in range(5):\\n    print('bright reading', sensor.value)\"\"\")\nbright reading 50859\nbright reading 51037\nbright reading 50720\nbright reading 50164\nbright reading 49886\n\u0026gt;\u0026gt;\u0026gt; exec(\"\"\"import time\\nDARK_ON = 58000\\nBRIGHT_OFF = 55000\\nstate = False\\nfor i in range(20):\\n    v = sensor.value\\n    if v \u0026gt; DARK_ON:\\n        state = True\\n    elif v \u0026lt; BRIGHT_OFF:\\n        state = False\\n    led.value = state\\n    print(v, state)\\n    time.sleep(0.5)\"\"\")\n50739 False\n51276 False\n50819 False\n50064 False\n49866 False\n49687 False\n50303 False\n51018 False\n50938 False\n50958 False\n50183 False\n49786 False\n49866 False\n50461 False\n51315 False\n62258 True\n62337 True\n49032 False\n48634 False\n48773 False\n\u0026gt;\u0026gt;\u0026gt; \nsoft reboot\n\nAuto-reload is on. Simply save files over USB to run them or enter REPL to disable.\ncode.py output:\n```\n\nAfter gathering enough data points, it confidently wrote code.py and ran the final code. It then asked me to confirm that the code was working."}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/530/original/image-6.png?1783572879","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eAs tested, the night light works as expected. When my hand covers the photoresistor, the LED turns on; when I remove my hand, it turns off.\nReading the code it wrote, I found it used hysteresis (two separate thresholds) to keep the LED from flickering on and off near the boundary, which is smart.\u003c/p\u003e\n\n\u003ch3\u003eStep 5: The agent plots your data, right in the IDE\u003c/h3\u003e\n\n\u003cp\u003eFollow-up prompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eIt is working now, and I want you to make a plot out of the sensor data and the two thresholds. Only keep 100 history data in this plot.\u003c/p\u003e\n\u003c/blockquote\u003e\n","metadata":{"markdown":"As tested, the night light works as expected. When my hand covers the photoresistor, the LED turns on; when I remove my hand, it turns off.\nReading the code it wrote, I found it used hysteresis (two separate thresholds) to keep the LED from flickering on and off near the boundary, which is smart.\n\n### Step 5: The agent plots your data, right in the IDE\n\nFollow-up prompt:\n\u0026gt; It is working now, and I want you to make a plot out of the sensor data and the two thresholds. Only keep 100 history data in this plot.\n"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/531/original/image-7.png?1783572901","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eThe agent read the IDE's plotting guide through the bridge, then updated the code to print the sensor readings in the IDE's plot format. The IDE's built-in serial plotter picked it up immediately, showing a live, scrolling graph of the room's brightness.\u003c/p\u003e\n\n\u003ch3\u003eConclusion\u003c/h3\u003e\n\n\u003cp\u003eThis first example confirms that the agent can:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003echeck the latest CircuitPython documentation\u003c/li\u003e\n\u003cli\u003erun experiments in the REPL\u003c/li\u003e\n\u003cli\u003ewrite CircuitPython code\u003c/li\u003e\n\u003cli\u003euse the IDE's tools, including the plotter\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003eExample 2: M5Stack CardPuter Calculator\u003c/h2\u003e\n\n\u003cp\u003eThe M5Stack CardPuter is a fun development board with a built-in keyboard and screen, so this time I didn't connect any external peripherals. The goal was to turn it into a pocket calculator using only what's on the board.\u003c/p\u003e\n\n\u003cp\u003eThis example is a harder test than it looks. Unlike Example 1, there was no \u003ccode class=\"inline\"\u003eCIRCUIT.md\u003c/code\u003e this time: I deliberately didn't tell the agent how the keyboard or the screen is connected, so it had to find the board's documentation on its own. On top of that, the screen doesn't work out of the box; it needs a display driver library that wasn't on the board yet.\u003c/p\u003e\n\n\u003cp\u003eI started from a blank project and built the whole thing with just two prompts:\u003c/p\u003e\n\n\u003cp\u003ePrompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eMake a calculator using the keyboard and screen on this board. The number keys are used for entering a number, and support plus, minus, multiply, and divide. Enter to submit.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003eFollow-up prompt:\u003c/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003eI want to support additional keys for the operations:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003eA for add\u003c/li\u003e\n\u003cli\u003eM for minus\u003c/li\u003e\n\u003cli\u003eX for multiply\u003c/li\u003e\n\u003cli\u003eD for divide\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\n\u003cp\u003eThe result is a fully functional calculator. Along the way, the agent looked up the CardPuter's documentation to learn how the onboard keyboard is wired, worked out how to capture keystrokes, picked the right display drivers (\u003ccode class=\"inline\"\u003eadafruit_display_text\u003c/code\u003e, \u003ccode class=\"inline\"\u003eadafruit_bitmap_font\u003c/code\u003e, \u003ccode class=\"inline\"\u003eadafruit_ticks\u003c/code\u003e), and installed them with the IDE's library management tool.\u003c/p\u003e\n","metadata":{"markdown":"The agent read the IDE's plotting guide through the bridge, then updated the code to print the sensor readings in the IDE's plot format. The IDE's built-in serial plotter picked it up immediately, showing a live, scrolling graph of the room's brightness.\n\n### Conclusion\n\nThis first example confirms that the agent can:\n- check the latest CircuitPython documentation\n- run experiments in the REPL\n- write CircuitPython code\n- use the IDE's tools, including the plotter\n\n## Example 2: M5Stack CardPuter Calculator\n\nThe M5Stack CardPuter is a fun development board with a built-in keyboard and screen, so this time I didn't connect any external peripherals. The goal was to turn it into a pocket calculator using only what's on the board.\n\nThis example is a harder test than it looks. Unlike Example 1, there was no `CIRCUIT.md` this time: I deliberately didn't tell the agent how the keyboard or the screen is connected, so it had to find the board's documentation on its own. On top of that, the screen doesn't work out of the box; it needs a display driver library that wasn't on the board yet.\n\nI started from a blank project and built the whole thing with just two prompts:\n\nPrompt:\n\u0026gt; Make a calculator using the keyboard and screen on this board. The number keys are used for entering a number, and support plus, minus, multiply, and divide. Enter to submit.\n\nFollow-up prompt:\n\u0026gt; I want to support additional keys for the operations:\n\u0026gt; - A for add\n\u0026gt; - M for minus\n\u0026gt; - X for multiply\n\u0026gt; - D for divide\n\nThe result is a fully functional calculator. Along the way, the agent looked up the CardPuter's documentation to learn how the onboard keyboard is wired, worked out how to capture keystrokes, picked the right display drivers (`adafruit_display_text`, `adafruit_bitmap_font`, `adafruit_ticks`), and installed them with the IDE's library management tool."}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/532/original/image-8.png?1783572949","metadata":{}},{"element_type":"markdown","content":"\u003cp\u003eThis example confirms that the agent can:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003echeck external documentation for a specific board to learn its peripheral connections\u003c/li\u003e\n\u003cli\u003einstall the latest versions of the necessary libraries using the IDE's library management tool\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003eYou can also try\u003c/h2\u003e\n\n\u003cp\u003eIn my personal projects, I have also used the agent for the following kinds of tasks, which you can use for inspiration:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003eExplain the code of a large existing CircuitPython project to me.\u003c/li\u003e\n\u003cli\u003eReview the code of an existing project, find issues, and fix them.\u003c/li\u003e\n\u003cli\u003eFix code issues caused by upgrading CircuitPython to a newer major version, along with all the library dependencies.\u003c/li\u003e\n\u003cli\u003eMake animations, not just plots, using the IDE's plot tool driven by changing sensor data.\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch2\u003eQ\u0026amp;A\u003c/h2\u003e\n\n\u003ch3\u003eWho is this for?\u003c/h3\u003e\n\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eBeginners\u003c/strong\u003e can treat the AI as a patient teacher. Ask it to explain every line it writes, ask \"why did that error happen,\" ask for a gentler version. It has your actual board and your actual output in front of it, so its explanations are grounded, not generic.\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eDIYers and makers\u003c/strong\u003e can finish the project without going deep into code. Describe the behavior you want; the agent handles pin setup, library installation, and debugging, and you verify the result on the bench.\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eExperts\u003c/strong\u003e get a fast lane for prototyping. Sketch an idea against real hardware in minutes. To be clear about the limits: Claude in Chrome is a generic agent that is good at coding and can handle small- to mid-scale projects well. For large-scale CircuitPython projects, a dedicated coding agent, like Claude Code, with a proper MCP setup is still a better workflow..\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch3\u003eHow is this different from copying code from a chatbot?\u003c/h3\u003e\n\n\u003cp\u003eA chatbot \u003cstrong\u003egives answers\u003c/strong\u003e; an agent \u003cstrong\u003edoes work\u003c/strong\u003e. With a chatbot, \u003cem\u003eyou\u003c/em\u003e are the LLM's hands: you paste code, run it, read the traceback, paste it back, repeat, and every round trip loses context. With the Agent Bridge, the agent runs the loop itself: it tests assumptions in the REPL, reads the real sensor values, sees the real error with full context, and fixes it.\u003c/p\u003e\n\n\u003ch3\u003eIs this safe?\u003c/h3\u003e\n\n\u003cp\u003eTwo layers, by design:\u003c/p\u003e\n\n\u003col\u003e\n\u003cli\u003e\u003cp\u003e\u003cstrong\u003eChrome's permission model guards the doors.\u003c/strong\u003e In the very first step of the IDE setup, we open the microcontroller's specific folder and connect to its specific serial port. The bridge passes only these to the agent, so they are the only things on your computer the agent can see. It never reaches the rest of your computer.\u003c/p\u003e\u003c/li\u003e\n\u003cli\u003e\u003cp\u003e\u003cstrong\u003eThe IDE's backup tool is your undo button.\u003c/strong\u003e Before an agent session, use the IDE's built-in backup to snapshot your board's files. If an experiment goes sideways, restore and try again. \u003c/p\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\n\u003ch3\u003eWhy Claude in Chrome?\u003c/h3\u003e\n\n\u003cp\u003eI evaluated AI agent Chrome extensions against the following criteria:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003ea first-party extension, for security and so there are no auth tokens to manage\u003c/li\u003e\n\u003cli\u003eable to run JavaScript commands on the website\u003c/li\u003e\n\u003cli\u003egood at programming\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cp\u003eAt the time of writing, Claude in Chrome is the only one that satisfies all three. If you find a third-party extension or AI browser that you trust, feel free to try it: it will work the same way.\u003c/p\u003e\n\n\u003cp\u003eCircuitPython Online IDE has no control over subscriptions; those go through the AI model providers.\u003c/p\u003e\n\n\u003ch2\u003eTry it out now\u003c/h2\u003e\n\n\u003cp\u003e\u003ca href=\"https://circuitpy.dev\"\u003eCircuitPython Online IDE\u003c/a\u003e is a powerful development tool for CircuitPython. In addition to the Agent Bridge feature, it has a lot of other powerful features such as Library Management and a Debugger. The IDE itself is completely free and open source. Check it out at CircuitPy.dev.\u003c/p\u003e\n\n\u003chr\u003e\n\n\u003cp\u003e\u003cem\u003eReferences: \u003ca href=\"https://medium.com/@gene.arnold/%EF%B8%8F-building-a-simon-says-game-with-chatgpt-and-a-raspberry-pi-pico-1806f3314e8b\"\u003eGene Arnold: Building a Simon Says Game with ChatGPT and a Raspberry Pi Pico\u003c/a\u003e · \u003ca href=\"https://adafruit-playground.com/u/dexter_starboard/pages/circuitpython-and-chatgpt-code-interpreter\"\u003eDexter Starboard: CircuitPython and ChatGPT Code Interpreter\u003c/a\u003e · \u003ca href=\"https://blog.adafruit.com/2026/01/14/scotts-circuitpython2026\"\u003eScott's #CircuitPython2026\u003c/a\u003e · \u003ca href=\"https://www.reddit.com/r/circuitpython/comments/1ollo56/comment/o1pzbz0/\"\u003eohararp-g on r/circuitpython: agents with hardware access over MCP\u003c/a\u003e\u003c/em\u003e\u003c/p\u003e\n","metadata":{"markdown":"This example confirms that the agent can:\n- check external documentation for a specific board to learn its peripheral connections\n- install the latest versions of the necessary libraries using the IDE's library management tool\n\n## You can also try\n\nIn my personal projects, I have also used the agent for the following kinds of tasks, which you can use for inspiration:\n- Explain the code of a large existing CircuitPython project to me.\n- Review the code of an existing project, find issues, and fix them.\n- Fix code issues caused by upgrading CircuitPython to a newer major version, along with all the library dependencies.\n- Make animations, not just plots, using the IDE's plot tool driven by changing sensor data.\n\n\n## Q\u0026amp;A\n\n### Who is this for?\n\n- **Beginners** can treat the AI as a patient teacher. Ask it to explain every line it writes, ask \"why did that error happen,\" ask for a gentler version. It has your actual board and your actual output in front of it, so its explanations are grounded, not generic.\n- **DIYers and makers** can finish the project without going deep into code. Describe the behavior you want; the agent handles pin setup, library installation, and debugging, and you verify the result on the bench.\n- **Experts** get a fast lane for prototyping. Sketch an idea against real hardware in minutes. To be clear about the limits: Claude in Chrome is a generic agent that is good at coding and can handle small- to mid-scale projects well. For large-scale CircuitPython projects, a dedicated coding agent, like Claude Code, with a proper MCP setup is still a better workflow..\n\n### How is this different from copying code from a chatbot?\n\n\nA chatbot **gives answers**; an agent **does work**. With a chatbot, *you* are the LLM's hands: you paste code, run it, read the traceback, paste it back, repeat, and every round trip loses context. With the Agent Bridge, the agent runs the loop itself: it tests assumptions in the REPL, reads the real sensor values, sees the real error with full context, and fixes it.\n\n### Is this safe?\n\nTwo layers, by design:\n\n1. **Chrome's permission model guards the doors.** In the very first step of the IDE setup, we open the microcontroller's specific folder and connect to its specific serial port. The bridge passes only these to the agent, so they are the only things on your computer the agent can see. It never reaches the rest of your computer.\n\n2. **The IDE's backup tool is your undo button.** Before an agent session, use the IDE's built-in backup to snapshot your board's files. If an experiment goes sideways, restore and try again. \n\n### Why Claude in Chrome?\n\nI evaluated AI agent Chrome extensions against the following criteria:\n- a first-party extension, for security and so there are no auth tokens to manage\n- able to run JavaScript commands on the website\n- good at programming\n\nAt the time of writing, Claude in Chrome is the only one that satisfies all three. If you find a third-party extension or AI browser that you trust, feel free to try it: it will work the same way.\n\nCircuitPython Online IDE has no control over subscriptions; those go through the AI model providers.\n\n## Try it out now\n\n[CircuitPython Online IDE](https://circuitpy.dev) is a powerful development tool for CircuitPython. In addition to the Agent Bridge feature, it has a lot of other powerful features such as Library Management and a Debugger. The IDE itself is completely free and open source. Check it out at CircuitPy.dev.\n\n---\n\n*References: [Gene Arnold: Building a Simon Says Game with ChatGPT and a Raspberry Pi Pico](https://medium.com/@gene.arnold/%EF%B8%8F-building-a-simon-says-game-with-chatgpt-and-a-raspberry-pi-pico-1806f3314e8b) · [Dexter Starboard: CircuitPython and ChatGPT Code Interpreter](https://adafruit-playground.com/u/dexter_starboard/pages/circuitpython-and-chatgpt-code-interpreter) · [Scott's #CircuitPython2026](https://blog.adafruit.com/2026/01/14/scotts-circuitpython2026) · [ohararp-g on r/circuitpython: agents with hardware access over MCP](https://www.reddit.com/r/circuitpython/comments/1ollo56/comment/o1pzbz0/)*\n"}}]