Spring I/O

The Spring AI Ecosystem in 2026: From Foundations to Agents @ Spring I/O 2026

43:39 · 13 Apr 2026 – 15 Apr 2026 · YouTube

About this talk

This talk explores the advancements and current state of Spring AI, focusing on building intelligent applications using large language models (LLMs). The speakers discuss the importance of creating efficient pipelines and managing input and output in LLMs, highlighting the need for context management through the use of advisors. They illustrate how to handle the stateless nature of LLMs by implementing a chat memory advisor that maintains conversational history. Additionally, they introduce the concept of retrieval-augmented generation (RAG) for enhancing context, alongside the Model Context Protocol (MCP) for integrating LLMs with existing systems. Throughout the session, practical examples and patterns, including progressive disclosure and agent-to-agent protocols, are presented to demonstrate how to optimize context and enhance agent capabilities. The speakers conclude with insights on future developments and community contributions in Spring AI.

Full transcript

Oh yeah, hi. I'm Mark. I'll be talking later. I'm the founder of Spring AI. Hello, my name Can you hear me? Is it work? Okay, perfect. So, my name is Christian and yeah, I'm leading the Spring AI effort right now. And also, I'm one of the maintainers of the MCP Java SDK. Together with me, Darius, I work on Spring team. I'm working on project reactor and also

helping Spring Take it away, Christian. Yeah. See you later. Um so, we're going to talk about the current state of Spring AI, what what's happening, and we try to cover a lot of space. We won't have much time to do any real demos, but we have follow-up sessions with hands-down explanation of what we're doing. So, Spring AI ecosystem 2026, from the basic to the agents. And if

you have tried Everyone has tried AI already, the most basic most most basic pipeline you're going to build is user ask question, get response, relentlessly try to improve its its original question in order to find the to get the the response he expects. The hello world representation of this expression is is Spring AI. It's straightforward. You just can create a pipeline, run it, and get the response.

And actually, the LLM is only as good a response as the input is. So, this is this constantly the The idea is how we can actually get the intelligence without There is so much goodies inside. How can we build a harness around the LLM? This is a new hype word. Practically, harness is everything that's not in the LLM. Technically, that means that Spring AI frameworks like this

are also harness frameworks, but the end goal is how actually you can make the LLM useful for our use cases. And in order to answer this question, we really have to understand what are at least the key limitation or constraints of the LLMs. And I want to highlight a couple of those. The stateless The LLM is stateless. They're frozen in the past, so they don't know don't

have real information about your particular domain. They're not structured, text in text out, and they're nondeterministic. Also, you have to pay attention that you have a limited amount of data you can pass in a single request and a single response. So, having Keep in mind this this constraint, this model like black box, and let's see how actually we can extend and build upon it in order to

solve interesting some of those limitations. So, foundations and how we are going to What are the primitive and extension points? I really want you to realize that at the end of the day, most for most of the use cases, you'd need to have two extension points, two calling and advisors, which is a special kind of interceptors. How this works? So, how are we going to solve the

problem with lack of state? You have to handle it at the foundation models. They don't have state, so you have to do this as a part of your applications. So, if you expand the same flow that we had before, we need to have ex- interception point where you intercept the input, put it in some sort application state, then we can As you can see, we can pass

the I can use the So, we can pass the subset of the previous conversation with the last user message to the LLM and get the response. On the way out, we can do the same exercise to intercept the output, append it to the our conversation history memory, so we can use this for our follow-up requests with the user. So, if you look into this, it is a

very common pattern where we're intercepting the input and the output of our conversations. We have this before part where you can intercept and intervene and do something with the context before it's reached LLM. And we can do same thing on the way out. We actually can intervene and augment the output before actually it is returned to the user. This is a common pattern which is You can

think of it like interceptors, hooks, filters, nothing new. In Spring AI, you call it an advisor, and it's a pluggable code that you can actually extend your existing pipelines. So, the chat memory advisor is a way how One of the ways how we implement state within your Spring chat client models. As you can see, the blue part, this is your advisor. It implements exactly the same flow.

It appends the input. It appends the output. And it sends to the LLM just subset of the last user request and request as well as subset of the previous conversation. In code, it looks even simpler to understand. You just can register this advisor, practically this interceptor, with your existing pipeline, and suddenly you don't have state. And there is a various implementation. We work with session API, which

