İstemci aktarımları
Makine çevirisi
Bu sayfa İngilizce dokümantasyondan otomatik olarak çevrildi; esas alınması gereken sürüm İngilizce sayfadır. Yanlış görünen bir şey varsa, nasıl bildireceğinizi Çeviriler sayfası açıklar.
Her Client, sunucusuyla bir aktarım üzerinden konuşur: mesajları fiilen taşıyan şey budur.
Aktarımı hiçbir zaman ayrıca yapılandırmazsınız. Client tek bir konumsal argüman alır ve aktarımı bu argümanın türünden çıkarır.
Her birinin sunucu tarafı (mcp.run()'ın ne yaptığı ve neyi dağıttığınız) Sunucunuzu çalıştırma sayfasında.
Bellek içinde
Sunucu nesnesinin kendisini geçirin:
from mcp import Client
from mcp.server import MCPServer
mcp = MCPServer("Bookshop")
@mcp.tool()
def search_books(query: str) -> str:
"""Search the catalog by title or author."""
return f"Found 3 books matching {query!r}."
async def main() -> None:
async with Client(mcp) as client:
result = await client.call_tool("search_books", {"query": "dune"})
print(result.structured_content)
Alt süreç yok, port yok, ağ üzerinde tek bir bayt yok. İstemci ve sunucu aynı süreçteki iki nesnedir; yine de çağrı gerçek protokol katmanından geçer: search_books, HTTP üzerinden nasıl olacaksa tam olarak öyle listelenir, doğrulanır ve çağrılır.
Bu, onu aynı anda iki şey yapar:
- Bir test düzeneği. Bu belgelerdeki her örnek bu şekilde çalıştırılır ve Test etme sayfası tüm deseni bunun üzerine kurar.
- Bir gömme API'si. Sunucuyu oluşturan bir uygulamanın, araçlarını çağırmak için ağ üzerinden bir sıçrama yapmasına gerek yoktur.
Streamable HTTP
Bir URL dizesi geçirin; arkasına dağıtım yaptığınız aktarım olan Streamable HTTP'yi elde edersiniz:
from mcp import Client
async def main() -> None:
async with Client("http://localhost:8000/mcp") as client:
result = await client.list_tools()
print([tool.name for tool in result.tools])
Üretim istemcisinin tamamı bu. Client, URL'yi sizin için streamable_http_client(...) ile sarar; bunu da MCP'nin gerektirdiği şekilde yapılandırılmış bir httpx2.AsyncClient üzerine kurar: follow_redirects=True, connect/write/pool için 30 saniyelik zaman aşımı ve sunucu bir yanıt akışını açık tutabileceği için 300 saniyelik okuma zaman aşımı.
Check
Oluşturduğunuz bir Client bağlı değildir. Oluşturma yalnızca aktarımı seçer;
onu açan async with'tir. İçine girmeden bağlantıya uzanırsanız SDK bunu size söyler:
RuntimeError: Client must be used within an async context manager
Client("http://...") yazdığınızda hiçbir şey çözümlenmedi, getirilmedi ya da başlatılmadı. O satır bedava.
Kendi httpx2.AsyncClient'ınızı getirme
Bir Authorization başlığına, bir çereze, bir vekil sunucuya, mTLS'e ya da farklı bir zaman aşımına ihtiyaç duyduğunuz anda httpx2.AsyncClient'ı kendiniz oluşturun ve streamable_http_client'a verin:
import httpx2
from mcp import Client
from mcp.client.streamable_http import streamable_http_client
async def main() -> None:
async with httpx2.AsyncClient(
headers={"Authorization": "Bearer ..."},
timeout=httpx2.Timeout(30.0, read=300.0),
follow_redirects=True,
) as http_client:
transport = streamable_http_client("http://localhost:8000/mcp", http_client=http_client)
async with Client(transport) as client:
result = await client.list_tools()
print([tool.name for tool in result.tools])
Dikkat edilecek iki şey:
httpx2.AsyncClient'ın sahibi sizsiniz, bu yüzden içine siz girer ve siz çıkarsınız. SDK, kendi oluşturmadığı bir istemciyi asla kapatmaz.streamable_http_client(url, http_client=...)bir aktarım döndürür veClient(transport)onu diğer her şey gibi kabul eder.
TLS ile ilgili bir not: httpx2, sertifikaları paketle gelen bir CA listesine göre değil, işletim sisteminin güven deposuna göre doğrular (
truststore aracılığıyla). Kullanılabilir bir sistem CA deposu olmayan bir ortamda (bazı minimal kapsayıcılar) standart SSL_CERT_FILE/SSL_CERT_DIR
ortam değişkenlerini ayarlayın ya da httpx2.AsyncClient'ınıza açıkça bir verify=ssl_context geçirin
(arka plan bilgisi için
httpx ve httpx-sse'nin yerini httpx2 aldı).
Warning
streamable_http_client eskiden headers= ve timeout= parametrelerini doğrudan alırdı. Artık almıyor:
tek parametreleri url, http_client ve terminate_on_close. Alışkanlıkla headers='a
uzanırsanız şunu alırsınız:
TypeError: streamable_http_client() got an unexpected keyword argument 'headers'
HTTP'yle ilgili her şey artık geçirdiğiniz o tek httpx2.AsyncClient üzerinde bulunur.
Info
httpx2, tanıdık httpx API'sini korur; yani httpx'i biliyorsanız kimlik doğrulama,
vekil sunucular, olay kancaları, yeniden denemeler ve bağlantı sınırlarının burada nasıl yapılacağını zaten biliyorsunuz. SDK üzerine hiçbir şey eklemez,
hiçbir şeyi de eksiltmez. OAuth'un takıldığı yer de burası:
httpx2.AsyncClient(auth=OAuthClientProvider(...)). Bu akışın tamamı OAuth istemcileri sayfasında.
stdio
Bir stdio sunucusu bir alt süreçtir. İstemci onu başlatır, stdin'ine JSON-RPC yazar ve stdout'undan JSON-RPC okur. Bir masaüstü host'un makinenizde bir sunucuyu çalıştırma biçimi budur: bir host, bu kod artı bir kullanıcı arayüzüdür ve Gerçek bir host'a bağlanma, aynı ilişkinin host'un tarafından, bir yapılandırma dosyası olarak görülen halidir.
Süreci StdioServerParameters ile tanımlayın, stdio_client ile bir aktarıma dönüştürün ve Client'a onu verin:
from mcp import Client, StdioServerParameters
from mcp.client.stdio import stdio_client
server = StdioServerParameters(
command="uv",
args=["run", "server.py"],
env={"BOOKSHOP_API_KEY": "secret"},
)
async def main() -> None:
async with Client(stdio_client(server)) as client:
result = await client.list_tools()
print([tool.name for tool in result.tools])
Client, parametre nesnesini tek başına kabul etmez. StdioServerParameters yapılandırmadır; stdio_client(server) ise ondan bir süreç başlatmayı bilen aktarımdır. Her zaman sarın.
async with bloğundan çıkmak alt süreci de kapatır: stdin'i kapat, bekle, oyalanıyorsa sonlandır. Onu hiçbir zaman kendiniz temizlemezsiniz.
Warning
Alt süreç ortamınızı devralmaz. Minimal bir izin listesi alır (POSIX'te HOME, LOGNAME,
PATH, SHELL, TERM ve USER); böylece sizin yazmamış olabileceğiniz bir sürece hassas hiçbir şey
sızmaz.
Bir API anahtarına ihtiyaç duyan bir sunucu onu orada bulamaz. env= ile açıkça geçirin; bu
değişkenler izin listesinin üstüne birleştirilir. Yukarıda BOOKSHOP_API_KEY'in yaptığı budur.
SSE
mcp.client.sse içindeki sse_client(url), Streamable HTTP'nin yerini aldığı HTTP aktarımıdır. Hâlâ onu konuşan bir sunucuyla konuşmak için aynı şekilde sarın, Client(sse_client("http://localhost:8000/sse")), ve üzerine yeni hiçbir şey kurmayın.
Transport protokolü
Client için yukarıdakilerin hepsi aynı şeydir.
Bir aktarım, (read, write) mesaj akışı çifti veren herhangi bir asenkron bağlam yöneticisidir: resmi olarak mcp.client içindeki Transport protokolü. Client, argümanını türüne göre çözümler: bir sunucu nesnesi süreç içinde bağlanır, bir str streamable_http_client(url) olur ve geri kalan her şeye doğrudan bir aktarım olarak girilir. stdio_client(...), streamable_http_client(...) ve sse_client(...)'in hepsinin aynı yuvaya oturmasının ve kendinizinkini yazabilmenizin nedeni bu son kuraldır.
Özet
Client(mcp)(sunucu nesnesi) bellek içinde bağlanır. Testler ve gömme için kullanın.Client("http://.../mcp")(bir URL), üretim aktarımı olan Streamable HTTP üzerinden bağlanır.- Başlıklar, kimlik doğrulama, vekil sunucular ve zaman aşımları,
streamable_http_client(url, http_client=...)'a geçirdiğiniz birhttpx2.AsyncClientüzerinde yer alır.headers=anahtar sözcüğü yoktur. - stdio
Client(stdio_client(StdioServerParameters(...)))'tır; asla tek başına parametre nesnesi değil. - Alt süreç sizinkini değil, izin listesine göre oluşturulmuş bir ortam alır;
env=buna ekleme yapar. - Bir aktarım,
async with x as (read, write)yapabildiğiniz herhangi bir şeydir.Client, sunucu nesnesi ya da URL olmayan her şeyi doğrudan bu protokole verir. - Bir
Clientoluşturmak aktarımı seçer. Onuasync withaçar.
Aktarım açıldıktan sonra iki tarafın bir protokol sürümünde anlaşması gerekir. Normalde bunu hiç düşünmezsiniz; düşünmeniz gerektiğinde gidilecek sayfa Protokol sürümleri'dir.