<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: h-wata</title>
    <description>The latest articles on DEV Community by h-wata (@h-wata).</description>
    <link>https://dev.to/h-wata</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3963953%2F6336aad2-cd02-4048-9bcb-e3e2d8141219.png</url>
      <title>DEV Community: h-wata</title>
      <link>https://dev.to/h-wata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/h-wata"/>
    <language>en</language>
    <item>
      <title>kioku-mesh: Why I put Zenoh under my AI's long-term memory</title>
      <dc:creator>h-wata</dc:creator>
      <pubDate>Fri, 05 Jun 2026 10:19:18 +0000</pubDate>
      <link>https://dev.to/h-wata/kioku-mesh-why-i-put-zenoh-under-my-ais-long-term-memory-28dn</link>
      <guid>https://dev.to/h-wata/kioku-mesh-why-i-put-zenoh-under-my-ais-long-term-memory-28dn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was written with help from Claude (an AI). I reviewed and edited it before publishing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The gap between Claude Code and the web app
&lt;/h2&gt;

&lt;p&gt;If you've lived in Claude Code for a while and then go back to the web version of an AI assistant, the gap is jarring. In the web app you end up explaining everything from scratch, to the point where you start wondering whether it's really the same model underneath. As a lot of you already know, the difference is context.&lt;/p&gt;

&lt;p&gt;Claude Code keeps its memory across sessions. But only on a single machine. The context I build up on my home box is a blank slate on my office box, and when several agents are running at once, each one "learns" on its own.&lt;/p&gt;

&lt;p&gt;The obvious first fix is to have the agent scribble notes into SQLite. Plenty of MCP memory apps stop right there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So why does kioku-mesh put a distributed messaging system (Zenoh) on top of that?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SQLite alone isn't enough
&lt;/h2&gt;

&lt;p&gt;SQLite is tied to one process and one file. For agents spread across several machines reading and writing the same memory, it's just the wrong shape.&lt;/p&gt;

&lt;p&gt;The naive workaround is to rsync the SQLite file between machines. That falls apart quickly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conflicts&lt;/strong&gt;: if home and office write at the same time, there's no way to decide which one wins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: depending on when the copy happens, one side keeps running on stale data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline&lt;/strong&gt;: lose the network and you can't sync at all, so conflicts just pile up when you reconnect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The moment you have multiple machines and multiple agents writing concurrently, copying a SQLite file means writing your own conflict-resolution logic. I didn't want to write that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Zenoh
&lt;/h2&gt;

&lt;p&gt;kioku-mesh leans on Zenoh exactly so I don't have to solve that conflict problem myself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Zenoh is&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zenoh is an open-source distributed communication middleware from the Eclipse Foundation. It was built for IoT and robotics, and the part I care about is that it runs entirely on your own machines with no cloud service in the loop. It gives you pub/sub plus a key-value store. (A KV store is the simple kind of database that reads and writes name/value pairs. Redis and DynamoDB are the famous examples.) Zenoh wraps networked pub/sub and replication around that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HLC (Hybrid Logical Clock) timestamps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An HLC is a timestamp that combines a physical clock (wall-clock time) with a logical clock (causal order). It came out of distributed-systems research and shows up in systems like CockroachDB.&lt;/p&gt;

&lt;p&gt;With plain wall-clock time, every machine's clock drifts a little (NTP skew), so you can't reliably tell which write came later. An HLC absorbs that drift while still recording causality correctly, i.e. that B happened after A.&lt;/p&gt;

&lt;p&gt;Zenoh's advantage here is that HLC is built in. You implement nothing; a timestamp is attached automatically on every write. In my own testing, causality held even when NTP skew went past 12 seconds, so conflict resolution needs no extra code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The replication plugin's digest comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To keep periodic syncing cheap while two nodes are connected, Zenoh compares digests at hot/warm/cold "era" granularity. My config checks for differences every &lt;code&gt;interval: 10.0&lt;/code&gt; seconds and propagates anything that doesn't match. After a split-brain, re-sync converges in about 5 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An eventually-consistent KV&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Writes don't have to reach every node instantly. Even on a flaky network, things sync automatically once a connection comes back. That's where the offline tolerance comes from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: the big picture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb6rc6na4vzd7hwjcacp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb6rc6na4vzd7hwjcacp.png" alt="kioku-mesh architecture: two machines, each running zenohd + RocksDB with a local SQLite cache, kept in sync by Zenoh replication" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The write path
&lt;/h3&gt;

