WEBVTT

00:00.320 --> 00:04.080
So what we're going to do now is create our own MCP client.

00:04.280 --> 00:05.560
And this is a bit unusual.

00:05.560 --> 00:08.200
It's not actually that common to need to write an MCP client.

00:08.200 --> 00:09.160
When would you do it?

00:09.160 --> 00:09.600
You would do it.

00:09.600 --> 00:14.600
If you're building your own application, that's going to be a host, that's going to be able to call

00:14.760 --> 00:15.640
MCP servers.

00:15.640 --> 00:21.480
And in your application, you want to be able to call a number of different, uh, MCP servers.

00:21.480 --> 00:23.800
And so you're going to want to write an MCP client.

00:24.040 --> 00:29.160
You'd also have to do this if you rewound the clock a few weeks and wanted to, to use OpenAI agents

00:29.160 --> 00:31.440
SDK, because they didn't used to have one built into them.

00:31.440 --> 00:33.760
But now they do, which makes this not as useful.

00:34.400 --> 00:37.920
But I did this the first time because I needed to, but no longer.

00:37.920 --> 00:43.400
And if you're using another framework or you're going natively to an LLM and you didn't have, uh,

00:43.480 --> 00:46.080
the client that you could use, then you would have to do this yourself.

00:46.080 --> 00:47.320
And it's pretty straightforward.

00:47.320 --> 00:48.520
So we might as well do it.

00:48.520 --> 00:49.440
Let's go do that now.

00:49.440 --> 00:57.720
So I'm going to go into this, uh, module called Accounts Client, which is our MCP client implementation.

00:57.960 --> 01:03.560
And we're using a bunch of MCP anthropic code from clients, standard Input-output.

01:03.560 --> 01:07.360
We're importing the standard Input-output client from MCP.

01:07.560 --> 01:12.440
We're importing this standard input output server parameters, which is going to use the parameters

01:12.440 --> 01:14.200
in the format that we're used to now.

01:14.400 --> 01:20.400
And this is something I'm importing from OpenAI, because I want to translate between Anthropic's description

01:20.400 --> 01:24.520
of tools for MCP into OpenAI's version for this purpose.

01:25.000 --> 01:29.040
So the parameters that we set up is one of these studio server parameters.

01:29.040 --> 01:33.040
Objects is basically the same parameters we were looking at before.

01:33.200 --> 01:39.880
You've run account server dot Pi uh to to to load to run our server.

01:40.320 --> 01:40.840
Okay.

01:41.120 --> 01:50.280
And so there is here a list tools function which is going to create our client, spawn a server and

01:50.280 --> 01:51.840
get it to list its tools.

01:51.840 --> 01:53.200
And this is how it works.

01:53.520 --> 02:00.360
Uh, you uh, use the context manager with to create a, a standard input output client.

02:00.560 --> 02:03.760
You start a session and then you initialize the session.

02:03.760 --> 02:07.880
And then we call this list tools on our session.

02:07.880 --> 02:09.440
And we get back the tools.

02:10.080 --> 02:14.560
We can also call a tool using this call tool function.

02:15.230 --> 02:19.390
We can read a resource, and this is one that we will actually continue to use.

02:19.390 --> 02:21.550
We'll use this approach for reading resources.

02:21.670 --> 02:22.510
Read a resource.

02:22.510 --> 02:28.030
We start the client the session and then we call read resource on our server.

02:28.790 --> 02:35.110
And so each of these three that you see here to list the tools to call a tool and to read the account's

02:35.150 --> 02:36.870
resource to read a resource.

02:37.110 --> 02:41.590
What they're all doing is they are spawning a Python process.

02:41.590 --> 02:46.070
They're calling this which which triggers which spawns another process.

02:46.070 --> 02:49.270
They're connecting to that process using its standard input output.

02:49.270 --> 02:50.830
That's how they're communicating.

02:50.830 --> 02:57.190
And they're using the agreed MCP protocol as the way to communicate and to communicate things like list

02:57.230 --> 03:00.270
tools and call tool and read resource.

03:00.270 --> 03:02.030
That's part of the protocol.

03:02.190 --> 03:03.150
That is what's happening.

03:03.150 --> 03:05.750
That is how the client talks to the server.

03:05.750 --> 03:07.550
And that's really at the root of all this.

03:07.550 --> 03:08.750
And that's why I show you this.

03:08.750 --> 03:11.870
So you see that's that's how it all fits together.

03:12.590 --> 03:19.510
And then I've got a utility method here a function get accounts tools OpenAI which is going to call

