Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Listing MCP Server Members

00:00 In this lesson, you’re going to be listing all of the members of a given MCP server. To do this, you’ll start by creating the subcommand list, and then you’re going to ask the server for all prompts, resources, and tools that the server exposes.

00:16 And once you’ve got all of that information, you’re going to display all the information to the user. When you’re ready, open your favorite code editor in the file cli.py.

00:28 To create a new subcommand, use the decorator mcp_cli.command. Now this will be the command list, so the help message could say something like, "List all tools, resources, and prompts from the given MCP server."

00:46 This is a very long string, so you can break it up.

00:53 After defining the command, you want to specify the argument it accepts, which is the server_command. And this will be something that you will see throughout the upcoming lessons.

01:05 Let’s call this command list. Actually, list is a built-in, so to avoid any conflicts, let’s define this command as ls.

01:15 It accepts an argument, server_command, which is a string and returns None, and it works by using asyncio to run the coroutine that will be responsible for connecting to the server through the client and getting all of the information you need.

01:31 How do you define _ls? It’s going to be a coroutine that accepts the server_command and returns None. The beginning should be familiar.

01:44 You use the MCP client as an asynchronous context manager, and now the fun stuff begins. Let’s start by printing all the tools available. How do you do this?

01:59 Well, you can grab the tools by using your client, accessing its client_session, and then using the function list_tools. Except this is not a function, it’s a coroutine, so you must await it, and then you want to extract the attribute tools.

02:17 Now you run a loop, and for each item in the tools, you’re going to grab its description, which is either saved in the attribute description, or if it’s not there, you can just say that there’s no description available.

02:32 And then you’re going to want to print the information about this tool. You’ll want the name of the tool, its description, and because later you will want to be able to call tools, you will also print the input schema of the tool, which is the schema that specifies what arguments the tool expects.

02:57 Once you’re done printing the tools, you’ll want to print the resources.

03:03 How do you do that? Well, you can grab the resources by taking your client, accessing the client_session, and running the function list_resources.

03:13 Except this is not a function, it’s a coroutine, so you must await it, and you can grab the resources from the attribute resources of the result.

03:23 You go through each item in the resources, you grab its description,

03:33 and then you can print it.

03:37 For the resources, you will want to print the name, you will want to print the item uri, the unique resource identifier, and you will want to print the description.

03:49 And finally, you print all prompts.

03:54 How can you do that? Well, similarly, the prompts come from awaiting the client.client_session.list_prompts coroutine. You access the attribute prompts from the result, and then for each item in prompts,

04:11 you grab its description,

04:18 and then you print the name of the prompt

04:23 and its description.

04:27 Save your code and open the terminal. To test the subcommand ls, you can start by running uv run mcp-client --help, and you will see a new subcommand in the help text.

04:39 Now run uv run mcp-client ls mcp-data, and you should see the three sections with one item each. Now you might notice the input schema from the tool looks a bit messy, because it’s a big dictionary with lots of keys and nested dictionaries and lots of information.

04:58 So to make this a bit better and a bit more readable, you’re going to add a new dependency with uv add rich, and you’re going to modify your code slightly. At the top of your file, next to click, you’ll want to import rich.

05:14 And inside the coroutine ls, where you were printing the input schema, instead of the built-in print, you’ll want to use rich.print.

05:24 You save this, you run your MCP client again with uv run mcp-client ls mcp-data, and you will see that the input schema is now much more readable.

05:37 Once this is done, you can move on to the next lesson, where you learn how to get specific prompts by name.

Become a Member to join the conversation.