Building a Personal AI Assistant (FinkBot)

I’ve been running OpenClaw on a Raspberry Pi 4 for a while. It’s a self-hosted AI assistant that lived in a terminal, had access to my email history and chat logs, and could answer questions about my own life with reasonable accuracy. It worked, mostly, but it was fragile. The Pi would fall over under load, the context window management was a mess, and every time I wanted to add something new I was fighting the architecture instead of building. And to be honest, nearly every update broke something fundamental.

So I rebuilt it from scratch. The result is FinkBot, named after my old BBS and Slashdot username, Finkployd. Here’s how it’s built and what it actually does.

The Stack

Three LXCs on a Proxmox host (Bosgame ADB20, Ryzen 5 3550H, 16GB RAM):

  • n8n — workflow orchestration. All the actual logic lives here.
  • Chroma + a query proxy — vector database for semantic memory. I wrote a small Flask proxy in front of it to handle embedding and expose a sane REST API.
  • A Discord bot — the interface. All interaction happens in a private Discord server.
  • A Mac Mini running Ollama — local AI models. No data leaves my network.

The interface choice was deliberate. I spend most of my day in Discord or Teams anyway. A dedicated server gives me structured channels for different types of output (#briefings, #alerts, #projects, #memory-log), persistent history, mobile notifications, and emoji reactions I can use to trigger actions. It’s a better interface than a chat window for something that pushes information proactively.

Privacy First

This was a hard requirement from the start. My emails, calendar events, and private Teams conversations aren’t going to third-party APIs. All LLM inference runs locally on the Mac Mini via Ollama. The only external calls are to Microsoft Graph (to fetch email, teams, and calendar data) and my personal email server; both necessary to retrieve data, not to process it.

Everything stays on my network.

Memory

FinkBot’s memory comes from two sources: a static corpus loaded at startup, and a growing corpus built from ongoing ingestion.

The static corpus is ~1,638 markdown files extracted from roughly 31,000 personal emails and 846 Pidgin/Adium chat logs spanning 2006-2025. These were processed by OpenClaw’s memory extraction pipeline before I shut it down, so FinkBot started with a reasonably complete picture of my life, work history, relationships, and recurring topics.

The growing corpus gets new chunks from every email that comes in (across two accounts), every Teams chat message, and every calendar event. Everything goes through Chroma with a content hash as the ID, so ingestion is idempotent, I can re-run it without creating duplicates.

Semantic search is straightforward: when you ask FinkBot something, it queries Chroma for the top N relevant chunks, injects them into the prompt as context, and the model reasons over them. No RAG pipeline complexity, no re-ranking. It works well enough for my needs.

What It Actually Does

Morning and evening briefings: At 8am and 5pm ET, FinkBot posts a briefing to #briefings. The morning brief covers today’s calendar (M365 + Nextcloud), any open action items, and things to be aware of. The evening brief reviews what happened today and previews tomorrow. Both are generated locally with strict anti-hallucination instructions. If there’s no data for a section, it says “nothing on record” rather than making something up.

Meeting prep: A workflow runs every minute checking whether any M365 calendar event starts in 30 minutes. If it finds one that hasn’t been prepped yet, it queries Chroma for relevant context about the meeting topic and attendees, generates a prep brief, and posts it to #projects. The brief covers meeting overview, key attendees, relevant history from memory, talking points, and action items to have completed. Context quality improves as more email and chat data accumulates.

Email monitoring: Both my personal (mystikos.org, IMAP via MXRoute) and work (instrumentalid.com, M365 Graph API) inboxes are monitored. Each email is analyzed locally for action items and urgency. Genuinely actionable emails get posted to #alerts. Automated emails, newsletters, and marketing get auto-blocklisted at the sender address level so they stop consuming inference cycles.

Teams chat ingestion: This was the interesting one. Reading your own Teams DMs via Graph API requires delegated auth. Application permissions can’t access cross-tenant conversations, which is most of mine. So there’s an MSAL device flow to get a refresh token, which gets stored and auto-renewed on every hourly run. The Chat Ingestor fetches all chats, processes messages through a Split In Batches node (one at a time to make de-duplication work correctly), and ingests new messages to Chroma.

Manual memory: /remember [text] stores an explicit memory chunk. Useful for things like “remember I agreed to do X for Y by Z date.”

Blocklist: reacting 🚫 to any alert in #alerts blocks the sender’s domain. 📵 blocks the specific address. The blocklist gates both ingestion and analysis, so blocked senders disappear completely.

LLM Routing

Everything runs locally via Ollama on the Mac Mini. The model split is based on task complexity:

  • Qwen2.5 32B handles the heavy lifting: briefings, meeting prep, email analysis. Long context, strong reasoning, handles complex synthesis tasks well.
  • Qwen2.5 7B handles interactive chat where latency matters more than depth. Fast enough to feel responsive for back-and-forth questions.

No tokens leave my network. No API costs. No third party seeing my calendar or reading my email.

Things That Were Annoying

n8n caches OAuth2 tokens encrypted in SQLite. Restarting n8n doesn’t clear them. If you update a client secret, the old cached token is used until it expires (~1 hour). The fix is to wait, or delete and recreate the credential.

Graph API datetimes are local time, not UTC. The calendarView endpoint returns datetimes like 2026-04-03T14:00:00.0000000 with a separate timeZone: "America/New_York" field. That 14:00 is 2pm ET, not 2pm UTC. Appending ‘Z’ to treat it as UTC gives you the wrong time by 4-5 hours. Parse it using the timeZone field directly.

n8n IF nodes eat your data. When data passes through an IF node, the output only contains what the preceding node returned. Everything from earlier nodes is gone unless you explicitly pass it through with a merge Code node. This bit me repeatedly.

Split In Batches is required for per-item HTTP chains. If you have a loop where each item needs to go through an HTTP Request → IF → HTTP Request chain, n8n’s default item processing only works for the first item. Wrap it in Split In Batches with batch size 1 and connect all branches (including the skip branch) back to the loop input.

Teams chat de-duplication. The processed message IDs are epoch millisecond timestamps, which are also valid Teams message IDs. This looked like a bug for a while. It’s not.

What’s Next

  • Vikunja task integration: already half-built, wiring up the Discord slash commands now
  • Full archive ingestion: the bulk of my email history hasn’t been processed yet
  • TLS + reverse proxy on Tailscale

The code isn’t public yet (too many credentials baked into the workflow exports) but the architecture is straightforward enough that this post covers the interesting parts. If you’re building something similar and have questions, KB3LYB on the air or [email protected].

The Band Anna – Gig On Main 2023

In 2023 The Band Anna played its last show and I feel we went out on top. Opening in Irwin’s annual “Gig On Main” show that was headline by the Clarks we played a full set IN THE POURING RAIN to an increasingly larger and more enthusiastic crowd. The Band Anna was:
– Brianna Acalotto – vocals
– Jesse Bergman – guitar, vocals, keyboard
– Mark Earnest – guitar, vocals
– Aaron McConnell – bass, guitar, vocals
– Matt Omler – drums

I’ve pulled out a few of the songs to post on YouTube and add some comments. Note that between the wind and rain, the audio (and for that matter video) is not ideal, but still represent I believe how we sounded in general at this time.


Boys of Summer has been a staple of ours from the very beginning. I feel like this one went a little fast (I can always tell when we get to the breakdown part and I find I have to scramble to get the syncopated part in) but still came off well. Also note that we are really shooting for more of The Ataris version and less Don Henley’s version, and as such I’m taking several overlapping guitars and trying to do them with one guitar, especially in the solo.


Truth be told, Under Pressure wasn’t even on our setlist, this was just something we tossed in as a soundcheck, but it came out pretty well and I wanted to preserve it. Jesse and I had a number of cues between each other in this song to verify we are where we think we are (this is literally the only song I ever count bars in, especially at the end where chord changes come at really non-intuitive places) so you will see us signaling behind Brianna and Aaron a few times. I am also very much a boring stationary performer but for some reason I kind of get into this one and almost move a bit (awkwardly)


Your Love is a fun song to perform, and Aaron and I have a little Easter Egg at the end we both love to do. If you listen in the outro we both play various parts from Fleetwood Mac’s Go Your Own way (bass and guitar solo respectively). This is also one of the few songs I actually sing loud on rather than just background harmonies.


Flagpole Sitta is a rare Jesse vocal led song, this one is just pure fun. High energy and a little silly. The guitar part is fairly simple, so I try to mix up how I am attacking each section.


This is the Fall Out Boy’s version of I Want to Dance with Somebody. I don’t remember exactly why we didn’t do the key change at the end, so it feels a little flat there to me, but still a jam and usually a crowd-pleaser.


Brooklyn was a late addition to our lineup, and I don’t have a lot of recordings of it. Also, my guitar was a bit quiet on this version which annoys me, but it is what it is. Another Jesse vocal performance, Jesse introduced us to this song and Patrick Droney in general which was a good find. I like to think with more time we would have really done this song justice (I’m playing a much more basic guitar part than I would have liked).


LOOK AT HOW HARD IT WAS RAINING DURING THIS! Also just a fun song to jam on


For anyone curious about my gear during this, the guitar is a Rick Turner Model 1, amp is a Peavey Classic 30 and the pedalboard was exactly set up like this (although much wetter by the end of the show).

A Better Human: Book Review

I’ve recently finished A Better Human, the debut novel from J Donald (if you’ve watched any of the videos on my music page, he’s the other guitarist), and I was blown away by how good this is. When I read novels, I like to mentally slot them into genre tropes, and this one subverted my expectations throughout. At various times I saw influences from sources as disparate as Invincible, The Walking Dead, Horizon Zero Dawn, Stranger Things, and even Dune (which the author hadn’t read, but somehow managed to channel in his fight scenes) yet it wasn’t really any of those. This book charts its own course and keeps you engaged from page one.

Two things I really appreciated plot-wise were the world building and character development. J doesn’t infodump or rely on the classic “as you know…” conversations; instead, he drops hints and builds the world organically in a way that feels natural. On the character side, books with large casts usually make it easy to lose track of minor characters or disregard them entirely, not here. Everyone has an arc and plot relevance, and some of the most gut-wrenching revelations are reserved for characters you’d initially write off as background filler.

From a structure standpoint, the chapter arrangement is particularly effective. I’m not a fan of books that end every chapter on a cliffhanger to keep you turning pages (cough Dan Brown), but this book takes a different approach: chapters often finish on a plot revelation, then sometimes the next jumps back in time to explain what just happened or set up what’s coming. It ends up feeling natural, allows for satisfying stopping points, and makes for an almost Memento-style storytelling experience, albeit much less confusing.

All in all, highly recommend.

WordPress Theme

I made a WordPress theme (you are soaking in it) to match the aesthetics of my Directory Master program, which in turn lovingly appropriated the idea from the old DOS Norton Utilities program (which, along with Wordperfect 5.1 represents the pinnacle of user interface design, it’s been downhill since).
Here is a screenshot of what it might look like



In addition to the nice edge effect and animated menu buttons, It has some rudimentary visual editor blocks like:

cool 3d blocks

And even

cooler inverse 3d blocks

And tables. Can you tell I really like the 3d bar effect?

ProgramMy UI rating on a scale of 1-10
Norton Utilities 510
Word Perfect 5.19
Windows 3.112
Windows 951

Source code and installable WordPress theme zip file can be downloaded from my github

Guitar Pedalboard Evolution

For a long time, I had an ART ECC 1 as my multi effects pedal. Around 2008 I decided I wanted to start using individual analog pedals. Over the decades (ugh) I have taken sporadic snapshots of the pedalboard before certain gigs or after major renovations and so I present here: the evolution of my pedalboard.

It’s 2008, I discovered General Guitar Gadgets kits (highly recommended) and built a germanium fuzz face, a triangle era Big Muff Pi, and a PT-80 delay. I also picked up an MXR Phase 90 and Dynacomp from the local music store, a Behringer Vintage Tube overdrive, and a sporadically functional wah pedal from Craigslist. What better way to organize these than on a panel from an IKEA desk with Lowe’s cabinet handles screwed on? I gigged with this setup for far too long before purchasing a proper board.

At this point my pedal building problem clearly comes into focus. Let’s take the signal path in order.

The Wah pedal has been gutted and replaced with GGG’s Mod Wah board including a rotary switch for 5 different tone caps (to adjust the Q position) and a three way selector for different inductors. I also have a switch to flip the input and output to achieve the loud “seagul” sound that can be heard on the middle part of Pink Floyd’s Echoes. Next is the the GGG Germanium Fuzz Face, followed by a dual pedal setup consisting of an always on buffer and dual compressors: a Ross and and a Dan Armstrong Orange Squeezer. Next is the GGG Big Muff Pi, a BYOC (Build Your Own Clone, sadly out of business) Tube Screamer (with multiple tone stacks and clipping options). Finishing out my overdrive chain is a Bajaman designed Real Tube Overdrive I built from his schematics and housing a 12AX7 tube.
For modulation I’m uncharacteristically lacking in this era. I swapped out the Phase 90 for a GGG Phase 45 kit, this pedal will nearly always be on my board and is something I consider a bit of a secret weapon for my tone. Rounding it out is a Deluxe Mistress Flanger I build from a GGG PCB (and some scavenged SAD1024 chips that I still hoard jealously) and my PT-80 delay, now featuring a “delay doubler” switch.

Now clearly entering my “too big for the IKEA wood slab” phase. Everything above, plus the addition of a Neovibe build from R.G. Keen’s specs and an unlabeled pedal that I believe is a BYOC Analog Chorus.
This is the pedalboard used on the Shadows Of Eve album Nowhere But Here.

Not much to add here. No new pedals but I did finally get my power distribution a bit under control with a power strip. Notice that the Neovibe needs an 18v DC power adapter and the Bajaman Tube Overdrive requires an inconvenient 16v AC power adapter which will account for it occasionally dropping off my board when space is at a premium.

Many changes. Change #1: A proper pedal-board with power and audio jacks. Change #2: labels are convenient, lose them. Change #3: Put an official Deluxe Mistress Flanger on my board to replace the homemade one which was on the bench being re-aligned. Nothing much new here, signal path is GGG Fuzz Face, Bi-Compressor, BYOC Rat clone, BYOC Bug Miff Pi, Bajaman Tube Overdrive, GGG Phase 45, BYOC Analog Chorus, GGG Tremelo, Flanger, Delay. This is the pedalboard used to record Broken World at Audible Images studio (This is a photo from that session)

My short lived attempt at being symmetrical. Also clearly my aesthetic of unlabeled pedals was giving way to at least trying to minimally label the knobs. A few new additions here are the excellent BYOC Stereo Flanger (mixed in with a Boss Line Selector) and Ditto looper. Also finally broke down and got a tuner for stage use. Otherwise my usual signal path of compressor, BYOC Big Muff Pi, Bajaman Tube Overdrive, Phase 45, Chorus, Tremolo, Flanger, Delay, Looper.

I briefly experimented with an Electro Harmonix POG2, but it definitely was not for me. I also built a BYOC programmable looper to make switching pedal on and off easier (and to program presets of groups of them). Otherwise nothing new here but a surprisingly minimal overdrive selection with only the Bajaman Tube Overdrive and Big Muff Pi.

Wah makes a reappearance and will very rarely leave my board from here out. I also have the #0001 serial number Sublime Pep-Pep Delay Pedal with custom graphics adding some rare color.

Clearly going for quantity over quality, I went through a period of time where I ditched nearly all of my homemade pedals for inexpensive Mooer clones. Included here are Big Muff Pi, Blues Driver, Boost, Blue’s Crab, Electro Flanger, and Analog Chorus along with my Ditto Looper, Pep Pep delay, a rare appearance by an EQ, and a BIG honking Univibe which I believe is why I switched to so many smaller pedals to try and fit it on the board. Mooer pedals are not the highest quality audio and they didn’t last long but I will say the Flanger is very high quality and matches up against both my Deluxe Mistress Flanger clone and the offical Electro Harmonix version.

Obviously neatness was not the goal here. This appears to be a random mix of quickly tossed together Mooer pedals with the Phase 45 and Pep Pep delay. The unfamiliar carpet and mess of wires leads me to believe this was taken at a show so it likely was an impromptu setup.

At this point I was going back to my roots of all homemade analog pedals. And again also no labels which makes identifying these kinda tricky many years later. I believe the signal path here is Wah, Bi-Compressor, Bajaman Tube Overdrive, Big Muff Pi, Rat, Phase 45, Chorus, Tremelo, Univibe, Flanger, Delay.

I had this new pedalboard for a while so I am surprised I only have one photo of it that I can find. A mix of previously seen homemade and Mooer pedals (including the Slow Engine to do Vertical Horizon’s Everything You Want) this is noteworthy because it was during a time where I was trying to use my Peavey Classic 30’s overdrive channel (thus the Peavey pedal on the left) and putting my modulation pedals in the amp’s effects loop. I didn’t maintain this setup long due to the fact that it required 4 cables (three in a bundle going back and forth between the pedalboard and amp). This is also marks the first appearance of a classic Boss CS-2 compressor to replace my large bi-compressor pedal and the MXR mini phaser pedal to replace my GGG Phase 45 (this pedal does both 90 and 45 but I only use the 45 setting)

New pedalboard with enough space to store everything I want, with power banks and adapters stored underneath. Wah and looper pedals return, as does the Mooer boost, Slow Engine, Flanger, and Chorus. An new addition is the Danelectro Big Spender spinning speaker simulator my wife got me which stayed in my lineup for a number of gigs.

Two notable additions here are a BK Butler Tube Driver to replace the Bajaman Tube Overdrive (not my preference, I actually lost the Bajaman pedal and the bi-compressor at some point but I will be building replacements). Also new to the pedal board is a dual pedal I built to house two Cornish pedal clones, the G2 and SS2.

The original GGG fuzz face returns in a custom made (sandblasted) circular enclosure, the GGG PT-80 delay and Phase 45 return along with a BYOC RAT, Chorus, Tubescreamer, Big Muff Pi, and Flanger. This is the pedalboard (and actual settings) used for this show.