is the new version of the that is going to replace chat model in 2.0 2.1. You already can give it a try in our community repository in the incubator incubation stage. And when we start you start building this extended pipeline, you'll see over time that you can chain multiple advisors to have more elaborate behavior. You'd need to have means to to monitor your application, your pipelines, get

my metrics, traces, logs if something gets wrong. And Spring AI provide excellent support based on the observability micrometer. Practically, everything that flows through these systems, you can actually observe and trace. Let's get into another example. So, another problem that we mentioned earlier, the models have been cut or pre-trained to some some period in the time, so they don't have most recent information about your domain or basically

any domain. And if you want to ask a question that is really relevant to your particular domain or information, you have to find a way to pass this additional information to to your models. And in very generic sense, this is called context stuffing or retrieval What it means is that along your user questions, you're going to pass additional context information that would inform the LLM how to

answer your question. It can be in very simple case of simple static file that you just attach along with your request or if the context is large, you're going to usually going to put in external storage. It could be as plain as relational database or inverted index. Common case is to use semantic search with embedding and vector stores, which would allow you to provide semantic search. And

the idea is that on the way in, your questions when question comes, you're going to retrieve This is configurable. Subset of this Search for top N entries in this knowledge stores that kind of match or similar to this user question, and that's what you're passing along with your request. So, we're trying to put in the context the most relevant information you think, and that's very important point

to observe. We are trying to compose the context as a human ourselves prescriptively. There is nothing agentic in this part of the behavior. Spring AI provides very extensive support for RAG. This is not the point here to explain it. Thomas Vitale, if he's around, kudos to him. Hi. So, visit his presentation. He would get much more in detail about advanced RAG, and he contributed to to the

project. Thanks. And so, what I want to stress here is practically you're going to use the same mechanism, advisor mechanism, to intercept the input. In this case with RAG, you can get the questions. Our implementation of the RAG is going to interact with the this case vector database, extract top K entries, augment it automatic- automatically into your context initial context, and ask the LLM. Again, in code,

this looks much simpler, and this is the simplest naive RAG case of implementation, where you just add yet another advisor that's configured with the vector store vector store, and you have automatically this enabled in your pipeline. Let's see if there is another use cases that are common for following the same patterns. Very common, we mentioned that LLMs are nondeterministic. By the way, this is a good and

bad thing. I mean, they are creative because of nondeterministic, but also they are prone to hallucination. And very often, you would like to find some sort of guards before and after the LLM, practically trying to to protect the data that reach the LLM in some cases or in other case, to protect what gets out of the LLM and sent to your customers. Again, it is very same

idea. You would like to intervene between the context being sent to the LLM and before the completion is sent to the user. You can you can build either imperative and predictive deterministic logic. This is called guardrails before or after your execution. And you can use exactly As you can see, you can use exactly the same concept. This is a very simple guardrail that tries to prevent you

sending some sensitive information to the LLM. For example, yeah, if you try to ask something as stupid as this, you can try This would prevent you from reaching the LLM altogether. And it's yet another advisor that you can register in your system. And you can do the same thing on the way out. And here, [snorts] I mentioned that the LLM there's text in text out. They're not

structured by nature. They use natural language to interact with you. But for most of the enterprise use cases, you're need going to need some sort of structure. And you can achieve this in various way. The common one is to implement pattern like this. If you want the response to be not plain text, but some certain type, you have to ask the Yeah, you Spring AI to provide

this type. And what Spring AI is going to do under the hood, it's going to generate a JSON schema for this type, ask politely inject this JSON schema in your own context, ask politely the LLM to provide the response not in plain text, but in JSON format that complies with this JSON schema. And the way out, it you're going to convert this format into a desired type

and return to the user. And this works in 99% of the cases. But in this 1% when it fails, the user would be presented with this type error that he has to handle itself. So, how can we solve this problem? Again, we can advisors, in this case a guardrail advisor, which would guard our output in deterministic way. What we can implement, it is special piece of code

that it's going to be plugged in our pipeline is going to intercept our output to to to the user and check if that generated text is actually compliant JSON text is compliant with the desired schema. If yes, just forward to the user with a fine. If not, the error that is detected can be fit back into the original context as a feedback and that's how the element

again. Very often the second attempt would be successful because now we can actually provide meaningful explanation what is missing in the original context and what's more important, this would happen without really bothering the user itself. So there's this internal iteration and that's very interesting observation. See we are calling back and having already a loop advisor that introduce a loop. In code it would looks as simple as

