<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AI on Shaaf's blog</title><link>https://shaaf.dev/categories/ai/</link><description>Recent content in AI on Shaaf's blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 14 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://shaaf.dev/categories/ai/index.xml" rel="self" type="application/rss+xml"/><item><title>Modernizing Legacy Code with Konveyor AI: From EJB to Kubernetes</title><link>https://shaaf.dev/post/2026-04-15-konveyor-ai-for-every-language-and-the-future-of-applications-modernization/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-04-15-konveyor-ai-for-every-language-and-the-future-of-applications-modernization/</guid><description>&lt;p>I always enjoy participating in KubeCon. This time it was at the RAI center in Amsterdam. I have been to many conferences and the ones that are the best IMHO are the ones that are very community focused. For example DevNexus for Java, GeeCon for Geeks ;), and obviously KubeCon for everything Kubernetes. And obvsiouly making new friends and connections is a great way of learning from all the cool stuff thats going on. Thats probably enough name dropping for a wednesday ;)&lt;/p></description></item><item><title>Nano Agent, Mega Senses: Adding LSP to the 260-Line Coding Agent</title><link>https://shaaf.dev/post/2026-04-09-nano-agent-mega-senses-adding-lsp-to-the-260-line-coding-agent/</link><pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-04-09-nano-agent-mega-senses-adding-lsp-to-the-260-line-coding-agent/</guid><description>&lt;p>Learn, learn, and learn more—that’s the name of the game. Coding agents are innovating fast; things are getting bigger and, quite often, bloated. To understand what an agent is actually doing, I’ve found it’s best to go back to the basics. It takes a bit more time, but the expertise you gain along the way sets you up for the long haul.&amp;quot; So here I read &lt;a href="https://xam.dk/blog/nanocode-coding-agent-in-260-lines-of-java/">Max&amp;rsquo;s&lt;/a> post and thought, how about add some more things to this. Fetching ideas&amp;hellip; done.. Lets add LSP support.&lt;/p></description></item><item><title>Using LLMs and MCP to generate static code analysis rules</title><link>https://shaaf.dev/post/2026-03-29-using-llms-and-mcp-to-generate-static-code-analysis-rules/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-03-29-using-llms-and-mcp-to-generate-static-code-analysis-rules/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Scribe&lt;/strong> is a &lt;a href="https://modelcontextprotocol.io/">Model Context Protocol (MCP)&lt;/a> server that exposes a single tool: &lt;strong>&lt;code>executeKantraOperation&lt;/code>&lt;/strong>. That tool turns structured parameters into &lt;strong>YAML rules&lt;/strong> compatible with &lt;a href="https://konveyor.io/">Konveyor&lt;/a> / &lt;a href="https://github.com/konveyor/kantra">Kantra&lt;/a>—the static analysis pipeline used for application migration and modernization. This post describes what Scribe does, how it is wired, and concrete examples you can copy.&lt;/p>&lt;/blockquote>
&lt;p>Static code analyzers are great at what they do. Having the ability to write custom rules is important because it can cover multiple usecases such as, if an organization has their own framework or libraries that do not exist in the public domain. Or to look for patterns or anti-patterns or even best practises such as exceptions, logging etc. It can get quite cumbersome to write these rules and test them. While every conference in the world today buzzes of the word &lt;strong>AI&lt;/strong>, how about we put it to real practise and provide this valuable feature with LLMs. Hence the advent of Scribe MCP server that will write Konveyor Kantra rules for an LLM.&lt;/p></description></item><item><title>Java+LLMs: A hands-on guide to building LLM Apps in Java</title><link>https://shaaf.dev/post/2026-03-05-handson-guide-to-building-llm-apps-in-java-jakartaee/</link><pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-03-05-handson-guide-to-building-llm-apps-in-java-jakartaee/</guid><description>&lt;p>I had the pleasure to present about building &lt;a href="https://dev.java/learn/">Java&lt;/a> applications using LLMs together with &lt;a href="https://x.com/bazlur_rahman">Bazlur&lt;/a> at &lt;a href="https://2025.geecon.org/">GeeCon 2025&lt;/a>. The weather was amazing and &lt;a href="https://en.wikipedia.org/wiki/Krak%C3%B3w">Krakow&lt;/a> is a beautiful historical city.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Zm6uhQNki_Q?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video">&lt;/iframe>
 &lt;/div>