03:19.550 --> 03:20.910
list accounts tools.

03:21.340 --> 03:22.740
and what comes back.

03:22.780 --> 03:29.900
It's in a format that is the MCP format, and OpenAI for its tools, has a slightly different format,

03:29.940 --> 03:31.060
just very slightly different.

03:31.060 --> 03:37.340
And so I map between them and I return that in the OpenAI version of things.

03:37.700 --> 03:44.460
And this code here, along with this client code, is basically what OpenAI has now written and provides

03:44.460 --> 03:45.460
to us out of the box.

03:45.460 --> 03:46.780
So we don't need this anymore.

03:46.940 --> 03:51.940
But if we wanted to, we could just do it this way and then and then we've written our own client.

03:52.180 --> 03:57.500
So as I say, not not necessary, but it shows you that writing an MCP client is no big deal.

03:57.500 --> 04:04.540
You just have to to use some of Anthropic's code to spawn a process, connect through its input, output

04:04.540 --> 04:09.220
its standard and standard out, and then ask questions like what are your tools?

04:09.260 --> 04:12.940
Let me call a tool and can I read your resources?

04:13.500 --> 04:18.460
And so that's all it takes to talk to our server.

04:18.460 --> 04:21.140
And of course these parameters could be anything that you want.

04:21.180 --> 04:23.820
So so it doesn't have to be specific to accounts.

04:23.820 --> 04:27.460
This could just be a sort of generic server that takes care of this.

04:27.900 --> 04:28.700
All right.

04:28.740 --> 04:30.340
So with that, let's go and give this a try.

04:30.380 --> 04:32.220
Let's try using our client.

04:32.220 --> 04:34.980
So we're back in in our lab.

04:35.220 --> 04:40.900
And from that client module we were just looking at I'm going to import two things get accounts tools

04:40.900 --> 04:45.220
open I the thing we were just looking at and read accounts resource.

04:45.220 --> 04:49.100
Another thing that we'd seen that just calls the server for the resource.

04:49.500 --> 04:51.740
Um, and uh, let's run this.

04:51.740 --> 04:54.260
And if I print open AI tools, we'll see there.

04:54.420 --> 04:56.340
These are the open AI tools.

04:56.820 --> 05:01.260
Uh, in fact, what I can also do, I can just call the list accounts tools.

05:01.260 --> 05:03.500
We can just directly call that as well.

05:03.500 --> 05:13.780
Let's just do this to show you, um, I will say list accounts, tools, um, uh, MCP tools equals

05:13.780 --> 05:14.500
await list.

05:14.660 --> 05:15.140
There we go.

05:15.180 --> 05:15.780
That's what I want.

05:15.820 --> 05:16.140
Thank you.

05:16.180 --> 05:16.700
Cursor.

05:16.820 --> 05:19.060
And then we will print those.

05:19.300 --> 05:26.060
And so just to show you what this means, if we run this, this first response here is exactly what

05:26.060 --> 05:31.220
comes back from the MCP server through our MCP client printing it.

05:31.220 --> 05:37.740
And this second line, the the OpenAI version is just what happens when I switch it up into being in

05:37.740 --> 05:42.140
the format that OpenAI expects, but that's the only distinction between them.

05:42.140 --> 05:48.220
But either way, making these calls it it started our client, it had that session in it.

05:48.260 --> 05:50.380
It spawned a process.

05:50.420 --> 05:52.260
It made a call to that process.

05:52.260 --> 05:56.300
The standard output was collected and returned right here.

05:56.300 --> 06:00.220
And that is an MCB client and server at work.

06:00.420 --> 06:05.180
It's also perhaps worth pointing out that the way I've written this is not efficient, that every single

06:05.180 --> 06:08.460
call in here is spawning another process.

06:08.460 --> 06:11.500
It's running this again, creating another session.

06:11.540 --> 06:16.740
In practice, you could do this more efficiently with one context manager that handles all of these

06:16.740 --> 06:17.660
different steps.

06:17.660 --> 06:22.060
But right now this doesn't matter to us particularly starting this Python process is super quick.

06:22.260 --> 06:25.460
So that that that that's not of consequence.

06:25.460 --> 06:29.020
But you may have noticed that that's probably not the way you would you would want to write it.

06:29.020 --> 06:33.380
If you needed to have this scale a lot, you would just have the one context manager.

06:34.260 --> 06:34.820
Okay.

06:35.020 --> 06:42.700
So, uh, going back to the lab, then let's actually use this client with an agent.