&lt;p&gt;When an agent calls &lt;code&gt;save_observation&lt;/code&gt;, this is what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;store.put_observation()&lt;/code&gt; issues a &lt;code&gt;PUT mem/obs/...&lt;/code&gt; to Zenoh.&lt;/li&gt;
&lt;li&gt;zenohd's storage_manager persists it to RocksDB.&lt;/li&gt;
&lt;li&gt;The replication plugin propagates it to the zenohd on other nodes.&lt;/li&gt;
&lt;li&gt;On success, the calling process upserts into its own SQLite right away.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The read path
&lt;/h3&gt;

&lt;p&gt;Search comes back from the local SQLite. It never asks Zenoh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# store.search_observations() (sketch)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_observations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...):&lt;/span&gt;
    &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;          &lt;span class="c1"&gt;# served from SQLite
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;_search_via_zenoh&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;       &lt;span class="c1"&gt;# fallback: full Zenoh scan
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Keeping SQLite fresh
&lt;/h3&gt;

&lt;p&gt;So how does SQLite stay current? Two mechanisms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Zenoh subscriber (real-time)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At process startup it subscribes to &lt;code&gt;mem/obs/**&lt;/code&gt; and &lt;code&gt;mem/tomb/**&lt;/code&gt;. Every time a PUT arrives from another node via replication, it upserts into SQLite immediately.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_obs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;obs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# write straight into SQLite
&lt;/span&gt;
&lt;span class="n"&gt;sub_obs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;declare_subscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mem/obs/**&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_obs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Rebuild on startup (consistency)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A long-running process (the MCP server) runs &lt;code&gt;rebuild_from_zenoh()&lt;/code&gt; once at startup, doing a full scan of Zenoh's &lt;code&gt;mem/obs/**&lt;/code&gt; to rebuild SQLite. This picks up anything that changed while the process was down, such as replication from other nodes.&lt;/p&gt;

&lt;p&gt;In practice that's about 0.4 seconds for 50k records. It only happens once at MCP server startup, so you don't notice it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;What sold me on SQLite was the measurements. I started out running full scans against Zenoh, but fetching was too slow, so I moved to SQLite as a cache.&lt;/p&gt;
&lt;h3&gt;
  
  
  Full scan over Zenoh (the old path)
&lt;/h3&gt;

&lt;p&gt;Pull everything over the network, then filter in Python.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Records&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;16k&lt;/td&gt;
&lt;td&gt;2.2 s (scan count dominates and ignores &lt;code&gt;limit&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;36MB store&lt;/td&gt;
&lt;td&gt;timeout (hits the 10-second limit)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  SQLite local index (the current path)
&lt;/h3&gt;

&lt;p&gt;Just throw a SQL query at the local SQLite.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Records&lt;/th&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;50k&lt;/td&gt;
&lt;td&gt;rebuild&lt;/td&gt;
&lt;td&gt;~0.4 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50k&lt;/td&gt;
&lt;td&gt;query p99&lt;/td&gt;
&lt;td&gt;~0.04 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50k&lt;/td&gt;
&lt;td&gt;Tier-4, real HW&lt;/td&gt;
&lt;td&gt;sub-200 ms confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50k&lt;/td&gt;
&lt;td&gt;file size&lt;/td&gt;
&lt;td&gt;~49 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The gap between a full Zenoh scan and SQLite is roughly 50,000x. On a 36MB store, searching through Zenoh times out, while SQLite returns in under a millisecond even at 50k records.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The short answer to "why does kioku-mesh use Zenoh" is: to build something that doesn't break when several machines write at the same time.&lt;/p&gt;

&lt;p&gt;SQLite is fast and easy, but it lives inside a single machine. Adding Zenoh syncs data across machines and resolves write conflicts automatically through HLC. Reads stay fast because they come straight from SQLite. Zenoh does the "write and sync" job, SQLite does the "read fast" job, and that split is what makes the distributed long-term memory work.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;kioku-mesh is open source.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/h-wata" rel="noopener noreferrer"&gt;
        h-wata
      &lt;/a&gt; / &lt;a href="https://github.com/h-wata/kioku-mesh" rel="noopener noreferrer"&gt;
        kioku-mesh
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Shared memory for AI coding agents, across tools and machines. Local-first SQLite, optional Zenoh+RocksDB mesh, MCP-native.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/h-wata/kioku-mesh/docs/assets/kioku-mesh-logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fh-wata%2Fkioku-mesh%2FHEAD%2Fdocs%2Fassets%2Fkioku-mesh-logo.png" alt="kioku-mesh" width="420"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://pypi.org/project/kioku-mesh/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a31e101f979ef987d10e65933b6f46e052aa20855586b63b751a0782b8e410b0/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f6b696f6b752d6d6573682e737667" alt="PyPI"&gt;&lt;/a&gt;
  &lt;a href="https://pypi.org/project/kioku-mesh/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a505a00458a6f36641392e95e7f77359bdf25a60cad24b4ddda52adf60b21559/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f6b696f6b752d6d6573682e737667" alt="Python"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/h-wata/kioku-mesh/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4cddc57dcff62eba4bd9194447047b6c3009fa6c50d9a698ed7050e53ed5d724/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f682d776174612f6b696f6b752d6d6573682e737667" alt="License"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Shared memory for AI coding agents, across tools and machines.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/h-wata/kioku-mesh/docs/assets/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fh-wata%2Fkioku-mesh%2FHEAD%2Fdocs%2Fassets%2Fdemo.gif" alt="One agent saves a decision; another agent recalls it over the mesh" width="760"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;kioku&lt;/code&gt; (記憶) means memory.&lt;/p&gt;
&lt;p&gt;kioku-mesh gives coding agents a shared memory store. Claude Code, Codex CLI
Gemini CLI, and other MCP clients can save and search the same observations from
one machine or from several machines on a trusted LAN/VPN mesh.&lt;/p&gt;
&lt;p&gt;The default setup is local and needs no daemon. Mesh mode is available when you
want the same memory pool replicated between hosts.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why kioku-mesh&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Coding-agent context gets fragmented across machines: which laptop did that work
what did the agent on the other host decide, and why does a secondary agent have
to re-read everything from scratch just to give a quick second opinion?
kioku-mesh keeps that memory in one shared pool so any agent, on any of your
machines, can recall it.&lt;/p&gt;
&lt;p&gt;Unlike long-term memory tools that store everything in one place, the shared
pool is a peer-to-peer…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/h-wata/kioku-mesh" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>mcp</category>
      <category>ai</category>
      <category>zenoh</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Show DEV: kioku-mesh — shared long-term memory for AI coding agents across PCs</title>
      <dc:creator>h-wata</dc:creator>
      <pubDate>Tue, 02 Jun 2026 07:05:26 +0000</pubDate>
      <link>https://dev.to/h-wata/show-dev-kioku-mesh-shared-long-term-memory-for-ai-coding-agents-across-pcs-4p1c</link>
      <guid>https://dev.to/h-wata/show-dev-kioku-mesh-shared-long-term-memory-for-ai-coding-agents-across-pcs-4p1c</guid>
      <description>&lt;p&gt;I made &lt;strong&gt;kioku-mesh&lt;/strong&gt;, which shares long-term memory for AI agents across multiple PCs and across multiple agents. &lt;code&gt;kioku&lt;/code&gt; (記憶) means memory in Japanese.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dk9apv1l3esrmfkkbx8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dk9apv1l3esrmfkkbx8.gif" alt="Demo: kioku-mesh sharing memory between agents across machines" width="720" height="820"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built kioku-mesh because I often work across my home PC and office PC over a VPN. A common pain for me was that I would do some development work on one machine, then continue on another machine, but the agent on the second machine had no memory of the previous context. I also found it painful that I could not easily remember when and why certain decisions were made. Another frustration was when I split work among multiple agents, for example one agent coding and another agent reviewing. The secondary agent often had to read the whole folder again from scratch, which made the workflow feel slow.&lt;/p&gt;

&lt;p&gt;There are already tools that give long-term memory to AI agents, but many of them either require SaaS or are limited to one local machine. I wanted something that could be shared across my own PCs while still staying inside my LAN/VPN.&lt;/p&gt;

&lt;p&gt;kioku-mesh uses Zenoh for the mesh. Zenoh + RocksDB acts as the source of truth, so when I add a new PC to the mesh, it can read memories that were saved on the other machines.&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool &lt;span class="nb"&gt;install &lt;/span&gt;kioku-mesh
kioku-mesh init &lt;span class="nt"&gt;--mode&lt;/span&gt; &lt;span class="nb"&gt;local
&lt;/span&gt;kioku-mesh save &lt;span class="s2"&gt;"Today lunch is Onigiri"&lt;/span&gt;
kioku-mesh search &lt;span class="s2"&gt;"Onigiri"&lt;/span&gt;
kioku-mesh mcp &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--client&lt;/span&gt; claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After &lt;code&gt;mcp install&lt;/code&gt;, agents can call &lt;code&gt;save_observation&lt;/code&gt; and &lt;code&gt;search_memory&lt;/code&gt; as normal MCP tools.&lt;/p&gt;

&lt;p&gt;Current limitations: This is still 0.x and experimental, so breaking changes may happen. Development is mainly Linux-focused, and I have not tested macOS or Windows enough yet. This is intended to be used only inside a trusted network. If you expose it to the public internet, Zenoh key-value data may be visible from outside through port 7447. I strongly recommend using it only in a closed network such as LAN/VPN/Tailscale.&lt;/p&gt;

&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/kioku-mesh/" rel="noopener noreferrer"&gt;https://pypi.org/project/kioku-mesh/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/h-wata/kioku-mesh" rel="noopener noreferrer"&gt;https://github.com/h-wata/kioku-mesh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo: &lt;a href="https://github.com/h-wata/kioku-mesh/blob/main/docs/assets/demo.gif" rel="noopener noreferrer"&gt;https://github.com/h-wata/kioku-mesh/blob/main/docs/assets/demo.gif&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would especially like feedback on what would be needed to make this useful for small teams in the future. I am also curious whether the setup and configuration feel too complicated when people actually try it.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/h-wata" rel="noopener noreferrer"&gt;
        h-wata
      &lt;/a&gt; / &lt;a href="https://github.com/h-wata/kioku-mesh" rel="noopener noreferrer"&gt;
        kioku-mesh
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Shared memory for AI coding agents, across tools and machines. Local-first SQLite, optional Zenoh+RocksDB mesh, MCP-native.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/h-wata/kioku-mesh/docs/assets/kioku-mesh-logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fh-wata%2Fkioku-mesh%2FHEAD%2Fdocs%2Fassets%2Fkioku-mesh-logo.png" alt="kioku-mesh" width="420"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://pypi.org/project/kioku-mesh/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a31e101f979ef987d10e65933b6f46e052aa20855586b63b751a0782b8e410b0/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f6b696f6b752d6d6573682e737667" alt="PyPI"&gt;&lt;/a&gt;
  &lt;a href="https://pypi.org/project/kioku-mesh/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a505a00458a6f36641392e95e7f77359bdf25a60cad24b4ddda52adf60b21559/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f6b696f6b752d6d6573682e737667" alt="Python"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/h-wata/kioku-mesh/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4cddc57dcff62eba4bd9194447047b6c3009fa6c50d9a698ed7050e53ed5d724/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f682d776174612f6b696f6b752d6d6573682e737667" alt="License"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Shared memory for AI coding agents, across tools and machines.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/h-wata/kioku-mesh/docs/assets/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fh-wata%2Fkioku-mesh%2FHEAD%2Fdocs%2Fassets%2Fdemo.gif" alt="One agent saves a decision; another agent recalls it over the mesh" width="760"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;kioku&lt;/code&gt; (記憶) means memory.&lt;/p&gt;
&lt;p&gt;kioku-mesh gives coding agents a shared memory store. Claude Code, Codex CLI
Gemini CLI, and other MCP clients can save and search the same observations from
one machine or from several machines on a trusted LAN/VPN mesh.&lt;/p&gt;
&lt;p&gt;The default setup is local and needs no daemon. Mesh mode is available when you
want the same memory pool replicated between hosts.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why kioku-mesh&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Coding-agent context gets fragmented across machines: which laptop did that work
what did the agent on the other host decide, and why does a secondary agent have
to re-read everything from scratch just to give a quick second opinion?
kioku-mesh keeps that memory in one shared pool so any agent, on any of your
machines, can recall it.&lt;/p&gt;
&lt;p&gt;Unlike long-term memory tools that store everything in one place, the shared
pool is a peer-to-peer…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/h-wata/kioku-mesh" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