this. We can introduce our desired type. We can have our pipeline and ask the Spring AI to return the desired type. We can skip this line here and as I said, 99% of the cases it would work. In the 1% you would have you would get an exception that you would have to handle yourself. But if you register advisor like this, the advisor is going to try

to improve and you can have a multiple times like this to recover from this bit before the response is returned to the user. Let's look into another example how we actually can expand on the same idea. Same type of guardrails, but in this case instead of have a deterministic checker at the end, we can actually plug yet another LLM to do something a little bit more sophisticated.

In this case, we are going to use a judge LLM to evaluate what whether the output was actually something that answered the actual user question. And if yes again, usually you're going to get some sort of a structured response, rating and if it's the response is satisfactory, okay, we are happy, we are going to reply to to respond to the user. If not, we are going to

extract a feedback practically the judge LLM is going to provide a real feedback that the advisor automatically is going to inject into original context and ask the LLM politely again, "Please, can you improve in your or fix this particular problem that the advisor the judge advisor detected?" And if you do this in code, you normally few words about a judge judge LLM, it's a whole topics, but

in general foundation models are considered not very good for judges. So we must we very frequently use them for for judges, but for example, they bias to their own answer. It really doesn't make sense to tell me what to ask yourself, "Is my answer the best?" Of course it's the best answer. So you usually you're going to need a dedicated more objective and there is this class

of a pre-trained fine-tuned LLMs you can find on Hugging Face. There is a leading board. In this case, yeah, for all these examples we have running demos. I'm going to show these demos in the follow-up presentations and I can show with the slides we're going to share the source code so you can run everything yourself. But what's happening here, the LLM actually answered yes or not and

it provide what is important though is that it's yet another advisor that intercept your output and have actually this loop and in code it would look something like this. You have your two definitions and you have this reflection reflection advisor or looping advisor that is going to implement this bit. There is a source code that experimented this particular example implements a blog post from Hugging Face how

it works. So stressing on this loop, this is another common pattern. So it's yet another advisor but but it has this behavior which is very powerful to run loops in to and implement more advanced behaviors. And with this in place, actually there is much more enriched pattern that you can leverage this advisor to this looping advisor to implement and I would invite my friend Darius to explain

you how it works. Good luck. >> [applause] >> Excellent. Thanks, Christian. So we've seen examples how to create a context. We treat the LLM as text in text out. But why are people so excited about building AI applications with large language models is because we start with a brain and we give it hands and we allow the model to integrate with the environment which is quite groundbreaking

and let's see how that actually works with Spring AI. What is the pattern to approach the ability that the model has to incorporate the tools we give it and make changes to the environment which it's interacting with. So autonomous LLMs, we can understand them as taking decisions on their own provided the goals that we set for them as well as the set of capabilities that we want

the application to expose to the model. In case of Spring AI, we can see that internally we have the LLM at the at in the middle and we have the input that we curate over time and once the LLM has predefined capabilities in the form of tools, their definitions, what is capable of doing, it can provide a specific output that we can intercept and we can infer

that this time we want to make a tool call for it and provide the result back to the LLM to make the final response. That turns away from a chat interaction to an actual autonomous system that can make changes to the its environment. And in Spring AI again, we use the advisors pattern and the advisors pattern allows us to uh remember the conversation history as we've seen

before and that allows the LLM to actually make inference about what was the thing that I asked for, what is the return that that now I have. So it can make more informed decisions following forward and it can work in the loop and change the environment, interact and you can build really interesting applications with tool calling. In code, how would that look like? We have a simple

question, what what what should I wear today if I'm in Amsterdam in the morning and then I go to Barcelona? And the model has no idea. So we give it the means to use the weather search weather tool and we provide an advisor that allows the chat client to use that tool calling capability. And the way we define the tools, as you can see here we integrate

with a weather service, we call the API of our on behalf of the model when it needs that information. So you can see that if we ask a question that is around weather, the LLM can decide, "Oh, I have a tool that's available for me that provides me weather information." So it gives us back the special response that we can take advantage of and and call the

this API. It might also use something else, but for this purpose, it's going to call the um the API. We return the result in a manner and the model can respond back, "You should wear a jacket." for instance. As we have seen, we are integrating with the external systems. Here in this case it's a an API, but what if we wanted to integrate more easily and provide

some means for the LLM to actually be able to connect to various systems and we are faced with a challenge that at the beginning we are facing building a single application, we might want to build more applications that talk to the LLMs. And on the other hand, we have communities that have built for years systems that we rely on such as databases, document stores and external API

