Introduction: Building a 100% Local MCP Client
Hey everyone, welcome to this video and today we are going to build a 100% local, secure and private MCP client that you can connect to any MCP server that is out there. So here's what we're going to cover in this tutorial. We'll start with some background on MCP, understand some of the key components and how a client server interacts with each other and then I'll explain you the architecture diagram of the app that we are going to build today that includes our local MCP client and an SQLite database over which we are going to build a server and connect it to our client. And finally, I'll be giving you a detailed walkthrough of the code on how you can build this yourself step by step. So without any further ado, let's get started.
All right. So let's set the context for this video by understanding what MCP is and why do we need to learn how to build a local client. So MCP as we all know is a standardized way that you can use to connect your LLMs or your AI agents to external APIs, data sources and for that matter any tool that is out there, right? You can think of it as a USBC port for your AI application, right? wherein you have your AI app and then you can easily plug and play database maybe an MCP server that is built over GitHub or Gmail or local file system and for that matter any API that is out there on the internet you can easily connect them to your AI agents using a standard interface. So that's about MCP right?
So there are two major components in an MCP setup. One is a MCP server right? So MCP server basically wraps up let's say the external APIs, database or for that matter like any API that is present on the internet. It can also be your local file system. It wraps them as MCP tools and make them available to the client. Now an MCP client is something that is used by our AI application and for that matter like the agents and LLMs that we're building to communicate with the MCP server. Right now we typically see that this MCP client is either hosted by cloud desktop or cursor ID. So there's a bit of problem with that. The reason being these MCP host use an external LLM, basically they would be calling an API and sending your data somewhere else. So let's say if you're working with some sensitive data that is very important to your organization and privacy is paramount right. So in that case you cannot use such a client wherein your data would be sent to some external server. So this is the exact problem that we are going to solve today. We'll be building our own local client that you can universally connect to any MCP server that is out there. Let's try to understand the architecture of the system that we are going to build today.
System Architecture Overview
All right. So before we jump into the demo, it's time to understand the key components and the architecture of how the system that we are building today is working. Right. So we are building a local MCP host which has a Llama Index agent which is powered by a locally running LLM using Olama and this agent is working together with our custom-made client. Right? So let's try to understand step by step how, you know, the life cycle of a user interacting with the system would work. Right? So user would come up with a query. Right? This query is going to be, you know, received by our agent and then the agent would use the client to, you know, connect with the MCP server. Excuse me for this typo. So this should be a local MCP server here. So what the client is going to do is it is going to connect with this MCP server, get information about all the tools that are available, right? So this is shown in the third step. And based on the user query, the agent would decide like what is the right tool to call. Right? So then we'll have an actual tool calling or function calling. Right? The MCP server that we have, it has two tools. So it's a server that is built on top of an SQLite database but as far as you are concerned, I mean you can replace this with any server. So our client is generic, universal and it it will easily connect to that without any sort of code change on the client side. Right? So to keep things simple and didactic, we have two tools in this server. One is to add data to the server and one is to read data from the server. And based on whatever tool is being called, it will, you know, finally generate a context or the response and this response is then received back by agent and on the basis of that it will be able to, you know, provide a final answer to the user query. So this is how the system work and the tech stack if you look at it we'll be using Llama Index to orchestrate all these things and then we'll be using, you know, to locally serve an LLM which is powering our agent and the LLM that we are going to use would be DeepSeek Coder v1. So I hope you got an idea of like how, so I hope you get an idea of like how this system is going to work. It's time to, you know, build this and I'll give you a step-by-step guide on how you can do it yourself. So I hope now you understand like how this system is going to work and it's time to, you know jump into the code and build it step by step.
Code Walkthrough: Building the SQLite MCP Server
All right. So now I'm in my cursor ID and it's time to understand all the code for building this system. Right. So I'll quickly start by explaining you the server that we are going to use for this demo, which is a simple SQLite server that I built. Right? So it has two tools which is an add data tool. So each of these tools are going to expect, you know, an SQL query in form of a string. Right? And I have also provided like all the description of like how the query should look like, what should be the schema of it and also gave a few examples so that it becomes for our agents or the LLM to make the tool call since we are using local LLMs. Right? So here's the actual functionality or the code to, you know, add new data to our SQLite server. Similarly, the second tool is a read data tool. Again takes a SQL query in form of a string. We have tried to be as descriptive as possible regarding what this tool does and examples and the argument that is it is going to take. Right? Again, the functionality is actually implemented here. So the tools are fairly simple and as far as you are concerned you can replace it with any server that is out there that you want to connect with our client and you do not have to, you know, make any sort of code changes on the client side. So the client is universal, it would generically connect to any MCP server that is out there. Right? Finally, we have some code to, you know, how you can run this server. So I mean you just need to run this command: ue run server.py and then specify like the transport mechanism. So we are using, typically like MCP provide two transport mechanism like how a server can send data to the client. So if you're, you know, doing something, some sort of experimentation and doing things locally, in that case you can use stdio. So basically everything that your server is going to print to your terminal or the stdio is going to be used by client and it will be used as a context by the agent that is working with the client. Another thing that we are going to use today is SSE which is like more sophisticated way. So let's say if you you are connecting to a remote server then the communication would happen or, you know, server sent event or just like HTTP. So do not get confused with the terminologies like these are just two ways on how your server can send data to your client. So that's about the server and so what we can do is we can already get our server started. Right? As you can see our server has started.
Code Walkthrough: Creating the Local MCP Client
The next step is to, you know, build an MCP client and establish a connection with our server, right? So as you can see Llama Index provide these two modules. One is the Basic MCP client and MCP tool spec. So Basic MCP client is will be used to, you know, we'll instantiate or create our own client and we'll provide like where the server is running. So our server is running at locally at 8,000 and you then also specify the transport mechanism or like how the server is going to send data to to this client. So as you know since we used SSE when we started the server so we are going to specify SSE here. So this would be connecting via server sent events. So now that our client is ready, what we're going to do is we'll be using the second thing which is, you know, MCP tool spec.
So if you look at the definition of this class, it is built on top of the basic tool spec class. So I'll give shed more light on it or I'll give more details about it very soon when we are going to build the agent. So if you read this definition, MCP toolspec will get the tools from MCP client, right? and convert them to Llama Index function tools. Right? So if you see here, we have already created the MCP client and using MCP tools spec what we do is we'll get all the tools that are available to this client which is already connected to our server right and then it will wrap up them in a form so that these tools can be used by the agent or the function calling agent that we have in Llama Index which we are soon going to build. Right? So these two lines are doing all the heavy lifting in terms of, you know, creating a client, connecting it to the server and then wrapping up those tools in a way so that it can be as easily used by our Llama Index agent that we are going to build right. So we have it here and as you can see we'll try to also print like what are all the tools that are available in our server since we already created the client and it will print all the metadata. So as you can see, so it is providing the tool name. So this is the tool name right and it is also giving the metadata description of like what exactly is present in this tool. Right? So this is the description that we provided for the two tools that we created. Right? So this is fairly simple, nothing confusing about it. Right?
Code Walkthrough: Building the Function-Calling Agent
So now we have access to the two tools that are present in that MCP server. We know like the description and what exactly they do and this is something that is going to be used by the LLM that is powering the agent that we are going to build. So without any further ado it's time to build the agent. Right? So before that we'll also define a system prompt. So this system prompt would, you know, steer the LLM in a way so that it knows that what exactly this LLM is supposed to do. So in this case, you know, it's an AI assistant that is used for tool calling. So we specify all that information here. But on need basis, let's say if you have a specific application, you can use this system prompt and modify it according to your needs. Right? So this step is also done. We have defined the system prompt. Now comes the important part wherein we define our function calling agent. Right? And how we provide this agent access to all the tools that are present in the MCP server. Right? So only these lines are important right.
So the function calling agent is nothing but a simple, you know, Llama Index function calling agent that has ability to call any tools that are provided to it right. So if we look at the arguments, it takes the name of the agent right, the description like what exactly this agent is supposed to do. Then it takes a list of tools, right, the LLM that is powering it and the system prompt that we defined. Now you should carefully look at, you know, this agent does not care whether the tools are coming from, you know, a simple python function that you have defined and you wrapped it up using the base tool spec of Llama Index, right? Or whether it is coming from MCP. But here we have made sure, you know, these tools are the MCP tools that we have got access to using our client. Right? So it's fairly simple. So it's just a typical function calling agent but we are using, making use of the MCP tool spec so that we are able to, you know, wrap up the tools that are present in the server that we are connected with right and they are wrapped up in a way so that the agent can easily use them. So that simple.
Next is, you know, we also need to define like how we handle the user messages right since we are going to have an interactive chat session. So we need to make sure like what all messages are there, what agent we are using, you know, for all this interaction. And then we also need to provide context so that let's say if I had a conversation with the agent. So it should also store all these messages in the context so that I can also ask a question which is a followup of my previous question. Right? So basically maintaining the chat context Right. So all of that this would be done here.
So we have this function that would take care of, you know, handling the user messages. Fairly simple, you can read about it. Like it takes the message context which is the string, the user message, the agent that, which is our function calling agent. We'll also define the context very soon so that this context would manage or, you know, take care of, you know, storing all the chat history and everything that is happening, like what tools have been called, like what what are the description or what are the metadata that is involved in the tool and the responses that we got out of our queries. Right? So everything would be stored in this context. So it's just a helper function that we have defined here. And so let's run this. So I mean we already initialized the client, but let's again do that. So if you see these four or five lines would completely explain like what exactly is going on. Right.
So first we create an MCP client right using the basic MCP client functionality that is provided by Llama Index. We provide the URL to our server. We also specify the transport mechanism. Right. Then we use MCP tool spec to, you know, wrap up the MCP tool in a way so that it can be easily used by the agents, the Llama Index agent that we are going to create. Right? So then we call get agent. Right? So get agent would take all these tools and it would be using it here. right so that's fairly simple. And finally we are going to create the agent context. Right? So this agent context would make sure agent keeps the context of the entire chat history or the entire chat session so that we can also ask follow-up question based on our previous conversation, tool information, what are the output, the raw output that was given by the tool and what is the final response that is being sent to the LLM. So this simple line would take care of all those things. Right?
Live Demo: Interacting With the Local Agent
All right so now it's time to interact with this agent, which is running completely locally and as we have like set up everything it has access to all the tools that are available in our MCP server. Right? So as you remember the two tools are simple. One is to, you know, add data to a database and another one is to, you know, fetch data from it. So let's get started and first we are going to add some data to it. So I'm providing a simple natural language query. I'm saying Rafael Nadal whose age is 39 and is a tennis player. So as you can see, this is the user query and we were able to, you know, successfully call the add data tools with these keyword arguments. So basically it converts it into an SQL query and then the agent says that the data has been successfully added.
So let's try to fetch this data now, right?
Okay so now you can see like it is calling the right tool again since now we are trying to fetch the data that we already added and it shows that okay against ID1 we have Rafael Nadal, age 39, profession is tennis player. So it nicely structures and store it in form of a table. Right? So let's try to add some new data.
So again we are able to, you know, add new data. So you can do fetch data again just for the sake of this demo. Right. So now it is able to, you know, fetch all the new records as well. So yeah, this is a fairly simple demo.
Conclusion and Next Steps
And the reason being I just wanted to focus on building a local MCP client, but this client can be universally connected to any MCP server that is out there so you barely have to like make any changes on the client side. And since MCP is so powerful, like it has standardized all this interaction, so it's a powerful setup. So yeah definitely try to try it out. Like let me know if you have any feedback what you liked about it. And I think that is all for this video and if you're watching this on Twitter I have also given a detailed description and a step-by-step guide in the thread that follows. And if you're watching this on YouTube, make sure that you know you like this video, you subscribe to my channel so that it gives me a signal that I should be creating more content like this. All right, thank you so much for watching this and thank you so much for your time. I'll see you in another video. Bye-bye.