Skip to content

Commit 68cd574

Browse files
docs: add client-side usage examples for get_display_name()
- Update simple-chatbot example to show title as separate field for LLM - Add "Client Display Utilities" section to README with usage examples - Enhance get_display_name() documentation to clarify client-side usage This demonstrates best practices for displaying human-readable titles in MCP clients while maintaining programmatic names for tool execution. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d1d0f7d commit 68cd574

File tree

3 files changed

+69
-6
lines changed

3 files changed

+69
-6
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,42 @@ async def main():
918918
tool_result = await session.call_tool("echo", {"message": "hello"})
919919
```
920920

921+
### Client Display Utilities
922+
923+
When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:
924+
925+
```python
926+
from mcp.shared.metadata_utils import get_display_name
927+
from mcp.client.session import ClientSession
928+
929+
930+
async def display_tools(session: ClientSession):
931+
"""Display available tools with human-readable names"""
932+
tools_response = await session.list_tools()
933+
934+
for tool in tools_response.tools:
935+
# get_display_name() returns the title if available, otherwise the name
936+
display_name = get_display_name(tool)
937+
print(f"Tool: {display_name}")
938+
if tool.description:
939+
print(f" {tool.description}")
940+
941+
942+
async def display_resources(session: ClientSession):
943+
"""Display available resources with human-readable names"""
944+
resources_response = await session.list_resources()
945+
946+
for resource in resources_response.resources:
947+
display_name = get_display_name(resource)
948+
print(f"Resource: {display_name} ({resource.uri})")
949+
```
950+
951+
The `get_display_name()` function implements the proper precedence rules for displaying names:
952+
- For tools: `title` > `annotations.title` > `name`
953+
- For other objects: `title` > `name`
954+
955+
This ensures your client UI shows the most user-friendly names that servers provide.
956+
921957
### OAuth Authentication for Clients
922958

923959
The SDK includes [authorization support](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for connecting to protected MCP servers:

examples/clients/simple-chatbot/mcp_simple_chatbot/main.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ async def list_tools(self) -> list[Any]:
123123
for item in tools_response:
124124
if isinstance(item, tuple) and item[0] == "tools":
125125
tools.extend(
126-
Tool(tool.name, tool.description, tool.inputSchema)
126+
Tool(tool.name, tool.description, tool.inputSchema, tool.title)
127127
for tool in item[1]
128128
)
129129

@@ -189,9 +189,14 @@ class Tool:
189189
"""Represents a tool with its properties and formatting."""
190190

191191
def __init__(
192-
self, name: str, description: str, input_schema: dict[str, Any]
192+
self,
193+
name: str,
194+
description: str,
195+
input_schema: dict[str, Any],
196+
title: str | None = None,
193197
) -> None:
194198
self.name: str = name
199+
self.title: str | None = title
195200
self.description: str = description
196201
self.input_schema: dict[str, Any] = input_schema
197202

@@ -211,13 +216,20 @@ def format_for_llm(self) -> str:
211216
arg_desc += " (required)"
212217
args_desc.append(arg_desc)
213218

214-
return f"""
215-
Tool: {self.name}
216-
Description: {self.description}
219+
# Build the formatted output with title as a separate field
220+
output = f"Tool: {self.name}\n"
221+
222+
# Add human-readable title if available
223+
if self.title:
224+
output += f"User-readable title: {self.title}\n"
225+
226+
output += f"""Description: {self.description}
217227
Arguments:
218228
{chr(10).join(args_desc)}
219229
"""
220230

231+
return output
232+
221233

222234
class LLMClient:
223235
"""Manages communication with the LLM provider."""

src/mcp/shared/metadata_utils.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
"""Utility functions for working with metadata in MCP types."""
1+
"""Utility functions for working with metadata in MCP types.
2+
3+
These utilities are primarily intended for client-side usage to properly display
4+
human-readable names in user interfaces.
5+
"""
26

37
from mcp.types import Implementation, Prompt, Resource, ResourceTemplate, Tool
48

@@ -7,9 +11,20 @@ def get_display_name(obj: Tool | Resource | Prompt | ResourceTemplate | Implemen
711
"""
812
Get the display name for an MCP object with proper precedence.
913
14+
This is a client-side utility function designed to help MCP clients display
15+
human-readable names in their user interfaces. When servers provide a 'title'
16+
field, it should be preferred over the programmatic 'name' field for display.
17+
1018
For tools: title > annotations.title > name
1119
For other objects: title > name
1220
21+
Example:
22+
# In a client displaying available tools
23+
tools = await session.list_tools()
24+
for tool in tools.tools:
25+
display_name = get_display_name(tool)
26+
print(f"Available tool: {display_name}")
27+
1328
Args:
1429
obj: An MCP object with name and optional title fields
1530

0 commit comments

Comments
 (0)