available systems. So that creates a problem. Every time we want to integrate with something, we have to write code specifically for this integration on both ends. That creates a big problem. Enter MCP. Model context protocol is all about integrating large language models with existing and newly created systems. And the entire idea is that now we decouple this communication pattern into what's in the blue box in the

middle. Uh the contract between clients that can talk to large language models and the service provider community that already has built their systems and now they can think in terms of how do we expose the capabilities of the system to large language models to take advantage. Because exposing an API might be too costly for the context which is quite limited in case of large language How MCP

is designed in terms of architecture, we have the host application, the AI application and we have the various servers. The servers can be exposed as connectors that are specific to MCP and they integrate with the actual back-end And internally in the host application, the AI application that has access to the LLM, we create clients respective for each of those servers. And you can think of the clients

that you might use every day such as Cloud Code or Cursor and you can plug in an MCP server that provides capabilities to the text-based interface that you are currently using. But with Spring AI, you can also build a client like that or you can build an application that doesn't have a particular UI like this, but it already connects the LLM with your existing systems and it

adds MCP capabilities on top. What are the actual capabilities of MCP? So we are talking about two ends which communicate and this communication can be bidirectional which means that you can communicate ask the server when you're developing a client for features and the server can also ask the client for some information that it might require. So, to list a few, there's tools that you have seen and

it's unified with MCP, but there's also resources which can be information documents stored in your company. There's prompts, so you can can have predefined prompts that are reusable and you you trust that they are shareable across teams. There's completions such as top completions that you know from text-based tools. There's also logging capabilities and what the client can provide to the are routes which can you can understand

as file system routes that the model can work with and the application can take advantage of, so it informs the MCP server and there's sampling. Sampling means that the server we can think of an entity that doesn't have access to an LLM. It might want to use an LLM to for instance summarize some information, make an inference based on what what it has and reuse that to

return a final response. So, there's sampling that achieves that goal and elicitation is whenever the MCP server wants to invoke the user's action for instance to provide more information like what what is your choice about this or there's a vote where you can ask for additional authorization to ask the user to go to an URL. And there's shared responsibilities that those both ends can have such as

sharing the progress of tool execution or pinging for just knowing that the other party is still alive. And they can also cancel tasks. In terms of the actual transport layers, MCP started as a standard input standard output communication between processes on a single machine. That created some problems. However, it originated from the fact that this protocol was built around IDEs and the protocol that that that had

similar foundations. When we take it to the enterprise, of course, we want to deploy remote servers, share them across clients. So, for that we have something that is called streamable HTTP. It builds around REST and server-sent events. And in Spring AI, we have two modes of operation. One is where we have sessions and we maintain bidirectional connections between the server and the client. However, that is not

very reliable for remote deployments when you have a load balancer, you need additional infrastructure to make this work. So, we also have a stateless mode which means that the server is unable to communicate with the client. There is no connection back to the client which means that you can easily scale the and replicate the same instance because that there is no handshake between the client and the

server, so that makes it much easier to deploy in cloud environments or in your data center. When we look at Spring AI, we provide familiar annotation-based configuration approach that everyone using Spring is working with every day. So, for tool calling, we have uh at MCP tool annotation and that's important to distinguish from the at tool annotation which where the difference here is that we now have the

access to the context that is associated with that conversation. So, in this example, you can see that the MCP server is able to call the client because it has access to that context that exposes the client and for instance it can do >> [snorts] >> send progress how the thing is going. We also have the other annotations for the other capabilities that you can use in the

code and when you build a client, similarly, you have annotations for the features that are client-centered. And on the configuration side, you might have multiple servers that you interact with. So, the way to define a server that the MCP client connects to is using a particular configuration. You pick the streamable pattern and you define the connection and you name the server that you're connecting to. >> We

also have history of securing Spring applications with Spring Security. That's why we have a community project in the Spring community as Spring AI community repository created by our colleague from Spring Security, Daniel. This integrates Spring Security with the way that MCP is evolving and MCP is evolving very fast. So, that's why it's a community. We hope to integrate it once the security patterns from MCP mature back

into Spring Security in Spring AI as first-class citizens. For now, you can use this external project to make annotations that you know from Spring Security work with MCP. You can also build amazing rich UI applications with MCP apps which takes the concepts a bit further and operates not just on text, but starts displaying a rich UI and the model is able to take actions using the user

