59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
"""Minimal MCP client for your own tools and agents.
|
|
|
|
Usage:
|
|
python examples/client_example.py # starts the server via stdio
|
|
python examples/client_example.py http://localhost:8080/mcp [TOKEN]
|
|
|
|
Wiring into your own LLM loop:
|
|
1. ``list_tools()`` -> pass name / description / input_schema of each tool to the
|
|
model as tool definitions (every major LLM API uses this JSON-schema shape).
|
|
2. When the model requests a tool call -> ``call_tool(name, arguments)``.
|
|
3. Return ``result.content[0].text`` (or ``structured_content``) to the model;
|
|
mark it as an error if ``result.is_error`` is true.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import sys
|
|
|
|
import httpx2
|
|
from mcp import Client, StdioServerParameters
|
|
from mcp.client.streamable_http import streamable_http_client
|
|
|
|
|
|
async def demo(client: Client) -> None:
|
|
print("Server instructions:\n", client.instructions, "\n", sep="")
|
|
|
|
tools = (await client.list_tools()).tools
|
|
print("Tools:", ", ".join(t.name for t in tools), "\n")
|
|
|
|
calls = [
|
|
("evaluate", {"expression": "sqrt(2)", "precision": 40}),
|
|
("solve", {"equations": ["x + y = 10", "x - y = 2"]}),
|
|
("calculus", {"operation": "integral", "expression": "x^2 * e^x"}),
|
|
("probability", {"distribution": "binomial", "operation": "cdf", "parameters": {"n": 20, "p": 0.3}, "x": 5}),
|
|
("convert_units", {"quantity": "60 mph", "to_unit": "km/h"}),
|
|
("matrix", {"operation": "inverse", "matrix": [[1, 2], [2, 4]]}), # error on purpose
|
|
]
|
|
for name, arguments in calls:
|
|
result = await client.call_tool(name, arguments)
|
|
status = "ERROR" if result.is_error else "ok"
|
|
print(f"[{status}] {name}({arguments})\n{result.content[0].text}\n")
|
|
|
|
|
|
async def main() -> None:
|
|
if len(sys.argv) > 1:
|
|
url = sys.argv[1]
|
|
headers = {"Authorization": f"Bearer {sys.argv[2]}"} if len(sys.argv) > 2 else {}
|
|
async with httpx2.AsyncClient(headers=headers, timeout=60) as http:
|
|
async with Client(streamable_http_client(url, http_client=http)) as client:
|
|
await demo(client)
|
|
else:
|
|
params = StdioServerParameters(command=sys.executable, args=["-m", "mcp_calculator"])
|
|
async with Client(params) as client:
|
|
await demo(client)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|