<rss xmlns:source="http://source.scripting.com/" version="2.0">
  <channel>
    <title>Numeric Citizen I/O — A Blog About Blogging</title>
    <link>https://meta.numericcitizen.me/</link>
    <description></description>
    
    <language>en-us</language>
    
    <lastBuildDate>Mon, 07 Sep 2026 07:04:15 -0400</lastBuildDate>
    <item>
      <title>Week 36 Summary (Aug 30 - Sep 5, 2026)</title>
      <link>https://meta.numericcitizen.me/2026/09/07/week-summary-aug-sep.html</link>
      <pubDate>Mon, 07 Sep 2026 07:04:15 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/09/07/week-summary-aug-sep.html</guid>
      <description>&lt;p&gt;A week built around one big unresolved question — whether &lt;strong&gt;Birchfeed&lt;/strong&gt; could replace &lt;strong&gt;Inoreader&lt;/strong&gt; and become the feed backbone for the RSS Flow web app. That thread ran Sunday through Tuesday, moving from curiosity to a Claude Code exploration to a firm decision on Tuesday night to keep the existing feed management. Publishing stayed steady around it: four blog posts went out (Apple&amp;rsquo;s inflection point under &lt;strong&gt;John Ternus&lt;/strong&gt;, &lt;strong&gt;CleanShot 5&lt;/strong&gt;, the August digest, and anticipation for the September 9th &lt;strong&gt;iPhone event&lt;/strong&gt;). Tool testing was the other constant — two &lt;strong&gt;Craft betas&lt;/strong&gt;, the CleanShot 5 upgrade and its video recording, &lt;strong&gt;Claude Design&lt;/strong&gt;, and Claude AI scheduled tasks all got a turn. The back half of the week tapered into lighter housekeeping and &lt;strong&gt;photo sharing on Moments&lt;/strong&gt;, the photo-journaling app discovered on day one and used three times before the week was out.&lt;/p&gt;