interface within your client. Here you can see Claude and Craig from our team has created this demo where he rolls the dice and the model is able to read what's on the dice and summarize them. So, let me head back to Christian and let's talk about more context optimization patterns. Thank you. I just want to say hello and thanks. >> Yeah, MCP is a great integration protocol

and solves enterprise patterns. I'm going to spend three slides. I really want to highlight very three very important patterns that builds on top of what we started before how we can optimize the context and I call this context optimization patterns. They all fall in this group of progressive disclosure or progressive The idea is that instead that your here we're starting to moving now that the dial from

the prescriptive user populating filling up the context from letting the agent decide what's getting to the context. So, the idea is that you should keep the context as minimal as possible as empty as possible and clean and let the LLM decide how actually it can extend it if something relevant to solve certain problems. So, the first type of solution is the tool search tool and I call

it also progressive tool disclosure. So, what you're trying to solve there if you're using the standard tool calling mechanisms, the framework you have to put the description of all tools that you have up front in your context and if you have using MCP as we discussed, it's very common to have hundreds or 300 tools up front that you are going to populate your context with and and

they those stay there consume your context even if you never use those tools. So, how can you get smarter on these bits? The best pattern we have implemented seen and implemented is called tool search tool. In this case, instead of actually pre-registering and passing all tools up front, you're just going to register a single tool called tool search tool which has a very smart definition practically telling

the LLM that if it needs additional information for more tools, just ask for them and and that's what happened. So, you for example can have a description of a weather forecast weather real-time weather forecast and you can ask question what should I wear today in Barcelona? LLM doesn't have this tool, but it see that there is a tool that can help you to find the necessary tool.

So, it is going to send a special request. There is a concept of a tool searcher we support Lucene, vector store or regular expression. This extendable way how actually could pre-index your existing tools based on their descriptions. We find what are the best matches, return them to the LLM and now LLM have actually extended list of specialized tool that LLM requested in order to call and provide.

If you use this, you're going to save depends on the number of tools, but 2/3 of yeah 50, 60, 70% less tokens on your process. So, in code, it looks something very straightforward. Instead of injecting your normal tool call advisor here, you're going to inject this version of tool call advisor which can be configured with vector store, Lucene and stuff to do this business and you're set.

For your AI application, this is transparent change and this is very powerful pattern. It is going to be part of 2.0 release of Spring AI. Another pattern that falls in the same concept is called progressive context disclosure. Maybe you have heard already, it's been a big rage agent skills. It tries to solve the same similar type of problem, but instead again using or prompt stuffing trying to

preset all the context up front, you are going to let the LLM you keeping your context very simple with very few instructions what what is available as a skills that the context that LLM can use and let the LLM decide as the progress of work and the discussion and the conversation go to decide what to load to increase its its capability to solve certain problem. The concept

of agent tool it started with uh cloud code, but it was generalized then and now there is a foundation practically specifications. Spring AI is compliant adapter of this specification and yeah, you have a simple with use markdown with metadata. Usually only the metadata is provided to the LLM up front and if the context requires it, the LLM is going to ask you to load the rest of

the specification. I'm just listing now and describing the general problem and it's solved. there is a session tomorrow where I'm going to get into detail with examples and hands-on example how to do these bits. So, the flow that you would see underneath. It is yet another tool. So, this is another important thing. So, so far we used advisors and tools to implement more and more advanced patterns.

In this case, we have have a special skill tools that allow us to implement this pattern. Upfront, another case, so it it would You would create the define these tools uh list of of of skills. Um you can actually have also um JAR dependency skills thanks to James Ward's work and contribution to the project. And the third part I want to discuss as optimization. It's called sub

agent. Again, the idea comes from the cloud agent. It's a different type of problem you're trying to solve uh in in more more beaten or complex tasks. Usually, you would have small sub tasks that you have to solve. And if you try to run everything in the single lead agent, uh the chances that you're going to pollute your context of the lead agent with unnecessary information while

solving this small sub problem is big and this actually decrease the quality the probability for proper response. So, what you're going to do, you're going to delegate the execution of this task to some small sub agents that runs in their own context. So, they run in their own context is independent of the parent context and the parent only the lead agent only receive the response. So, again

the the concept and the way how you define this is as a yet another markdown file that defines have meta data, what is the name of the agent, description, some additional tools and skills it can have. And most importantly, actually you can specify different AI one very often the sub agents running their dedicated smaller, faster AI ones to solve certain tasks. But you solve this problem and

