<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Iot on Daniel Michaels | Developer | Entrepreneur | Veteran</title><link>https://danielms.site/tags/iot/</link><description>Recent content in Iot on Daniel Michaels | Developer | Entrepreneur | Veteran</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 25 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://danielms.site/tags/iot/index.xml" rel="self" type="application/rss+xml"/><item><title>Amp + reMarkable</title><link>https://danielms.site/blog/remarkable-pdf-preview/</link><pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate><guid>https://danielms.site/blog/remarkable-pdf-preview/</guid><description>&lt;p&gt;I had a thought, what if I could read things AI creates offline and on my distraction free reMarkable tablet?&lt;/p&gt;&#10;&lt;p&gt;And, what if I could get Amp to send docs to reMarkable, I annotate or scribble on them and then Amp updates its own state based on that? We could collaboratively iterate.&lt;/p&gt;&#10;&lt;p&gt;Wouldn&amp;rsquo;t that be insanely useful when an LLM creates a PDF which is good but has some junk in it you don&amp;rsquo;t want and instead of a back and forth you just want to draw the changes. Move section from here to here. Use this style of alert box. Tweak the diagram like this.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;ve lost countless tokens explaining this stuff only to have it be not &lt;em&gt;quite&lt;/em&gt; right.&lt;/p&gt;&#10;&lt;p&gt;So, I just opened &lt;a href="https://ampcode.com/news/meet-puck"&gt;Puck&lt;/a&gt; and asked him; &amp;ldquo;is this feasible?&amp;rdquo;.&lt;/p&gt;&#10;&lt;p&gt;Ten minutes later with the help of &lt;a href="https://github.com/SamMorrowDrums/remarkable-mcp"&gt;remarkable-mcp&lt;/a&gt;we had a prototype.&lt;/p&gt;&#10;&lt;h3 id="an-example"&gt;An example&lt;/h3&gt;&#10;&lt;p&gt;This is a draft to try the &lt;code&gt;pdf&lt;/code&gt; shortcode with the real guide of how I got this all to work.&lt;/p&gt;&#10;&lt;figure class="pdf-viewer"&gt;&#10; &lt;div class="pdf-viewer-track" tabindex="0" role="region"&#10; aria-label="Amp &amp;#43; reMarkable: Review Documents by Hand: 4 pages. Use the arrow keys or swipe to change page."&gt;&#10; &lt;img src="https://danielms.site/images/amp-remarkable-guide-1.webp" width="1600" height="2265"&#10; alt="Page 1 of 4 of Amp &amp;#43; reMarkable: Review Documents by Hand"&#10; loading="eager" decoding="async"&gt;&#10; &lt;img src="https://danielms.site/images/amp-remarkable-guide-2.webp" width="1600" height="2265"&#10; alt="Page 2 of 4 of Amp &amp;#43; reMarkable: Review Documents by Hand"&#10; loading="lazy" decoding="async"&gt;&#10; &lt;img src="https://danielms.site/images/amp-remarkable-guide-3.webp" width="1600" height="2265"&#10; alt="Page 3 of 4 of Amp &amp;#43; reMarkable: Review Documents by Hand"&#10; loading="lazy" decoding="async"&gt;&#10; &lt;img src="https://danielms.site/images/amp-remarkable-guide-4.webp" width="1600" height="2265"&#10; alt="Page 4 of 4 of Amp &amp;#43; reMarkable: Review Documents by Hand"&#10; loading="lazy" decoding="async"&gt;&#10; &lt;/div&gt;&#10; &lt;div class="pdf-viewer-toolbar"&gt;&#10; &lt;button type="button" data-action="prev" aria-label="Previous page" disabled&gt;&lt;i class="fas fa-chevron-left" aria-hidden="true"&gt;&lt;/i&gt;&lt;/button&gt;&#10; &lt;span class="pdf-viewer-count" aria-live="polite"&gt;Page &lt;span data-page-num&gt;1&lt;/span&gt; of 4&lt;/span&gt;&#10; &lt;button type="button" data-action="next" aria-label="Next page"&gt;&lt;i class="fas fa-chevron-right" aria-hidden="true"&gt;&lt;/i&gt;&lt;/button&gt;&#10; &lt;a class="pdf-viewer-open" href="https://danielms.site/images/amp-remarkable-guide.pdf" target="_blank" rel="noopener"&gt;Open PDF&lt;/a&gt;&#10; &lt;/div&gt;&#10; &lt;figcaption&gt;Amp &amp;#43; reMarkable: Review Documents by Hand&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h3 id="details"&gt;Details&lt;/h3&gt;&#10;&lt;p&gt;This is made up of three parts:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://ampcode.com"&gt;Amp&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;a &lt;a href="#skill"&gt;remarkable&lt;/a&gt; skill&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/SamMorrowDrums/remarkable-mcp"&gt;remarkable-mcp&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;I initially used this on my macbook runner but have now migrated to a cloud &lt;a href="https://ampcode.com/what-are-orbs"&gt;Orb&lt;/a&gt; so I can do this from anywhere - even when my macbook is in my backpack.&lt;/p&gt;&#10;&lt;p&gt;The rough idea is:&lt;/p&gt;&#10;&lt;div class="mermaid"&gt;&#10;flowchart LR&#10; source["Markdown draft"] --&gt; cloud["PDF in reMarkable cloud"]&#10; cloud --&gt; tablet["Read and annotate offline on tablet"]&#10; tablet --&gt;|"Close document and sync online"| notes["Synced handwritten notes"]&#10; notes --&gt; review["Read back and agree edits in Amp"]&#10; review --&gt; version["New version; preserve prior rounds"]&#10; version --&gt; cloud&#10;&lt;/div&gt;&#10;&#10;&lt;p&gt;For full setup details the PDF above is an authorative source.&lt;/p&gt;&#10;&lt;p&gt;But my main takeaway from this in the age of AI is - just ask. Literally, just ask AI if you/it can do something. Often times it can and I find that so liberating.&lt;/p&gt;&#10;&lt;h3 id="skill"&gt;Skill&lt;/h3&gt;&#10;&lt;p&gt;Just tell your AI to read the PDF and setup the skill. The days of telling you how to set this up manually are over!&lt;/p&gt;&#10;&#10;&lt;details&gt;&#10;&#9;&lt;summary&gt;Details&lt;/summary&gt;&#10;&#9;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;remarkable&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Sends PDFs or Markdown to Daniel&amp;#39;s reMarkable tablet and reads his handwritten annotations back, so a document can go through review rounds. Use when the user asks to send, upload, or push something to the reMarkable, to read or apply what they wrote on it, or to do another review round. Works in orbs and on local machines.&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# reMarkable review loop&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This skill starts the reMarkable MCP server (&lt;span class="sb"&gt;`uvx remarkable-mcp`&lt;/span&gt;, cloud mode) from &lt;span class="sb"&gt;`mcp.json`&lt;/span&gt;. The server reads its token from the &lt;span class="sb"&gt;`REMARKABLE_TOKEN`&lt;/span&gt; environment variable. Orbs get it from Daniel&amp;#39;s personal Amp secrets. On the MacBook, the server reads &lt;span class="sb"&gt;`~/.rmapi`&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 1. Check the connection&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; Run &lt;span class="sb"&gt;`tool_search(&amp;#34;remarkable&amp;#34;)`&lt;/span&gt;. If it finds no functions, run &lt;span class="sb"&gt;`reload_mcp`&lt;/span&gt; once and search again. The search can leave out some functions, such as &lt;span class="sb"&gt;`remarkable_upload`&lt;/span&gt;. Import them anyway, and use &lt;span class="sb"&gt;`tool_describe(&amp;#34;remarkable.remarkable_upload&amp;#34;)`&lt;/span&gt; for their parameters.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; Call &lt;span class="sb"&gt;`remarkable_status()`&lt;/span&gt; through &lt;span class="sb"&gt;`code_exec`&lt;/span&gt;. It must show &lt;span class="sb"&gt;`authenticated: true`&lt;/span&gt; and &lt;span class="sb"&gt;`transport: &amp;#34;cloud&amp;#34;`&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;If it fails:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`uvx`&lt;/span&gt; not found: install uv with &lt;span class="sb"&gt;`curl -LsSf https://astral.sh/uv/install.sh | sh`&lt;/span&gt;, then run &lt;span class="sb"&gt;`reload_mcp`&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; &amp;#34;No reMarkable token found&amp;#34;: the orb has no &lt;span class="sb"&gt;`REMARKABLE_TOKEN`&lt;/span&gt;. Tell the user to check the personal secret in Amp settings. Do not ask for the token in the thread.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 2. Folder&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Upload everything to the top-level folder &lt;span class="sb"&gt;`/Amp Uploads`&lt;/span&gt;. The user sorts the documents from there.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Use another folder only when the user names it. Do not create folders.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; If &lt;span class="sb"&gt;`/Amp Uploads`&lt;/span&gt; does not exist, create it once with &lt;span class="sb"&gt;`remarkable_mkdir({ folder_name: &amp;#34;Amp Uploads&amp;#34;, parent: &amp;#34;/&amp;#34; })`&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 3. Upload&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; PDF: &lt;span class="sb"&gt;`remarkable_upload({ file_path, parent_folder, document_name })`&lt;/span&gt;. &lt;span class="sb"&gt;`file_path`&lt;/span&gt; is an absolute path in this workspace.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Markdown: &lt;span class="sb"&gt;`remarkable_markdown_to_pdf({ markdown, document_name, parent_folder })`&lt;/span&gt;. Use this when you do not already have a PDF.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; To make a PDF from HTML in an orb, use headless Chrome: &lt;span class="sb"&gt;`--headless --print-to-pdf=&amp;lt;out.pdf&amp;gt; &amp;lt;file.html&amp;gt;`&lt;/span&gt;. Python PDF libraries such as reportlab are usually not installed.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Name the first version &lt;span class="sb"&gt;`&amp;lt;Title&amp;gt;`&lt;/span&gt;. Name each new round &lt;span class="sb"&gt;`&amp;lt;Title&amp;gt; v2`&lt;/span&gt;, &lt;span class="sb"&gt;`&amp;lt;Title&amp;gt; v3`&lt;/span&gt;, and so on. Do not replace the earlier version. It keeps the user&amp;#39;s annotations.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 4. Read annotations&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Ink syncs to the cloud only after the user closes the document on the tablet and the tablet is online. If you see no ink, tell the user to close the document and wait a few seconds.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Do not use &lt;span class="sb"&gt;`modified`&lt;/span&gt; times to find changes. The tablet clock can differ from the cloud clock. Render the pages and look.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`remarkable_image.raw({ document, page })`&lt;/span&gt; returns the PDF page with the ink on it. Pass the result to &lt;span class="sb"&gt;`content(r.content)`&lt;/span&gt; to see the image, then read the handwriting yourself. You do not need OCR.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`remarkable_read({ document })`&lt;/span&gt; gives typed text and highlights. It does not give handwriting.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Read every page. For a long document, ask the user which pages have notes.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Before you change the source, tell the user what you read on each page. Ask about writing you cannot read.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 5. Writes and errors&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Do one write (upload, move, rename) per &lt;span class="sb"&gt;`code_exec`&lt;/span&gt; call when you can.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; If the executor disconnects during a write, browse the folders to see what happened before you retry. Do not repeat a write blindly.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; This skill leaves &lt;span class="sb"&gt;`remarkable_delete`&lt;/span&gt; out on purpose with &lt;span class="sb"&gt;`includeTools`&lt;/span&gt; in &lt;span class="sb"&gt;`mcp.json`&lt;/span&gt;. &lt;span class="sb"&gt;`remarkable_status`&lt;/span&gt; still reports &lt;span class="sb"&gt;`delete: true`&lt;/span&gt;, because that is the server&amp;#39;s capability. Do not delete. Tell the user to delete items on the tablet.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/details&gt;&#10;&#10;</description></item></channel></rss>