</description>
      <source:markdown>A week built around one big unresolved question — whether **Birchfeed** could replace **Inoreader** and become the feed backbone for the RSS Flow web app. That thread ran Sunday through Tuesday, moving from curiosity to a Claude Code exploration to a firm decision on Tuesday night to keep the existing feed management. Publishing stayed steady around it: four blog posts went out (Apple&#39;s inflection point under **John Ternus**, **CleanShot 5**, the August digest, and anticipation for the September 9th **iPhone event**). Tool testing was the other constant — two **Craft betas**, the CleanShot 5 upgrade and its video recording, **Claude Design**, and Claude AI scheduled tasks all got a turn. The back half of the week tapered into lighter housekeeping and **photo sharing on Moments**, the photo-journaling app discovered on day one and used three times before the week was out.
</source:markdown>
    </item>
    
    <item>
      <title>Making Eight Years of Blogging Searchable</title>
      <link>https://meta.numericcitizen.me/2026/09/06/making-eight-years-of-blogging.html</link>
      <pubDate>Sun, 06 Sep 2026 10:20:14 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/09/06/making-eight-years-of-blogging.html</guid>
      <description>&lt;p&gt;I have been publishing on Ghost since October 2018. That is 677 posts, and until this week I had no good way to ask questions about any of it. I could search my own site, which matches titles. I could remember roughly what I wrote and when, which works for the last few months and fails completely for 2019.&lt;/p&gt;
&lt;p&gt;What I wanted was to ask &amp;ldquo;what have I written about X&amp;rdquo; and get a real answer drawn from the full text of every post. Ghost offers an API but no MCP endpoint, so the obvious path was not available. Here is what it actually took, including the parts I got wrong.&lt;/p&gt;
&lt;h2 id=&#34;starting-with-what-already-exists&#34;&gt;Starting with what already exists&lt;/h2&gt;
&lt;p&gt;There are several community-built Ghost MCP servers. I tried one that supports the read-only Content API, and it worked immediately. Posts, pages, tags, authors, all queryable in conversation.&lt;/p&gt;
&lt;p&gt;For about an hour I thought I was done.&lt;/p&gt;
&lt;h2 id=&#34;the-thing-that-quietly-breaks-everything&#34;&gt;The thing that quietly breaks everything&lt;/h2&gt;
&lt;p&gt;Ghost 6.0 removed support for &lt;code&gt;?limit=all&lt;/code&gt; and imposed a maximum page size of 100 on every API endpoint. That change is documented and reasonable, since unbounded queries hurt large sites.&lt;/p&gt;
&lt;p&gt;The problem is how it fails. Requesting &lt;code&gt;?limit=all&lt;/code&gt; does not error. It returns 100 items and says nothing about the other 577.&lt;/p&gt;
&lt;p&gt;I found this by running a &lt;code&gt;curl&lt;/code&gt; command to measure my archive size and getting back exactly 100 posts. A suspiciously round number for a blog running since 2018. The same cap applies to any MCP server built on the Content API, which means every answer I had been getting was drawn from my most recent fourteen months of writing while presenting itself as complete.&lt;/p&gt;
&lt;p&gt;That is worse than an error. An error tells you to fix something. This just quietly narrows your world.&lt;/p&gt;
&lt;p&gt;There is a second limitation underneath it. Ghost&amp;rsquo;s NQL filter language has no &lt;code&gt;like&lt;/code&gt; operator and no partial matching, and content fields are not filterable at all. You can retrieve &lt;code&gt;plaintext&lt;/code&gt; in a response, but you cannot query against it. So even with correct pagination, there is no way to search article bodies through the API.&lt;/p&gt;
&lt;p&gt;Ghost&amp;rsquo;s own site search works around this the same way I ended up doing: download the corpus and search it locally.&lt;/p&gt;
&lt;h2 id=&#34;the-local-copy&#34;&gt;The local copy&lt;/h2&gt;
&lt;p&gt;The design that followed is unglamorous and took an afternoon.&lt;/p&gt;
&lt;p&gt;A Postgres table holding one row per post, with the full body in a &lt;code&gt;plaintext&lt;/code&gt; column and a generated &lt;code&gt;tsvector&lt;/code&gt; column indexed with GIN. An n8n workflow pulls the archive weekly with explicit pagination, seven pages at 100 posts each with a one second delay between them, and upserts everything in a single round trip.&lt;/p&gt;
&lt;p&gt;The schema is boring on purpose:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;create&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;table&lt;/span&gt; ghost.posts (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id            text &lt;span style=&#34;color:#66d9ef&#34;&gt;primary&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  slug          text &lt;span style=&#34;color:#66d9ef&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;unique&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  title         text,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  plaintext     text,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  url           text,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  tags          text[],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  published_at  timestamptz,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  updated_at    timestamptz,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synced_at     timestamptz &lt;span style=&#34;color:#66d9ef&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fts tsvector &lt;span style=&#34;color:#66d9ef&#34;&gt;generated&lt;/span&gt; always &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    setweight(to_tsvector(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;english&amp;#39;&lt;/span&gt;::regconfig, coalesce(title, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)),     &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;A&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    setweight(to_tsvector(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;english&amp;#39;&lt;/span&gt;::regconfig, coalesce(plaintext, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)), &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;B&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) stored
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;setweight&lt;/code&gt; calls mean a title match outranks a body match. Without them, a post that mentions a term once in passing can outrank the post named after it.&lt;/p&gt;
&lt;p&gt;Two details in the sync are worth stealing if you build something similar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Full reconcile, not incremental.&lt;/strong&gt; My first instinct was a watermark on &lt;code&gt;updated_at&lt;/code&gt;, which is what I use for feed-based syncs. It is the wrong tool here. It would save six HTTP calls a week and would never detect a deleted or unpublished post. Pulling everything self-heals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A guard on the delete step.&lt;/strong&gt; Every row gets stamped with the run&amp;rsquo;s timestamp, and anything older gets pruned, which is how deletions propagate. But the prune only runs if this pass fetched at least 80% of the rows already in the table. Without that check, one bad fetch silently wipes eight years of archive. This is the kind of thing you want in place before you need it.&lt;/p&gt;
&lt;h2 id=&#34;i-was-wrong-about-the-size&#34;&gt;I was wrong about the size&lt;/h2&gt;
&lt;p&gt;I nearly did not build this because I assumed the archive would blow past my database provider&amp;rsquo;s free tier. That assumption was off by roughly two orders of magnitude.&lt;/p&gt;
&lt;p&gt;677 posts come to 3.2 million characters of body text. The table with its full-text index totals 11 MB against a 512 MB limit. I would need something like 32,000 posts to be in trouble.&lt;/p&gt;
&lt;p&gt;A related surprise: my recent posts average about 8,400 characters while the archive average is 4,700. My writing has roughly doubled in length over eight years. I did not know that about myself before running the query.&lt;/p&gt;
&lt;p&gt;The more useful lesson is that on serverless Postgres, storage is almost never the binding constraint for text. Compute hours are. Every query wakes the database for a minimum billing interval regardless of how fast it runs, so a scattered handful of ad-hoc searches costs more than the weekly bulk write does. Worth knowing before you optimise the wrong thing, which I did for a while.&lt;/p&gt;
&lt;h2 id=&#34;the-part-i-did-not-anticipate&#34;&gt;The part I did not anticipate&lt;/h2&gt;
&lt;p&gt;With the table populated, I assumed I was finished. I was not, and the gap here is the least obvious thing in this whole project.&lt;/p&gt;
&lt;p&gt;Nothing routes the question.&lt;/p&gt;
&lt;p&gt;Each time you ask something, the assistant picks tools based on their names and descriptions. It sees a Ghost MCP whose tools are explicitly labelled as browsing and reading blog posts. It also sees a generic SQL tool pointed at a database it knows nothing about. Ask &amp;ldquo;what have I written about X&amp;rdquo; and the match is overwhelmingly toward the Ghost tools, which return the 100 most recent posts and no warning.&lt;/p&gt;
&lt;p&gt;Building the better data source does not cause it to be used. You have to say so, explicitly, somewhere persistent.&lt;/p&gt;
&lt;p&gt;I solved this with a Skill: a set of instructions that triggers on phrasings like &amp;ldquo;what did I write about X&amp;rdquo; and states the routing rule as a prohibition rather than a preference. Do not use the Ghost browse tools for search, here is why they fail, here is the table and the query shape to use instead.&lt;/p&gt;
&lt;p&gt;The skill also pins the retrieval pattern, which matters more than I expected. Search first with ranked snippets, then fetch full bodies for only the three to five posts that are actually relevant. And read whole posts, never fragments. A paragraph mentioning a product without the surrounding argument is exactly how you end up having your own past position mischaracterised back to you.&lt;/p&gt;
&lt;h2 id=&#34;full-text-is-not-semantic-search&#34;&gt;Full-text is not semantic search&lt;/h2&gt;
&lt;p&gt;I conflated these two for a while, and the distinction is worth being precise about.&lt;/p&gt;
&lt;p&gt;What I built matches words and their grammatical variants. Ask about &amp;ldquo;Apple Intelligence&amp;rdquo; and it finds posts containing those words. Ask &amp;ldquo;how has my thinking about AI subscriptions evolved&amp;rdquo; and it will find something, because the words appear somewhere, but it has no way to surface a post that discusses the same idea in entirely different vocabulary.&lt;/p&gt;
&lt;p&gt;Semantic search needs embeddings, a vector column, and a model called at both index and query time. That is a real layer of work.&lt;/p&gt;
&lt;p&gt;I deliberately did not build it. Full-text over 677 posts with English stemming handles the lookup questions well, and lookup is most of what I actually ask. If the thematic questions come back consistently thin, the embeddings layer drops into the same table without rearchitecting anything. Building it up front would have been solving a problem I had not yet confirmed I have.&lt;/p&gt;
&lt;h2 id=&#34;what-it-does-not-do&#34;&gt;What it does not do&lt;/h2&gt;
&lt;p&gt;Four posts have empty bodies. The unauthenticated Content API cannot see members-only content, so gated posts arrive with a title and nothing else. They are findable by name but their text is not indexed. Fixing that means switching to the Admin API with JWT signing, which is not worth it for four posts.&lt;/p&gt;
&lt;p&gt;The copy is up to seven days stale. Irrelevant for archive questions, relevant if I ask about something published yesterday.&lt;/p&gt;
&lt;p&gt;And the whole thing is lexical. When a thematic question comes back thin, the honest answer is that the tool is not built for it, not that the archive is silent.&lt;/p&gt;
&lt;h2 id=&#34;was-it-worth-it&#34;&gt;Was it worth it&lt;/h2&gt;
&lt;p&gt;An afternoon, one database table, one scheduled workflow, and one skill file.&lt;/p&gt;
&lt;p&gt;The first real test was asking what I had written about GuruShots, a photography game I covered in late 2018. Two posts came back with dates and links. Through the Ghost API alone, that question has no answer at all.&lt;/p&gt;
&lt;p&gt;That is the whole point. Eight years of writing is only an archive if you can reach into it.&lt;/p&gt;
</description>
      <source:markdown>I have been publishing on Ghost since October 2018. That is 677 posts, and until this week I had no good way to ask questions about any of it. I could search my own site, which matches titles. I could remember roughly what I wrote and when, which works for the last few months and fails completely for 2019.


What I wanted was to ask &#34;what have I written about X&#34; and get a real answer drawn from the full text of every post. Ghost offers an API but no MCP endpoint, so the obvious path was not available. Here is what it actually took, including the parts I got wrong.


## Starting with what already exists


There are several community-built Ghost MCP servers. I tried one that supports the read-only Content API, and it worked immediately. Posts, pages, tags, authors, all queryable in conversation.


For about an hour I thought I was done.


## The thing that quietly breaks everything


Ghost 6.0 removed support for `?limit=all` and imposed a maximum page size of 100 on every API endpoint. That change is documented and reasonable, since unbounded queries hurt large sites.


The problem is how it fails. Requesting `?limit=all` does not error. It returns 100 items and says nothing about the other 577.


I found this by running a `curl` command to measure my archive size and getting back exactly 100 posts. A suspiciously round number for a blog running since 2018. The same cap applies to any MCP server built on the Content API, which means every answer I had been getting was drawn from my most recent fourteen months of writing while presenting itself as complete.


That is worse than an error. An error tells you to fix something. This just quietly narrows your world.


There is a second limitation underneath it. Ghost&#39;s NQL filter language has no `like` operator and no partial matching, and content fields are not filterable at all. You can retrieve `plaintext` in a response, but you cannot query against it. So even with correct pagination, there is no way to search article bodies through the API.


Ghost&#39;s own site search works around this the same way I ended up doing: download the corpus and search it locally.


## The local copy


The design that followed is unglamorous and took an afternoon.


A Postgres table holding one row per post, with the full body in a `plaintext` column and a generated `tsvector` column indexed with GIN. An n8n workflow pulls the archive weekly with explicit pagination, seven pages at 100 posts each with a one second delay between them, and upserts everything in a single round trip.


The schema is boring on purpose:


```sql
create table ghost.posts (
  id            text primary key,
  slug          text not null unique,
  title         text,
  plaintext     text,
  url           text,
  tags          text[],
  published_at  timestamptz,
  updated_at    timestamptz,
  synced_at     timestamptz not null,
  fts tsvector generated always as (
    setweight(to_tsvector(&#39;english&#39;::regconfig, coalesce(title, &#39;&#39;)),     &#39;A&#39;) ||
    setweight(to_tsvector(&#39;english&#39;::regconfig, coalesce(plaintext, &#39;&#39;)), &#39;B&#39;)
  ) stored
);
```


The `setweight` calls mean a title match outranks a body match. Without them, a post that mentions a term once in passing can outrank the post named after it.


Two details in the sync are worth stealing if you build something similar.


**Full reconcile, not incremental.** My first instinct was a watermark on `updated_at`, which is what I use for feed-based syncs. It is the wrong tool here. It would save six HTTP calls a week and would never detect a deleted or unpublished post. Pulling everything self-heals.


**A guard on the delete step.** Every row gets stamped with the run&#39;s timestamp, and anything older gets pruned, which is how deletions propagate. But the prune only runs if this pass fetched at least 80% of the rows already in the table. Without that check, one bad fetch silently wipes eight years of archive. This is the kind of thing you want in place before you need it.


## I was wrong about the size


I nearly did not build this because I assumed the archive would blow past my database provider&#39;s free tier. That assumption was off by roughly two orders of magnitude.


677 posts come to 3.2 million characters of body text. The table with its full-text index totals 11 MB against a 512 MB limit. I would need something like 32,000 posts to be in trouble.


A related surprise: my recent posts average about 8,400 characters while the archive average is 4,700. My writing has roughly doubled in length over eight years. I did not know that about myself before running the query.


The more useful lesson is that on serverless Postgres, storage is almost never the binding constraint for text. Compute hours are. Every query wakes the database for a minimum billing interval regardless of how fast it runs, so a scattered handful of ad-hoc searches costs more than the weekly bulk write does. Worth knowing before you optimise the wrong thing, which I did for a while.


## The part I did not anticipate


With the table populated, I assumed I was finished. I was not, and the gap here is the least obvious thing in this whole project.


Nothing routes the question.


Each time you ask something, the assistant picks tools based on their names and descriptions. It sees a Ghost MCP whose tools are explicitly labelled as browsing and reading blog posts. It also sees a generic SQL tool pointed at a database it knows nothing about. Ask &#34;what have I written about X&#34; and the match is overwhelmingly toward the Ghost tools, which return the 100 most recent posts and no warning.


Building the better data source does not cause it to be used. You have to say so, explicitly, somewhere persistent.


I solved this with a Skill: a set of instructions that triggers on phrasings like &#34;what did I write about X&#34; and states the routing rule as a prohibition rather than a preference. Do not use the Ghost browse tools for search, here is why they fail, here is the table and the query shape to use instead.


The skill also pins the retrieval pattern, which matters more than I expected. Search first with ranked snippets, then fetch full bodies for only the three to five posts that are actually relevant. And read whole posts, never fragments. A paragraph mentioning a product without the surrounding argument is exactly how you end up having your own past position mischaracterised back to you.


## Full-text is not semantic search


I conflated these two for a while, and the distinction is worth being precise about.


What I built matches words and their grammatical variants. Ask about &#34;Apple Intelligence&#34; and it finds posts containing those words. Ask &#34;how has my thinking about AI subscriptions evolved&#34; and it will find something, because the words appear somewhere, but it has no way to surface a post that discusses the same idea in entirely different vocabulary.


Semantic search needs embeddings, a vector column, and a model called at both index and query time. That is a real layer of work.


I deliberately did not build it. Full-text over 677 posts with English stemming handles the lookup questions well, and lookup is most of what I actually ask. If the thematic questions come back consistently thin, the embeddings layer drops into the same table without rearchitecting anything. Building it up front would have been solving a problem I had not yet confirmed I have.


## What it does not do


Four posts have empty bodies. The unauthenticated Content API cannot see members-only content, so gated posts arrive with a title and nothing else. They are findable by name but their text is not indexed. Fixing that means switching to the Admin API with JWT signing, which is not worth it for four posts.


The copy is up to seven days stale. Irrelevant for archive questions, relevant if I ask about something published yesterday.


And the whole thing is lexical. When a thematic question comes back thin, the honest answer is that the tool is not built for it, not that the archive is silent.


## Was it worth it


An afternoon, one database table, one scheduled workflow, and one skill file.


The first real test was asking what I had written about GuruShots, a photography game I covered in late 2018. Two posts came back with dates and links. Through the Ghost API alone, that question has no answer at all.


That is the whole point. Eight years of writing is only an archive if you can reach into it.

</source:markdown>
    </item>
    
    <item>
      <title>Week 35 Summary (Aug 23 - Aug 29, 2026)</title>
      <link>https://meta.numericcitizen.me/2026/08/30/week-summary-aug-aug.html</link>
      <pubDate>Sun, 30 Aug 2026 09:07:13 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/08/30/week-summary-aug-aug.html</guid>
      <description>&lt;p&gt;A week bookended by &lt;strong&gt;writing&lt;/strong&gt;. It opened with &lt;a href=&#34;https://numericcitizen.me/on-integrating-quick-reads-into-my-digital-ecosystem/&#34;&gt;On Integrating Quick Reads Into My Digital Ecosystem&lt;/a&gt; going out the door on Sunday, and closed with three consecutive mornings on &amp;ldquo;&lt;strong&gt;I’m proud of my failures&lt;/strong&gt;&amp;rdquo; article as a creator alongside the next issue of the ephemeral scrapbook newsletter. Underneath it all was a sustained hunt for better reading sources — chasing an RSS feed on understandingwar.org, adopting &lt;a href=&#34;https://bubbles.town/&#34;&gt;Bubbles.town&lt;/a&gt;, and opening a trial of &lt;a href=&#34;https://standard-reader.app/about&#34;&gt;Standard Reader&lt;/a&gt;. &lt;strong&gt;AI experiments&lt;/strong&gt; ran in parallel almost daily: Whisper transcription on the M4 Mac mini, scheduled tasks in the Claude cloud, Claude in gateway mode against &lt;strong&gt;Ollama&lt;/strong&gt;, and an attempt to make &lt;strong&gt;Ghost&lt;/strong&gt; CMS content searchable through Claude — most of them reaching a verdict rather than staying open. Maintenance took a real share of the week too, with &lt;strong&gt;n8n instability&lt;/strong&gt;, a manual &lt;strong&gt;MCP&lt;/strong&gt; config merge, and a refreshed ecosystem diagram, while a consistent editorial stance on engagement-driven platforms surfaced twice in conversation.&lt;/p&gt;
</description>
      <source:markdown>A week bookended by **writing**. It opened with [On Integrating Quick Reads Into My Digital Ecosystem](https://numericcitizen.me/on-integrating-quick-reads-into-my-digital-ecosystem/) going out the door on Sunday, and closed with three consecutive mornings on &#34;**I’m proud of my failures**&#34; article as a creator alongside the next issue of the ephemeral scrapbook newsletter. Underneath it all was a sustained hunt for better reading sources — chasing an RSS feed on understandingwar.org, adopting [Bubbles.town](https://bubbles.town/), and opening a trial of [Standard Reader](https://standard-reader.app/about). **AI experiments** ran in parallel almost daily: Whisper transcription on the M4 Mac mini, scheduled tasks in the Claude cloud, Claude in gateway mode against **Ollama**, and an attempt to make **Ghost** CMS content searchable through Claude — most of them reaching a verdict rather than staying open. Maintenance took a real share of the week too, with **n8n instability**, a manual **MCP** config merge, and a refreshed ecosystem diagram, while a consistent editorial stance on engagement-driven platforms surfaced twice in conversation.
</source:markdown>
    </item>
    
    <item>
      <title>Week 34 Summary (Aug 16 - Aug 22, 2026)</title>
      <link>https://meta.numericcitizen.me/2026/08/23/week-summary-aug-aug.html</link>
      <pubDate>Sun, 23 Aug 2026 10:52:27 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/08/23/week-summary-aug-aug.html</guid>
      <description>&lt;p&gt;A week with one clear centre of gravity: the On Integrating &lt;strong&gt;Quick Reads Into My Digital Ecosystem&lt;/strong&gt; piece, picked up on five consecutive mornings — continued, diagrammed, re-diagrammed, then restarted from scratch on Thursday. Around it, Claude AI shifted from assistant to workbench: &lt;strong&gt;documenting MCP endpoint dependencies&lt;/strong&gt;, connecting Neon Postgres, refreshing n8n workflow docs, and by week&amp;rsquo;s end &lt;strong&gt;turning bank statements into a financial dashboard&lt;/strong&gt; for retirement planning. &lt;strong&gt;Reading&lt;/strong&gt; was front-loaded into early mornings and skewed toward AI commentary and Apple&amp;rsquo;s App Store fight, with a detour into Craft Agents. Infrastructure got quiet attention too — an &lt;strong&gt;n8n upgrade to 2.35.4&lt;/strong&gt;, and a failed Micro.blog highlight deletion that turned into a support ticket. Momentum tapered after Wednesday: Friday came down to a single entry, and Saturday was blank.&lt;/p&gt;
</description>
      <source:markdown>A week with one clear centre of gravity: the On Integrating **Quick Reads Into My Digital Ecosystem** piece, picked up on five consecutive mornings — continued, diagrammed, re-diagrammed, then restarted from scratch on Thursday. Around it, Claude AI shifted from assistant to workbench: **documenting MCP endpoint dependencies**, connecting Neon Postgres, refreshing n8n workflow docs, and by week&#39;s end **turning bank statements into a financial dashboard** for retirement planning. **Reading** was front-loaded into early mornings and skewed toward AI commentary and Apple&#39;s App Store fight, with a detour into Craft Agents. Infrastructure got quiet attention too — an **n8n upgrade to 2.35.4**, and a failed Micro.blog highlight deletion that turned into a support ticket. Momentum tapered after Wednesday: Friday came down to a single entry, and Saturday was blank.
</source:markdown>
    </item>
    
    <item>
      <title>Week 33 Summary (Aug 09 - Aug 15, 2026)</title>
      <link>https://meta.numericcitizen.me/2026/08/16/week-summary-aug-aug.html</link>
      <pubDate>Sun, 16 Aug 2026 10:48:05 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/08/16/week-summary-aug-aug.html</guid>
      <description>&lt;p&gt;This is my first week summary. It is built automatically with AI by consuming my manually-written notes Craft Daily notes where I document most of my activities. Then, I do some touch ups before publishing here.&lt;/p&gt;
&lt;p&gt;A week centered on the &lt;strong&gt;Quick Reads&lt;/strong&gt; read-later service, which threaded through nearly every day — from drafting a review and appreciation piece to extracting text highlights, weighing data portability, and wiring a Quick Reads section into the personal Dashboard. &lt;strong&gt;Automation&lt;/strong&gt; was the second big theme: the newly discovered &lt;strong&gt;Brrr push-notification app&lt;/strong&gt; went from curiosity on Tuesday to being integrated into four &lt;strong&gt;n8n workflows&lt;/strong&gt; by Saturday, while &lt;strong&gt;Claude Code&lt;/strong&gt; helped tidy the bookmarking app&amp;rsquo;s documentation and fix its code. Two blog posts shipped — &amp;lsquo;The digital toxicity&amp;rsquo; on the return to the web for app development, and &amp;lsquo;It&amp;rsquo;s fun to go back&amp;rsquo; reflecting on past writing. &lt;strong&gt;Reading and watching leaned heavily on AI and industry shifts&lt;/strong&gt;, spanning antirez on lab risks, the OpenAI/Hugging Face incident timeline, the end of &lt;strong&gt;Google Search&lt;/strong&gt;, and self-hosting LLMs to control token costs. The week opened with continued research for an upcoming iPhone review, focused on the camera control button.&lt;/p&gt;
</description>
      <source:markdown>This is my first week summary. It is built automatically with AI by consuming my manually-written notes Craft Daily notes where I document most of my activities. Then, I do some touch ups before publishing here. 

A week centered on the **Quick Reads** read-later service, which threaded through nearly every day — from drafting a review and appreciation piece to extracting text highlights, weighing data portability, and wiring a Quick Reads section into the personal Dashboard. **Automation** was the second big theme: the newly discovered **Brrr push-notification app** went from curiosity on Tuesday to being integrated into four **n8n workflows** by Saturday, while **Claude Code** helped tidy the bookmarking app&#39;s documentation and fix its code. Two blog posts shipped — &#39;The digital toxicity&#39; on the return to the web for app development, and &#39;It&#39;s fun to go back&#39; reflecting on past writing. **Reading and watching leaned heavily on AI and industry shifts**, spanning antirez on lab risks, the OpenAI/Hugging Face incident timeline, the end of **Google Search**, and self-hosting LLMs to control token costs. The week opened with continued research for an upcoming iPhone review, focused on the camera control button.
</source:markdown>
    </item>
    
    <item>
      <title>Experimenting with a new visitor card design</title>
      <link>https://meta.numericcitizen.me/2026/08/02/experimenting-with-a-new-visitor.html</link>
      <pubDate>Sun, 02 Aug 2026 09:34:43 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/08/02/experimenting-with-a-new-visitor.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m currently working on an updated visitor card for my digital space. The following is an updated version, the same design as before but with updated information. It&amp;rsquo;s done in Keynote. The second is an AI-generated concept for a refreshed design. I&amp;rsquo;m kind of liking the new structure (my wife, too). I might try to reproduce this in Keynote, but I see a few challenges. Keynote is limited for things like this, and I&amp;rsquo;m not sure I want to switch to another app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/image.png&#34; alt=&#34;Numeric Citizen Digital Space visitor card previous design&#34;&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/ce3b3640dc.png&#34; alt=&#34;Numeric Citizen Digital Space visitor card new concept design built using AI&#34;&gt;&lt;/p&gt;
</description>
      <source:markdown>I&#39;m currently working on an updated visitor card for my digital space. The following is an updated version, the same design as before but with updated information. It&#39;s done in Keynote. The second is an AI-generated concept for a refreshed design. I&#39;m kind of liking the new structure (my wife, too). I might try to reproduce this in Keynote, but I see a few challenges. Keynote is limited for things like this, and I&#39;m not sure I want to switch to another app.

&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/image.png&#34; alt=&#34;Numeric Citizen Digital Space visitor card previous design&#34;&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/ce3b3640dc.png&#34; alt=&#34;Numeric Citizen Digital Space visitor card new concept design built using AI&#34;&gt;
</source:markdown>
    </item>
    
    <item>
      <title>I went looking for a reason to use Ollama</title>
      <link>https://meta.numericcitizen.me/2026/07/26/i-went-looking-for-a.html</link>
      <pubDate>Sun, 26 Jul 2026 15:39:46 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/07/26/i-went-looking-for-a.html</guid>
      <description>&lt;p&gt;I tried to find a place for Ollama in my automation stack. I wanted two things: a lower Anthropic bill, and Ollama running somewhere in my workflows. The first reason didn&amp;rsquo;t survive contact with the data.&lt;/p&gt;
&lt;h2 id=&#34;the-number&#34;&gt;The number&lt;/h2&gt;
&lt;p&gt;I have a workflow that pulls my Anthropic cost report every morning and posts it to Discord and my Craft daily note. So I checked it.&lt;/p&gt;
&lt;p&gt;Thirty days, 56 workflows, every LLM call I make: $7.48. Twenty-five cents a day, already down 60% over that window.&lt;/p&gt;
&lt;p&gt;Moving everything off Claude would save about $90 a year. Keeping Claude for work where quality matters brings that closer to thirty.&lt;/p&gt;
&lt;p&gt;I standardized most of my stack on Haiku months ago. That&amp;rsquo;s where the savings already went. I went looking to cut a bill that was already at its floor, because reducing API costs sounds like good engineering whether or not the number supports it.&lt;/p&gt;
&lt;h2 id=&#34;ollama-cloud-costs-more-than-i-spend&#34;&gt;Ollama Cloud costs more than I spend&lt;/h2&gt;
&lt;p&gt;Two things I had confused: open-weight models and locally-hosted models are separate choices. I don&amp;rsquo;t want models running on my Mac. That&amp;rsquo;s not an argument against open models — Ollama Cloud runs them on their hardware behind a normal API. I&amp;rsquo;d even set up the credentials back in December and forgotten.&lt;/p&gt;
&lt;p&gt;But Ollama Cloud doesn&amp;rsquo;t bill per token. It&amp;rsquo;s a flat subscription metered by GPU time, with session limits every five hours and weekly limits every seven days. Pro is $20 a month — nearly three times my current bill, for smaller models.&lt;/p&gt;
&lt;p&gt;The free tier might cover my volume. I can&amp;rsquo;t confirm that, because Ollama has no account usage endpoint. Checking your quota means logging into the web dashboard. Several open feature requests ask for an API; none have shipped. You find out you&amp;rsquo;re near the ceiling when they email you at 90%.&lt;/p&gt;
&lt;p&gt;I went looking to reduce a cost I track with a daily automated report, and the alternative can&amp;rsquo;t be tracked with one.&lt;/p&gt;
&lt;h2 id=&#34;the-reason-that-holds-up&#34;&gt;The reason that holds up&lt;/h2&gt;
&lt;p&gt;Cost is out. Privacy doesn&amp;rsquo;t apply — I&amp;rsquo;m summarizing my own RSS feeds and my own billing data.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s left: I don&amp;rsquo;t know which of my workflows actually need a frontier model.&lt;/p&gt;
&lt;p&gt;I have a dozen-plus workflows making LLM calls. Some summarize articles or pull signal out of a week of notes. Others do arithmetic and pattern-matching dressed up as reasoning. I&amp;rsquo;ve never tested the difference. Everything points at the same model because at twenty-five cents a day there was no reason to check.&lt;/p&gt;
&lt;p&gt;An open model is a cheap way to test that. Not to replace Claude — to find out where the line is. Any task where a small open model matches Haiku is a task I&amp;rsquo;ve been over-provisioning.&lt;/p&gt;
&lt;h2 id=&#34;the-experiment&#34;&gt;The experiment&lt;/h2&gt;
&lt;p&gt;I picked the most mechanical node I have: the one that asks four questions about thirty numbers. Trend, spikes, projection. 570 tokens in, no nuance required.&lt;/p&gt;
&lt;p&gt;Both models now run in parallel from the same prompt, joined by a merge node so the message builder doesn&amp;rsquo;t fire twice and double-post. Both answers print back to back, labelled with their model. The Ollama arm fails soft — a rate limit on the test shouldn&amp;rsquo;t break the report.&lt;/p&gt;
&lt;p&gt;One thing I nearly got wrong: I reached for the largest open model first, because it was the name I recognized from the docs. Wrong instrument. A big model will obviously handle a trend summary, and confirming that tells me nothing. If you&amp;rsquo;re looking for the floor, start at the floor.&lt;/p&gt;
&lt;h2 id=&#34;if-youre-considering-the-same-thing&#34;&gt;If you&amp;rsquo;re considering the same thing&lt;/h2&gt;
&lt;p&gt;Spending real money on inference? Do the migration. The math works.&lt;/p&gt;
&lt;p&gt;Bill is a rounding error? Then cost isn&amp;rsquo;t your reason and privacy probably isn&amp;rsquo;t either. The useful question is which of your automations need a frontier model and which ones you&amp;rsquo;re over-provisioning out of habit.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll report back either way.&lt;/p&gt;
</description>
      <source:markdown>I tried to find a place for Ollama in my automation stack. I wanted two things: a lower Anthropic bill, and Ollama running somewhere in my workflows. The first reason didn&#39;t survive contact with the data.

## The number

I have a workflow that pulls my Anthropic cost report every morning and posts it to Discord and my Craft daily note. So I checked it.

Thirty days, 56 workflows, every LLM call I make: $7.48. Twenty-five cents a day, already down 60% over that window.

Moving everything off Claude would save about $90 a year. Keeping Claude for work where quality matters brings that closer to thirty.

I standardized most of my stack on Haiku months ago. That&#39;s where the savings already went. I went looking to cut a bill that was already at its floor, because reducing API costs sounds like good engineering whether or not the number supports it.

## Ollama Cloud costs more than I spend

Two things I had confused: open-weight models and locally-hosted models are separate choices. I don&#39;t want models running on my Mac. That&#39;s not an argument against open models — Ollama Cloud runs them on their hardware behind a normal API. I&#39;d even set up the credentials back in December and forgotten.

But Ollama Cloud doesn&#39;t bill per token. It&#39;s a flat subscription metered by GPU time, with session limits every five hours and weekly limits every seven days. Pro is $20 a month — nearly three times my current bill, for smaller models.

The free tier might cover my volume. I can&#39;t confirm that, because Ollama has no account usage endpoint. Checking your quota means logging into the web dashboard. Several open feature requests ask for an API; none have shipped. You find out you&#39;re near the ceiling when they email you at 90%.

I went looking to reduce a cost I track with a daily automated report, and the alternative can&#39;t be tracked with one.

## The reason that holds up

Cost is out. Privacy doesn&#39;t apply — I&#39;m summarizing my own RSS feeds and my own billing data.

What&#39;s left: I don&#39;t know which of my workflows actually need a frontier model.

I have a dozen-plus workflows making LLM calls. Some summarize articles or pull signal out of a week of notes. Others do arithmetic and pattern-matching dressed up as reasoning. I&#39;ve never tested the difference. Everything points at the same model because at twenty-five cents a day there was no reason to check.

An open model is a cheap way to test that. Not to replace Claude — to find out where the line is. Any task where a small open model matches Haiku is a task I&#39;ve been over-provisioning.

## The experiment

I picked the most mechanical node I have: the one that asks four questions about thirty numbers. Trend, spikes, projection. 570 tokens in, no nuance required.

Both models now run in parallel from the same prompt, joined by a merge node so the message builder doesn&#39;t fire twice and double-post. Both answers print back to back, labelled with their model. The Ollama arm fails soft — a rate limit on the test shouldn&#39;t break the report.

One thing I nearly got wrong: I reached for the largest open model first, because it was the name I recognized from the docs. Wrong instrument. A big model will obviously handle a trend summary, and confirming that tells me nothing. If you&#39;re looking for the floor, start at the floor.

## If you&#39;re considering the same thing

Spending real money on inference? Do the migration. The math works.

Bill is a rounding error? Then cost isn&#39;t your reason and privacy probably isn&#39;t either. The useful question is which of your automations need a frontier model and which ones you&#39;re over-provisioning out of habit.

I&#39;ll report back either way.

</source:markdown>
    </item>
    
    <item>
      <title>AI made me replace another subscription: Ulysses</title>
      <link>https://meta.numericcitizen.me/2026/07/18/ai-made-me-replace-another.html</link>
      <pubDate>Sat, 18 Jul 2026 17:07:43 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/07/18/ai-made-me-replace-another.html</guid>
      <description>&lt;p&gt;I finally cancelled my subscription to Ulysses. Why? I was using Ulysses because it supported Craft&amp;rsquo;s export document so that I could then publish either to Ghost or Micro.blog. Since the beginning of this year, I&amp;rsquo;ve created two n8n automation workflows to publish directly from Craft to Ghost or Micro.blog.&lt;/p&gt;
&lt;h1 id=&#34;publishing-from-craft-to-microblog-with-a-single-n8n-workflow&#34;&gt;Publishing from Craft to Micro.blog with a Single n8n Workflow&lt;/h1&gt;
&lt;p&gt;This is a technical write-up of an n8n automation that takes a document written in &lt;a href=&#34;https://www.craft.do&#34;&gt;Craft&lt;/a&gt;, converts it to clean HTML, rehosts its images, and publishes it to &lt;a href=&#34;https://micro.blog&#34;&gt;Micro.blog&lt;/a&gt; as a draft — all from a single webhook call. It&amp;rsquo;s a companion to an earlier Craft → Ghost publisher and reuses the same document-fetching approach, but targets Micro.blog&amp;rsquo;s &lt;a href=&#34;https://www.w3.org/TR/micropub/&#34;&gt;Micropub&lt;/a&gt; API instead of a proprietary CMS.&lt;/p&gt;
&lt;p&gt;The goal is to write in one place (Craft) and let automation handle the tedious, error-prone part: block conversion and image migration.&lt;/p&gt;
&lt;h2 id=&#34;what-it-does&#34;&gt;What it does&lt;/h2&gt;
&lt;p&gt;An AI assistant (via n8n&amp;rsquo;s MCP integration) or any HTTP client sends a webhook request naming a Craft document by title. The workflow then:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Searches the Craft space for that title.&lt;/li&gt;
&lt;li&gt;Scores the search results to pick the &lt;em&gt;actual&lt;/em&gt; matching document.&lt;/li&gt;
&lt;li&gt;Fetches the document&amp;rsquo;s full block tree.&lt;/li&gt;
&lt;li&gt;Converts Craft blocks into Micropub-ready HTML.&lt;/li&gt;
&lt;li&gt;Extracts every Craft-hosted image, downloads it, and re-uploads it to Micro.blog&amp;rsquo;s media endpoint.&lt;/li&gt;
&lt;li&gt;Swaps the original image URLs for their new Micro.blog-hosted equivalents.&lt;/li&gt;
&lt;li&gt;Publishes the result as a &lt;strong&gt;draft&lt;/strong&gt; for manual review before it goes live.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The whole run typically completes in about 4–6 seconds, with image uploads accounting for most of the overhead.&lt;/p&gt;
&lt;h2 id=&#34;trigger-and-input&#34;&gt;Trigger and input&lt;/h2&gt;
&lt;p&gt;The workflow is triggered by an HTTP &lt;code&gt;POST&lt;/code&gt; webhook that waits for the full run to complete before responding (a &amp;ldquo;response node&amp;rdquo; pattern), so the caller gets the final published URL back synchronously. It&amp;rsquo;s also exposed through n8n&amp;rsquo;s MCP server, which is what lets an assistant invoke it conversationally.&lt;/p&gt;
&lt;p&gt;The input payload is minimal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;targetTitle&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;My Article Title&amp;#34;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;flow-overview&#34;&gt;Flow overview&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Webhook
  → Search Document in Craft
  → Find Best Matching Document
  → Fetch Document Content
  → Convert Craft Blocks to HTML
  → Set Micro.blog Token
  → Extract Craft Image URLs
  → Has Images?
       ├─ true  → Split by Image URL → Download from Craft → Fix Filename
       │          → Upload to Micro.blog Media → Merge Upload Result
       │          → Reassemble HTML → Merge Before Publish
       └─ false → Format No-Image Post → Merge Before Publish
  → Publish to Micro.blog
  → Respond to Webhook
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;the-interesting-problems&#34;&gt;The interesting problems&lt;/h2&gt;
&lt;p&gt;Most of the engineering effort went into three areas that aren&amp;rsquo;t obvious until you hit them.&lt;/p&gt;
&lt;h3 id=&#34;1-title-matching-against-a-full-text-search&#34;&gt;1. Title matching against a full-text search&lt;/h3&gt;
&lt;p&gt;Craft&amp;rsquo;s search API does &lt;em&gt;full-text&lt;/em&gt; search, not title-only. That means a document that merely &lt;em&gt;mentions&lt;/em&gt; the target title somewhere in its body can rank above the document actually named that. Publishing the wrong document is a nasty failure mode.&lt;/p&gt;
&lt;p&gt;The fix is a small scoring node that runs after the search and ranks each candidate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Exact title match:&lt;/strong&gt; 100&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Title starts with the query:&lt;/strong&gt; 80&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Title contains the query:&lt;/strong&gt; under 50, penalized by how much longer the title is than the query&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before comparing, it strips Markdown noise — bold markers, italics, and heading prefixes — so formatting in a title doesn&amp;rsquo;t throw off the match. If nothing scores above zero, the node throws a descriptive error that lists every candidate it saw, which makes debugging a missed title trivial. The node emits the single best match in the same shape as the search results, so the downstream &amp;ldquo;fetch content&amp;rdquo; step doesn&amp;rsquo;t need to know any scoring happened.&lt;/p&gt;
&lt;h3 id=&#34;2-converting-craft-blocks-to-html&#34;&gt;2. Converting Craft blocks to HTML&lt;/h3&gt;
&lt;p&gt;Craft stores documents as a nested tree of typed blocks, not as HTML. A dedicated conversion node walks that tree and emits Micropub-ready markup. It covers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paragraphs and headings (h1–h4)&lt;/li&gt;
&lt;li&gt;Blockquotes and horizontal rules&lt;/li&gt;
&lt;li&gt;Unordered and ordered lists — consecutive list-item blocks are grouped into a single &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; rather than emitting one list per item&lt;/li&gt;
&lt;li&gt;Task checkboxes (rendered as ✅ / ☐)&lt;/li&gt;
&lt;li&gt;Images, wrapped in &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rich-link bookmarks, rendered as a styled bookmark block&lt;/li&gt;
&lt;li&gt;Code blocks (&lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Inline formatting: bold, italic, strikethrough, inline code, links, and proper HTML-entity escaping&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also handles two different document shapes — a notebook with sub-pages and a flat single document — with a fallback lookup, so it doesn&amp;rsquo;t matter how the source is organized.&lt;/p&gt;
&lt;h3 id=&#34;3-rehosting-images-across-services&#34;&gt;3. Rehosting images across services&lt;/h3&gt;
&lt;p&gt;Craft images live on Craft&amp;rsquo;s own CDN. If you publish those URLs directly, your post depends on Craft continuing to serve them — not acceptable for a permanent blog post. So every Craft image has to be pulled down and re-uploaded to Micro.blog.&lt;/p&gt;
&lt;p&gt;The image branch:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Regex-scans the generated HTML for Craft image URLs.&lt;/li&gt;
&lt;li&gt;Splits into one item per image.&lt;/li&gt;
&lt;li&gt;Downloads each image&amp;rsquo;s binary from Craft.&lt;/li&gt;
&lt;li&gt;Fixes the filename extension based on the response&amp;rsquo;s MIME type (Craft URLs don&amp;rsquo;t always carry a usable extension).&lt;/li&gt;
&lt;li&gt;Uploads each image to Micro.blog&amp;rsquo;s media endpoint as &lt;code&gt;multipart/form-data&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A subtle detail: Micro.blog&amp;rsquo;s media endpoint returns &lt;code&gt;202 Accepted&lt;/code&gt; and puts the new image URL in the HTTP &lt;strong&gt;&lt;code&gt;Location&lt;/code&gt; response header&lt;/strong&gt;, not in the body. To capture a header you have to ask the HTTP node for the &lt;em&gt;full&lt;/em&gt; response rather than just the parsed body. A later node maps each uploaded image&amp;rsquo;s &lt;code&gt;Location&lt;/code&gt; back to its original Craft URL by index, and the HTML is reassembled with every Craft URL replaced by its Micro.blog equivalent.&lt;/p&gt;
&lt;p&gt;Image failures are handled gracefully: the upload node continues on error, so if one image fails (AVIF, for instance, tends to be rejected), the post still publishes — that image just keeps its original URL instead of breaking the whole run.&lt;/p&gt;
&lt;h2 id=&#34;why-micropub&#34;&gt;Why Micropub&lt;/h2&gt;
&lt;p&gt;The most reusable idea here is that Micro.blog speaks &lt;a href=&#34;https://www.w3.org/TR/micropub/&#34;&gt;Micropub&lt;/a&gt;, a W3C standard, rather than a proprietary publishing API. The final payload is a standard &lt;code&gt;h-entry&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;h-entry&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;My Article Title&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;h2&amp;gt;...&amp;lt;/h2&amp;gt;&amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt;&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;post-status&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;draft&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Any Micropub-compatible endpoint would accept the same shape, so the publishing half of this workflow isn&amp;rsquo;t locked to one host. The &lt;code&gt;post-status: draft&lt;/code&gt; field is deliberate — &lt;strong&gt;every post lands as a draft&lt;/strong&gt; so it can be reviewed in the editor before going public. The endpoint responds with the new post&amp;rsquo;s URL, a preview link, and an edit link, which the workflow passes straight back to the webhook caller.&lt;/p&gt;
&lt;h2 id=&#34;error-handling&#34;&gt;Error handling&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A shared error-handler workflow catches failures across the automation.&lt;/li&gt;
&lt;li&gt;The webhook always responds, even on failure, so a caller never hangs.&lt;/li&gt;
&lt;li&gt;Image-upload failures are non-fatal (see above).&lt;/li&gt;
&lt;li&gt;A missing title produces an explicit, descriptive error listing what was searched.&lt;/li&gt;
&lt;li&gt;Full-text false positives are neutralized by the scoring node rather than by hoping the search ranks correctly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;credentials-and-configuration-redacted&#34;&gt;Credentials and configuration (redacted)&lt;/h2&gt;
&lt;p&gt;For obvious reasons, the specifics below are not published:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Craft Connect REST link&lt;/strong&gt; — a private access link used to search Craft and fetch block content.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Micro.blog app token&lt;/strong&gt; — a Bearer token generated in Micro.blog account settings, stored in a dedicated &amp;ldquo;Set Token&amp;rdquo; node so it can be rotated in one place.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;n8n instance URL, webhook path, and internal workflow IDs&lt;/strong&gt; — infrastructure details specific to a self-hosted deployment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you rebuild something like this, you&amp;rsquo;d supply your own Craft access link and your own Micro.blog token, and point the workflow at your own n8n instance.&lt;/p&gt;
&lt;h2 id=&#34;takeaways&#34;&gt;Takeaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Treat a full-text search as untrusted input and score its results before acting on them.&lt;/li&gt;
&lt;li&gt;When migrating content between hosts, migrate the &lt;em&gt;assets&lt;/em&gt; too — don&amp;rsquo;t hotlink another service&amp;rsquo;s CDN.&lt;/li&gt;
&lt;li&gt;Watch where an API returns the data you need; a &lt;code&gt;Location&lt;/code&gt; header is easy to miss if you only read response bodies.&lt;/li&gt;
&lt;li&gt;Prefer open standards (Micropub) over proprietary APIs where you can — it keeps the integration portable.&lt;/li&gt;
&lt;li&gt;Publish to draft first. Automation should hand you a reviewable result, not a live surprise.&lt;/li&gt;
&lt;/ul&gt;
</description>
      <source:markdown>I finally cancelled my subscription to Ulysses. Why? I was using Ulysses because it supported Craft&#39;s export document so that I could then publish either to Ghost or Micro.blog. Since the beginning of this year, I&#39;ve created two n8n automation workflows to publish directly from Craft to Ghost or Micro.blog. 

# Publishing from Craft to Micro.blog with a Single n8n Workflow


This is a technical write-up of an n8n automation that takes a document written in [Craft](https://www.craft.do), converts it to clean HTML, rehosts its images, and publishes it to [Micro.blog](https://micro.blog) as a draft — all from a single webhook call. It&#39;s a companion to an earlier Craft → Ghost publisher and reuses the same document-fetching approach, but targets Micro.blog&#39;s [Micropub](https://www.w3.org/TR/micropub/) API instead of a proprietary CMS.


The goal is to write in one place (Craft) and let automation handle the tedious, error-prone part: block conversion and image migration.


## What it does


An AI assistant (via n8n&#39;s MCP integration) or any HTTP client sends a webhook request naming a Craft document by title. The workflow then:


1. Searches the Craft space for that title.
2. Scores the search results to pick the *actual* matching document.
3. Fetches the document&#39;s full block tree.
4. Converts Craft blocks into Micropub-ready HTML.
5. Extracts every Craft-hosted image, downloads it, and re-uploads it to Micro.blog&#39;s media endpoint.
6. Swaps the original image URLs for their new Micro.blog-hosted equivalents.
7. Publishes the result as a **draft** for manual review before it goes live.


The whole run typically completes in about 4–6 seconds, with image uploads accounting for most of the overhead.


## Trigger and input


The workflow is triggered by an HTTP `POST` webhook that waits for the full run to complete before responding (a &#34;response node&#34; pattern), so the caller gets the final published URL back synchronously. It&#39;s also exposed through n8n&#39;s MCP server, which is what lets an assistant invoke it conversationally.


The input payload is minimal:


```json
{ &#34;targetTitle&#34;: &#34;My Article Title&#34; }
```

## Flow overview


```
Webhook
  → Search Document in Craft
  → Find Best Matching Document
  → Fetch Document Content
  → Convert Craft Blocks to HTML
  → Set Micro.blog Token
  → Extract Craft Image URLs
  → Has Images?
       ├─ true  → Split by Image URL → Download from Craft → Fix Filename
       │          → Upload to Micro.blog Media → Merge Upload Result
       │          → Reassemble HTML → Merge Before Publish
       └─ false → Format No-Image Post → Merge Before Publish
  → Publish to Micro.blog
  → Respond to Webhook
```

## The interesting problems


Most of the engineering effort went into three areas that aren&#39;t obvious until you hit them.


### 1. Title matching against a full-text search


Craft&#39;s search API does *full-text* search, not title-only. That means a document that merely *mentions* the target title somewhere in its body can rank above the document actually named that. Publishing the wrong document is a nasty failure mode.


The fix is a small scoring node that runs after the search and ranks each candidate:


- **Exact title match:** 100
- **Title starts with the query:** 80
- **Title contains the query:** under 50, penalized by how much longer the title is than the query


Before comparing, it strips Markdown noise — bold markers, italics, and heading prefixes — so formatting in a title doesn&#39;t throw off the match. If nothing scores above zero, the node throws a descriptive error that lists every candidate it saw, which makes debugging a missed title trivial. The node emits the single best match in the same shape as the search results, so the downstream &#34;fetch content&#34; step doesn&#39;t need to know any scoring happened.


### 2. Converting Craft blocks to HTML


Craft stores documents as a nested tree of typed blocks, not as HTML. A dedicated conversion node walks that tree and emits Micropub-ready markup. It covers:


- Paragraphs and headings (h1–h4)
- Blockquotes and horizontal rules
- Unordered and ordered lists — consecutive list-item blocks are grouped into a single `&lt;ul&gt;` or `&lt;ol&gt;` rather than emitting one list per item
- Task checkboxes (rendered as ✅ / ☐)
- Images, wrapped in `&lt;figure&gt;`
- Rich-link bookmarks, rendered as a styled bookmark block
- Code blocks (`&lt;pre&gt;&lt;code&gt;`)
- Inline formatting: bold, italic, strikethrough, inline code, links, and proper HTML-entity escaping


It also handles two different document shapes — a notebook with sub-pages and a flat single document — with a fallback lookup, so it doesn&#39;t matter how the source is organized.


### 3. Rehosting images across services


Craft images live on Craft&#39;s own CDN. If you publish those URLs directly, your post depends on Craft continuing to serve them — not acceptable for a permanent blog post. So every Craft image has to be pulled down and re-uploaded to Micro.blog.


The image branch:


1. Regex-scans the generated HTML for Craft image URLs.
2. Splits into one item per image.
3. Downloads each image&#39;s binary from Craft.
4. Fixes the filename extension based on the response&#39;s MIME type (Craft URLs don&#39;t always carry a usable extension).
5. Uploads each image to Micro.blog&#39;s media endpoint as `multipart/form-data`.


A subtle detail: Micro.blog&#39;s media endpoint returns `202 Accepted` and puts the new image URL in the HTTP **`Location` response header**, not in the body. To capture a header you have to ask the HTTP node for the *full* response rather than just the parsed body. A later node maps each uploaded image&#39;s `Location` back to its original Craft URL by index, and the HTML is reassembled with every Craft URL replaced by its Micro.blog equivalent.


Image failures are handled gracefully: the upload node continues on error, so if one image fails (AVIF, for instance, tends to be rejected), the post still publishes — that image just keeps its original URL instead of breaking the whole run.


## Why Micropub


The most reusable idea here is that Micro.blog speaks [Micropub](https://www.w3.org/TR/micropub/), a W3C standard, rather than a proprietary publishing API. The final payload is a standard `h-entry`:


```json
{
  &#34;type&#34;: [&#34;h-entry&#34;],
  &#34;properties&#34;: {
    &#34;name&#34;: [&#34;My Article Title&#34;],
    &#34;content&#34;: [&#34;&lt;h2&gt;...&lt;/h2&gt;&lt;p&gt;...&lt;/p&gt;&#34;],
    &#34;post-status&#34;: [&#34;draft&#34;]
  }
}
```

Any Micropub-compatible endpoint would accept the same shape, so the publishing half of this workflow isn&#39;t locked to one host. The `post-status: draft` field is deliberate — **every post lands as a draft** so it can be reviewed in the editor before going public. The endpoint responds with the new post&#39;s URL, a preview link, and an edit link, which the workflow passes straight back to the webhook caller.


## Error handling


- A shared error-handler workflow catches failures across the automation.
- The webhook always responds, even on failure, so a caller never hangs.
- Image-upload failures are non-fatal (see above).
- A missing title produces an explicit, descriptive error listing what was searched.
- Full-text false positives are neutralized by the scoring node rather than by hoping the search ranks correctly.


## Credentials and configuration (redacted)


For obvious reasons, the specifics below are not published:


- **Craft Connect REST link** — a private access link used to search Craft and fetch block content.
- **Micro.blog app token** — a Bearer token generated in Micro.blog account settings, stored in a dedicated &#34;Set Token&#34; node so it can be rotated in one place.
- **n8n instance URL, webhook path, and internal workflow IDs** — infrastructure details specific to a self-hosted deployment.


If you rebuild something like this, you&#39;d supply your own Craft access link and your own Micro.blog token, and point the workflow at your own n8n instance.


## Takeaways


- Treat a full-text search as untrusted input and score its results before acting on them.
- When migrating content between hosts, migrate the *assets* too — don&#39;t hotlink another service&#39;s CDN.
- Watch where an API returns the data you need; a `Location` header is easy to miss if you only read response bodies.
- Prefer open standards (Micropub) over proprietary APIs where you can — it keeps the integration portable.
- Publish to draft first. Automation should hand you a reviewable result, not a live surprise.
</source:markdown>
    </item>
    
    <item>
      <title>The Second Half of 2026</title>
      <link>https://meta.numericcitizen.me/2026/06/16/the-second-half-of.html</link>
      <pubDate>Tue, 16 Jun 2026 21:53:16 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/16/the-second-half-of.html</guid>
      <description>&lt;p&gt;After spending the &lt;a href=&#34;https://meta.numericcitizen.me/2026/06/15/reach-is-the-right-word.html&#34;&gt;first half of 2026&lt;/a&gt; vibe-coding web applications, now that they are mature and operational, I&amp;rsquo;m thinking about how I&amp;rsquo;m going to spend the second half: setting up and finding the right use cases for running agentic AI locally on my dormant M4 Mac mini. Just another digital world open for exploration.&lt;/p&gt;
</description>
      <source:markdown>After spending the [first half of 2026](https://meta.numericcitizen.me/2026/06/15/reach-is-the-right-word.html) vibe-coding web applications, now that they are mature and operational, I&#39;m thinking about how I&#39;m going to spend the second half: setting up and finding the right use cases for running agentic AI locally on my dormant M4 Mac mini. Just another digital world open for exploration.
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/06/16/manton-reece-on-wordpress-blogs.html</link>
      <pubDate>Tue, 16 Jun 2026 19:27:58 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/16/manton-reece-on-wordpress-blogs.html</guid>
      <description>&lt;p&gt;Manton Reece on &lt;a href=&#34;https://www.manton.org/2026/06/16/wordpress-blogs-in-microblog.html&#34;&gt;WordPress blogs in Micro.blog&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Several months ago I blogged that we wanted to have more integration with WordPress and Ghost in Micro.blog. I’ve now rolled out the first part of that, with an option to add a WordPress blog to Micro.blog’s web interface. New posts and edits sync back and forth between Micro.blog and WordPress.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I no longer use WordPress; I use Ghost since I moved out a few years ago. I&amp;rsquo;m really looking forward to seeing how this new integration enables new workflows or simply tweaks existing ones. Some posts are rather complex, and I&amp;rsquo;m curious to see how Micro.blog would handle these.&lt;/p&gt;
</description>
      <source:markdown>Manton Reece on [WordPress blogs in Micro.blog](https://www.manton.org/2026/06/16/wordpress-blogs-in-microblog.html):

&gt; Several months ago I blogged that we wanted to have more integration with WordPress and Ghost in Micro.blog. I’ve now rolled out the first part of that, with an option to add a WordPress blog to Micro.blog’s web interface. New posts and edits sync back and forth between Micro.blog and WordPress.

I no longer use WordPress; I use Ghost since I moved out a few years ago. I&#39;m really looking forward to seeing how this new integration enables new workflows or simply tweaks existing ones. Some posts are rather complex, and I&#39;m curious to see how Micro.blog would handle these.
</source:markdown>
    </item>
    
    <item>
      <title>Reach is the right word</title>
      <link>https://meta.numericcitizen.me/2026/06/15/reach-is-the-right-word.html</link>
      <pubDate>Mon, 15 Jun 2026 21:46:59 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/15/reach-is-the-right-word.html</guid>
      <description>&lt;p&gt;I was exploring the GitHub website, my profile page to be exact. Here&amp;rsquo;s my GitHub activity panel for 2026 so far. Apart from the commits from the Micro.blog auto-archiving process, this is what it shows, with everything beginning on January 1st: the contributions coming from my vibe activities. This represents nearly 8 commits per day, every day, resulting in seven custom-built web applications.&lt;/p&gt;
&lt;p&gt;Looking back on the past six months, I cannot believe how far I&amp;rsquo;ve come with all this. If I could choose one word to summarize what generative AI and vibe coding have done for me, it would be &amp;ldquo;reach&amp;rdquo;. I have achieved goals that would otherwise have required years of coding experience. The only thing I had was years of end-user experience and a clear idea of what would be fulfilling.&lt;/p&gt;
&lt;p&gt;Excited to see what the next six months of 2026 have in store.&lt;/p&gt;
&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/github-activity-first-half-2026.png&#34; width=&#34;600&#34; height=&#34;205&#34; alt=&#34;&#34;&gt;
</description>
      <source:markdown>I was exploring the GitHub website, my profile page to be exact. Here&#39;s my GitHub activity panel for 2026 so far. Apart from the commits from the Micro.blog auto-archiving process, this is what it shows, with everything beginning on January 1st: the contributions coming from my vibe activities. This represents nearly 8 commits per day, every day, resulting in seven custom-built web applications. 

Looking back on the past six months, I cannot believe how far I&#39;ve come with all this. If I could choose one word to summarize what generative AI and vibe coding have done for me, it would be &#34;reach&#34;. I have achieved goals that would otherwise have required years of coding experience. The only thing I had was years of end-user experience and a clear idea of what would be fulfilling. 

Excited to see what the next six months of 2026 have in store.

&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/github-activity-first-half-2026.png&#34; width=&#34;600&#34; height=&#34;205&#34; alt=&#34;&#34;&gt;
</source:markdown>
    </item>
    
    <item>
      <title>Here and There</title>
      <link>https://meta.numericcitizen.me/2026/06/14/here-and-there.html</link>
      <pubDate>Sun, 14 Jun 2026 15:28:48 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/14/here-and-there.html</guid>
      <description>&lt;p&gt;If it&amp;rsquo;s a very short thought, it goes &lt;a href=&#34;https://blips.numericcitizen.me&#34;&gt;here&lt;/a&gt;. If it&amp;rsquo;s a great link, I share it &lt;a href=&#34;https://blips.numericcitizen.me&#34;&gt;there&lt;/a&gt;, too. Any in-the-moment thing is &lt;a href=&#34;https://blips.numericcitizen.me&#34;&gt;here&lt;/a&gt;, too. When I explain why I do this and how I do that, it&amp;rsquo;s &lt;a href=&#34;https://meta.numericcitizen.me&#34;&gt;right here&lt;/a&gt;. Long-form articles or a new edition of my newsletter, well, that&amp;rsquo;s over &lt;a href=&#34;https://numericcitizen.me&#34;&gt;there&lt;/a&gt;. Other written tidbits, not too short, not too long, well, it goes &lt;a href=&#34;https://blog.numericcitizen.me&#34;&gt;here&lt;/a&gt;, of course. I wish I could make this post stick to the main page.&lt;/p&gt;
</description>
      <source:markdown>If it&#39;s a very short thought, it goes [here](https://blips.numericcitizen.me). If it&#39;s a great link, I share it [there](https://blips.numericcitizen.me), too. Any in-the-moment thing is [here](https://blips.numericcitizen.me), too. When I explain why I do this and how I do that, it&#39;s [right here](https://meta.numericcitizen.me). Long-form articles or a new edition of my newsletter, well, that&#39;s over [there](https://numericcitizen.me). Other written tidbits, not too short, not too long, well, it goes [here](https://blog.numericcitizen.me), of course. I wish I could make this post stick to the main page. 
</source:markdown>
    </item>
    
    <item>
      <title>From Craft to Ghost (images included)</title>
      <link>https://meta.numericcitizen.me/2026/06/07/from-craft-to-ghost-images.html</link>
      <pubDate>Sun, 07 Jun 2026 08:46:20 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/07/from-craft-to-ghost-images.html</guid>
      <description>&lt;p&gt;I finally have a Claude skill that works end-to-end for publishing a document (with images) in draft mode from Craft to Ghost. Two important things happen with this workflow: Claude invokes an n8n workflow that first creates the article in Ghost and performs a full image rehosting from the Craft backend to Ghost. Without this rehosting, images in the Ghost article would still refer to resources hosted on the Craft backend, which I don&amp;rsquo;t want. 😎&lt;/p&gt;
&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/fromcrafttoghostworkflow.png&#34; width=&#34;600&#34; height=&#34;979&#34; alt=&#34;&#34;&gt;
&lt;p&gt;Of course, none of this would be required if there were a way to publish directly to Ghost from within Craft. 🤷🏻‍♂️&lt;/p&gt;
</description>
      <source:markdown>I finally have a Claude skill that works end-to-end for publishing a document (with images) in draft mode from Craft to Ghost. Two important things happen with this workflow: Claude invokes an n8n workflow that first creates the article in Ghost and performs a full image rehosting from the Craft backend to Ghost. Without this rehosting, images in the Ghost article would still refer to resources hosted on the Craft backend, which I don&#39;t want. 😎

&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/fromcrafttoghostworkflow.png&#34; width=&#34;600&#34; height=&#34;979&#34; alt=&#34;&#34;&gt;

Of course, none of this would be required if there were a way to publish directly to Ghost from within Craft. 🤷🏻‍♂️
</source:markdown>
    </item>
    
    <item>
      <title>The Numeric Citizen Analytics Dashboard Experiment</title>
      <link>https://meta.numericcitizen.me/2026/06/06/the-numeric-citizen-analytics-dashboard.html</link>
      <pubDate>Sat, 06 Jun 2026 08:49:07 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/06/06/the-numeric-citizen-analytics-dashboard.html</guid>
      <description>&lt;p&gt;This morning, I delved into integrating Craft with Claude Cowork. Using the Craft MCP connector, I built a dashboard that sources data directly from Craft tables. This setup generates a Live Artifact in Claude Cowork, which dynamically updates as more data is added. Although Lovable could have been used to achieve this, the absence of custom domain support in its free tier led me to choose Claude Cowork, which offers more flexibility for my needs.&lt;/p&gt;
&lt;p&gt;&lt;video controls=&#34;controls&#34; playsinline=&#34;playsinline&#34; preload=&#34;none&#34; width=&#34;2140&#34; height=&#34;1440&#34; poster=&#34;https://cdn.uploads.micro.blog/143495/2026/frames/1775364-0-8bb8a5.jpg&#34; src=&#34;https://cdn.uploads.micro.mov/143495/2026/numericcitizenanalyticsdashboard/playlist.m3u8&#34;&gt;&lt;/video&gt;&lt;/p&gt;
</description>
      <source:markdown>This morning, I delved into integrating Craft with Claude Cowork. Using the Craft MCP connector, I built a dashboard that sources data directly from Craft tables. This setup generates a Live Artifact in Claude Cowork, which dynamically updates as more data is added. Although Lovable could have been used to achieve this, the absence of custom domain support in its free tier led me to choose Claude Cowork, which offers more flexibility for my needs. 

&lt;video controls=&#34;controls&#34; playsinline=&#34;playsinline&#34; preload=&#34;none&#34; width=&#34;2140&#34; height=&#34;1440&#34; poster=&#34;https://cdn.uploads.micro.blog/143495/2026/frames/1775364-0-8bb8a5.jpg&#34; src=&#34;https://cdn.uploads.micro.mov/143495/2026/numericcitizenanalyticsdashboard/playlist.m3u8&#34;&gt;&lt;/video&gt;
</source:markdown>
    </item>
    
    <item>
      <title>The Numeric Citizen Digital Ecosystem — Edition 2026-04</title>
      <link>https://meta.numericcitizen.me/2026/04/27/the-numeric-citizen-digital-ecosystem.html</link>
      <pubDate>Mon, 27 Apr 2026 17:38:17 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/27/the-numeric-citizen-digital-ecosystem.html</guid>
      <description>&lt;p&gt;Today, I’m excited to share my latest digital ecosystem update, previously known as “The Numeric Citizen Content Creator Workflow”. The diagram sports a new title: “The Numeric Citizen Digital Ecosystem” to better reflect its scope: to enumerate services and apps at the center of my digital presence. It was entirely rebuilt in Apple Freeform, leaving Apple Keynote behind. Freeform is a joy to use; it’s much more flexible and powerful than Keynote, too. The content was also expanded to include a new set of tools I have built over the last few months since publishing &lt;a href=&#34;https://meta.numericcitizen.me/2025/11/02/my-content-creation-ecosystem-fall.html&#34;&gt;the previous update&lt;/a&gt;. Let&#39;s dive in for all the details. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-0-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;The entire ecosystem diagram was rebuilt from the ground up. Full resolution version available &lt;a href=&#34;https://go.numericcitizen.me/kXrGe2Fk&#34;&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At a high level, both Micro.blog and Ghost remain the two hosting and publishing pillars for most of my *.numericcitizen.me websites, while a few other websites, like my Ko-fi page and my new about website, Who Is Numeric Citizen, are hosted elsewhere. On the diagram, my websites are positioned on the left and in the top-left portion. &lt;/p&gt;
&lt;p&gt;As you might notice, a lot has happened since my last update. Thanks to Claude AI and Claude Code, I made a major shift toward web app to meet two fundamental needs: a brand new bookmark manager (replacing AnyBox), and a lightweight RSS reader that integrates with my bookmark manager. Together, they support my reading workflow and help me produce the &lt;a href=&#34;https://numericcitizen.me/tag/ephemeral-scrapbook/&#34;&gt;Ephemeral Scrapbook newsletter&lt;/a&gt;. See both web apps in &lt;a href=&#34;A%20Quick%20Tour%20of%20the%20Best%20Bookmark%20Manager%20&amp;%20RSS%20Reader%20Built%20Entirely%20With%20Claude%20Code%20https://youtu.be/Wb5r61MeSQY&#34;&gt;this YouTube video&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-1-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;My custom-built RSS reader web application&lt;/p&gt;
&lt;h3&gt;What’s in, what changed since last fall &lt;/h3&gt;
&lt;p&gt;AI is now playing a more prominent role in my digital ecosystem since the beginning of 2026. It’s mainly used for vibe coding, maintaining my web applications, and content summarization. You’ll see little light bulbs (💡) in the diagram; they indicate where AI summarization is involved. Anthropic’s Claude AI replaced OpenAI’s ChatGPT in all my workflows. Plus, Claude AI and Claude Code enabled many new possibilities for helping me build small digital services and web apps for my personal needs. It’s something I couldn’t have imagined a year ago.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-2-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;Claude Code’s main window with some of my projects on the left sidebar and the DIFF view shown on the right&lt;/p&gt;
&lt;p&gt;Another milestone was to &lt;a href=&#34;https://blog.numericcitizen.me/2025/12/17/goodbye-ifttt.html&#34;&gt;replace IFTTT with n8n automation&lt;/a&gt;. It’s a major upgrade in functionality and usability. My n8n instance is running on the Digital Ocean hosting service, inside a pre-packaged “droplet” with 1 GB of RAM and 10 GB of disk space for $6 a month. Digital Ocean provides a one-click install of n8n which really made a difference in selecting Digital Ocean as a hosting service. I created more than a dozen automations, far more complex and useful than what I could build with IFTTT. Claude AI was also involved in optimizing many n8n workflows. It was possible because n8n supports the MCP endpoint that is exposed to Claude AI. In the following table, I present a summary of my n8n automation workflows. As you will see, Discord is a new entry, as it provides a custom server to receive n8n workflow outputs and some status reports from Tinylytics. Also good to know: all my n8n workflows are automatically documented in a Craft document, thanks to Claude Code, which connects to both the n8n and Craft backends. To get a well-structured documentation, I created a Claude Skill.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-3-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;A portion of an automation workflow shown in the n8n canvas&lt;/p&gt;
&lt;h4&gt;My automated n8n workflows &lt;/h4&gt;
&lt;p&gt;Here’s a list of utilities running as n8n workflows on my self-hosted DigitalOcean instance. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Credit Health Check&lt;/strong&gt; — Pre-flight check on Anthropic credits; alerts Discord if depleted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Today&#39;s Forecast&lt;/strong&gt; — Pulls weather data into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tinylytics Insights&lt;/strong&gt; — Injects site analytics summary into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple Daily News&lt;/strong&gt; — Fetches MacSurfer headlines into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setup Craft Daily Note&lt;/strong&gt; — Creates the day&#39;s 8-section journaling scaffold in Craft&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic Daily Cost Report&lt;/strong&gt; — Posts 7-day and 30-day AI spend breakdown to Discord&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example of automatically propulated Craft Daily note, thanks to n8n automation. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-4-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h4&gt;RSS &amp; News Aggregation &lt;/h4&gt;
&lt;p&gt;A few workflows are used for content processing in the context of news consumption and Micro.blog timeline processing. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RSS Daily Summary&lt;/strong&gt; — Aggregates RSS feeds and delivers an AI-summarized digest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro.blog Timeline Highlights&lt;/strong&gt; — Summarizes Micro.blog activity via Claude&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple News Flash Alerts&lt;/strong&gt; — Real-time Apple news alerts from RSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apps &amp; Services Release Highlights&lt;/strong&gt; — Monitors release notes feeds for notable updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Content &amp; Publishing &lt;/h4&gt;
&lt;p&gt;Other workflows for supporting my content creation include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Craft → Ghost&lt;/strong&gt; — Two workflows (specific and generic) push Craft documents to Ghost as drafts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ghost Publish Proxy&lt;/strong&gt; — Triggers final publication on Ghost via webhook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Craft Fetch Proxy&lt;/strong&gt; — Fetches Craft document content on demand for downstream processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poke to Craft / Peek at Ghost&lt;/strong&gt; — Manual/chat-triggered utilities for quick content inspection&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Newsletter &amp; Email &lt;/h4&gt;
&lt;p&gt;A special workflow automation is processing email summarization on demand: simply forwarding an email to a dedicated Gmail account and after a few seconds I’ll receive a summary on my Discord server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email Summarizer&lt;/strong&gt; — Polls Gmail every minute; summarizes newsletters and posts to Discord&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Maintenance &lt;/h4&gt;
&lt;p&gt;Finally, backing up my workflows is a must, just in case something really bad happens on my n8n instance. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Backup&lt;/strong&gt; — Backs up all n8n workflow definitions to a GitHub repo every Sunday&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-5-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;The Craft Agents main window&lt;/p&gt;
&lt;p&gt;The updated diagram illustrates this: Craft consists of two parts—Craft content stored in the Craft cloud backend and various Craft clients, including the native general-purpose client and Craft Agents. Additionally, Craft now supports MCP and offers a comprehensive set of APIs, emphasizing the division between data storage and client applications. These latest additions to Craft are game changers and enable new use cases. &lt;/p&gt;
&lt;p&gt;A few thoughts and observations about Craft Agents, a sort of spin-off of Craft, are worth sharing here. Think about Craft Agents as an orchestrator of AI agents. In many ways, Craft Agents can be compared to the Claude Desktop app. There is a high level of affinity between Craft Agents and Craft, connected via APIs or MCP. Consuming Craft content through Craft Agents is an obvious use case. Yet, I’m still not sure why the team behind Craft is spending so much effort on this, but it’s interesting to follow nonetheless. I’m still looking for clear use cases for it, hence the yellow dot (🟡) on its icon in the diagram. There are a few aspects of the app’s design and structure that I don’t like. I don’t like using the task manager to organize conversations. I don’t think task management belongs in this app. Plus, Craft Agents is a very hungry consumer of AI credits. It’s a major concern unless you subscribe to the highest tier of any AI provider (OpenAI, Anthropic, etc.). It’s worth noting that Craft also offers an assistant working inside Craft itself. &lt;/p&gt;
&lt;p&gt;Also added to my digital ecosystem is CleanShot Cloud for hosting publicly shared screenshots or short screen recordings. I use that to share bugs or feedback. CleanShot X is sort of the client to CleanShot Cloud and is the best Mac utility you can get if you tae a lot of screenshots. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-6-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;One last automation that prevented me from closing my IFTTT account was the process of automatically archiving my publications in DayOne. This process was briefly described in &lt;a href=&#34;https://meta.numericcitizen.me/2023/03/06/documenting-my-numeric-life-with.html&#34;&gt;this blog post&lt;/a&gt;. Each time I share a blog post or an article, it is saved in DayOne. Micro.blog added a send-to-DayOne feature, which was the last needed nail in the coffin of IFTTT. It was such a relief. &lt;/p&gt;
&lt;p&gt;Speaking of Micro.blog, I created a new website for sharing automated blog post digests on a monthly basis. Most of the process is supported by the use of AI summarization. It’s not fully automated but very effective. Each month I send my Micro.blog postss digest to Craft fo later processing using Craft Agents. The process takes less than 15 minutes to complete. I know there is a potential for a fully automated process. It’s on my todo list. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-7-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h3&gt;What’s out since the last update &lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Chillidog Web Hosting&lt;/strong&gt; is out (the service hosting the &lt;a href=&#34;https://whois.numericcitizen.me&#34;&gt;Who Is Numeric Citizen website&lt;/a&gt;). It was replaced with Realmac Software Elements’ hosting solution. You can read the doc &lt;a href=&#34;https://docs.realmacsoftware.com/elements-docs/hosting&#34;&gt;here&lt;/a&gt;. The transition was seamless. I prefer integrated solutions, which Realmac is now offering. Plus. &lt;a href=&#34;https://support.exacthosting.com/support/solutions/articles/201000125536-chillidog-hosting-customer-acquisition-guide-welcome-to-exact-hosting&#34;&gt;Chillidog was &lt;/a&gt;purchased last year by Exact Hosting, and the purchase has been reported to degrade customer service.&lt;/p&gt;
&lt;p&gt;Last fall, I added the &lt;strong&gt;ChatGPT Atlas&lt;/strong&gt; browser to my ecosystem, but I removed it after switching to Claude AI. OpenAI Atlas was mainly used for summarizing articles, but now I do this within the Claude Desktop app. I still prefer using the ARC Browser, even though it might eventually be discontinued. The new browser, Dia, could take its place, but I’m interested to see how things unfold. Dia appears to require a Pro subscription to enable AI features in the browser. At $20 a month, I’ll pass. &lt;/p&gt;
&lt;p&gt;Gone is &lt;strong&gt;Google News&lt;/strong&gt; for cross-posting from Micro.blog. It never took off. Also gone is AnyBox, the very well-done bookmark manager available on all Apple platforms, but not available on the web, like Raindrop.io. I never liked Raindrop.io, so I built my own bookmark manager as a web-only app. It’s one of my new custom-built web apps.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;strong&gt;numericcitizen.io&lt;/strong&gt; domain will be retired when it expires later this year, and the content hosted on a dedicated Craft subscription has already been moved to my main Craft subscription, helping me reduce costs. The &lt;a href=&#34;https://meta.numericcitizen.me&#34;&gt;meta.numericcitizen.me&lt;/a&gt; is taking over (my previous content was migrated there during 2025). Some of my content was also simply removed from public access. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-8-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;My newly redesigned metablog as seen in dark mode&lt;/p&gt;
&lt;h3&gt;Still pondering about these &lt;/h3&gt;
&lt;p&gt;You’ll find yellow dots on the diagram which points to services or apps that I’m reconsidering. Let’s review a few of them. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plausible vs Tinylytics&lt;/strong&gt;: I use two web analytics. Plausible has been around in my ecosystem since I left Google Analytics. Then came long Tinylytics and I wanted to support its developer plus it provides a great design compared to Plausible. Yet, I have a lot of historic data in the latter. Plus, I started using Tinylytics APIs to feed one of my workflows who inject data inside Craft daily notes and dashboard web application. I could replace this with Plausible’s APIs but I don’t feel it’s worth the effort. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Things 3&lt;/strong&gt;, a popular and highly regarded task manager, is currently being reconsidered. I like managing my to-dos, but I don’t have many. If I want to eliminate Things 3, I could switch to Craft’s basic task management, but it’s quite limited. For now, my most likely option is to create my own app, much like I did with my RSS reader or bookmark manager. However, I’m not in a hurry to switch away since it doesn’t require a subscription, giving me plenty of time to decide and develop a replacement. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ulysses&lt;/strong&gt; is another case where I’m pondering its long-term usefulness. If I can post to Micro.blog or Ghost directly from Craft (using my custom-made n8n workflows), why should I continue paying for this app? The next renewal is a year from now.&lt;/p&gt;
&lt;p&gt;Finally, my &lt;strong&gt;Flipboard&lt;/strong&gt; account hosts a magazine that pulls content from my main website via its RSS feed. I have 8 followers, apparently. I never get any reactions or comments from this place. The bigger question: is Flipboard still a thing these days?&lt;/p&gt;
&lt;h3&gt;Risk management &lt;/h3&gt;
&lt;p&gt;In this edition of the diagram, I included red dots (🔴) to indicate potential disruption risks. For example, Anthropic recently adjusted Claude&#39;s credit consumption, leading to a fivefold increase in the number of credits needed to perform the same task; something I&#39;ve noticed too. Additionally, Anthropic conducted an experiment in which new subscribers could access Claude Code only if they chose the Max subscription tier at $200 per month. Although they quickly reversed this change, it raises the concern that they might eliminate the $20 plan altogether. If that happened, I could face serious difficulties and might stop maintaining my web applications built with Claude Code. Vercel is another risk potential: I’m using the free tier, which is rather generous. If they decided to remove this free tier, I would have to reconsider my position: either drop my web application or accept paying the monthly price they charge. &lt;/p&gt;
&lt;h3&gt;Concluding thoughts &lt;/h3&gt;
&lt;p&gt;This evolution reflects a fundamental shift in how I approach my digital life. By embracing AI assistants like Claude and building custom tools tailored to my specific needs, I&#39;ve moved away from cobbling together disparate services toward a more cohesive, intentional ecosystem. The transition from automation platforms like IFTTT to n8n, coupled with the ability to code solutions with Claude Code, has given me both flexibility and control—rare commodities in the world of Software-as-a-Service.&lt;/p&gt;
&lt;p&gt;The introduction of AI summarization across my workflows has transformed how I consume information, while the consolidation of my web presence under fewer, better-managed domains simplifies my digital footprint. Yet this ecosystem remains dynamic and somewhat fragile, dependent on the sustained availability of key services and the pricing decisions of AI providers. The risk management considerations I&#39;ve outlined aren&#39;t just technical footnotes—they&#39;re essential guideposts for maintaining digital independence in an increasingly interconnected world.&lt;/p&gt;
&lt;p&gt;As I continue to iterate and refine this ecosystem, the principles remain constant: intentionality, control, and the ability to evolve. The next edition will likely bring even more changes, but I&#39;m optimistic that the foundations I&#39;ve built will prove resilient enough to adapt to whatever comes next.&lt;/p&gt;
&lt;p&gt;Previous update to my digital ecosystem can be found &lt;a href=&#34;https://meta.numericcitizen.me/categories/meta/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
      <source:markdown>&lt;p&gt;Today, I’m excited to share my latest digital ecosystem update, previously known as “The Numeric Citizen Content Creator Workflow”. The diagram sports a new title: “The Numeric Citizen Digital Ecosystem” to better reflect its scope: to enumerate services and apps at the center of my digital presence. It was entirely rebuilt in Apple Freeform, leaving Apple Keynote behind. Freeform is a joy to use; it’s much more flexible and powerful than Keynote, too. The content was also expanded to include a new set of tools I have built over the last few months since publishing &lt;a href=&#34;https://meta.numericcitizen.me/2025/11/02/my-content-creation-ecosystem-fall.html&#34;&gt;the previous update&lt;/a&gt;. Let&#39;s dive in for all the details. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-0-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;The entire ecosystem diagram was rebuilt from the ground up. Full resolution version available &lt;a href=&#34;https://go.numericcitizen.me/kXrGe2Fk&#34;&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At a high level, both Micro.blog and Ghost remain the two hosting and publishing pillars for most of my *.numericcitizen.me websites, while a few other websites, like my Ko-fi page and my new about website, Who Is Numeric Citizen, are hosted elsewhere. On the diagram, my websites are positioned on the left and in the top-left portion. &lt;/p&gt;
&lt;p&gt;As you might notice, a lot has happened since my last update. Thanks to Claude AI and Claude Code, I made a major shift toward web app to meet two fundamental needs: a brand new bookmark manager (replacing AnyBox), and a lightweight RSS reader that integrates with my bookmark manager. Together, they support my reading workflow and help me produce the &lt;a href=&#34;https://numericcitizen.me/tag/ephemeral-scrapbook/&#34;&gt;Ephemeral Scrapbook newsletter&lt;/a&gt;. See both web apps in &lt;a href=&#34;A%20Quick%20Tour%20of%20the%20Best%20Bookmark%20Manager%20&amp;%20RSS%20Reader%20Built%20Entirely%20With%20Claude%20Code%20https://youtu.be/Wb5r61MeSQY&#34;&gt;this YouTube video&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-1-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;My custom-built RSS reader web application&lt;/p&gt;
&lt;h3&gt;What’s in, what changed since last fall &lt;/h3&gt;
&lt;p&gt;AI is now playing a more prominent role in my digital ecosystem since the beginning of 2026. It’s mainly used for vibe coding, maintaining my web applications, and content summarization. You’ll see little light bulbs (💡) in the diagram; they indicate where AI summarization is involved. Anthropic’s Claude AI replaced OpenAI’s ChatGPT in all my workflows. Plus, Claude AI and Claude Code enabled many new possibilities for helping me build small digital services and web apps for my personal needs. It’s something I couldn’t have imagined a year ago.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-2-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;Claude Code’s main window with some of my projects on the left sidebar and the DIFF view shown on the right&lt;/p&gt;
&lt;p&gt;Another milestone was to &lt;a href=&#34;https://blog.numericcitizen.me/2025/12/17/goodbye-ifttt.html&#34;&gt;replace IFTTT with n8n automation&lt;/a&gt;. It’s a major upgrade in functionality and usability. My n8n instance is running on the Digital Ocean hosting service, inside a pre-packaged “droplet” with 1 GB of RAM and 10 GB of disk space for $6 a month. Digital Ocean provides a one-click install of n8n which really made a difference in selecting Digital Ocean as a hosting service. I created more than a dozen automations, far more complex and useful than what I could build with IFTTT. Claude AI was also involved in optimizing many n8n workflows. It was possible because n8n supports the MCP endpoint that is exposed to Claude AI. In the following table, I present a summary of my n8n automation workflows. As you will see, Discord is a new entry, as it provides a custom server to receive n8n workflow outputs and some status reports from Tinylytics. Also good to know: all my n8n workflows are automatically documented in a Craft document, thanks to Claude Code, which connects to both the n8n and Craft backends. To get a well-structured documentation, I created a Claude Skill.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-3-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;A portion of an automation workflow shown in the n8n canvas&lt;/p&gt;
&lt;h4&gt;My automated n8n workflows &lt;/h4&gt;
&lt;p&gt;Here’s a list of utilities running as n8n workflows on my self-hosted DigitalOcean instance. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Credit Health Check&lt;/strong&gt; — Pre-flight check on Anthropic credits; alerts Discord if depleted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Today&#39;s Forecast&lt;/strong&gt; — Pulls weather data into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tinylytics Insights&lt;/strong&gt; — Injects site analytics summary into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple Daily News&lt;/strong&gt; — Fetches MacSurfer headlines into the Craft daily note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setup Craft Daily Note&lt;/strong&gt; — Creates the day&#39;s 8-section journaling scaffold in Craft&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic Daily Cost Report&lt;/strong&gt; — Posts 7-day and 30-day AI spend breakdown to Discord&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example of automatically propulated Craft Daily note, thanks to n8n automation. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-4-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h4&gt;RSS &amp; News Aggregation &lt;/h4&gt;
&lt;p&gt;A few workflows are used for content processing in the context of news consumption and Micro.blog timeline processing. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RSS Daily Summary&lt;/strong&gt; — Aggregates RSS feeds and delivers an AI-summarized digest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micro.blog Timeline Highlights&lt;/strong&gt; — Summarizes Micro.blog activity via Claude&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple News Flash Alerts&lt;/strong&gt; — Real-time Apple news alerts from RSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apps &amp; Services Release Highlights&lt;/strong&gt; — Monitors release notes feeds for notable updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Content &amp; Publishing &lt;/h4&gt;
&lt;p&gt;Other workflows for supporting my content creation include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Craft → Ghost&lt;/strong&gt; — Two workflows (specific and generic) push Craft documents to Ghost as drafts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ghost Publish Proxy&lt;/strong&gt; — Triggers final publication on Ghost via webhook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Craft Fetch Proxy&lt;/strong&gt; — Fetches Craft document content on demand for downstream processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poke to Craft / Peek at Ghost&lt;/strong&gt; — Manual/chat-triggered utilities for quick content inspection&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Newsletter &amp; Email &lt;/h4&gt;
&lt;p&gt;A special workflow automation is processing email summarization on demand: simply forwarding an email to a dedicated Gmail account and after a few seconds I’ll receive a summary on my Discord server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email Summarizer&lt;/strong&gt; — Polls Gmail every minute; summarizes newsletters and posts to Discord&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Maintenance &lt;/h4&gt;
&lt;p&gt;Finally, backing up my workflows is a must, just in case something really bad happens on my n8n instance. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Backup&lt;/strong&gt; — Backs up all n8n workflow definitions to a GitHub repo every Sunday&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-5-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;The Craft Agents main window&lt;/p&gt;
&lt;p&gt;The updated diagram illustrates this: Craft consists of two parts—Craft content stored in the Craft cloud backend and various Craft clients, including the native general-purpose client and Craft Agents. Additionally, Craft now supports MCP and offers a comprehensive set of APIs, emphasizing the division between data storage and client applications. These latest additions to Craft are game changers and enable new use cases. &lt;/p&gt;
&lt;p&gt;A few thoughts and observations about Craft Agents, a sort of spin-off of Craft, are worth sharing here. Think about Craft Agents as an orchestrator of AI agents. In many ways, Craft Agents can be compared to the Claude Desktop app. There is a high level of affinity between Craft Agents and Craft, connected via APIs or MCP. Consuming Craft content through Craft Agents is an obvious use case. Yet, I’m still not sure why the team behind Craft is spending so much effort on this, but it’s interesting to follow nonetheless. I’m still looking for clear use cases for it, hence the yellow dot (🟡) on its icon in the diagram. There are a few aspects of the app’s design and structure that I don’t like. I don’t like using the task manager to organize conversations. I don’t think task management belongs in this app. Plus, Craft Agents is a very hungry consumer of AI credits. It’s a major concern unless you subscribe to the highest tier of any AI provider (OpenAI, Anthropic, etc.). It’s worth noting that Craft also offers an assistant working inside Craft itself. &lt;/p&gt;
&lt;p&gt;Also added to my digital ecosystem is CleanShot Cloud for hosting publicly shared screenshots or short screen recordings. I use that to share bugs or feedback. CleanShot X is sort of the client to CleanShot Cloud and is the best Mac utility you can get if you tae a lot of screenshots. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-6-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;One last automation that prevented me from closing my IFTTT account was the process of automatically archiving my publications in DayOne. This process was briefly described in &lt;a href=&#34;https://meta.numericcitizen.me/2023/03/06/documenting-my-numeric-life-with.html&#34;&gt;this blog post&lt;/a&gt;. Each time I share a blog post or an article, it is saved in DayOne. Micro.blog added a send-to-DayOne feature, which was the last needed nail in the coffin of IFTTT. It was such a relief. &lt;/p&gt;
&lt;p&gt;Speaking of Micro.blog, I created a new website for sharing automated blog post digests on a monthly basis. Most of the process is supported by the use of AI summarization. It’s not fully automated but very effective. Each month I send my Micro.blog postss digest to Craft fo later processing using Craft Agents. The process takes less than 15 minutes to complete. I know there is a potential for a fully automated process. It’s on my todo list. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-7-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h3&gt;What’s out since the last update &lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Chillidog Web Hosting&lt;/strong&gt; is out (the service hosting the &lt;a href=&#34;https://whois.numericcitizen.me&#34;&gt;Who Is Numeric Citizen website&lt;/a&gt;). It was replaced with Realmac Software Elements’ hosting solution. You can read the doc &lt;a href=&#34;https://docs.realmacsoftware.com/elements-docs/hosting&#34;&gt;here&lt;/a&gt;. The transition was seamless. I prefer integrated solutions, which Realmac is now offering. Plus. &lt;a href=&#34;https://support.exacthosting.com/support/solutions/articles/201000125536-chillidog-hosting-customer-acquisition-guide-welcome-to-exact-hosting&#34;&gt;Chillidog was &lt;/a&gt;purchased last year by Exact Hosting, and the purchase has been reported to degrade customer service.&lt;/p&gt;
&lt;p&gt;Last fall, I added the &lt;strong&gt;ChatGPT Atlas&lt;/strong&gt; browser to my ecosystem, but I removed it after switching to Claude AI. OpenAI Atlas was mainly used for summarizing articles, but now I do this within the Claude Desktop app. I still prefer using the ARC Browser, even though it might eventually be discontinued. The new browser, Dia, could take its place, but I’m interested to see how things unfold. Dia appears to require a Pro subscription to enable AI features in the browser. At $20 a month, I’ll pass. &lt;/p&gt;
&lt;p&gt;Gone is &lt;strong&gt;Google News&lt;/strong&gt; for cross-posting from Micro.blog. It never took off. Also gone is AnyBox, the very well-done bookmark manager available on all Apple platforms, but not available on the web, like Raindrop.io. I never liked Raindrop.io, so I built my own bookmark manager as a web-only app. It’s one of my new custom-built web apps.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;strong&gt;numericcitizen.io&lt;/strong&gt; domain will be retired when it expires later this year, and the content hosted on a dedicated Craft subscription has already been moved to my main Craft subscription, helping me reduce costs. The &lt;a href=&#34;https://meta.numericcitizen.me&#34;&gt;meta.numericcitizen.me&lt;/a&gt; is taking over (my previous content was migrated there during 2025). Some of my content was also simply removed from public access. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-8-1777325734547.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;p&gt;My newly redesigned metablog as seen in dark mode&lt;/p&gt;
&lt;h3&gt;Still pondering about these &lt;/h3&gt;
&lt;p&gt;You’ll find yellow dots on the diagram which points to services or apps that I’m reconsidering. Let’s review a few of them. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plausible vs Tinylytics&lt;/strong&gt;: I use two web analytics. Plausible has been around in my ecosystem since I left Google Analytics. Then came long Tinylytics and I wanted to support its developer plus it provides a great design compared to Plausible. Yet, I have a lot of historic data in the latter. Plus, I started using Tinylytics APIs to feed one of my workflows who inject data inside Craft daily notes and dashboard web application. I could replace this with Plausible’s APIs but I don’t feel it’s worth the effort. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Things 3&lt;/strong&gt;, a popular and highly regarded task manager, is currently being reconsidered. I like managing my to-dos, but I don’t have many. If I want to eliminate Things 3, I could switch to Craft’s basic task management, but it’s quite limited. For now, my most likely option is to create my own app, much like I did with my RSS reader or bookmark manager. However, I’m not in a hurry to switch away since it doesn’t require a subscription, giving me plenty of time to decide and develop a replacement. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ulysses&lt;/strong&gt; is another case where I’m pondering its long-term usefulness. If I can post to Micro.blog or Ghost directly from Craft (using my custom-made n8n workflows), why should I continue paying for this app? The next renewal is a year from now.&lt;/p&gt;
&lt;p&gt;Finally, my &lt;strong&gt;Flipboard&lt;/strong&gt; account hosts a magazine that pulls content from my main website via its RSS feed. I have 8 followers, apparently. I never get any reactions or comments from this place. The bigger question: is Flipboard still a thing these days?&lt;/p&gt;
&lt;h3&gt;Risk management &lt;/h3&gt;
&lt;p&gt;In this edition of the diagram, I included red dots (🔴) to indicate potential disruption risks. For example, Anthropic recently adjusted Claude&#39;s credit consumption, leading to a fivefold increase in the number of credits needed to perform the same task; something I&#39;ve noticed too. Additionally, Anthropic conducted an experiment in which new subscribers could access Claude Code only if they chose the Max subscription tier at $200 per month. Although they quickly reversed this change, it raises the concern that they might eliminate the $20 plan altogether. If that happened, I could face serious difficulties and might stop maintaining my web applications built with Claude Code. Vercel is another risk potential: I’m using the free tier, which is rather generous. If they decided to remove this free tier, I would have to reconsider my position: either drop my web application or accept paying the monthly price they charge. &lt;/p&gt;
&lt;h3&gt;Concluding thoughts &lt;/h3&gt;
&lt;p&gt;This evolution reflects a fundamental shift in how I approach my digital life. By embracing AI assistants like Claude and building custom tools tailored to my specific needs, I&#39;ve moved away from cobbling together disparate services toward a more cohesive, intentional ecosystem. The transition from automation platforms like IFTTT to n8n, coupled with the ability to code solutions with Claude Code, has given me both flexibility and control—rare commodities in the world of Software-as-a-Service.&lt;/p&gt;
&lt;p&gt;The introduction of AI summarization across my workflows has transformed how I consume information, while the consolidation of my web presence under fewer, better-managed domains simplifies my digital footprint. Yet this ecosystem remains dynamic and somewhat fragile, dependent on the sustained availability of key services and the pricing decisions of AI providers. The risk management considerations I&#39;ve outlined aren&#39;t just technical footnotes—they&#39;re essential guideposts for maintaining digital independence in an increasingly interconnected world.&lt;/p&gt;
&lt;p&gt;As I continue to iterate and refine this ecosystem, the principles remain constant: intentionality, control, and the ability to evolve. The next edition will likely bring even more changes, but I&#39;m optimistic that the foundations I&#39;ve built will prove resilient enough to adapt to whatever comes next.&lt;/p&gt;
&lt;p&gt;Previous update to my digital ecosystem can be found &lt;a href=&#34;https://meta.numericcitizen.me/categories/meta/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</source:markdown>
    </item>
    
    <item>
      <title>Solving Broken Images When Exporting Craft Documents</title>
      <link>https://meta.numericcitizen.me/2026/04/25/solving-broken-images-when-exporting.html</link>
      <pubDate>Sat, 25 Apr 2026 13:27:03 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/25/solving-broken-images-when-exporting.html</guid>
      <description>&lt;h2&gt;The Problem &lt;/h2&gt;
&lt;p&gt;When exporting articles from Craft to Ulysses and Micro.blog, images referenced by temporary URLs quickly become broken links. Craft hosts images with public URLs that expire within days, leaving your published posts with missing images. This automation workflow solves that problem by re-hosting all images on Micro.blog before publishing.&lt;/p&gt;
&lt;h2&gt;How It Works &lt;/h2&gt;
&lt;p&gt;The workflow is triggered when you request to publish a Craft document to Micro.blog. Here&#39;s what happens behind the scenes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A request is send in Claude with the article title to publish&lt;/li&gt;
&lt;li&gt;The n8n automation searches my Craft space and uses a scoring algorithm to find the exact document (preventing false matches from body text mentions)&lt;/li&gt;
&lt;li&gt;The document&#39;s content is converted from Craft&#39;s block format into clean HTML, preserving headings, lists, formatting, quotes, code blocks, and more&lt;/li&gt;
&lt;li&gt;The workflow scans for all image URLs pointing to Craft&#39;s backend hosting&lt;/li&gt;
&lt;li&gt;Each image is downloaded from Craft and immediately re-uploaded to Micro.blog&#39;s permanent media storage&lt;/li&gt;
&lt;li&gt;All image references in the post are updated to point to the new, stable Micro.blog URLs&lt;/li&gt;
&lt;li&gt;The article is published as a draft to Micro.blog for review before going live, which is a manual process&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-0-1777137965533.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h2&gt;Key Technical Features &lt;/h2&gt;
&lt;h3&gt;Smart Document Matching &lt;/h3&gt;
&lt;p&gt;The search algorithm scores results by how closely the document title matches the request. Exact matches score 100, partial matches score lower, and body-text mentions are heavily penalized. This ensures I get the right document even if multiple articles discuss similar topics. The search is done via Craft API endpoint.&lt;/p&gt;
&lt;h3&gt;Rich Content Support &lt;/h3&gt;
&lt;p&gt;The conversion preserves all the formatting: paragraph styles, heading levels (h1–h4), bullet and numbered lists, blockquotes, task checkboxes, strikethrough text, code blocks, horizontal rules, and rich link bookmarks. Consecutive list items are automatically grouped into single lists.&lt;/p&gt;
&lt;h3&gt;Graceful Image Handling &lt;/h3&gt;
&lt;p&gt;If an image fails to upload (for example, unsupported formats like AVIF), the system keeps the original Craft URL in your post rather than failing entirely. This ensures the article publishes even if one image has issues.&lt;/p&gt;
&lt;h3&gt;Manual Review &lt;/h3&gt;
&lt;p&gt;All posts are created as drafts in Micro.blog. I can review the final result, check that images loaded correctly, and make edits before publishing it live.&lt;/p&gt;
&lt;h2&gt;Workflow Specifications &lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger:&lt;/strong&gt; Webhook at craft-to-microblog (available in my n8n instance wirh MCP endpoint enabled)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input:&lt;/strong&gt; Simple JSON with the article title to publish&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs used:&lt;/strong&gt; Craft&#39;s document search and block retrieval, Micro.blog&#39;s Micropub standard API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typical execution:&lt;/strong&gt; 4–6 seconds (image uploads add ~1.5 seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Draft post URL, preview link, and edit URL from Micro.blog&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why This Matters &lt;/h2&gt;
&lt;p&gt;This automation fills a gap in the content publishing process. I can craft and organize my articles in Craft, a versatile and attractive writing environment, and then publish them to Micro.blog without losing images or manually fixing broken links. I use a similar method to publish new editions of the Ephemeral Scrapbook newsletter, which relies on a separate n8n workflow to handle Ghost CMS-specific requirements. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-1-1777137965533.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
</description>
      <source:markdown>&lt;h2&gt;The Problem &lt;/h2&gt;
&lt;p&gt;When exporting articles from Craft to Ulysses and Micro.blog, images referenced by temporary URLs quickly become broken links. Craft hosts images with public URLs that expire within days, leaving your published posts with missing images. This automation workflow solves that problem by re-hosting all images on Micro.blog before publishing.&lt;/p&gt;
&lt;h2&gt;How It Works &lt;/h2&gt;
&lt;p&gt;The workflow is triggered when you request to publish a Craft document to Micro.blog. Here&#39;s what happens behind the scenes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A request is send in Claude with the article title to publish&lt;/li&gt;
&lt;li&gt;The n8n automation searches my Craft space and uses a scoring algorithm to find the exact document (preventing false matches from body text mentions)&lt;/li&gt;
&lt;li&gt;The document&#39;s content is converted from Craft&#39;s block format into clean HTML, preserving headings, lists, formatting, quotes, code blocks, and more&lt;/li&gt;
&lt;li&gt;The workflow scans for all image URLs pointing to Craft&#39;s backend hosting&lt;/li&gt;
&lt;li&gt;Each image is downloaded from Craft and immediately re-uploaded to Micro.blog&#39;s permanent media storage&lt;/li&gt;
&lt;li&gt;All image references in the post are updated to point to the new, stable Micro.blog URLs&lt;/li&gt;
&lt;li&gt;The article is published as a draft to Micro.blog for review before going live, which is a manual process&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-0-1777137965533.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
&lt;h2&gt;Key Technical Features &lt;/h2&gt;
&lt;h3&gt;Smart Document Matching &lt;/h3&gt;
&lt;p&gt;The search algorithm scores results by how closely the document title matches the request. Exact matches score 100, partial matches score lower, and body-text mentions are heavily penalized. This ensures I get the right document even if multiple articles discuss similar topics. The search is done via Craft API endpoint.&lt;/p&gt;
&lt;h3&gt;Rich Content Support &lt;/h3&gt;
&lt;p&gt;The conversion preserves all the formatting: paragraph styles, heading levels (h1–h4), bullet and numbered lists, blockquotes, task checkboxes, strikethrough text, code blocks, horizontal rules, and rich link bookmarks. Consecutive list items are automatically grouped into single lists.&lt;/p&gt;
&lt;h3&gt;Graceful Image Handling &lt;/h3&gt;
&lt;p&gt;If an image fails to upload (for example, unsupported formats like AVIF), the system keeps the original Craft URL in your post rather than failing entirely. This ensures the article publishes even if one image has issues.&lt;/p&gt;
&lt;h3&gt;Manual Review &lt;/h3&gt;
&lt;p&gt;All posts are created as drafts in Micro.blog. I can review the final result, check that images loaded correctly, and make edits before publishing it live.&lt;/p&gt;
&lt;h2&gt;Workflow Specifications &lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger:&lt;/strong&gt; Webhook at craft-to-microblog (available in my n8n instance wirh MCP endpoint enabled)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input:&lt;/strong&gt; Simple JSON with the article title to publish&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs used:&lt;/strong&gt; Craft&#39;s document search and block retrieval, Micro.blog&#39;s Micropub standard API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typical execution:&lt;/strong&gt; 4–6 seconds (image uploads add ~1.5 seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Draft post URL, preview link, and edit URL from Micro.blog&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why This Matters &lt;/h2&gt;
&lt;p&gt;This automation fills a gap in the content publishing process. I can craft and organize my articles in Craft, a versatile and attractive writing environment, and then publish them to Micro.blog without losing images or manually fixing broken links. I use a similar method to publish new editions of the Ephemeral Scrapbook newsletter, which relies on a separate n8n workflow to handle Ghost CMS-specific requirements. &lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/craft-image-1-1777137965533.png&#34; alt=&#34;&#34;&gt;&lt;/figure&gt;
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/24/now-that-i-manage-all.html</link>
      <pubDate>Fri, 24 Apr 2026 09:22:57 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/24/now-that-i-manage-all.html</guid>
      <description>&lt;p&gt;Now that I manage all my issues and enhancements in GitHub Issues, I just realized that I could automate many manual workflows on issues closure&amp;hellip; many interesting ideas here, like updating the README.md file once an issue is closed by Claude Code. 🤓&lt;/p&gt;
</description>
      <source:markdown>Now that I manage all my issues and enhancements in GitHub Issues, I just realized that I could automate many manual workflows on issues closure... many interesting ideas here, like updating the README.md file once an issue is closed by Claude Code. 🤓
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/23/im-not-planning-to-go.html</link>
      <pubDate>Thu, 23 Apr 2026 22:18:53 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/23/im-not-planning-to-go.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m not planning to go any further with &lt;a href=&#34;https://meta.numericcitizen.me/2026/04/19/just-testing-something-for-my.html&#34;&gt;my Lovable experimentation&lt;/a&gt;. The reason? On the free plan, custom domains are not supported. It&amp;rsquo;s a complete deal-breaker. Plus, the free tier doesn&amp;rsquo;t provide enough credits to build something meaningful, and you have to wait 24 hours before getting more. Too bad, it was somewhat promising. Pass. 😔 The good thing is that I&amp;rsquo;m focusing on Vercel for hosting web apps like mine.&lt;/p&gt;
</description>
      <source:markdown>I&#39;m not planning to go any further with [my Lovable experimentation](https://meta.numericcitizen.me/2026/04/19/just-testing-something-for-my.html). The reason? On the free plan, custom domains are not supported. It&#39;s a complete deal-breaker. Plus, the free tier doesn&#39;t provide enough credits to build something meaningful, and you have to wait 24 hours before getting more. Too bad, it was somewhat promising. Pass. 😔 The good thing is that I&#39;m focusing on Vercel for hosting web apps like mine. 
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/23/restarted-work-for-maintaining-and.html</link>
      <pubDate>Thu, 23 Apr 2026 07:32:29 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/23/restarted-work-for-maintaining-and.html</guid>
      <description>&lt;p&gt;Restarted work for maintaining and updating the &amp;ldquo;&lt;a href=&#34;https://whois.numericcitizen.me&#34;&gt;Who Is Numeric Citizen&lt;/a&gt;&amp;rdquo; website, now that my 90% of my vibe coding work is completed. See the latest &lt;a href=&#34;https://whois.numericcitizen.me/news/&#34;&gt;news post&lt;/a&gt; for more details.&lt;/p&gt;
</description>
      <source:markdown>Restarted work for maintaining and updating the &#34;[Who Is Numeric Citizen](https://whois.numericcitizen.me)&#34; website, now that my 90% of my vibe coding work is completed. See the latest [news post](https://whois.numericcitizen.me/news/) for more details.
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/19/just-testing-something-for-my.html</link>
      <pubDate>Sun, 19 Apr 2026 17:14:13 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/19/just-testing-something-for-my.html</guid>
      <description>&lt;p&gt;Just testing something for my next project&amp;hellip; for that one, I might try Lovable instead of Vercel&amp;hellip; because I want to try different services.&lt;/p&gt;
&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/testing-lovable-things3-duplicate.png&#34; width=&#34;600&#34; height=&#34;345&#34; alt=&#34;&#34;&gt;
</description>
      <source:markdown>Just testing something for my next project... for that one, I might try Lovable instead of Vercel... because I want to try different services.

&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/testing-lovable-things3-duplicate.png&#34; width=&#34;600&#34; height=&#34;345&#34; alt=&#34;&#34;&gt;
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/16/from-now-on-i-will.html</link>
      <pubDate>Thu, 16 Apr 2026 21:59:31 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/16/from-now-on-i-will.html</guid>
      <description>&lt;p&gt;From now on, I will document and track all bugs in my custom web apps using GitHub, instead of relying on checklists in Craft. Centralizing everything isn’t ideal; organizing issues in their appropriate locations is smarter. Additionally, Claude Code will be able to close issues on my request.&lt;/p&gt;
</description>
      <source:markdown>From now on, I will document and track all bugs in my custom web apps using GitHub, instead of relying on checklists in Craft. Centralizing everything isn’t ideal; organizing issues in their appropriate locations is smarter. Additionally, Claude Code will be able to close issues on my request. 
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/04/12/today-i-went-ahead-and.html</link>
      <pubDate>Sun, 12 Apr 2026 09:16:49 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/12/today-i-went-ahead-and.html</guid>
      <description>&lt;p&gt;Today I went ahead and fully migrated &amp;ldquo;&lt;a href=&#34;https://whois.numericcitizen.me&#34;&gt;Who Is Numeric Citizen&lt;/a&gt;&amp;rdquo; website to Realmac Software Elements Hosting instead of Chillidog Hosting service. Here&amp;rsquo;s why: A) Chillidog was recently sold, and people are already complaining about a decline in service quality. B) What Realmac Software accomplished with Elements in the last year is nothing less than exemplary. They built mature, native web design software for the Mac and a hosting service. I prefer to reward this company for this hard work.&lt;/p&gt;
&lt;p&gt;The migration was really simple and took me less than an hour. The service is a bit more expensive but includes more storage and unlimited network bandwidth. This could enable a future option for hosting more photography-related content. Finally, the web service feels snappier, too!&lt;/p&gt;
</description>
      <source:markdown>Today I went ahead and fully migrated &#34;[Who Is Numeric Citizen](https://whois.numericcitizen.me)&#34; website to Realmac Software Elements Hosting instead of Chillidog Hosting service. Here&#39;s why: A) Chillidog was recently sold, and people are already complaining about a decline in service quality. B) What Realmac Software accomplished with Elements in the last year is nothing less than exemplary. They built mature, native web design software for the Mac and a hosting service. I prefer to reward this company for this hard work.

The migration was really simple and took me less than an hour. The service is a bit more expensive but includes more storage and unlimited network bandwidth. This could enable a future option for hosting more photography-related content. Finally, the web service feels snappier, too! 
</source:markdown>
    </item>
    
    <item>
      <title>Coming Soon </title>
      <link>https://meta.numericcitizen.me/2026/04/09/coming-soon.html</link>
      <pubDate>Thu, 09 Apr 2026 19:20:16 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/04/09/coming-soon.html</guid>
      <description>&lt;p&gt;One of the first things I’m going to do when I come back home is to deploy my new blog visual theme built entirely with Claude Code. It’s ready. I’m anxiously awaiting for the moment I put that project behind. Next, I’ll spend some time on &lt;a href=&#34;https://whois.numericcitizen.me&#34;&gt;Who Is Numeric Citizen website&lt;/a&gt; design and hosting solution (I’m thinking of leaving Chillidog Hosting hosting service to go with Elements’ built in solution instead).&lt;/p&gt;
</description>
      <source:markdown>One of the first things I’m going to do when I come back home is to deploy my new blog visual theme built entirely with Claude Code. It’s ready. I’m anxiously awaiting for the moment I put that project behind. Next, I’ll spend some time on [Who Is Numeric Citizen website](https://whois.numericcitizen.me) design and hosting solution (I’m thinking of leaving Chillidog Hosting hosting service to go with Elements’ built in solution instead). 
</source:markdown>
    </item>
    
    <item>
      <title></title>
      <link>https://meta.numericcitizen.me/2026/03/30/i-realized-i-forgot-to.html</link>
      <pubDate>Mon, 30 Mar 2026 20:42:52 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/03/30/i-realized-i-forgot-to.html</guid>
      <description>&lt;p&gt;I realized I forgot to clearly state the design goals before starting to build this custom theme for Micro.blog. They became clearer as I progressed and explored how Hugo and Micro.blog work, especially with assistance from Claude AI, and as I encountered various challenges. Here are the goals: a) I want a theme that stands out and doesn&amp;rsquo;t resemble typical Micro.blog blogs. b) I aim to minimize the use of external plugins, ensuring that all functionality is integrated within the custom theme. c) I want the same theme to be usable on more than one blog (I have two). Stay tuned for more news.&lt;/p&gt;
</description>
      <source:markdown>I realized I forgot to clearly state the design goals before starting to build this custom theme for Micro.blog. They became clearer as I progressed and explored how Hugo and Micro.blog work, especially with assistance from Claude AI, and as I encountered various challenges. Here are the goals: a) I want a theme that stands out and doesn&#39;t resemble typical Micro.blog blogs. b) I aim to minimize the use of external plugins, ensuring that all functionality is integrated within the custom theme. c) I want the same theme to be usable on more than one blog (I have two). Stay tuned for more news. 
</source:markdown>
    </item>
    
    <item>
      <title>Takeaways From Building a Custom Micro.blog Theme Using Claude Code and Claude AI</title>
      <link>https://meta.numericcitizen.me/2026/03/29/takeaways-from-building-a-custom.html</link>
      <pubDate>Sun, 29 Mar 2026 19:14:16 -0400</pubDate>
      
      <guid>http://numericcitizen-meta.micro.blog/2026/03/29/takeaways-from-building-a-custom.html</guid>
      <description>&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/numericcitizen-beta-theme-small.png&#34; width=&#34;600&#34; height=&#34;677&#34; alt=&#34;&#34;&gt;
&lt;p&gt;Building a custom visual theme for Micro.blog presents unique challenges at the intersection of web design, static site generation, and AI-assisted development. This blog post captures practical insights and lessons learned from creating a custom theme with Claude Code and Claude AI, including key considerations on Hugo compatibility, plugin conflicts, and theme architecture.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude AI isn&amp;rsquo;t well-trained on Micro.blog architecture and dependency on Hugo static website generator. Claude doesn’t make a clear distinction between Hugo’s capabilities and Micro.blog’s unique features.&lt;/li&gt;
&lt;li&gt;Plugins are a challenge because they might inject conflicting formatting instructions into your custom-built theme. It’s hard to debug.&lt;/li&gt;
&lt;li&gt;Plugins can conflict with each other.&lt;/li&gt;
&lt;li&gt;Don’t use the latest Hugo version (0.158) and stay on 0.117 if you use many plugins. By removing low-value plugins, you increase your chance of using version 0.158.&lt;/li&gt;
&lt;li&gt;The workflow for updating a GitHub repo hosting your custom theme to the deployment on The process of Micro.blog is tedious because it’s manual and slow, especially for large websites and Hugo rendering engine. Hugo 0.158 could help, unless it conflicts with one plugin that you need.&lt;/li&gt;
&lt;li&gt;More than ever: less is more. Keep it simple, and problems will be kept at bay: removing low-value plugins can make a big difference.&lt;/li&gt;
&lt;li&gt;Test the website after each plugin removal, force a rebuild of the entire site to cleanup things. It’s slow but it might help debug later.&lt;/li&gt;
&lt;li&gt;If a plugin introduces support for smart code in blog posts, after removing that plugin, Hugo will generate errors. These blog posts need to be either updated or deleted.&lt;/li&gt;
&lt;li&gt;If the custom-built theme covers a specific design area, like a /photos page, don’t use a plugin touching the same area, prioritize the custom-built theme and skip the plugin. The idea is to have a self-contained custom theme.&lt;/li&gt;
&lt;li&gt;Stay away from abandoned-ware plugins.&lt;/li&gt;
&lt;li&gt;Prefer adding stuff in the custom theme instead of relying on an external plugin, so the theme is self-contained.&lt;/li&gt;
&lt;li&gt;The lower the number of plugins, the better the chance you can use the latest version of Hugo.&lt;/li&gt;
&lt;li&gt;Using the custom.css functionality, which helps externalize and override the custom-theme’s styling, speeds up testing different styling options.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Creating a custom Micro.blog theme using Claude AI revealed both the power and limitations of AI-assisted development in specialized ecosystems. While the tools provided invaluable support, the real breakthroughs came from hands-on debugging and understanding the unique interactions between Hugo, Micro.blog, and plugins. These takeaways form the foundation for a more robust theme architecture—one that will continue to improve with future iterations.&lt;/p&gt;
&lt;p&gt;I’m still not done with my design. As I progress, you can visit &lt;a href=&#34;https://numericcitizen-test.micro.blog&#34;&gt;my test blog&lt;/a&gt;.&lt;/p&gt;
</description>
      <source:markdown>&lt;img src=&#34;https://cdn.uploads.micro.blog/143495/2026/numericcitizen-beta-theme-small.png&#34; width=&#34;600&#34; height=&#34;677&#34; alt=&#34;&#34;&gt;

Building a custom visual theme for Micro.blog presents unique challenges at the intersection of web design, static site generation, and AI-assisted development. This blog post captures practical insights and lessons learned from creating a custom theme with Claude Code and Claude AI, including key considerations on Hugo compatibility, plugin conflicts, and theme architecture.

- Claude AI isn&#39;t well-trained on Micro.blog architecture and dependency on Hugo static website generator. Claude doesn’t make a clear distinction between Hugo’s capabilities and Micro.blog’s unique features. 
- Plugins are a challenge because they might inject conflicting formatting instructions into your custom-built theme. It’s hard to debug. 
- Plugins can conflict with each other.
- Don’t use the latest Hugo version (0.158) and stay on 0.117 if you use many plugins. By removing low-value plugins, you increase your chance of using version 0.158. 
- The workflow for updating a GitHub repo hosting your custom theme to the deployment on The process of Micro.blog is tedious because it’s manual and slow, especially for large websites and Hugo rendering engine. Hugo 0.158 could help, unless it conflicts with one plugin that you need. 
- More than ever: less is more. Keep it simple, and problems will be kept at bay: removing low-value plugins can make a big difference. 
- Test the website after each plugin removal, force a rebuild of the entire site to cleanup things. It’s slow but it might help debug later. 
- If a plugin introduces support for smart code in blog posts, after removing that plugin, Hugo will generate errors. These blog posts need to be either updated or deleted.
- If the custom-built theme covers a specific design area, like a /photos page, don’t use a plugin touching the same area, prioritize the custom-built theme and skip the plugin. The idea is to have a self-contained custom theme. 
- Stay away from abandoned-ware plugins. 
- Prefer adding stuff in the custom theme instead of relying on an external plugin, so the theme is self-contained.
- The lower the number of plugins, the better the chance you can use the latest version of Hugo. 
- Using the custom.css functionality, which helps externalize and override the custom-theme’s styling, speeds up testing different styling options.

Creating a custom Micro.blog theme using Claude AI revealed both the power and limitations of AI-assisted development in specialized ecosystems. While the tools provided invaluable support, the real breakthroughs came from hands-on debugging and understanding the unique interactions between Hugo, Micro.blog, and plugins. These takeaways form the foundation for a more robust theme architecture—one that will continue to improve with future iterations.

I’m still not done with my design. As I progress, you can visit [my test blog](https://numericcitizen-test.micro.blog).

</source:markdown>
    </item>
    
  </channel>
</rss>