at run time the implementation underneath and Spring AI is again yet another type of task. And all these implementation optimization now are part of Spring AI community agents use utility skills. Uh you can use it today and it's 0.7 release I believe. And yeah, under the hood it's again chat client. You define it yet another type of class. But in this case, you can have something more.

And with this, I would like to switch to the agent protocols part. Uh this is the last part of the our discussions. Just one slide. So, we're going to talk about agent-to-agent protocols, which is the common way for the while the MCP is protocol that allows to provide enterprise capabilities to agent. Agent-to-agent aims to provide a unifier unified integration, multi-platform integration between agents remotely working to each

other. So, Spring AI provides initial version of uh A2A integrations. The under the hood, you can just register a auto configuration and you can provide two beans. It it's something that identifies the agent and something uh yeah, out of the book executor that would allow you to run this and connect to this agent. So, this is simple as this. We have a very nice examples and stuff.

So, come tomorrow to find more about this. At the end, it's just single boot with single configuration. And with this, I really want to turn now um the attention to another very exciting protocol, which is newcomer. It's our agent client protocol. It tries to solve the problem to provide unified interface between users, CLIs and any agentic system, either be be in any language. So, I would really

want to invite my friend Mark and my uh brother in AI arms. So. Cool. Take over. >> Okay. I think that's it. So, show of hands how many people are using coding agents in IDE? How many people are using uh coding agent CLIs? That is a very good response. That was almost equal. I'm round of applause. If you look at how the sausage was made, however, these

AI agent and coding in the IDEs, uh they kind of had this problem of uh making a new fork, usually a VS Code for various reasons, right? And the reason is kind of the same way by analogy of the issue that happened with IDEs themselves and all the tooling around specific languages. And LSP, language service protocol, that was kind of what made life really good for IDE

developers. Uh they didn't have to have this N by M problem of supporting N languages and M editors. And it's kind of a mirror image in the AI world with agents. You have N agents, M editors. How do you get them all to talk uh and make life easy for developers to add AI agents into the And so, I'm sure we're tired of protocols. I kind of

am too. I have three-letter acronym burnout. Um but agent client protocol, think of it as the language service protocol for for AI agents, right? Uh it's an open standard created by Zed and later uh JetBrains jumped on board. So, it's a standard interface between the uh IDEs and the AI uh coding agents. And so, you implement it once and now your agent can run in any of

these IDEs. Really great, right? It's where you can actually end up delivering functionality to your team inside of an IDE. And uh it's gained momentum uh quite a lot of momentum. And there's a proposal for it to go into the Linux Foundation. And there's a long long list of all the companies who are behind this. You know, it's kind of every usual suspect you you'd think. So,

it's kind of already garnered this uh industry uh adoption. And there are SDKs for it. Python, TypeScript, Rust, Kotlin. And I wrote the Java implementation for uh the ACP SDK, which talk about next. So, it's a pure Java, right? Uh Spring style annotation model, similar from MVC. Uh there's three types of APIs. And the idea is to have you know, usually the highest level is annotation-driven model.

But then you can have a sync API. Uh you don't get as much of the uh convenience, let's say, of the annotation model. And then an async uh version based on a Project Reactor. There's a boot starter project, which lives in the Spring AI community uh organization. one thing that is uh a little bit tedious, I guess, or not tedious, but you know, uh first rule of

distributed computing is don't distribute, right? So, uh when you're doing this, it's essentially spawning off a process, right? And it communicates over standard in, standard out, or web socket. We'll get to that in a minute. Uh but when you're developing this, you kind of don't want to go through that. You can have an in-memory uh sort of transport that that helps between the client and a server.

And this is essentially a client-server relationship. The client is the IDE. The server is called an ACP agent, right? So, if you think of agent, just think of server component or agent server uh in your architectural diagram. So, here's the world's simple hello world. Uh there's an annotation to to configure certain things, the name and version. This is useful for uh tracking it cuz you can have

many of these inside the IDE, not just one. Uh initialize, that's like the first handshake in the protocol. You know, you might want to put a message here, but this we're just returning okay. Uh kind of looks a little boiler platey here, but usually you do some more stuff in that initialize. And then you have sessions. Um long-lived sessions and you get to decide basically what that

