So you've covered sequential calls and hierarchical calls. But there's one thing we haven't quite covered, MCP. How can we get ACP and MCP to work together? That's exactly what we're going to do now. We're going to convert our hospital ACP server to use MCP as well. So there's a lot of talk about ACP and MCP. Well, remember ACP allows agents to communicate to each other. It provides an agent communication protocol. MCP provides a communication protocol for mainly tools. So we can actually use them together. The first thing that we're going to need is a MCP server. So what we're going to do is we're once again going to use a Jupyter notebook magic function to write at our MCP server. Now, this MCP server is going to allow users to find doctors near them. And it's going... we're going to use this particular capability to override our hospital server. So, how do we go about doing this? Well, first up, you're going to use the write file function to go and write at MCP server to the my ACP project directory. Because we're eventually going to need our ACP server to communicate with our MCP server file by standard input/output. So then what we need to do is define the MCP server. So first up what we're going to do is import colorama. And we're going to use fore for some terminal formatting. While we're at it we'll also going to import the fast MCP capability from the MCP SDK. That's going to allow us to define our MCP server. We're also going to import JSON to handle the data that we're going to be using. And I'll come back to this in a second. And we're also going to need requests because the data that we're going to be returning using this particular MCP server is currently served via GitHub. Now, what exactly is this MCP server going to do? Well, it's going to return a list of doctors, and we're going to use it to return the most relevant doctor to a particular person based on their state, assuming they live in the United States. So, let's go and define this tool. So first up we're going to create our MCP server. So we're going to create a new variable called MCP and set that equal to fast MCP which we've just imported over here. And we're going to name the server, doctor server. We're being a little bit verbose here. Then what we're going to do is we're going to build out our tool. So we are going to use the MCP tool decorator and then create a new function called List doctors. This is going to take in one argument which is going to be a state as a string. And it's going to return a string back. Then you're going to provide your docstring. So in this case, this particular tool returns doctors that may be near you. It's going to take in state, as we've mentioned as a two-letter state code based on where you live. And it's going to return a list of doctors that may be near you. So, how are we going to do this? Well, I've currently got the data stored on GitHub. And you can see that we've got a big JSON document of a number of fictional doctors that we're going to be able to return back. So, in order to bring that back via our MCP server, we're going to make a request to add to that URL. So that's the URL there. So it's raw dot GitHub user content.com/my GitHub which is Nick Knock Nack. And then we're looking at the ACP walkthrough repository. We're looking at the refs the head's main and doctors dot Json. That's where that file resides. Then to bring that back via MCP server we're going to make a Get request to that URL. We're then going to load that response back via Json dot loads. And we're specifically extracting the text from the response. And that should give us a list of doctors. But remember what we want to do is we want to filter through based on the user's state. So we're going to loop through each one of those doctors. Probably not the most efficient way to do this, but this gives you an example of what's possible. We're going to loop through each one of the doctors inside of that list. So, for doctor in doctors dot values, if the doctor's address and specifically their state matches the state that we've passed through to our MCP server, we're going to return that doctor back in a list, and that's going to be stored inside of a variable called matches. And then what we want to do is we want to return that back as a string. So that's pretty much our MCP server done in terms of the core functionality. Now, if our ACP server calls this via standard input output, we want to make sure that we run it using If name equals main then we're going to use MCP dot run. And we're going to set the transport type to STDIO. So that's pretty much our MCP server now created. Now, if we run this cell, it's going to override it inside of our my ACP project repository. So that that MCP server is available to our ACP server, which we're going to update next. Now that brings us to our ACP server. We're going to take our existing hospital ACP server and add in another agent. But this second agent is going to be leveraging MCP as well. So remember, we define our initial small agents agent which was a health agent. And this was sort of there to help handle general hospital-based queries. You can see that that was our docstring. Current, perspective patients can use it to find answers about their health and hospital treatments, so on and so forth. Now, this second agent is going to be using the MCP server that we've just gone and defined. So we're probably going to define a doctor based agent. So, how might we go about doing this? Because so far, we've only really had one agent per ACP server. But you definitely can have more. So we're going to add a second one. So the first thing that we need to do in order to do that is bring in a couple more dependencies. So from smolagent so far, we've had the code agent, the DuckDuckGo search tool Light LLM and the visit web page as well. We're also going to bring in the tool calling agent and the tool collection. These two are going to help facilitate working with MCP. Now, whilst we're at it we're also going to bring in an MCP dependency because we're going to need to connect to our MCP server using STDIO. So we're going to bring that in. So we're going to go from MCP. We're going to import STDIO server print. This is just going to make it a little bit easier to help define how to connect and run it against our MCP server over here. So, how exactly do we do this? Well, remember when we went and export out MCP server. We defined it as MCP server dot py and it's running inside of the my_ACP_project directory. So we need to be able to connect and run our MCP server which the command for that would be uv run MCP server dot py. So we can construct that command inside of the STDIO server parameters class. So let's do exactly that. So I'm going to define a new variable called server parameters. And I'm going to set that equal to STDIO server params. And what you're going to do is create a new argument which is going to be command. And that is going to be equal to UV. So that's the first part of the command that you need to be able to access the MCP server. So what are the other two? Remember, the full argument or the full command was UV run MCP server py. So we've got our command. We now need to pass through the arguments. So to our args keyword argument we're going to set that as a list. And we're going to pass through the last two arguments which are going to be run. And then MCP server.py. So this is effectively going to allow us to run and access our List doctors tool inside of the MCP server. Now we also want to pass through one last keyword argument. And that is going to be ENV. And we're going to set that equal to none because we don't have any environment parameters. Now, what we're going to do is we're going to define our next agent. So, so far we've had our first health agent, which you can see over there. We're now going to create another agent. But this one is going to use MCP. So this first one is using our code agent. The next one is going to use the tool calling agent and the tool collection. So in terms of the structure it's pretty similar. We're just going to sub out the agent and get it to use MCP. So let's begin doing that. Well first I'm going to define a decorator. And we're going to set that equal to the server dot agent decorator. We're then going to create a new function. And this is going to be an asynchronous function. It's going to be defined as the doctor agent. Remember when we went and discovered our agents we were able to see that they pick up the name of the agent or the name of the function as the name of the agent. So in this particular case, if we went and reran that hierarchical workflow, we'd see the doctor agent popping up with our new hospital server. And then, as usual, we're going to pass through our same input. This is going to be a list of messages, and that is going to return an asynchronous generator, which is going to have parameters of run yield and run yield resume. Then we're going to define a docstring. This one's going to be pretty simple. So this is a doctor agent which helps users find doctors near them. Now, what we need to do is start defining our tool collection. Now, a tool collection is going to allow us to discover tools on the MCP server. So to do that, we're going to create a new with statement. And this is going to connect to the tool collection using the from MCP method. We're going to pass through our server parameters which we've just defined up here. And then we're going to set the trust remote code parameter equal to true. So that's going to allow us to access those tools on that server. And we're going to run this as the tool collection. So we'll be able to access it using this shorthand statement. Now, what we need to do is we need to pass these tools to our tool calling agent, because so far we haven't actually defined an agent. We've defined the tool collection, but not the agent itself. So let's do that. So we're going to create a new agent. And this is going to be equal to tool calling agent, to that we're going to pass our first keyword argument which is going to be tools. And this is going to be a list which is going to be an unpacked set of values from our tool collection dot tool value. So, effectively grabbing all the tools from the tool collection over here, and we're passing them to our tool calling agent over here. Now we also need to give our tool calling agent an LLM. So we're going to set that parameter as model is equal to model. That's just going to take in our GPT-4 LLM over here. But again you can go and update this to what you want. You can use Ollama. You can use WatsonX. You can use a number of different providers ACP is framework and provider agnostic okay. So that is pretty much our agent now done. Now we also need to go and extract our prompt. Now remember because we had our input, we can go and grab the first prompt and then grab the first part of that prompt and then the content value. And that should be our prompt. So let's do that. So we're going to grab our prompt variable. And we're going to set that equal to input zero. And then part zero. And then we're going to grab the content. And then we're going to send that to our agent. So to do that we can create a new response variable. And we're going to set that equal to agent dot run. And we're going to pass our prompt to it. So that's pretty much the crux of our agent now using MCP. The last thing that we need to do is yield this back to our user when they go and run the server. So we're going to go yield message. And that message is going to be constructed of a number of parts. The main message part is going to take in all of our content, which is going to be the response from our MCP or our two calling agent. So that is that there. Perfect. Cool. That should be our MCP agent now done. Now, if we go and run this, that is our smolagent server now updated. So now, if we go and take a look at that smolagent's server.py file, maybe go and take a look inside of that repository now. So it's going to be available for you to take note and play around with. So if you go to my ACP project and then go and take a look at the smolagents.server.py file, you'll see that we now have a doctor agent. So you can see that we're now running two agents on this one ACP server. Now, we need to make sure that we go and rerun the server now that we've gone and updated it. So, if we go and open up our terminal again we're going to make a quick update. Remember the environment is going to stay up for 120 minutes. If you go away from this lesson and come back, just make sure that you double check that the server is still up and running. And then we're going to render that iframe. So remember we're going to be running on terminal two because that's where we've run the hospital server so far. If we go and run this we're going to bring up our terminal. Take a look, that's available there. What we'll do is we're just going to stop that server. We're just going to run clear to clear that terminal. And then we're going to make sure that we rerun our server. So remember it's been exported to smolagents_server dot py So let's just make sure we run that particular server. So we're going now uv run smolagent server.py. And if we go and run that let's see if we get any errors. That's looking pretty good so far. So we can see that our server is now up and running. And it's running at port 8000. All that's really left to do is actually make a call. Now remember when we've gone and connected to MCP servers before our ACP servers before, we've gone and use the ACP SDK client. That's exactly what we're going to do here. But remember, now that we've gone and defined another agent, we're just going to make sure that we target this agent rather than the health agent. So let's go and do that. To begin with we need a couple of dependencies. So let's bring those in. So we're going to bring asyncIO to make the call. We're going to be nest asyncIO. So we can nest them. We're going to bring in the client from the ACP SDK. And we're also going to bring in Colorama. So we can print it out using a colored output. We're then going to apply nest asyncIO. And that should be pretty much it when it comes to our dependencies. Now, when it comes to actually making our call, we're going to create a new client. And this is going to be a new function which allows us to call that. Now main difference is we're going to change the agent that we use, and we're going to change the prompt that we use. So let's go in to define this. We're going to create an asynchronous function called run doctor workflow. This is going to return nothing. And that is going to connect to our client using a with statement. And remember we're still running on port 8000 so we can connect to that there, but also take note that we're getting this warning: cannot reach server, check if running on http://127.0.0.1:8333 This is occurring because when we set up our ACP server, it's automatically going to try to register our agents onto the BeeAI platform. This provides a register for your agents so you can call them via UI but also via the command line, and orchestrate them all together. We're going to start this up in the next lesson, but for now, just be mindful of this warning. It won't affect the running of this code. So let's keep going and connect to our hospital server. So we're going to create a base URL. We're going to set that equal to Http colon forward forward slash localhost 8000 and we're going to run that as the hospital client. Then what we're going to do is we're going to make asynchronous call and call out to our hospital client. So this is going to be stored inside of a variable called run one. We're going to set that equal to await hospital dot run sync. We're then going to pass through the agent that we want to call out to, which is going to be the doctor agent. Because remember we've gone and defined a second agent. Now we're going to call that to the doctor agent rather than the health agent. So we're going to hit that agent. And now we pass through our prompt. Our prompt is going to be: I'm based in Atlanta, Georgia. We are there any cardiologist near me? Question mark. So that's going to be our prompt. And keep in mind, this should ideally take the state Georgia and go and find whether or not we've got any doctors or cardiologists that are available in that particular state. We haven't actually gone and done a filter for the type of doctor. You might go and choose to update that and see how that performs. For now, we just very much focus on state. So what we can go and do is then we just need to print out our content and remember when because we're getting the message pods and the messages back, we want to make sure that we get the result from our first prompt because we're only passing one through, and the first part, we're only outputting everything as a single part. So we're just going to grab everything. So if you're doing streaming, you'd be able to grab each one of those parts as they generated. Okay. So let's create a new variable called content. And we're going to set that equal to run 1 dot output. We're going to grab the first message. We're then going to grab the first part and then grab the content. And then we're going to print it out. So we're going to use light magenta to print it out to our terminal. And we're going to print out the content. And reset the terminal so that we go back to our regular coloring. Okay. Cool. Now, if we go and run that that is our workflow now defined. All that's really left to do is actually go and run this workflow. So to do that, we can use asyncIO dot run. And to that we're going to pass through our run doctor workflow function. And if we go and run that, take look looks like the run started with searching. It looks like we've found a doctor. Do we get a final response? There we go. So we've now got a final response. Yes, there are cardiologists near you in Atlanta, Georgia, for example, Doctor Sarah Mitchell, who specializes in cardiology, is based at 1247 Medical Center Drive, Atlanta, Georgia. She has 15 years of experience and is board certified. Now, I wonder if we go back to the data set, if we can find that particular doctor and take a look, that's actually our first result. So you can say that we've gone and found that first doctor, and they just so happen to be a cardiologist, but we haven't actually focus on that. We filtered purely based on the state. What you might go and do is try updating the prompt, see if you can find a doctor in Arizona or in California or in Colorado. You should be able to use your doctor agent to now do that. But we've now demonstrated how we can use MCP and ACP together.