
io.Intelligence Architecture and the Evolving AI Standards Landscape
io.Intelligence Engineering Lead Kalin Kostov walks through what’s been built and what’s available today – the architecture behind io.Intelligence, how its modules work together, and where AI standards like MCP fit in. A technical session from the London 2026 Dev Community AI Meet-Up.
Hi, everyone. Just a quick intro for those of you who don't know me. My name is Kalin. I've been in the company since the Stone Age. I've been in the engineering product team in io.Connect Desktop, then io.Connect Browser, and now I lead the engineering for io. Intelligence. So I've spoken quite a bit in recent months, last year in New York, and so on, about our plans, our vision, what do we want to do, what we're about to do. But today, with this first session, I would like to actually show you what we've done. We've gone through two major releases. And everything I'm about to show you now is what we have currently. Why did we build it? How did we build it? And what can you use today, generally available, with documentation, with everything. So what you're going to see now is no longer concepts, it's where we are at right now. And later today, you'll see what the near future holds. So first, I'm going to kick off because I have the opportunity to be the first speaker here with our favorite slide. We're not an AI company. We cannot have a presentation without explicitly saying that. And for good reason. The reason is that we're not specialized in AI, we know interop. We're specialists in interoperability, connecting applications in very different ways on the desktop, in the browser, and so on and so forth. We know that our clients, you guys, most of you or all of you, are heavily invested in AI in a variety of ways. And we're not trying to displace an AI company and swap our domain for an AI one. What we want to do is we want to bring our expertise to where you are with your AI initiatives. We want to sprinkle that interop expertise that we know because we believe that is a key missing layer in any AI environment. The ability to understand the applications, the ability to connect the applications, this is something that LLMs can really benefit from. So what we ended up building is we wanted to build a chat assistant that can deeply understand io.Connect. However, we didn't really want to do it as a monolith. We wanted to build it modularly so that you can pick and choose what you need from those pieces. Maybe you need the whole bit. Maybe you're very early in your AI adoption, and you need the whole bit to get started from the front end to the back end. Or maybe you're very heavily invested, and you just need the tooling that connects interop and the interop.io platforms to the LLMs. So that was our idea. And we went ahead constructing this framework in that way with Working Context, MCP SDK, front-end runtime, which we call AI Web, back-end, which we call AI Server, and our ready-to-use package, which is io. Assist. So those are the big five moving pieces. Once again, all of them are available today. So let's zoom in a little bit on the first ones. So our first major release, which was in Q4 of 2025, we did our best to, as soon as possible, meet those of you who are very first and very advanced in your AI experiments and are already heavily invested in that. We wanted to quickly meet you where you are and plug in our expertise. So we released two of the modules. The first one was the Working Context, which is designed to bring context awareness of io.Connect to the LLMs, and also our MCP SDK, which is designed to show the LLMs how they can invoke interop tools, intent tools, FDC3 tools, and system tooling. So that was our focus, to as quickly as possible bring you the tooling so that your systems can understand the interop. So let's zoom in a little bit on the first one - the Working Context. The Working Context is a very simple module. This is a JavaScript module that is available in the public NPM registry. And it's designed to accept a schema that instructs it what data should be tracked and from where. Because io.Connect stores data, or should I say allows you to store data in a variety of places. Global context, window context, workspaces context, channel context, a lot of spaces. So your context is all over the place in the place that you need it. The Working Context is designed to accept the schema by which you instructed what data should be tracked and from where explicitly. And then the Working Context takes care of the rest. Global tracking, channel tracking, workspace tracking, and app tracking. So that it keeps a fresh snapshot of exactly what you need and provides that snapshot to the LLM. So how does this look like? I'm going to be jumping left and forward through the docs so that you can actually see it a little bit more in practice. Here in our documentation we have in the API reference an example of this is an example of how you configure the Working Context. And this is what I mean by explicit. Let's say the first example. We're instructing here the Working Context to track a property of the user ID. We're going to be looking for it in the global context under the key user session in path user dot ID. And only this location. We're not going to be tracking it anywhere else. The idea is that we don't want to provide by default your data to the LLMs. No. By default, we track nothing. We track only what you want us to from where you want us. And we just make sure that we bring in our knowledge of our own platform to make sure that data is perfectly fresh every time. So this is a very simple module, but it is the first piece to tying a picture that I would like to paint for you today. And because I like living on the edge, I like to show you stuff live. So let's hope that Anthropic plays along. What you see here on the screen, this is our io.Assist chat assistant. And I'm going to bring in an application, which is a very simple application. It's designed to select the client. The idea is that right now, I haven't clicked anything. So if I ask the assistant: "Who is my client?". Well, it doesn't know. He doesn't know, but he has knowledge of the Working Context. But he doesn't know who the client is. Well, actually, the version would have said Leslie, but we cropped that out because. So I'm going to select John here, and I'm just going to run the exact same prompt: "Who is my client?". And all of sudden now, the LLM knows that the client is John Smith. Now this is a very Hello World example, but I want to draw your attention to a couple of things. Number one, there was no tool calling involved. Which tool calling basically relies on the LLM to decide to call the tool, to decide to call the tool repetitively to get the fresh data. We don't depend on that. We plug the current state of the Working Context directly as a system instruction. There are a few ways, but that's the one that we go about here. We plug it as a system instruction, which gives pros and cons. But we'll discuss that with those of you who are interested. The idea is that now me as a user, I can talk to it in a way that I don't need to be so explicit. For example, if I need to service John Smith, I can bring up an application that accepts it's ID without me knowing the ID. But I know that I work with John Smith. And all of the data is already loaded in. So I can be situationally aware or my LLM can be situationally aware. So that was the first piece that we brought into the table, the Working Context. The second piece is our MCP SDK. Our MCP SDK came in a variety of flavors, but the center of it offers a few ways to connect interop to the LLM. The first way is using dynamic tools. Dynamic Tools is a way for any application to register a method, an interop method in a special way with a special flag, so that our MCP SDK picks it up and understands that's a tool and broadcast it to the LLM. Let me show you how this works. So, going again to our docs, we'll go quickly to our MCP core, and here we have our tool types, dynamic tools. So I'm just gonna copy this snippet. Most of you are familiar. This is a simple interop method registration, name, description, and this is where the magic happens. This flux property contains the input schema, output schema, and the name of the tool that's going to be registered. And this is the callback that's going to be executed. So I'm just going to go right ahead and copy this one. And let's continue with our example. I'll paste it here. An awesome greeting tool, and it's going to greet stuff. Okay. Let me register this method. I registered the method, and now when I see the tools here, all of a sudden an io greeting tool appeared. So our stuff was able to detect it. So now I'm just gonna see if the LLM is going to decide to call it. Can you greet my client please? Here we see that tool is being called. And yeah, it gets the correct data because it gets it from the Working Context. So we have the two pieces kind of starting to tie in together. And the idea of this hello world concept is very simple, that you can have, you can put your applications in the driver's seat to register their functionalities as interop methods. And then the MCP SDK will pick them up, and expose them, and bundle them as tools to the LLM. This is the first way that you can introduce dynamic tools to your system. Obviously, it is the easiest way, but it's also the most dangerous one because you lose control of how many tools and how well-defined are those tools, which can lead to problems that we're going to discuss a little bit later. So we have two other options. The other two options are to define static tools. Static tools are defined during the initialization of the MCP SDK, which are basically kind of like dynamic tools. They define a configuration, the name of the tool, and how it should behave in input and output schema. And also it declares what interop method or intent or FDC3 intent is responsible for handling them. So how does this look like? If we go again to the docs, here we can see static tools. And this is an example configuration of a static tool. So in this case, it's a static method tool. I'm going to skip the availability for now. We have a name, configuration, basically the stuff that you're expecting to see. Input schema, output schema, description, and also what interop is responsible for handling this tool. In this in this case, it's this interop method and the allowed applications are those with some response time out. So what this does is once the MCP gets started, those configurations will be fed in and those tools be prepared. Now, about the availability. We offer constant and variable. The constant availability means that when the MCP starts up, it's going to read this and it's going to register the tool immediately to the LLM, regardless of whether this interop method exists or not. The variable one does the opposite. The MCP is ready for this, but it's not going to register it until this method appears. There are pros and cons here, but the common ground is that this puts you as the admins in control of how many tools and how well defined are they in terms of descriptions and schemas because this is vital. And then you delegate execution to the applications that you trust. So it's kind of in the middle between the having dynamic tools and having basically no tools. In terms of constant versus variable, the reason why we chose to have two different options is because there are people who want one or the other. The constant one is great because it keeps your prompt cash stable. We're not introducing new tools midterms, which means you can benefit from cash tokens, better speed, lower cost, all that good stuff. But if the LLM decides to call a tool and this method doesn't exist, well we're going to throw an error. But for those of you that don't really care about the caching in some situations, the variable will be best because the LLM will be able to call methods that actually achieve stuff. So that is our MCP SDK in terms of dynamic functionalities. But we also introduced tools out of the box. Because we are the people that understand best the applications that run in our system and we understand how to interop with them. This is our stuff. So we went and designed four tools which are their role is to help the LLM understand what capabilities does your io.Connect has in terms of applications, in terms of workspaces, and how do they operate. What do I mean by that? We have a couple of searching tools, search workspaces, and search applications. So once the user starts to type in, the LLM is instructed to first understand the intent of the user, and then use the tools to understand, to find out if there are applications or workspaces that will single handedly or collectively satisfy this intent that the user wants to do, and return not only the names of the applications in the workspaces, but also what kind of interop they expect. You'll see that in a minute. Because then we have the starting tools. They're designed not only to start applications and workspaces by name, but they're also designed to understand once you start those applications, what data should those applications receive in terms of context, invoking methods, invoking intents, channels context setting, or what have you. So how does this look like? I'll bring in again my example here, but I'll start fresh and I'll just copy my prompt and read it out loud before I send it. So the idea here is the following. I still have John selected and let me move this away. I need to review my client's portfolio performance and check if we need to rebalance based on direct allocation. Now notice my client, who my client is, I'm not saying. The LLM presumably doesn't know, presumably it will find out. Now I'm expressing what I need to do, but I'm not telling it I need this application or that application because I have hundreds of applications here. I mean, if I open up here, you'll see that I have a lot of apps. This is not like a three-app environment. So it simulates a real-world usage. I don't know what applications will help me. I just need to do this job. So what will happen? First, it understands that we're working with John Smith. Then it searches Workspaces, but it doesn't find any workspace. So it asks my permission to delve into the applications. And let's see. Okay. So we found three applications that will collectively achieve the task at hand, portfolio overview, asset allocation, rebalancing tool. So we were able to identify three of the apps. But I want to show you what I was talking so far. So here as a result, we can see that inside the system tool we received the user intent. And as a response to the LLM we gave back that yeah, we'll be able to satisfy this, the next steps that we're instructing the LLM so that we can chain some flow. And also, we identify the apps, just like here. But we group them in the workspace property because each of the apps works with a workspace context. So we were able to identify that they can play nicely together in a workspace built on the fly. So here you can see that we return not only the name of the app, the description of the app, but also what kind of interop it works with. It works with in this case with the workspace context, and this is the schema of the data that it's expecting to read from the workspace. So it's working with a portfolio ID, client ID, client name, and so on and so forth. So this is the knowledge that we give back to the LLM. And that's why the LLM is able to understand that, yeah, we were able to do this job. And as a result, I get prompted. Hey, do you wanna create a new workspace with this? Alright, let's do that. Now using the starting workspace tool. Yep. I would like to go ahead. And here we have our workspace. And we can see that John Smith is passed correctly to each of the three applications. So this is what I meant when I said that our system tools are designed to give a deeper understanding of what the user wants to do and help the user achieve what he or she wants to do by starting the apps, starting the workspaces, and passing the data in. There is another optional tool, which is the Working Context tool. You can configure the Working Context to work inside the MCP server, and that will expose a new tool. But that's a different use case, which I'm not going to now because I have other stuff I want to show you. So that was our Q4 release. Now moving on to our second release, which was in Q1 this year, we wanted to round things up. Basically, what you saw here on the screen, here, we've been talking about that, and we've been teasing, but we weren't really making this available. So we wanted to round things up by giving the necessary modules so that people that want to have an end-to-end experience can achieve what you saw on the screen. And that's completed by having three additional modules. AI Web, this is the front end library that drives everything that you saw on the screen. AI Server, which is not a server SDK, but it's a set of server-side adapters to achieve specific tasks. And we have io.Assist, which is the UI library that drives the visuals that you saw so far. So let's zoom in on each one of those. The AI Web. The AI Web is a JavaScript SDK that is published into NPM, available today, and is designed to be used for building the front end of assistants. That be chat assistant. It can be some kind of other assistant because it doesn't have a UI. It exposes a set of APIs. Agents API, threads API, Working Context API, tools API, prompts, and MCP apps. So basically, this SDK is unopinionated in terms of framework, in terms of visuals, and it takes care of all the heavy lifting for you. Which is, it has built-in system prompts to make sure that the tools that it receives from our MCP is chained correctly. Also that it understands Working Context correctly, and you have the option to tune them. Next, it has context management, because it understands deeply the Working Context and explains that optimally to the LLM. Next, it's an MCP host. It can connect to our MCP servers regardless of the transport that it uses, and also third-party ones simultaneously. It's also, of course, an io.Connect client, both for desktop and for browser, so it can do io.Connect operations. It's a server client, connects to AI Server naturally. And also it's compatible, like I said, with not only io.Intelligence MCP servers, but also custom servers. The second bit of our release was AI Server. Now we didn't want to go ahead and build a back-end AI SDK because there are great options out there. And quite frankly, it's not our focus currently. Instead, what we wanted to do is we wanted to bring our tech to as many places as possible and work with as many back ends as possible. That's why we chose AI Web to talk AG-UI. This is a protocol for communication between the front end and the back-end of agents. It's defined on streaming and streaming events. It's pioneered by the CopilotKit guys. And we implemented on the front-end side with AI Web. And also we published our first adapter for Mastra AI, which we call Mastra Bridge. This adapter you can plug it into your Mastra deployment and it makes so that your Mastra understands the AG-UI protocol and also make sure that the stuff that we expect in terms of front-end operations works correctly. So in terms of our AI Server initiative, it's not so much server SDK right now. It's a set of adapters and extensions for all LLM servers. The next bit is the io.Assist. Now io.Assist is a ready-to-use UI library, which is a very thin UI/UX layer that is built on top of AI Web, of course, in two different flavors, in a React flavor and an Angular flavor. And it's designed to give, for those of you that like this chat experience, ready-to-go in 15 minutes chat assistant. So you don't have to code any of the front-end logic so that you can get going immediately. We also offer some personalizations, but that's not really the strength io.Assist. The strength of io.Assist is speed to market, so to say. And it's very thin in terms of UI/UX. So we designed it in a way that can be easily replaced, either manually or through LLM coding. And like I said, it's a ready to use system. And essentially, this drives everything that I showed you today. However, that's not all. And I've deliberately went through everything because most of you have seen it, but most of you have probably not seen what we've done with MCP apps. Now MCP apps is another standard. And talking about standards, we're doing our best to play along with where the industry is in terms of standardization. Because it's really beneficial to be able to plug where you are. And MCP apps is one of those standards. In essence, instead of having just a generic text answer from your LLM assistant, you can render in your chat an interactive app. This is available in OpenAI in their ChatGPT apps. And Claude is also using it in desktop and so on and so forth. So it is everywhere. The problem with that is that they're all rendering those interactive elements inside the chat canvas. And that's great. And we support that. However, just like that, we have some agent response and we render it here. However, we can do more and we've done more. So we can render the apps either inside the chat canvas or we can render it beside the chat in a workspace. This opens up interesting possibilities in terms of seeing your apps next to each other for comparisons, multitasking, and better screen real estate management. But also we extended the protocol so that apps can ask for their lifecycle to be managed, to be closed, and also for their state to be managed. And the interesting bit is that this allows us any MCP app that exists according to the MCP standard to be able to ultimately interop with the Connect world without understanding the Connect API. Because we have the MCP app talking to the AI Web and the LLM, and they in turns talk to the io.Connect apps via tools. So we're able to bridge MCP functionality and io.Connect functionality without them knowing the API. Now how does this work? Let me show you. I'll start here fresh, and I don't even need this. I'm going to pop out the assistant out of the workspace right now because I want to show you first the traditional way of doing the MCP apps. Right. So I have here a set of prompts. So let's see how this goes. I'm going to plan a vacation. I'm based in London. What are my options as destinations? Yeah, you can use Canada or Miami. Great. Now, but I want to see the weather for Toronto. And this is an MCP app. This is an MCP app that we've created. And it's basically how they work. Some UI elements here just to make visuals a little bit better because without the MCP app, well, we have just the text here and basically a markdown. Well, that's great. But I want to compare with Miami. I want to see because I'm choosing between one of those two destinations. So let's see how it goes in Miami. Yeah, we have some markdown comparison that we're used to. And here we have the widget. But if I want to compare between them, I need to jump back in history, back and forward, see this, see that. And in a real-world situation, which is more complicated than this Hello World one, you have in your chat history tens, if not more, MCP apps. And it will be very hard to navigate yourself between that. And that's what the best are doing right now. So let's see what we can do. We can obviously do that. Now what I'm going to do differently now is I'm going to open io.Assist in the workspace. Because I've configured it so that if io. Assist is running in a, or I should say AI Web is running in a workspace, then it should fall back to opening the MCP apps in the workspace. But that is, of course, configurable. So let's run the exact same flow and see the difference this time. I'll prep the next prompt here. Yeah, the exact same response. And this time we get our MCP up on the site. It's not even in the chat. So I can have my chat here, I can do my work here, and I can inspect the UI much better. But it gets even cooler because if I ask for a second one now before I send it, I want to make a note. If you remember correctly, this is going to ask us to render another weather widget. And we're going to render it here. We were rendering it here previously. But now because we have the option to render it side by side, what you see is a prompt asking me, hey, I want to render the same app as the one that you already have on the screen. Do you want this replaced or do you want a new instance? And that's important because I want I might want one or the other. In this instance, I would like to have a new one so I can compare. Here is the prompt. Yes, I want a new instance. And this is what I meant. Now I have my weather apps side by side and I can make my choice. But we can proceed with there's some other cool things here. So I'll continue this example by saying, all right, based on what I see I'll definitely going to Miami because yeah, I don't want to be freezing. It was winter already so let's go somewhere warmer. And this is going to open up another MCP app. This time it didn't ask me do I want a new instance because it's a different MCP app. So it opened it side by side here. And all of a sudden, I've dynamically composed my workspace out of apps that have zero understanding of io.Connect, zero understanding of workspaces, and they're only following the MCP app standard, of which there are many already. But I want to show you what I said by us extending the protocol by giving the apps the ability to request their lifecycle to be managed and their context also. So what I mean by that? I'm going to be flying to Miami, so I don't want Toronto. So I'm going to tell this app that it's done and it disappears. And I'm also wondering which flight should I take. I'm going to favorite this one and this one. So obviously the state of this app is now different compared to what it was in the beginning. And all of a sudden I realized that I'm planning my vacation in front of you guys, so that's not appropriate and I'll start a new session to do some very important work. Right? I'm going to be pretending like everything is doing, I'm doing something very important. Yes, yes, really important. But then I remember that this is a demo and you're cool. So just return back to that original, to that previous thread. And as soon as I click it, I get my session restored. It's better arranged, obviously, though they're not side by side, but this uses better screen real estate. And if you can see here, this app received its previous state. So those two flights are now also favorited, and the Toronto app is not present anywhere. This is what I meant by us offering this capability to the apps to declare their state and then request it on load up. And we're also backwards compatible with the current way MCP apps standard is declared, which I mean by that is if I pop out now io.Assist out, it will go back to being a singular window and we will load the same thread. And if you can see, this time io.Assist is working in a window and we render the apps just like the MCP standard expects. They're there. But they're not only there. This one, remember, knows its state. And this is all driven by AI Web and surfaced as a UI using io.Assist. In essence, AI Web takes care of understanding the MCP app standard, understanding the resources and the tools that drive this functionality. It takes care of the communication with the workspace, saving the state using the Preference API file connect, restoring the state, all of that management is done automatically. So you don't have to do anything to achieve this flow. However, we expose events where you can override this behavior on however you see fit. So in essence, this is where we are today. And the even better thing is that everything that I've been talking about, you can actually follow step by step or you can direct your coding agent to follow step by step. On our guides, we have a guide which we call io.Assist Anywhere, and it has eleven or something chapters, which walks you through building a system a little bit less complex than what you've seen so far. But in terms of moving pieces, the same bit. So you can get quickly started with everything that you saw. Setting up your project, your first integration with the MCP in the browser, the agent configuration, creating the io. Assist as fast as possible, adding your workspace context, updating your app definitions in io.Connect so that the LLM has better understanding, adding support for MCP apps, which very cool. Then we also talk about something else, which is our MCP can run externally or internally in the client itself. So this is a chapter where we show you how that's done. And then everything that you've seen so far works flawlessly also in desktop. So in this chapter, we show you how you can take the work you've done and just move it over to desktop without any code change. As a next step, desktop is able to naturally start Node processes. So we show you how to declare the same MCP functionality, but as a Node HTTP process in case you want that functionality. For example, you want to have also file system access or whatever it is a desktop process can expect. And the last chapter shows you how you can basically remove io.Assist and using AI Web in half an hour, create your own custom chat experience with the same functionality, just looking vastly different. And this is what we have for you live today.
io.Intelligence is interop.io’s AI layer for capital markets desktops – not a standalone AI product, but the missing interoperability layer that makes AI agents actually useful in a financial desktop environment.
In this session, Kalin Kostov, Engineering Lead for io.Intelligence, presents the current state of the platform after two major releases. This is not a roadmap talk – everything shown is live, documented, and generally available.
What you’ll learn
- How Working Context feeds real-time desktop state to LLMs as a system instruction, without relying on tool calls – so the assistant always knows which client, instrument, or workspace is in focus
- How the MCP SDK exposes interop methods, FDC3 intents, and system tooling as callable tools for any LLM
- How AI Web handles front-end AI runtime: MCP app rendering, workspace composition, session state persistence, and lifecycle management – automatically
- How io.Assist provides a ready-to-deploy chat UI on top of AI Web, with full workspace integration on both browser and desktop
- How AI Server handles back-end agent orchestration, and how the full stack can be adopted incrementally – from a single module to the complete setup
Who this is for
Engineers and heads of desk building AI workflows on top of io.Connect – whether you’re early in AI adoption and want a full-stack starting point, or already running LLM agents and need the interop layer to connect them to your desktop.
Explore the docs