ID is, right? And here, you know, it's pretty simple in a way. Uh you have one user sitting in front of the IDE. So, it's not very complicated session management. And then the real meat, right? The sort of request handler uh sorry in a type analogy, is uh you get a prompt request from the user who's typing in the IDE. And uh then you do whatever processing

you want and you return a value. Uh you bootstrap up uh with a certain transport, in this case standard IO, and run it. And you know, just like in Spring MVC, there is flexible return types. You know, there's an underlying prompt response, but there are many ways to massage a return type into that more structured object uh for convenience. So, here's one that shows a little bit

more realistic example. you're getting uh the prompt request, but also you're getting the session information. And most importantly, you're getting this class called uh prompt context. And prompt context is essentially how you communicate back from your server agent to IDE functions, right? So, for example, the first thing we can do is we can send a thought. That's kind of funny, right? Uh and that's where you you'll

see the uh IDEs say thinking about sessions such, right? Sure we've all seen that. Uh but then you can send a message, right? And return results specific to the question that's say being asked. Uh and there are more helper methods. Um oh, I didn't list them. But yeah, there are a bunch basically of how you can interact. You can ask questions of the user and get a

little Q&A. You know, would you prefer A, B, C, or D? And you know, select that. That's an example of another interaction of the agent uh to the server. I mean, agent to the IDE. >> And uh also, I developed uh a version of uh I call Bud. You you you code you know, your programming bud, right? And it's a Spring Boot development agent. It's not really

doing code generation. Kind of a mixture, right? Not like templating code generation. The whole thing though really is it uses an LLM to understand what you want to build. So, it's kind of capturing your intent. And then it can create projects or add to your existing projects based on this, And you know, it's kind of interesting. It's kind of you give it the nucleus of your patterns,

right? Like this is how I build rest apps. This is how I build batch apps. This is how I build spring integration apps. That kind of forms the nucleus of what it will create. So for example, it could add domain models on top of that based on your specific use case. So you can say create me a customer support, you know, web API and it'll frame the

problem, kind of collect the appropriate things from you and and off off you go. And one thing I think is pretty slick for people who are using CLIs. How many people are using agentic CLIs on their work computer in their company? Show of hands. Okay, not as many, but way more than it was before, right? It wasn't the same number of cuz most people are doing their

learning on a private laptop, I bet, because of uh company restrictions. So instead of, you know, writing your agent in Java, what you can do is no problem with that, you can call out to the CLIs of these agentic tools such as Claude Code, right? And the approach Claude or Anthropic has taken to how they build agents is they provide an agent SDK, which is really a

wrapper around their agentic CLI tool. And so by this mechanism, you don't really need a key because presumably your company said you're free to use Code X, Gemini CLI, Claude Code, whatever it is and you're all authenticated. So it should hopefully plug right into your existing Uh you can get that on my personal GitHub. And these are the remaining resources. So there's a lot of stuff here

to play with. There is the um ACP Java SDK that's in the agent client protocol GitHub organization, you know, right next to the rust one and TypeScript and all the other languages. Uh there's then added on top of that, you know, a little extra love for spring developers uh with a starter and auto Uh there's a very very extensive tutorial, you know, taking you from beginning to

end, you know, hello world until you have it in one of your uh IDEs of choice. And then there's a kind of a sample app, let's say, right? For this domain of modifying and creating spring apps. So with that, uh I think we're done. Uh thank you so much for taking the time to come to our talk. Oh, sorry. I forgot. Christian has something more to say

in 3 minutes. All right. Let me just recap. I actually we did the the the road map this morning. So I'm just going to recap the important bits of it, which are important with the 2.0. We're going to provide solid foundations released next month in May. So very nice improvements in our API stability that helps would help us to iterate faster. Uh with uh 2.0 MCP release

targeted GA with along with Spring AI next month, we're going to support 2020 2025 version of MCP specifications. Um All these goodies, we discussed a little bit of those. And looking forward November, this is very ambitious goals and very exciting. We're going to start focusing on agentic foundations and new Spring AI abstractions for agentic buildings and implementations. And one last diagram that I hope brings together the

protocol part that we discussed, the MCP as a way to enable capabilities to your application built in Spring AI. Spring AI supports first class. Now we have initial support for A2A. We can show tomorrow how this works in the practice and what Mark wrapped up. This is a very nice way to actually interact and unify to wait from any client to your applications. So with this, thank

you very much and yeah, thank you for your attention.

From event

Spring I/O

13 Apr 2026 – 15 Apr 2026

All event videos
Back to Watch