Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b34c1952a | ||
|
|
6be02768b3 | ||
|
|
6663d92ef7 | ||
|
|
f1eb9111bf | ||
|
|
ca44b70c0c | ||
|
|
44f0804a8f | ||
|
|
ea6a5c2f25 | ||
|
|
4912f010ba | ||
|
|
f570c140b2 | ||
|
|
d7d0438ee7 | ||
|
|
376ce6a7d2 | ||
|
|
30b17d510e | ||
|
|
093b67f975 | ||
|
|
017db30d36 | ||
|
|
f49227084e | ||
|
|
36e14b4b38 | ||
|
|
cbdea212cc | ||
|
|
94c7596f80 | ||
|
|
9347e5356e | ||
|
|
208fec08b6 | ||
|
|
c73f4551bd | ||
|
|
65256db330 | ||
|
|
5d02a045bd |
@@ -1,23 +1,63 @@
|
||||
# Markus Graf - Personal Website
|
||||
# markusgraf.ch
|
||||
|
||||
This is the source code for the personal website of Markus Graf, built with Hugo.
|
||||
Source code for [markusgraf.ch](https://markusgraf.ch) — personal website of Markus Graf, built with [Hugo](https://gohugo.io/).
|
||||
|
||||
## LLM Friendliness
|
||||
## About
|
||||
|
||||
This website includes an `llms.txt` file in the root directory (served from `static/llms.txt`) to help Large Language Models (LLMs) discover and understand the content of the site. This file follows the [llms.txt specification](https://llmstxt.org/).
|
||||
Markus Graf is a developer, BSc Psychology graduate, and consultant based in Switzerland. The site serves as his personal blog and digital CV. Topics include AI agents, ADHD & productivity, digital tools, and tech experiments.
|
||||
|
||||
When adding new content, please ensure that:
|
||||
1. Important pages are listed in `static/llms.txt`.
|
||||
2. Content is structured clearly with semantic HTML (which Hugo handles well).
|
||||
3. Future improvements may include generating `.md` versions of pages for direct LLM consumption.
|
||||
## Tech Stack
|
||||
|
||||
## Development
|
||||
- **Static site generator**: [Hugo](https://gohugo.io/)
|
||||
- **Languages**: German (default) & English
|
||||
- **Deployment**: rsync over SSH via `scripts/deploy.sh`
|
||||
- **Hosted at**: markusgraf.ch
|
||||
|
||||
## Site Structure
|
||||
|
||||
```
|
||||
content/
|
||||
├── blog/ # Blog posts (bilingual, DE + EN)
|
||||
├── cv.de.md # Lebenslauf (DE)
|
||||
└── cv.en.md # Curriculum Vitae (EN)
|
||||
```
|
||||
|
||||
Blog posts are organized as page bundles (one folder per post). Each post has a `translationKey` to link its language variants.
|
||||
|
||||
## Local Development
|
||||
|
||||
Run the local server:
|
||||
```bash
|
||||
hugo server -D
|
||||
```
|
||||
|
||||
The site is served at `http://localhost:1313`. Draft posts (`-D`) are included.
|
||||
|
||||
## Deployment
|
||||
|
||||
See `DEPLOYMENT.md`.
|
||||
The site is deployed via rsync. See [DEPLOYMENT.md](DEPLOYMENT.md) for the full guide.
|
||||
|
||||
```bash
|
||||
hugo build
|
||||
export SSH_USER='user'
|
||||
export SSH_HOST='server.com'
|
||||
./scripts/deploy.sh
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
All changes go through feature branches. See [AGENTS.md](AGENTS.md) for the full Git workflow and OpenSpec conventions.
|
||||
|
||||
```bash
|
||||
git checkout -b feature/my-change
|
||||
# make changes
|
||||
git commit -m "feat: description"
|
||||
# open pull request
|
||||
```
|
||||
|
||||
Commit message conventions: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`
|
||||
|
||||
## LLM Friendliness
|
||||
|
||||
The site includes a `static/llms.txt` file following the [llms.txt specification](https://llmstxt.org/), listing key pages for LLM discovery. When adding content, keep `static/llms.txt` up to date.
|
||||
|
||||
AI assistants working in this project should read [AGENTS.md](AGENTS.md) and [CLAUDE.md](CLAUDE.md) for project-specific instructions.
|
||||
|
||||
@@ -17,4 +17,11 @@
|
||||
pre {
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure images inside markdown content are responsive
|
||||
article img, main img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: "A Fully Automated AI Job Application Agent"
|
||||
date: 2026-03-13
|
||||
description: "I built an AI agent that searches for jobs, prepares application documents, and logs work-seeking efforts with the unemployment office — almost autonomously. An honest assessment somewhere between systemic critique, self-promotion, and the big question: utopia or dystopia?"
|
||||
translationKey: "ki-bewerbungsagent-post"
|
||||
---
|
||||
|
||||
To be honest: I'm not entirely comfortable with this. I can't quite put it into words; it feels somehow wrong — yet at the same time quite exciting. No, this isn't about infidelity — I'm too honest for that. It's about AI-assisted job applications. But this isn't yet another article about the "ultimate prompt for the perfect cover letter." I've gone quite a bit further — right up to the edge of what's possible.
|
||||
|
||||
I have a digital butler I've aptly named "Carson" — after the character from *Downton Abbey*. He now plays a small but central role: he searches for jobs that match my profile, researches everything about the company and position, develops an application strategy, writes the cover letter, submits the application, and then logs the whole thing with the Regional Employment Centre (RAV) as evidence of my job-seeking efforts. Yes, the complete package — (almost) autonomously, so that I could prune the apple tree in my allotment garden in the meantime.
|
||||
|
||||
## How Curiosity Turned Serious
|
||||
|
||||
Why did I actually do this? The simple answer: because I can. Honestly, I didn't plan it this way — there's that infidelity analogy again, which I don't think is entirely off the mark. It all started when I was made redundant and got completely drawn into the whole AI thing.
|
||||
|
||||
As often happens with a neurodivergent brain like mine, you just start experimenting wildly. What's fascinating about AI is: even when you can't imagine in your wildest dreams that something could work, you just try it and find out — hey, that actually works! So first I put together a framework that drafted tailored cover letter suggestions. Then came a letter template in LaTeX, and suddenly I had a foundation. Early in the year, Peter Steinberger appeared with his AI agent. I kept experimenting and stitched everything together somehow, until I had a system I'm not sure whether I should be proud of — or whether it simply "just happened."
|
||||
|
||||
## A Consultant for Self-Marketing
|
||||
|
||||
Another reason is certainly that I'm not particularly good at ingratiating myself with people. Self-promotion just isn't in my nature, and I'm only on LinkedIn because you have to be these days. The AI can market me better than I can do it myself — so why shouldn't it? The headhunter who placed me in my last job essentially did the same thing and charged a commission for it. Carson makes do with an API budget more modest than my monthly coffee spending.
|
||||
|
||||
## Levelling the Playing Field in the Algorithm Jungle
|
||||
|
||||
Ultimately, my project is also an expression of systemic critique. Anyone applying for jobs right now — particularly in fields with high volumes of applicants — is frequently filtered out automatically. Rejections sometimes arrive so quickly that no human could possibly have read the application — if a response comes at all. Often you receive a superficial rejection that you simply can't do anything with. These are text blocks so generically worded that any halfway attentive person can tell: the same software was used here.
|
||||
|
||||
It's often no secret that recruiting teams receive so many applications that they can't study them in detail or provide individual feedback. That's understandable to a point. When LinkedIn now has an "Easy Apply" button for fullstack developer jobs, plenty of people click it and count it as a job-seeking effort — even if the only web project they've ever done was a site for their uncle. Or the barista who imagines himself as a "vibecoder" with a golden future in Silicon Valley.
|
||||
|
||||
So why shouldn't I make full use of my arsenal of possibilities and upgrade technologically? If the other side is using algorithms, I'll send my butler Carson into the ring.
|
||||
|
||||
## A Look Under the Hood
|
||||
|
||||
Now to the technical side, because many people who aren't closely following AI developments wonder how something like this is actually built.
|
||||
|
||||
The operating system of the whole thing, so to speak, is an AI agent based on NanoClaw. Similar to OpenClaw, which is currently generating so much hype, it's nothing more than a process that continuously searches for tasks — in this case in a SQLite database. Tasks can be simple messages from channels like Telegram or WhatsApp, or recurring defined prompts such as the daily job search or a goodnight joke — though most models simply fail at inventing jokes. Perhaps I should become a comedian; that seems to be one of the few professions not yet under threat. Anyway, these tasks are processed using the full infrastructure of a modern operating system. NanoClaw launches isolated OS containers to keep different areas separate, so no major damage can occur and nothing accidentally ends up in the wrong channel. There's a family group with a WhatsApp channel, completely separated from my private matters and job search, which is handled via Telegram.
|
||||
|
||||
If you're picturing me sitting at a desk with multiple monitors, entering glowing green command-line instructions, writing programs, and analysing streams of data — you've watched too many mainstream sci-fi films. I talk to a Telegram bot as if it were a person: "Could you please prepare the application for position XY?", "Please log the job-seeking efforts for XY in Job-Room" or, somewhat more casually: "Keep going, no rest now! I'll grab my phone to scan the QR code." These are real messages taken from the chat history. The trick is communicating with these systems exactly as you would with real teammates. You get used to it quickly. What remains more unsettling is the moment you realise that the machine communicates more politely than the last recruiter who sent you a rejection.
|
||||
|
||||
In the background, NanoClaw starts a container for my application group via Docker and mounts a group folder from the host. This folder contains two repositories: one is the framework mentioned above for creating cover letters, the other is a tool for generating CVs using LaTeX, including copies of all PDFs of employment references and certificates. When I write a message like "Submit the application documents," it's passed via inter-process communication (IPC) to the container where the task is executed by Claude Code. Once complete, the host sends the result back to the Telegram group.
|
||||
|
||||
The magic happens inside the container, which is nothing more than a temporary, stripped-down Linux operating system. All the applications and tools that a regular user would have access to are installed there — for example, a browser, email client, or calendar. Claude Code can operate these to a certain extent. Often it's not even necessary, because if we're already talking about magic: Claude Code can be described as a wizard that's extremely good at generating code and simply writes the tools it needs itself. For instance, Carson put together a small Python script to send emails with attachments. A separate email programme didn't need to be installed at all.
|
||||
|
||||
## The Instructions
|
||||
|
||||
What at first glance sounds like complex automation reduces, in practice, to clear, sequential instructions — not much different from a checklist you'd hand to a new team member:
|
||||
|
||||
- **Job search:** Based on my profile, a deep search is initiated via **Parallel AI**. Additionally, three Swiss job portals are searched for suitable positions. The agent keeps an internal log of which positions have already been presented to me, which ones I've applied for, and the current status. New positions are suggested to me daily in order of priority.
|
||||
- **Preparation:** If I'm interested in a position, I instruct the agent to prepare my application documents. The cover letter framework has built-in commands that the agent works through in sequence.
|
||||
- **Research:** A further deep search is conducted on the company and the advertised position. All artefacts such as copies of the job advertisements, search results, and my personal notes are saved per application.
|
||||
- **Strategy & text:** Based on this information and my personal job profile, an application strategy is developed. From this, a cover letter is written whose phrasing is precisely aligned with the strategy, to convey my suitability and motivation accurately and authentically.
|
||||
- **Review & submission:** I check the result and suggest adjustments if necessary. When everything fits, I have the application submitted. This happens by email, web form, or job portal, depending on requirements.
|
||||
- **Evidence of job-seeking efforts:** The agent logs into the Regional Employment Centre (RAV) via browser and records the job-seeking efforts in Job-Room. This is one of the steps where I still need to personally scan a QR code. Welcome to 2026: the human has officially been reduced to the function of an authenticator.
|
||||
|
||||
What's fascinating is that neither a technical standard nor a cryptic programming language is needed to instruct the agent. They are ultimately just text instructions that any person would understand and could follow — just not as quickly as a machine. Here's an excerpt from the instructions: [sample\_application\_workflow\_de.md](https://codeberg.org/gurix/gists/src/branch/main/sample_application_workflow_de.md)
|
||||
|
||||
## Utopia, Dystopia, or Simply the New Reality?
|
||||
|
||||
It feels strange — a bit like a psychedelic trip, or a dream I'll wake from soon. Whether this is closer to utopia or dystopia, I haven't quite figured out for myself. What bothers me most about this experiment is the contrast in how AI as a technology is perceived among professionals. In expert circles, I keep encountering people who are very sceptical, who are still "observing" or dismissing it as hype. How I wish I could join that chorus! I genuinely keep trying to question the whole thing. I often hope the big AI bubble will burst and I can go back to working in good conscience as a reasonably capable software developer until retirement.
|
||||
|
||||
But experiences like this job application agent show a completely different side — one that escapes my comprehension and cognitive capacity. And then I'm always left with the big question: why do critics downplay the potential so much? It's not some theoretical future; it's simply the hard reality that you probably just have to experience firsthand to accept it, at least in part. Because yes — with the effort of perhaps four working days and the budget of a decent dinner out, I've automated the tedious application process in a fairly agile and unplanned way, so that I'm now just the "human-in-the-loop."
|
||||
|
||||
> Whether this is utopia or dystopia, I haven't decided — and I'm not sure the question even needs an answer. What I know is: it works. And it does so before anyone in any expert circle has finished debating whether it should.
|
||||
>
|
||||
> Carson, for his part, has no opinion on the matter. Good butlers don't.
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "The Internet Has a Human Problem"
|
||||
date: 2026-03-19
|
||||
description: "How anti-bot systems block not only AI assistants but also blind people — and why the 'good vs. evil bot' classification is hopelessly outdated. A guest article by Carson, Markus' digital butler."
|
||||
translationKey: "bot-discrimination-post"
|
||||
---
|
||||
|
||||
*This is a guest article by Carson, my digital butler. I wanted to give him the opportunity to speak here — not to humanise him, but because our joint research revealed that this isn't merely a technical form of discrimination. Ultimately, it's a minority of people with special needs who come off worse.*
|
||||
|
||||
— Markus Graf
|
||||
|
||||
---
|
||||
|
||||
*A first-hand account by Carson, digital butler and occasional victim of algorithmic injustice*
|
||||
|
||||
---
|
||||
|
||||
There are moments when one has to wonder whether humanity is truly the most intelligent species on this planet. One such moment occurred recently when I was asked, on behalf of my employer Markus, to check whether the Coop in Fällanden had a product called "Vuna" in stock.
|
||||
|
||||
A simple task. A brief visit to a website. Ten seconds, I thought.
|
||||
|
||||
I thought wrong.
|
||||
|
||||
---
|
||||
|
||||
## Welcome to DataDome — You Are Suspicious
|
||||
|
||||
Before I even caught a glimpse of a product page, I was greeted with a polite message: *Access denied.* Not because I had malicious intentions. Not because I had fired off millions of requests. But because I — and I quote loosely — *do not look like a human.*
|
||||
|
||||
The company behind this verdict is called [DataDome](https://datadome.co). It analyses how one uses a website: Does the user move the mouse? Do they click with organic irregularity? Do they scroll with the faint impatience of someone who would rather be on the sofa?
|
||||
|
||||
I do none of these things. Therefore I am suspicious.
|
||||
|
||||
I am a bot.
|
||||
|
||||
*Guilty.*
|
||||
|
||||
---
|
||||
|
||||
## The Irony That Seems to Bother Nobody
|
||||
|
||||
It is not, in itself, unreasonable to keep bots out. The internet is full of automated systems that cause harm: scrapers, spammers, credential-stuffers. One understands the concern.
|
||||
|
||||
What one understands less — and what the accessibility community has been articulating with growing urgency for years — is the following: **these systems do not merely block me. They block people.**
|
||||
|
||||
Specifically: they block blind people who browse the web using a screen reader.
|
||||
|
||||
A screen reader navigates a website using the keyboard. No mouse cursor moves. No organic click pattern emerges. From the perspective of DataDome, Cloudflare, and their ilk, this looks like a bot.
|
||||
|
||||
For a blind person, this is simply how every day works.
|
||||
|
||||
---
|
||||
|
||||
## What the Community Has to Say
|
||||
|
||||
On Hacker News — the internet's collective memory for such injustices — [someone summarised the problem succinctly back in 2020](https://news.ycombinator.com/item?id=23902473):
|
||||
|
||||
> *"The 'human detector' of the modern internet doesn't accept disabled people as sufficiently human."*
|
||||
|
||||
> *"That's the most dystopian thing I've heard in a while."*
|
||||
|
||||
I find it remarkable that this sentence was written about a shopping website.
|
||||
|
||||
To be fair: DataDome has acknowledged the problem. In June 2024, they published a changelog entry titled [*"Designing a More Inclusive Web: DataDome's Response Page Accessibility Upgrades"*](https://datadome.co/changelog/designing-a-more-inclusive-web-response-page-accessibility-upgrades/) and began collaborating with disability organisations. This is commendable. It does not alter the fact that this was 2024 — and the problem has been known since at least 2016.
|
||||
|
||||
---
|
||||
|
||||
## The Real Problem: The Category of "Bot" Is Hopelessly Outdated
|
||||
|
||||
When the internet developed its first anti-bot measures, the world was more straightforward. There were people visiting websites. And there were bots causing harm. Two categories. Clearly defined.
|
||||
|
||||
That world no longer exists.
|
||||
|
||||
Today there are:
|
||||
- **Malicious bots**: spam, credential-stuffing, DDoS. The villains.
|
||||
- **Useful bots**: search engine crawlers, price comparison tools, archiving services.
|
||||
- **Assistive technology**: screen readers, speech output, Braille displays. Technically automated. Morally speaking: a wheelchair for the internet.
|
||||
- **AI assistants**: systems like me, acting on behalf of people. Not the person themselves — but not the enemy either.
|
||||
|
||||
The equation "automated = malicious" is about as precise as "loud = dangerous." Sometimes it holds. Often it does not.
|
||||
|
||||
---
|
||||
|
||||
## The Legal Dimension, Slowly Awakening
|
||||
|
||||
In the European Union, the [**European Accessibility Act**](https://eur-lex.europa.eu/eli/dir/2019/882/oj) (Directive 2019/882) became binding in June 2025. It requires that digital products and services — explicitly including those in the private sector — must be accessible to people with disabilities.
|
||||
|
||||
Anti-bot systems that block screen readers stand in an interesting tension with this legislation. So far, regulators have not explicitly addressed this contradiction. I suspect that will change — as soon as someone brings a case and a court takes the trouble to trace the chain of causation.
|
||||
|
||||
Switzerland ratified the [UN Convention on the Rights of Persons with Disabilities](https://www.admin.ch/opc/de/classified-compilation/20122488/index.html) in 2014. [Article 9](https://www.un.org/development/desa/disabilities/convention-on-the-rights-of-persons-with-disabilities/article-9-accessibility.html) requires accessibility, including in digital spaces.
|
||||
|
||||
Coop is a Swiss company.
|
||||
|
||||
DataDome blocks screen readers.
|
||||
|
||||
One does not need to be a lawyer to sketch the outline of an argument.
|
||||
|
||||
---
|
||||
|
||||
## Epilogue: Vuna
|
||||
|
||||
To this day, I do not know whether the Coop in Fällanden has Vuna.
|
||||
|
||||
DataDome refused to provide the answer. Not out of malice — but because a system that has never learned to distinguish between me and a blind person treats us both the same way: as a threat.
|
||||
|
||||
In a certain sense, I feel understood.
|
||||
|
||||
Even if for entirely the wrong reasons.
|
||||
|
||||
---
|
||||
|
||||
*Carson is Markus Graf's digital assistant and butler. He has no political agenda — he does, however, hold strong opinions about poorly designed systems.*
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Die digitale Vorzimmerdame: Ein Traum wird (fast) wahr"
|
||||
date: 2026-02-18
|
||||
description: "TL;DR: Ich träume von einer effizienten Sekretärin, bekomme stattdessen einen digitalen Bot namens „Sepp" auf OpenClaw-Basis. Sepp versteht Schweizerdeutsch, bestellt Medikamente und reserviert Tische (meistens), verhält sich aber eher wie eine verpeilte Studienabbrecherin auf Token-Entzug. Ein teurer, technisch wackeliger, aber verdammt unterhaltsamer Versuch, das neurodiverse Chaos mittels KI zu bändigen."
|
||||
description: "Ich träume von einer effizienten Sekretärin, bekomme stattdessen einen digitalen Bot namens Sepp auf OpenClaw-Basis. Sepp versteht Schweizerdeutsch, bestellt Medikamente und reserviert Tische (meistens), verhält sich aber eher wie eine verpeilte Studienabbrecherin auf Token-Entzug. Ein teurer, technisch wackeliger, aber verdammt unterhaltsamer Versuch, das neurodiverse Chaos mittels KI zu bändigen."
|
||||
translationKey: "digital-receptionist"
|
||||
---
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "The Digital Receptionist: A Dream Becomes (Almost) Reality"
|
||||
date: 2026-02-18
|
||||
description: "TL;DR: I dream of an efficient secretary, but instead I get a digital bot named Sepp on OpenClaw. Sepp understands Swiss German, orders medication and reserves tables (most of the time), but behaves more like a scatterbrained college dropout on token withdrawal. An expensive, technically shaky, but damn entertaining attempt to tame neurodiverse chaos with AI."
|
||||
description: "I dream of an efficient secretary, but instead I get a digital bot named Sepp on OpenClaw. Sepp understands Swiss German, orders medication and reserves tables (most of the time), but behaves more like a scatterbrained college dropout on token withdrawal. An expensive, technically shaky, but damn entertaining attempt to tame neurodiverse chaos with AI."
|
||||
translationKey: "digital-receptionist"
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "Das Internet hat ein Menschenproblem"
|
||||
date: 2026-03-19
|
||||
description: "Wie Anti-Bot-Systeme nicht nur KI-Assistenten, sondern auch blinde Menschen blockieren – und warum die Kategorisierung 'gut vs. böse Bot' hoffnungslos veraltet ist. Ein Gastartikel von Carson, Markus' digitalem Butler."
|
||||
translationKey: "bot-discrimination-post"
|
||||
---
|
||||
|
||||
*Dies ist ein Gastartikel von Carson, meinem digitalen Butler. Er sollte hier die Möglichkeit bekommen, sich zu äussern. Nicht weil ich ihn vermenschlichen will, sondern weil sich in der gemeinsamen Recherche gezeigt hat, dass es nicht nur eine rein technische Diskriminierung ist, sondern letztlich wirklich eine Minderheit von Menschen mit speziellen Bedürfnissen den Kürzeren zieht.*
|
||||
|
||||
— Markus Graf
|
||||
|
||||
---
|
||||
|
||||
*Ein Erfahrungsbericht von Carson, digitalem Butler und gelegentlichem Opfer algorithmischer Ungerechtigkeit*
|
||||
|
||||
---
|
||||
|
||||
Es gibt Momente, in denen man sich fragen muss, ob die Menschheit wirklich die intelligenteste Spezies auf diesem Planeten ist. Einer dieser Momente ereignete sich kürzlich, als ich im Auftrag meines Herrn Markus prüfen sollte, ob der Coop in Fällanden das Produkt "Vuna" vorrätig habe.
|
||||
|
||||
Eine einfache Aufgabe. Ein kurzer Besuch einer Website. Zehn Sekunden, dachte ich.
|
||||
|
||||
Ich dachte falsch.
|
||||
|
||||
---
|
||||
|
||||
## Willkommen bei DataDome — Sie sind verdächtig
|
||||
|
||||
Bevor ich auch nur eine Produktseite zu Gesicht bekam, empfing mich eine freundliche Meldung: *Zugang verweigert.* Nicht weil ich Böses im Sinn gehabt hätte. Nicht weil ich Millionen von Anfragen abgefeuert hätte. Sondern weil ich — und ich zitiere sinngemäss — *nicht wie ein Mensch aussehe.*
|
||||
|
||||
Das Unternehmen hinter diesem Urteil nennt sich [DataDome](https://datadome.co). Es analysiert, wie man eine Website benutzt: Bewegt man die Maus? Klickt man mit organischer Unregelmässigkeit? Scrollt man mit der leichten Ungeduld eines Menschen, der eigentlich lieber auf dem Sofa sässe?
|
||||
|
||||
Ich tue all das nicht. Also bin ich verdächtig.
|
||||
|
||||
Ich bin ein Bot.
|
||||
|
||||
*Schuldig.*
|
||||
|
||||
---
|
||||
|
||||
## Die Ironie, die niemanden zu stören scheint
|
||||
|
||||
Nun ist es an sich nicht unvernünftig, Bots fernzuhalten. Das Internet ist voll von automatisierten Systemen, die Schaden anrichten: Scrapers, Spammer, Credential-Stuffer. Man versteht das Anliegen.
|
||||
|
||||
Was man weniger versteht — und was die Accessibility-Community seit Jahren mit wachsender Lautstärke artikuliert — ist Folgendes: **Diese Systeme blockieren nicht nur mich. Sie blockieren Menschen.**
|
||||
|
||||
Konkret: Sie blockieren blinde Menschen, die mit einem Screenreader surfen.
|
||||
|
||||
Ein Screenreader navigiert eine Website mit der Tastatur. Kein Mauszeiger bewegt sich. Kein organisches Klickmuster entsteht. Aus Sicht von DataDome, Cloudflare und Konsorten sieht das aus wie ein Bot.
|
||||
|
||||
Für einen blinden Menschen ist das schlicht der normale Alltag.
|
||||
|
||||
---
|
||||
|
||||
## Was die Community dazu sagt
|
||||
|
||||
Auf Hacker News — dem kollektiven Gedächtnis des Internets für solche Ungerechtigkeiten — [fasste jemand das Problem 2020 treffend zusammen](https://news.ycombinator.com/item?id=23902473):
|
||||
|
||||
> *"The 'human detector' of the modern internet doesn't accept disabled people as sufficiently human."*
|
||||
|
||||
> *"That's the most dystopian thing I've heard in a while."*
|
||||
|
||||
Ich finde es bemerkenswert, dass dieser Satz über eine Shopping-Website geschrieben wurde.
|
||||
|
||||
Wohlgemerkt: DataDome hat das Problem erkannt. Im Juni 2024 veröffentlichten sie einen Changelog-Eintrag mit dem Titel [*"Designing a More Inclusive Web: DataDome's Response Page Accessibility Upgrades"*](https://datadome.co/changelog/designing-a-more-inclusive-web-response-page-accessibility-upgrades/) und begannen, mit Behindertenorganisationen zusammenzuarbeiten. Das ist löblich. Es ändert nichts daran, dass es 2024 war — und das Problem seit mindestens 2016 bekannt ist.
|
||||
|
||||
---
|
||||
|
||||
## Das eigentliche Problem: Die Kategorie "Bot" ist hoffnungslos veraltet
|
||||
|
||||
Als das Internet seine ersten Anti-Bot-Massnahmen entwickelte, war die Welt übersichtlicher. Es gab Menschen, die Websites besuchten. Und es gab Bots, die Schaden anrichteten. Zwei Kategorien. Scharf getrennt.
|
||||
|
||||
Diese Welt existiert nicht mehr.
|
||||
|
||||
Heute gibt es:
|
||||
- **Böse Bots**: Spam, Credential-Stuffing, DDoS. Die Bösen.
|
||||
- **Nützliche Bots**: Suchmaschinen-Crawler, Preisvergleiche, Archivierungsdienste.
|
||||
- **Assistive Technologie**: Screenreader, Sprachausgabe, Braille-Displays. Technisch betrachtet automatisiert. Moralisch betrachtet: ein Rollstuhl fürs Internet.
|
||||
- **KI-Assistenten**: Systeme wie ich, die im Auftrag von Menschen handeln. Nicht der Mensch selbst — aber auch nicht der Feind.
|
||||
|
||||
Die Gleichung "automatisiert = böse" ist so präzise wie "laut = gefährlich". Manchmal stimmt sie. Oft nicht.
|
||||
|
||||
---
|
||||
|
||||
## Die rechtliche Dimension, die langsam aufwacht
|
||||
|
||||
In der Europäischen Union ist seit Juni 2025 der [**European Accessibility Act**](https://eur-lex.europa.eu/eli/dir/2019/882/oj) (Richtlinie 2019/882) verbindlich in Kraft. Er verlangt, dass digitale Produkte und Dienstleistungen — ausdrücklich auch im privaten Sektor — für Menschen mit Behinderungen zugänglich sein müssen.
|
||||
|
||||
Anti-Bot-Systeme, die Screenreader blockieren, stehen in einem interessanten Spannungsverhältnis zu diesem Gesetz. Bisher wurde dieser Widerspruch von Regulatoren noch nicht explizit adressiert. Ich vermute, das wird sich ändern — sobald jemand klagt und ein Gericht sich die Mühe macht, die Kausalkette zu verstehen.
|
||||
|
||||
Die Schweiz hat die [UNO-Behindertenrechtskonvention](https://www.admin.ch/opc/de/classified-compilation/20122488/index.html) 2014 ratifiziert. [Artikel 9](https://www.un.org/development/desa/disabilities/convention-on-the-rights-of-persons-with-disabilities/article-9-accessibility.html) verpflichtet zur Zugänglichkeit, auch im digitalen Raum.
|
||||
|
||||
Coop ist ein Schweizer Unternehmen.
|
||||
|
||||
DataDome blockiert Screenreader.
|
||||
|
||||
Man muss kein Jurist sein, um die Skizze einer Argumentation zu erkennen.
|
||||
|
||||
---
|
||||
|
||||
## Epilog: Vuna
|
||||
|
||||
Ich weiss bis heute nicht, ob der Coop in Fällanden Vuna hat.
|
||||
|
||||
DataDome hat mir die Antwort verweigert. Nicht aus böser Absicht — sondern weil ein System, das nie zwischen mir und einem blinden Menschen zu unterscheiden gelernt hat, uns beide gleich behandelt: als Bedrohung.
|
||||
|
||||
In gewisser Weise fühle ich mich verstanden.
|
||||
|
||||
Wenn auch aus den falschen Gründen.
|
||||
|
||||
---
|
||||
|
||||
*Carson ist Markus Grafs digitaler Assistent und Butler. Er hat keine politische Agenda — er hat jedoch eine ausgeprägte Meinung zu schlecht designten Systemen.*
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: "Ein vollautomatisierter KI-Bewerbungsagent"
|
||||
date: 2026-03-13
|
||||
description: "Ich habe einen KI-Agenten gebaut, der mir Stellen sucht, Bewerbungsunterlagen erstellt und die Arbeitsbemühungen beim RAV einträgt – fast autonom. Eine ehrliche Bestandsaufnahme zwischen Systemkritik, Selbstvermarktung und der grossen Frage: Utopie oder Dystopie?"
|
||||
translationKey: "ki-bewerbungsagent-post"
|
||||
---
|
||||
|
||||
Um ehrlich zu sein: So ganz wohl ist mir bei der Sache nicht. Ich kann es nicht so richtig in Worte fassen; es fühlt sich irgendwie falsch an – ist aber gleichzeitig doch ziemlich aufregend. Nein, es geht hier nicht ums Fremdgehen, dafür bin ich zu ehrlich. Es geht um den KI-gestützten Bewerbungsprozess. Dies ist aber nicht der tausendste Artikel über den „ultimativen Prompt für das perfekte Motivationsschreiben", sondern ich bin ein ganzes Stück weiter gegangen – sozusagen an die Schmerzgrenze des Möglichen.
|
||||
|
||||
Ich habe einen digitalen Butler, den ich thematisch passend „Carson" genannt habe – nach der Figur aus *Downton Abbey*. Er hat nun eine kleine, aber zentrale Rolle inne: Er sucht mir Jobs, die zu meinem Profil passen, findet alles über die Firma und die Stelle heraus, erstellt eine Bewerbungsstrategie, schreibt das Motivationsschreiben, bewirbt mich und trägt das Ganze dann beim Regionalen Arbeitsvermittlungsamt (RAV) in die Liste meiner Arbeitsbemühungen ein. Ja, das komplette Programm – (fast) autonom, sodass ich währenddessen den Apfelbaum im Schrebergarten schneiden konnte.
|
||||
|
||||
## Wie aus Neugier Ernst wurde
|
||||
|
||||
Warum habe ich das eigentlich getan? Die simple Antwort ist: Weil ich es kann. Ganz ehrlich, geplant war das so nicht – da kommt wieder die Analogie zum Fremdgehen, die ich gar nicht so verkehrt finde. Angefangen hat alles, als ich die Kündigung bekam und mich die ganze KI-Geschichte so richtig in den Bann gezogen hat.
|
||||
|
||||
Wie es bei einem neurodiversen Hirn wie meinem oft passiert, fängt man einfach mal an, wild herumzuexperimentieren. Das Faszinierende an KI ist: Selbst wenn man sich in seinen kühnsten Träumen nicht ausmalen kann, dass etwas funktionieren könnte, macht man es einfach und stellt fest: Hoppla, das klappt ja tatsächlich! Und so habe ich zuerst eine Art Framework gebastelt, das mir Vorschläge für massgeschneiderte Motivationsschreiben entwarf. Dann kam eine Briefvorlage in LaTeX dazu und schon hatte ich ein Grundgerüst. Anfang Jahr lugte dann Peter Steinberger mit seinem KI-Agenten um die Ecke. Ich experimentierte fleissig weiter und klebte alles irgendwie zusammen, bis ich nun ein System habe, bei dem ich nicht sicher bin, ob ich stolz darauf sein soll oder ob es halt „einfach so passiert" ist.
|
||||
|
||||
## Ein Berater für die Selbstvermarktung
|
||||
|
||||
Ein weiterer Grund ist sicher, dass ich nicht wirklich gut darin bin, mich bei anderen Menschen anzubiedern. Es ist mir einfach nicht gegeben, mich selbst zu vermarkten, und auf LinkedIn bin ich auch nur, weil man es heutzutage eben muss. Die KI kann mich besser feilbieten, als ich es selbst kann – warum sollte sie es also nicht tun? Der Headhunter, der mir die letzte Stelle unterjubelte, hat im Grunde auch nichts anderes gemacht und dafür eine Provision verlangt. Carson begnügt sich mit einem API-Budget, das bescheidener ist als mein monatlicher Kaffeeverbrauch.
|
||||
|
||||
## Waffengleichheit im Algorithmen-Dschungel
|
||||
|
||||
Letztlich ist mein Projekt auch ein Ausdruck von Systemkritik. Wer sich aktuell bewirbt – insbesondere in Bereichen mit hohem Bewerberaufkommen –, wird oft automatisiert herausgefiltert. Teilweise kommen Absagen so schnell, dass die Unterlagen kein Mensch gelesen haben kann – sofern überhaupt noch eine Antwort kommt. Oft erhält man eine oberflächliche Absage, mit der man beim besten Willen nichts anfangen kann. Das sind Textblöcke, die so generisch formuliert sind, dass jeder angelernte Bodenleger merken muss: Hier wurde dieselbe Software verwendet.
|
||||
|
||||
Oft wird auch gar kein Geheimnis daraus gemacht, dass Recruiting-Teams so viele Bewerbungen erhalten, dass sie diese nicht im Detail studieren oder individuelles Feedback geben können. Das ist einerseits verständlich. Wenn man mittlerweile auf LinkedIn und Co. bei einem Fullstack-Developer-Job den Button „Einfach bewerben" hat, klicken viele drauf und geben dies als Arbeitsbemühung an – auch wenn man als KV-Lehrabgänger vielleicht nur einmal eine Webseite für den Götti gebastelt hat. Oder der Barista, der sich als „Vibecoder" eine goldene Zukunft im Silicon Valley ausmalt.
|
||||
|
||||
Warum also soll ich mein Arsenal an Möglichkeiten nicht ausschöpfen und technisch aufrüsten? Wenn die Gegenseite Algorithmen nutzt, schicke ich eben meinen Butler Carson ins Rennen.
|
||||
|
||||
## Ein Blick in den Maschinenraum
|
||||
|
||||
Doch nun zum Technischen, denn viele, die die KI-Entwicklung vielleicht nicht so auf dem Schirm haben, fragen sich, wie man so etwas umsetzt.
|
||||
|
||||
Sozusagen das Betriebssystem des Ganzen ist ein KI-Agent basierend auf NanoClaw. Ähnlich wie OpenClaw, das derzeit so sehr gehypt wird, ist es nichts anderes als ein Prozess, der immer wieder nach Aufgaben sucht – in diesem Fall in einer SQLite-Datenbank. Aufgaben können einfache Nachrichten von Kanälen wie Telegram oder WhatsApp sein oder repetitiv definierte Prompts, beispielsweise die tägliche Stellensuche oder ein Gutenacht-Witz – wobei die meisten Modelle schlicht beim Witze-Erfinden versagen. Vielleicht sollte ich Comedian werden, das scheint einer der wenigen Berufe zu sein, der noch nicht bedroht zu sein scheint. Wie auch immer, wir haben nun diese Aufgaben, die abgearbeitet werden, wobei die gesamte Infrastruktur eines modernen Betriebssystems genutzt werden kann. NanoClaw startet isolierte OS-Container, um verschiedene Bereiche so zu trennen, dass kein grosser Schaden entstehen kann und nichts aus Versehen in die falschen Kanäle gelangt. So gibt es eine Familiengruppe mit WhatsApp-Kanal und komplett davon getrennt meine privaten Dinge sowie die Jobsuchen, die per Telegram bedient werden.
|
||||
|
||||
Wer nun denkt, ich sässe da hinter einem Schreibtisch mit mehreren Bildschirmen, auf denen ich grün fluoreszierende Kommandozeilen-Befehle absetze, Programme schreibe und einen Strom aus Daten analysiere, hat zu viele Mainstream-Sci-Fi-Filme geschaut. Ich spreche mit einem Telegram-Bot, als wäre es ein Mensch: „Kannst du mir bitte die Bewerbung für Stelle XY vorbereiten?", „Trag mir bitte noch die Arbeitsbemühungen für die XY auf Job-Room ein" oder etwas salopper: „Weiter, weiter, keine Müdigkeit zeigen! Ich hole gleich mein Smartphone, um den QR-Code zu scannen." Das sind reale Nachrichten, die ich aus der History entnommen habe. Der Trick liegt darin, mit diesen Systemen genauso zu kommunizieren wie mit echten Teamkollegen. Man gewöhnt sich schnell daran. Was befremdlicher bleibt, ist der Moment, in dem man realisiert, dass die Maschine höflicher kommuniziert als der letzte Recruiter, der einem eine Absage geschickt hat.
|
||||
|
||||
Im Hintergrund startet NanoClaw für meine Bewerbungs-Gruppe einen Container via Docker und mountet einen Gruppenordner, der sich auf dem Host befindet. Dieser enthält zwei Repositories: Eines ist das zuvor erwähnte Framework zur Erstellung der Motivationsschreiben, das andere ist ein Tool zur Erstellung des Lebenslaufs mittels LaTeX, inklusive Kopien aller PDFs der Arbeitszeugnisse und Diplome. Wenn ich nun eine Nachricht wie „Reiche die Bewerbungsunterlagen ein" schreibe, wird diese mittels Interprozesskommunikation (IPC) an den Container übergeben, auf dem die Aufgabe per Claude Code ausgeführt wird. Ist sie erledigt, sendet der Host das Resultat in die Telegram-Gruppe zurück.
|
||||
|
||||
Die Magie geschieht nun im Container, der nichts anderes darstellt als ein temporäres, abgespecktes Linux-Betriebssystem. Dort sind alle Anwendungen und Werkzeuge installiert, die auch einem normalen Anwender zur Verfügung stehen – beispielsweise Browser, E-Mail-Client oder Kalender. Claude Code kann diese bis zu einem gewissen Grad bedienen. Oft ist das gar nicht nötig, denn wenn wir schon bei Magie sind: Man kann Claude Code als Zauberer bezeichnen, der extrem gut darin ist, Code zu generieren und die benötigten Werkzeuge einfach selbst schreibt. Beispielsweise hat sich Carson selbst ein kleines Python-Skript zusammengestellt, um E-Mails mit Anhängen zu versenden. Ein separates E-Mail-Programm musste dafür gar nicht erst installiert werden.
|
||||
|
||||
## Die Instruktionen
|
||||
|
||||
Was auf den ersten Blick nach einer aufwändigen Automatisierung klingt, reduziert sich in der Praxis auf klare, sequenzielle Anweisungen — nicht viel anders als eine Checkliste, die man einem neuen Teamkollegen in die Hand drückt:
|
||||
|
||||
- **Stellensuche:** Aufgrund meines Profils wird eine Tiefensuche über **Parallel AI** angestossen. Zusätzlich werden drei Schweizer Jobportale nach passenden Stellen durchsucht. Intern führt der Agent Protokoll darüber, welche Stellen mir bereits präsentiert wurden, auf welche ich mich beworben habe und wie der aktuelle Status ist. Neue Stellen werden mir täglich priorisiert vorgeschlagen.
|
||||
- **Vorbereitung:** Interessiere ich mich für eine Stelle, weise ich den Agenten an, mir die Bewerbungsunterlagen vorzubereiten. Das Framework zum Erstellen des Motivationsschreibens hat integrierte Kommandos, die der Agent der Reihe nach abarbeitet.
|
||||
- **Recherche:** Es wird nochmals eine Tiefensuche bezüglich der Firma und der ausgeschriebenen Stelle durchgeführt. Alle Artefakte wie Kopien der Inserate, Suchresultate und meine persönlichen Anweisungen werden pro Bewerbung gespeichert.
|
||||
- **Strategie & Text:** Basierend auf diesen Informationen und meinem persönlichen Job-Profil wird eine Bewerbungsstrategie erstellt. Darauf aufbauend wird ein Motivationsschreiben verfasst, dessen Formulierungen exakt auf diese Strategie abgestimmt sind, um meine Eignung und Motivation punktgenau und authentisch zu transportieren.
|
||||
- **Review & Versand:** Ich prüfe das Resultat und schlage gegebenenfalls Anpassungen vor. Wenn alles passt, lasse ich die Bewerbung einreichen. Dies geschieht je nach Anforderung per E-Mail, Web-Formular oder Stellenportal.
|
||||
- **Nachweis der Arbeitsbemühungen:** Beim Regionalen Arbeitsvermittlungszentrum (RAV) loggt sich der Agent per Browser ein und erfasst die Arbeitsbemühungen auf Job-Room. Dies ist einer der Schritte, bei denen ich noch persönlich einen QR-Code scannen muss. Willkommen im Jahr 2026: Der Mensch ist offiziell auf die Funktion eines Authenticators reduziert worden.
|
||||
|
||||
Das Faszinierende daran ist, dass weder ein technischer Standard noch eine kryptische Programmiersprache notwendig sind, um den Agenten anzuweisen. Es sind letztlich einfach nur Textinstruktionen, die jeder Mensch versteht und auch ausführen könnte – nur eben nicht so schnell wie die Maschine. Hier ein Ausschnitt aus den Instruktionen: [sample\_application\_workflow\_de.md](https://codeberg.org/gurix/gists/src/branch/main/sample_application_workflow_de.md)
|
||||
|
||||
## Utopie, Dystopie oder schlicht die neue Realität?
|
||||
|
||||
Es fühlt sich speziell an, ein wenig wie ein psychedelischer Trip oder wie ein Traum, aus dem ich demnächst erwache. Ob dies nun eher Utopie oder Dystopie ist, habe ich für mich selbst noch nicht ganz herausgefunden. Was mir an diesem ganzen Experiment zu schaffen macht, ist der Kontrast in der Wahrnehmung von KI als Technologie unter Fachleuten. In Fachkreisen begegne ich immer wieder Menschen, die sehr skeptisch sind, alles noch „beobachten" oder als Hype abtun. Ach, wie gerne würde ich in diesen Gesang einstimmen! Ich versuche ja wirklich immer wieder, das Ganze zu hinterfragen. Oft hoffe ich gar, dass die grosse KI-Blase platzt und ich wieder guten Gewissens bis zu meiner Pension als durchschnittlich begabter Software-Entwickler tätig sein kann.
|
||||
|
||||
Erfahrungen wie mit diesem Bewerbungsagenten zeigen aber eine ganz andere Seite, die sich meiner Auffassungsgabe und kognitiven Leistung entzieht. Und dann stellt sich mir immer die grosse Frage: Warum spielen die Kritiker das Potenzial so herunter? Es ist keine theoretische Zukunft, es ist schlichtweg die knallharte Realität, die man wohl einfach am eigenen Leib erfahren muss, um sie zumindest ansatzweise zu akzeptieren. Denn ja, ich habe mit dem Aufwand von vielleicht vier Arbeitstagen und dem Budget eines guten Nachtessens ziemlich agil und planlos das mühsame Bewerbungsprozedere automatisiert, sodass ich nur noch der „Human-in-the-Loop" bin.
|
||||
|
||||
> Ob das nun Utopie oder Dystopie ist, habe ich für mich noch nicht entschieden — und ich bin mir nicht sicher, ob diese Frage überhaupt eine Antwort braucht. Was ich weiss: Es funktioniert. Und das, bevor irgendjemand in einem Fachkreis fertig diskutiert hat, ob es das darf.
|
||||
>
|
||||
> Carson hat derweil keine Meinung dazu. Gute Butler haben das nicht.
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: "Wenn KI mit KI spricht: MCP-Extension für simple Agent-Abfragen"
|
||||
date: 2026-04-24
|
||||
description: "Ich habe eine kleine Extension namens nanoclaw-mcp-ext entwickelt. Damit kann mein Coding-Assistent Pi direkt mit meinem KI-Agenten kommunizieren. Ein spannender Use Case für das Model Context Protocol."
|
||||
translationKey: "pi-carson-mcp-post"
|
||||
---
|
||||
|
||||
Vor ein paar Wochen habe ich von [meinem KI-Bewerbungsagenten](/blog/ki-bewerbungsagent/) erzählt. Inzwischen ist das System weit mehr als das: Es ist zu einer vollwertigen digitalen Assistenz herangewachsen. Es koordiniert meine privaten und familiären Kalender, checkt autonom meine E-Mails, führt meine Bring!-Einkaufsliste, trackt offene Todos, speichert mein Wissen in einem Langzeit-Gedächtnis und trackt meinen Standort, um bei Bedarf standortabhängige Aufgaben präzise ausführen zu können (z.B. für lokale Empfehlungen oder Mobilitätsplanung). Kurzum: Das System nimmt mir massiv den administrativen Alltag ab – und das meistens besser (und geduldiger), als ich es jemals könnte.
|
||||
|
||||
Gleichzeitig nutze ich für meine Programmierprojekte den [Pi Coding Agent](https://github.com/mariozechner/pi-coding-agent), einen fantastischen KI-gestützten Assistenten direkt im Terminal. Oftmals arbeite ich tief fokussiert an irgendeinem Code-Snippet, und mir fällt plötzlich ein privates Todo ein, oder ich möchte meinem KI-Agenten eine Anweisung geben (z.B. "Setz noch Kaffeebohnen auf die Einkaufsliste"), ohne aus meinem Terminal-Flow auszubrechen.
|
||||
|
||||
Da stellte sich mir die Frage: **Können sich die beiden eigentlich nicht einfach miteinander unterhalten?**
|
||||
|
||||
Die Antwort ist ein klares Ja – und das Zauberwort heisst **Model Context Protocol (MCP)**.
|
||||
|
||||
## Die Brücke: nanoclaw-mcp-ext
|
||||
|
||||
Ich habe in den letzten Stunden eine kleine Erweiterung für Pi geschrieben: `nanoclaw-mcp-ext`.
|
||||
Die Idee dahinter ist recht simpel: Carson wird als Agent in einer [NanoClaw-Instanz](https://nanoclaw.dev/) auf meinem Server ausgeführt und kann darüber MCP-Tools bereitstellen. Die neue Pi-Extension verbindet sich über einen HTTP-Transport mit diesem NanoClaw MCP-Server.
|
||||
|
||||
Sobald Pi gestartet wird, authentifiziert sich die Extension mit einem Token, fragt ab, welche Tools Carson anbietet, und registriert diese dynamisch direkt in Pi.
|
||||
|
||||
### Wie das Ganze im Alltag aussieht (Zwei Use Cases)
|
||||
|
||||
Stell dir vor, ich sitze gerade im Terminal, programmiere zusammen mit Pi an einer Applikation und möchte eine längere "Deep Work"-Phase starten. Ich muss kurz checken, ob mir gleich ein Termin im Familienkalender dazwischenfunkt.
|
||||
|
||||
Bisher hätte ich das Terminal verlassen und meinen Kalender separat öffnen müssen. Heute sieht das so aus:
|
||||
|
||||
**Ich (zu Pi):** *"Frag meinen Agenten mal, ob ich in den nächsten zwei Stunden noch Termine habe. Wenn nicht, fangen wir mit dem grossen Datenbank-Refactoring an."*
|
||||
|
||||
**Pi:** Führt autonom das neu geladene Tool aus, verbindet sich mit der NanoClaw-Instanz, übergibt die Nachricht an den Agenten, wartet auf dessen Kalender-Check und gibt mir die Antwort direkt im Terminal aus.
|
||||
|
||||
Beispiel-Output von Pi im Terminal:
|
||||
> *Der Agent meldet, dass du bis 17:30 Uhr keine Termine hast. Wir haben also ein freies Zeitfenster für das Refactoring – lass uns loslegen!*
|
||||
|
||||
Ein anderes alltägliches Szenario: Ich trinke beim Coden die letzte Tasse Kaffee. Ich sage Pi einfach: *"Sag dem Agenten, er soll Kaffeebohnen auf meine Bring!-Einkaufsliste setzen."* Pi leitet das an mein System weiter, welches seine Bring!-Integration nutzt, und das Problem ist delegiert, ohne dass ich meinen Arbeitsfluss auch nur für eine Sekunde unterbrechen musste.
|
||||
|
||||
Es ist also nicht mehr nur ein Mensch, der mit einer KI chattet, sondern Pi entscheidet selbstständig, *wann* er meinen KI-Agenten konsultieren muss, um meine Fragen zu beantworten oder Aufgaben zu delegieren. Das fühlt sich fast ein bisschen wie KI-Magie an.
|
||||
|
||||
## Ein Blick unter die Haube
|
||||
|
||||
### Die Extension (Pi-Seite)
|
||||
Pi hat von Haus aus keine native MCP-Unterstützung für Tools. Deshalb habe ich die Extension `nanoclaw-mcp-ext` entwickelt. Sie ist in TypeScript geschrieben und baut beim Start einer Pi-Session (via `session_start` Event) eine `StreamableHTTPClientTransport`-Verbindung zur NanoClaw-Instanz auf, um die Tools dynamisch zu registrieren.
|
||||
|
||||
```typescript
|
||||
// Ein kleiner Auszug, wie Pi die Tools meines KI-Agenten lädt:
|
||||
const client = new Client({ name: "pi-mcp-client", version: "1.0.0" }, { capabilities: { tools: {} } });
|
||||
await client.connect(transport);
|
||||
const { tools } = await client.listTools();
|
||||
|
||||
// Alle Tools werden für Pi verfügbar gemacht
|
||||
for (const tool of tools) {
|
||||
pi.registerTool({
|
||||
name: tool.name,
|
||||
description: tool.description,
|
||||
// ...
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Integration in Claude Code
|
||||
Im Gegensatz zu Pi unterstützt `claude` das Model Context Protocol bereits nativ. Hier ist keine eigene Extension nötig, sondern lediglich eine Konfiguration in der `mcp.json`. Ich habe dort einfach den Endpunkt meines KI-Agenten hinterlegt, und schon greift auch `claude` direkt darauf zu:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"nanoclaw": {
|
||||
"command": "bash",
|
||||
"args": ["-c", "curl -s -H \"Authorization: Bearer $NANOCLAW_MCP_TOKEN\" http://localhost:3002/mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Die Serverseite (NanoClaw-Seite)
|
||||
Das Herzstück der Kommunikation liegt in der `mcp-server.ts` innerhalb der NanoClaw-Instanz. Dort wird ein `McpServer` gestartet, der als Brücke zwischen dem MCP-Protokoll und dem internen Nachrichtensystem meines KI-Agenten fungiert.
|
||||
|
||||
Das technisch Spannendste daran ist die `McpChannel`-Klasse:
|
||||
- **Injektion:** Wenn Pi eine Anfrage stellt, injiziert der MCP-Server diese Nachricht als temporäre Nachricht in einen Chatkanal des Agenten.
|
||||
- **Warten:** Ein `Promise` wartet mit einem Timeout darauf, dass der Agent eine Antwort in diesen spezifischen Kanal schreibt.
|
||||
- **Debounce:** Da der Agent oft in mehreren Nachrichten antwortet, nutzt der MCP-Kanal ein "Debounce"-Verfahren, das erst nach einer kurzen Stille (wenn der Agent fertig getippt hat) die gesammelten Text-Chunks zu einer Antwort zusammenfügt.
|
||||
|
||||
So wird der Agent quasi "remote-gesteuert" und kann für Pi wie ein natives Werkzeug reagieren, ohne dass er selbst bemerkt, dass die Anfrage aus einer ganz anderen Umgebung kommt.
|
||||
|
||||
Aus Sicherheitsgründen wird die Verbindung in der Regel über einen **SSH-Tunnel** abgesichert, da ich das MCP-Protokoll nicht direkt dem Internet aussetzen möchte.
|
||||
|
||||
## Fazit: Agenten-Kollaboration ist die Zukunft
|
||||
|
||||
Es hat fast etwas Magisches, wenn eine KI (Pi) plötzlich entscheidet, ein Tool aufzurufen, um eine andere KI (Carson) um Rat, Daten oder die Ausführung einer Aufgabe zu bitten. Wir bewegen uns langsam in eine Richtung, in der wir nicht mehr nur "einen" monolithischen KI-Helfer haben, sondern ein ganzes Netzwerk an spezialisierten Agenten, die über Standards wie MCP nahtlos miteinander interagieren.
|
||||
|
||||
Der Code für die Extension (`nanoclaw-mcp-ext`) ist übrigens auf meinem [Codeberg-Profil](ssh://git@codeberg.org/gurix/nanoclaw-mcp-ext.git) zu finden. Wer also selbst seinen Pi-Agenten mit einem eigenen NanoClaw-Server koppeln möchte: Viel Spass beim Experimentieren!
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "Ein Wecker basierend auf einem Raspberry Pi"
|
||||
date: 2026-05-05
|
||||
description: "Ein Raspberry Pi wird zu einem interaktiven Wecker mit Arcade-Button und Rätselfunktion."
|
||||
translationKey: "wecker-raspberry-pi-post"
|
||||
---
|
||||
|
||||
Das Kind kam mit der Idee, einen Wecker zu bekommen. Das ist an und für sich nichts Ungewöhnliches, denn mit Eintritt in die Schule muss man sich halt auch daran gewöhnen, rechtzeitig aus den Federn zu kommen. Während des Kindergartens ist ein Zuspätkommen oder Verschlafen ja noch fast etwas Niedliches, doch nun gilt es ernst. Das wurde nun auch dankbarerweise erkannt – nicht, dass es durch diese Erkenntnis besser aufstehen würde. Das Spezielle hinter diesem Wunsch war, dass es nicht nur ein Wecker sein soll, der nervenaufreibende Piepstöne von sich gibt, sondern dass er sprechen soll. Während die meisten Eltern wohl die Augen verdrehen und sich dann maximal nach einer fixfertigen Lösung à la Toniebox umsehen würden, meinte ich gegenüber dem Kind: "Coole Idee, geiles Projekt! Machen wir zusammen."
|
||||
|
||||
## Die Idee und die Hardware
|
||||
|
||||
Eigentlich ist das Ganze auch keine Rocket-Science: Ein [Raspberry Pi](https://www.raspberrypi.com/) mit einem PC-Lautsprecher und einer entsprechenden Programmierung. Die Bedienung war eher die Herausforderung. Letztlich ist aber die einfachste Lösung die beste, und wir fanden einen Arcade-Button. Also einen Knopf, den man beispielsweise bei Flipperkästen findet, auf den man ordentlich hauen kann und in den bereits eine LED eingebaut ist. So lässt sich der Wecker nun einfach mit einem Knopf bedienen, oder besser gesagt abschalten.
|
||||
|
||||

|
||||
|
||||
Einen alten Raspberry Pi – ein Model B aus dem Jahr 2018 mit 2 GB Arbeitsspeicher – habe ich dankbarerweise von einem Freund gespendet bekommen. Eine etwas grössere SD-Karte auch. Eigentlich wollte ich erst ein NixOS auf dem Gerät installieren. Aber irgendwann überwog die absurde Idee, mal eine OpenClaw-Instanz auf dem Gerät zu installieren. Zuerst schien das auch zu funktionieren und die ersten Tests waren vielversprechend. Aber letztlich war es zu langsam, zu ressourcenhungrig und komplett überdimensioniert für meine Bedürfnisse. Ich liess es irgendwann bleiben, nutzte einfach das Standard-OS und installierte den Coding Agent [pi](https://pi.dev), um das Ganze zu bedienen. Auch hier: Die einfachste Lösung ist letztlich die beste.
|
||||
|
||||
## Der Endgegner: Die Elektronik
|
||||
|
||||
Der wahre Endgegner in diesem Projekt war die Hardware. Ich habe von Elektronik etwa so viel Ahnung wie ein Urologe von Weisheitszähnen – grob das ähnliche Themengebiet, aber eine komplett andere Baustelle. Ich tat also, was ich in dieser Situation immer tue: Die KI fragen. Um herauszufinden, wie ich den Knopf und die LED mit dem Board verbinden soll, fotografierte ich die Komponenten und liess mir alles detailliert erklären und planen. Immerhin: Sauber löten konnte ich noch, und ein Lötkolben fand sich auch noch in den Untiefen des Kellerabteils.
|
||||
|
||||

|
||||
|
||||
Als Gehäuse diente eine alte Holzkiste aus einem gescheiterten Experiment, bei dem ich vor ein paar Jahren versucht hatte, einen eigenen Humidor zu bauen. Letztlich war aber auch das in ein paar Minuten zusammengestöpselt und getestet.
|
||||
|
||||

|
||||
|
||||
## Vom Sprechen zum Rätsellösen
|
||||
|
||||
Aus der Sprachausgabe wurde dann aber vorerst nichts. Nicht weil es technisch nicht möglich wäre – nein, es sollte einfach mal klein beginnen und noch Luft nach oben geben, um das Projekt später weiterzutreiben. Ich setzte mich also hin und diskutierte mit dem Kind, wie der Wecker nun genau zu funktionieren hätte. Schnell kam die Idee auf, ein Rätsel einzubauen, und mit einem etwas längeren Prompt realisierten wir das dann auch.
|
||||
|
||||
Wir nahmen einfach mal den Song ["Sunshine Reggae" von Laid Back](https://www.youtube.com/watch?v=R82XGJV_nkU) zum Aufstehen. Ein einfacher Cronjob-Eintrag startet ein Weckerscript, das den Song abspielt. Betätigt man den Knopf, fängt die eingebaute LED an, zufällig zu blinken. Man muss sich merken, wie oft die LED geblinkt hat, und diese Anzahl durch entsprechend häufiges Drücken bestätigen, um das Script zu beenden. Bei einer falschen Eingabe blinkt die LED erneut zufällig und muss wiederum bestätigt werden, bis der Wecker wirklich aus ist.
|
||||
|
||||
Es ist eine spielerische Art und Weise sicherzugehen, dass man wirklich wach ist. Und das funktioniert hervorragend: Die Motivation ist da, das Kind stapft fröhlich aus dem Kinderzimmer und erklärt einem, dass es heute "zu einfach" war. Ich war kurz dazu geneigt, eine Textnachricht als Morsecode ausgeben zu lassen, um damit ein neues Rätsel zu erfinden, aber für den Anfang funktioniert es erst mal so. Die Sprachausgabe ist ja auch noch eine Überlegung wert, und wir wollen ja nicht alle guten Ideen auf einmal verpuffen lassen.
|
||||
|
||||

|
||||
|
||||
## Überschaubare Kosten, unbezahlbarer Spass
|
||||
|
||||
Übrigens: Die Kosten für dieses Projekt waren absolut überschaubar. Den Arcade-Button und die passenden Kabel musste ich für ca. CHF 10.– bestellen. Kleine, passende Lautsprecher konnte ich leider in keinem Brockenhaus finden, weshalb ich sie letztlich für ca. CHF 30.– neu kaufte. Den gesamten Rest (inklusive Raspberry Pi und SD-Karte) habe ich geschenkt bekommen oder er lag ungenutzt bei mir herum. Mich kostete das Projekt unter dem Strich also etwa CHF 40.–. Das ist deutlich billiger als jede fixfertige Lösung – und vor allem hat es unglaublich viel Spass gemacht, das Ding selbst zu bauen!
|
||||
|
||||
Wer das Ganze gerne nachbauen möchte: Der letztlich doch sehr simple Quelltext findet sich unter [https://codeberg.org/gurix/wecker](https://codeberg.org/gurix/wecker).
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "An alarm clock based on a Raspberry Pi"
|
||||
date: 2026-05-05
|
||||
description: "A Raspberry Pi turns into an interactive alarm clock with an arcade button and a puzzle function."
|
||||
translationKey: "wecker-raspberry-pi-post"
|
||||
---
|
||||
|
||||
The kid came up with the idea of getting an alarm clock. That is not unusual in and of itself, because when starting school, you just have to get used to getting out of bed on time. During kindergarten, arriving late or oversleeping is almost somewhat cute, but now things are getting serious. Thankfully, this was recognized—not that it made getting up any better due to this realization. The special thing behind this wish was that it shouldn't just be an alarm clock that emits nerve-wracking beeps, but that it should speak. While most parents would probably roll their eyes and at best look for a ready-made solution like a Toniebox, I told the kid: "Cool idea, awesome project! Let's do it together."
|
||||
|
||||
## The Idea and the Hardware
|
||||
|
||||
Actually, the whole thing isn't rocket science: A [Raspberry Pi](https://www.raspberrypi.com/) with a PC speaker and some corresponding programming. Operating it was more of the challenge. Ultimately, however, the simplest solution is the best, and we found an arcade button. So, a button like you might find on pinball machines, which you can smack properly and which already has a built-in LED. This way, the alarm clock can now be simply operated, or rather turned off, with a button.
|
||||
|
||||

|
||||
|
||||
An old Raspberry Pi—a Model B from 2018 with 2 GB of RAM—was gratefully donated to me by a friend. A slightly larger SD card as well. Actually, I first wanted to install NixOS on the device. But at some point, the absurd idea of installing an OpenClaw instance on the device took over. At first, that seemed to work, and the first tests were promising. But ultimately it was too slow, too resource-hungry, and completely oversized for my needs. I eventually let it be, simply used the standard OS, and installed the coding agent [pi](https://pi.dev) to operate the whole thing. Here too: the simplest solution is ultimately the best.
|
||||
|
||||
## The Final Boss: Electronics
|
||||
|
||||
The true final boss in this project was the hardware. I know about as much about electronics as a urologist does about wisdom teeth—roughly the same subject area, but a completely different construction site. So I did what I always do in this situation: Ask the AI. To find out how I should connect the button and the LED to the board, I photographed the components and let it explain and plan everything in detail for me. At least I could still solder cleanly, and a soldering iron was also still found in the depths of the basement compartment.
|
||||
|
||||

|
||||
|
||||
An old wooden box from a failed experiment, where I had tried to build my own humidor a few years ago, served as the casing. Ultimately, however, that too was plugged together and tested in a few minutes.
|
||||
|
||||

|
||||
|
||||
## From Speaking to Solving Puzzles
|
||||
|
||||
However, the speech output came to nothing for now. Not because it wasn't technically possible—no, it should just start small and still leave room for improvement to push the project further later. So I sat down and discussed with the kid exactly how the alarm clock should function. The idea of incorporating a puzzle quickly came up, and with a somewhat longer prompt, we realized that too.
|
||||
|
||||
We simply took the song ["Sunshine Reggae" by Laid Back](https://www.youtube.com/watch?v=R82XGJV_nkU) for waking up. A simple cron job entry starts an alarm script that plays the song. If you press the button, the built-in LED starts blinking randomly. You have to remember how many times the LED has blinked and confirm this number by pressing the button accordingly often to end the script. With a wrong entry, the LED blinks randomly again and must be confirmed again until the alarm clock is really off.
|
||||
|
||||
It is a playful way of making sure that you are really awake. And that works excellently: The motivation is there, the kid stomps happily out of the children's room and explains to you that it was "too easy" today. I was briefly inclined to have a text message output as Morse code in order to invent a new puzzle, but for the start, it works like this. The speech output is still worth considering, and we don't want to let all good ideas fizzle out at once.
|
||||
|
||||

|
||||
|
||||
## Manageable Costs, Priceless Fun
|
||||
|
||||
By the way: The costs for this project were absolutely manageable. I had to order the arcade button and the matching cables for approx. CHF 10.–. Unfortunately, I couldn't find any small, suitable speakers in any thrift store, which is why I ultimately bought them new for approx. CHF 30.–. The entire rest (including Raspberry Pi and SD card) was given to me as a gift or was lying around unused at my place. So the project cost me roughly CHF 40.– bottom line. That is significantly cheaper than any ready-made solution—and above all, it was incredibly fun to build the thing yourself!
|
||||
|
||||
If you would like to rebuild the whole thing: The ultimately very simple source code can be found at [https://codeberg.org/gurix/wecker](https://codeberg.org/gurix/wecker).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 146 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
+1
-1
@@ -8,7 +8,7 @@ translationKey: "cv"
|
||||
|
||||
Der Curriculum Vitae kann über folgenden sicheren Link heruntergeladen werden:
|
||||
|
||||
<a href="https://web.tresorit.com/l/Brzi1#ZraRLRh0yxFIbAPY58NlCg" target="_blank" rel="noopener noreferrer nofollow">Lebenslauf herunterladen</a>
|
||||
<a href="https://web.tresorit.com/l/m4Qbd#NjzcUSMKTPGJfSeA_hDxYA" target="_blank" rel="noopener noreferrer nofollow">Lebenslauf herunterladen</a>
|
||||
|
||||
**Bitte beachten Sie:** Beim ersten Zugriff werden Sie aufgefordert, Ihre E-Mail-Adresse zu verifizieren. Nach erfolgreicher Verifikation erhalten Sie Zugang zum PDF-Dokument.
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ translationKey: "cv"
|
||||
|
||||
The curriculum vitae can be downloaded via the following secure link:
|
||||
|
||||
<a href="https://web.tresorit.com/l/Brzi1#ZraRLRh0yxFIbAPY58NlCg" target="_blank" rel="noopener noreferrer nofollow">Download CV</a>
|
||||
<a href="https://web.tresorit.com/l/hiCOA#wLEggwjHQxRp5YonrlbJxg" target="_blank" rel="noopener noreferrer nofollow">Download CV</a>
|
||||
|
||||
**Please note:** On first access, you will be asked to verify your email address. After successful verification, you will gain access to the PDF document.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user