&lt;h1 id="key-topics-covered">Key Topics Covered&lt;/h1>
&lt;p>Here are the key topics from the video with direct links to those sections:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D251s">LangChain4j Basics&lt;/a>:&lt;/strong> An introduction to the framework, demonstrating how it abstracts communication with various LLMs like OpenAI and Gemini using builder patterns.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D443s">Prompt Engineering&lt;/a>:&lt;/strong> The speakers explain the difference between &lt;strong>System Prompts&lt;/strong> (defining the AI&amp;rsquo;s behavior/personality) and &lt;strong>User Prompts&lt;/strong> (the specific query).&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D547s">AI Services &amp;amp; Streaming&lt;/a>:&lt;/strong> A look at how to create high-level interfaces for AI interactions, including streaming responses for real-time chat experiences.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D720s">Memory Management&lt;/a>:&lt;/strong> How to provide LLMs with context from previous conversations using providers like &lt;code>MessageWindowChatMemory&lt;/code> and storing history in databases.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D904s">Tools (Function Calling)&lt;/a>:&lt;/strong> A deep dive into how LLMs can trigger Java methods to perform specific tasks, such as fetching web content or compiling Java code.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D1306s">Jakarta EE Project Generator&lt;/a>:&lt;/strong> A demonstration of using an LLM tool to generate a complete Jakarta EE project structure via a chat interface.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D1635s">Retrieval-Augmented Generation (RAG)&lt;/a>:&lt;/strong> Using &lt;strong>PGVector&lt;/strong> and embedding models to store and retrieve private data efficiently.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D1784s">Chunking and Tokenization&lt;/a>:&lt;/strong> The importance of segmenting data so the AI receives the right context without exceeding token limits.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D2387s">Model Context Protocol (MCP)&lt;/a>:&lt;/strong> An introduction to the standard for connecting AI models to external data sources and tools.&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://www.google.com/search?q=https://www.youtube.com/watch%3Fv%3DZm6uhQNki_Q%26t%3D2948s">Q&amp;amp;A Session&lt;/a>:&lt;/strong> Discussions on prompt injection, guardrails, and testing non-deterministic AI outputs.&lt;/li>
&lt;/ul>
&lt;p>Next up we are both busy building a workshop about Langchain4j and its integration with Spring. If you are interested in learning more join us at &lt;a href="https://jnation.pt">JNation.pt&lt;/a>. Bring your laptop the session will be 180 minutes and lots to code about ;)&lt;/p></description></item><item><title>Two Essential Patterns for Building MCP Servers</title><link>https://shaaf.dev/post/2026-01-08-two-essential-patterns-for-buildingm-mcp-servers/</link><pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-01-08-two-essential-patterns-for-buildingm-mcp-servers/</guid><description>&lt;p>When building Model Context Protocol (MCP) servers, I learned two critical design patterns the hard way. What started as a straightforward implementation of a Keycloak administration server quickly became unwieldy—until I discovered &lt;strong>Intent Multiplexing&lt;/strong> and the &lt;strong>Command Pattern&lt;/strong>. Together, these patterns transformed a maintenance nightmare into an elegant, extensible architecture.&lt;/p>
&lt;p>This post shares those lessons so you can avoid the same pitfalls.&lt;/p>
&lt;p>Replicate each operation from your API and viola! you have a tool explosion. And that might not seem evident in the first place, but becomes a serious problem. An LLM might not be able to handle that large context, it might even start to halluncinate.&lt;/p></description></item><item><title>Keycloak MCP Server: Manage Identity with Natural Language</title><link>https://shaaf.dev/post/2026-01-02-keycloak-mcp-server/</link><pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2026-01-02-keycloak-mcp-server/</guid><description>&lt;p>There is always a distinct thrill in learning something new and immediately putting it to the test. My journey with Model Context Protocol (MCP) servers began with a basic &amp;lsquo;books API&amp;rsquo; demo, but I quickly wanted to take it a step further and build something with real-world utility. Since I enjoy working with &lt;a href="https://www.keycloak.org/">Keycloak&lt;/a>, I thought: Why not create an MCP server for it?&lt;/p>
&lt;p>The vision was simple: enable developers to just &amp;lsquo;chat&amp;rsquo; with Keycloak. There are so many standard tasks—setting up new users, groups, clients, and browser workflows—that could be streamlined through conversation. For those unfamiliar, Keycloak is an open-source identity and access management solution. I released the &lt;a href="https://dzone.com/articles/keycloak-mcp-server-tools-quarkus">first experimental version this past summer&lt;/a>, and since then, the wave of constructive community feedback has been incredible. That momentum is exactly what gets me excited to keep building.&lt;/p></description></item><item><title>Complete local setup development guide for Konveyor Analyzer-lsp 🚀</title><link>https://shaaf.dev/post/2025-09-08-complete-local-setup-development-guide-for-konveyor-analyzer-lsp/</link><pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2025-09-08-complete-local-setup-development-guide-for-konveyor-analyzer-lsp/</guid><description>&lt;blockquote>
&lt;p>Build, test, and develop Kantra rules locally with full JDT-LS and multi-language provider support. Some content in this post was generated using an LLM.&lt;/p>&lt;/blockquote>
&lt;p>Modernizing large, complex codebases is a significant challenge. Identifying migration blockers, deprecated APIs, and technology-specific patterns requires deep, accurate code analysis. The Konveyor Analyzer LSP is engineered to solve this problem by providing a flexible and powerful static analysis engine. It uniquely leverages the Language Server Protocol (LSP) to tap into rich, IDE-level code intelligence for multiple languages.&lt;/p></description></item><item><title>A Keycloak example - building my first MCP server Tools with Quarkus</title><link>https://shaaf.dev/post/2025-05-12-keycloak-mcp-server-quarkus/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2025-05-12-keycloak-mcp-server-quarkus/</guid><description>&lt;p>Recently I wrote an article about &amp;ldquo;&lt;a href="https://www.infoq.com/news/2025/05/mcp-within-java-ecosystem/">Adoption of the Model Context Protocol Within the Java Ecosystem&lt;/a>&amp;rdquo;. Now it was also time to start experimenting with writing an MCP Server myself (well maybe not the &lt;a href="https://youtu.be/LCzeb61bU9A?si=7mwaSEcaoEWuUB2z&amp;amp;t=5255">first time&lt;/a>).
Certainly I don&amp;rsquo;t want to be left out of all the cool things being demonstrated by the community. The goal for me is to learn, and creating perhaps a more practical example. In this post I am going to choose &lt;a href="https://www.keycloak.org/">Keycloak&lt;/a>, and write an experimental MCP server implementation for keycloak. The post is also to spark interest around this topic. Will it be useful to have an MCP server for Keycloak?&lt;/p></description></item><item><title>TechTalk - Java + LLMs: A hands-on guide to building LLM Apps in Java with Jakarta</title><link>https://shaaf.dev/post/2025-04-23-jakarta-tech-talk-llm-apps-java/</link><pubDate>Wed, 23 Apr 2025 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2025-04-23-jakarta-tech-talk-llm-apps-java/</guid><description>&lt;p>&lt;a href="https://docs.langchain4j.dev/">Langchain4j&lt;/a> is my favorite framework for working with large language models and &lt;a href="https://dev.java/learn/">Java&lt;/a>. In the last couple of weeks, both &lt;a href="https://x.com/bazlur_rahman">Bazlur&lt;/a> and I have presented to multiple user groups and &lt;a href="https://shaaf.dev/conferences/">conferences&lt;/a>. This week, we had the privilege of presenting at the Jakarta Tech Talk, which both of us were looking very much forward to.&lt;/p>
&lt;p>We now have so much demo code on the topic that we cannot present all the variations in one hour. We are still building along as we learn &lt;a href="https://github.com/learnj-ai/llm-jakarta">here&lt;/a>.&lt;/p></description></item><item><title>Migrating JavaEE apps using Generative AI and Konveyor AI</title><link>https://shaaf.dev/post/2025-02-22-migrating-javaee-to-quarkus-using-konveyor-ai/</link><pubDate>Sat, 22 Feb 2025 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2025-02-22-migrating-javaee-to-quarkus-using-konveyor-ai/</guid><description>&lt;p>&lt;a href="https://github.com/konveyor/kai">Konveyor AI&lt;/a> is a tool used to migrate Java applications to different Java frameworks, such as from JavaEE to &lt;a href="https://quarkus.io/">Quarkus&lt;/a> or &lt;a href="https://spring.io/">Spring&lt;/a> or from Spring 5 to 6, using Generative AI and static code analysis. I wrote a detailed post about this last year for the &lt;a href="https://www.javaadvent.com/2024/12/java-migrations-argh-and-now-large-language-models.html">Java Advent Calendar&lt;/a>.&lt;/p>
&lt;p>Most recently, we have all been hard at work, bringing a preview for our community of users. In this post, I will outline how you can install and configure Konveyor AI using &lt;a href="https://openai.com/">OpenAI&lt;/a> and make meaningful generations. However, I have chosen OpenAI for the sake of simplicity in this post. Users can choose many other models, which are documented &lt;a href="https://github.com/konveyor/kai/blob/main/docs/llm_selection.md">here&lt;/a>.&lt;/p></description></item><item><title>Java + LLMs: A hands-on guide to building LLM Apps in Java with Jakarta</title><link>https://shaaf.dev/post/2025-02-05-a-handson-guide-to-building-llm-apps-in-java-with-jakarta/</link><pubDate>Tue, 04 Feb 2025 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2025-02-05-a-handson-guide-to-building-llm-apps-in-java-with-jakarta/</guid><description>&lt;p>&lt;a href="https://foojay.io/">Java&lt;/a> is an amazing language to work with. Millions of developers use it for daily work routines, and many mission-critical applications run on Java today. Whether we talk about banks, stock exchanges, or space, Java is prevalent and a language of choice.&lt;/p>
&lt;p>With the advent of Large Language Models(LLM), new opportunities are at play. While Python has been the dominating language runtime for apparent reasons, there is a misconception that creating applications, agents, or other components for LLMs should also be done in Python. Most of the integration in LLMs is achieved by using REST API. Java is not short on anything in that space. System integration has been pretty awesome in Java, with many tools in that space. So why not Java?&lt;/p></description></item><item><title>Embracing the Future of Application Modernization with KAI</title><link>https://shaaf.dev/post/2024-07-23-embracing-the-future-of-app-mod-with-konveyor-ai/</link><pubDate>Tue, 23 Jul 2024 00:00:00 +0000</pubDate><guid>https://shaaf.dev/post/2024-07-23-embracing-the-future-of-app-mod-with-konveyor-ai/</guid><description>&lt;p>&lt;a href="https://www.konveyor.io">Konveyor’s&lt;/a> main strength lies in its comprehensive approach to migration and modernization. At the core of &lt;a href="https://www.konveyor.io">Konveyor’s&lt;/a> functionality is its powerful analysis engine. This engine performs static source code analysis, identifying anti-patterns and issues that might hinder the application’s operation on a target platform. Utilizing community standards like the Language Server Protocol, Konveyor&amp;rsquo;s analysis engine uses rules designed to aid in various migration scenarios. Users can also create custom rules to address specific migration needs, enhancing Konveyor&amp;rsquo;s flexibility and adaptability.&lt;/p></description></item></channel></rss>