-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcp_client_example.py
More file actions
184 lines (147 loc) Β· 6.43 KB
/
Copy pathmcp_client_example.py
File metadata and controls
184 lines (147 loc) Β· 6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
"""
MCP Client Example
Demonstrates how to connect to and interact with an MCP service.
Shows both untyped and typed client usage patterns.
Author: Chandra Shettigar <chandra@devteds.com>
"""
import asyncio
import httpx
from mcp import types
class MCPProductClient:
"""A client for interacting with our Product Search MCP server."""
def __init__(self, base_url: str = "http://localhost:8000"):
self.base_url = base_url
self.session = None
async def connect_sse(self):
"""Connect to MCP server using Server-Sent Events (SSE)."""
# Note: This would be used if our server supported SSE transport
# For now, we'll use HTTP requests directly
pass
async def discover_capabilities(self):
"""Discover what tools the MCP server provides using raw HTTP."""
async with httpx.AsyncClient() as client:
response = await client.post(
f"{self.base_url}/api/v1/mcp/message",
json={"id": "capabilities",
"method": "capabilities", "params": {}},
)
return response.json()
async def call_tool(self, tool_name: str, arguments: dict):
"""Call a tool on the MCP server."""
async with httpx.AsyncClient() as client:
response = await client.post(
f"{self.base_url}/api/v1/mcp/message",
json={
"id": f"call_{tool_name}",
"method": tool_name,
"params": arguments,
},
)
return response.json()
async def search_products(self, query: str = "", category: str = ""):
"""Search for products."""
result = await self.call_tool(
"search_products", {"query": query, "category": category}
)
return result.get("result", {})
async def get_product_details(self, product_id: str):
"""Get detailed information about a product."""
result = await self.call_tool("get_product_details", {"product_id": product_id})
return result.get("result", {})
async def check_inventory(self, product_id: str):
"""Check inventory for a product."""
result = await self.call_tool("check_inventory", {"product_id": product_id})
return result.get("result", {})
async def demo_mcp_client():
"""Demonstrate using the MCP client."""
print("π MCP Client Demo")
print("=" * 50)
client = MCPProductClient()
try:
# 1. Discover capabilities
print("\n1. π Discovering server capabilities...")
capabilities = await client.discover_capabilities()
if "result" in capabilities:
tools = capabilities["result"]["capabilities"]["tools"]
print(f" Found {len(tools)} tools:")
for tool in tools:
print(f" - {tool['name']}: {tool['description']}")
# 2. Search for products
print("\n2. ποΈ Searching for electronics...")
electronics = await client.search_products(category="Electronics")
if "products" in electronics:
print(f" Found {electronics['count']} electronics:")
for product in electronics["products"]:
print(f" - {product['name']}: ${product['price']}")
# 3. Get product details
print("\n3. π± Getting iPhone details...")
iphone = await client.get_product_details("1")
if "name" in iphone:
print(f" Product: {iphone['name']}")
print(f" Description: {iphone['description']}")
print(f" Price: ${iphone['price']}")
print(f" Stock: {iphone['stock']} units")
# 4. Check inventory
print("\n4. π¦ Checking Nike shoes inventory...")
inventory = await client.check_inventory("3")
if "product_name" in inventory:
print(f" Product: {inventory['product_name']}")
print(f" Stock: {inventory['stock']} units")
status = "Yes" if inventory["in_stock"] else "No"
print(f" Available: {status}")
print("\nβ
Demo completed successfully!")
except Exception as e:
print(f"\nβ Error: {e}")
print("Make sure the MCP server is running on http://localhost:8000")
# Alternative approach using the official MCP types
class TypedMCPClient:
"""Example using official MCP types for better type safety."""
def __init__(self, base_url: str = "http://localhost:8000"):
self.base_url = base_url
async def call_tool_typed(self, request: types.CallToolRequest):
"""Call a tool using official MCP types."""
async with httpx.AsyncClient() as client:
# Convert MCP request to our server's format
response = await client.post(
f"{self.base_url}/api/v1/mcp/message",
json={
"id": "typed_call",
"method": request.params.name,
"params": request.params.arguments or {},
},
)
return response.json()
async def search_products_typed(self, query: str = "", category: str = ""):
"""Search products using typed request."""
request = types.CallToolRequest(
method="tools/call",
params=types.CallToolRequestParams(
name="search_products", arguments={"query": query, "category": category}
),
)
return await self.call_tool_typed(request)
async def demo_typed_client():
"""Demonstrate using typed MCP client."""
print("\n" + "=" * 50)
print("π― Typed MCP Client Demo")
print("=" * 50)
client = TypedMCPClient()
try:
# Search using typed request
print("\nπ Searching for 'iPhone' using typed client...")
result = await client.search_products_typed(query="iPhone")
if "result" in result and "products" in result["result"]:
products = result["result"]["products"]
print(f" Found {len(products)} products:")
for product in products:
print(f" - {product['name']}: ${product['price']}")
print("\nβ
Typed demo completed!")
except Exception as e:
print(f"\nβ Error: {e}")
if __name__ == "__main__":
print("Starting MCP Client Examples...")
print("Make sure your MCP server is running: python -m mcp_service")
print()
# Run both demos
asyncio.run(demo_mcp_client())
asyncio.run(demo_typed_client())