Ana içeriğe geç

Sunucunuzu çalıştırma

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.

mcp.run() sunucuyu başlatır.

Vermeniz gereken tek karar aktarım: sunucunuzla istemcisi arasındaki baytların gerçekte nasıl taşındığı.

Aktarım seçme

Aktarım Ne olduğu Ne zaman
stdio Host, dosyanızı bir alt süreç olarak başlatır ve onunla stdin ve stdout'u üzerinden konuşur. Yerel sunucular. Varsayılan.
streamable-http Bir portu dinleyen gerçek bir HTTP sunucusu. Dağıttığınız her şey.
sse Eski HTTP aktarımı. Hiçbir zaman.

Warning

SSE, 2025-03-26 protokol sürümünde yerini Streamable HTTP'ye bıraktı. mcp.run(transport="sse") kendi sse_path= ve message_path= seçenekleriyle hâlâ çalışır, ancak yalnızca henüz geçiş yapmamış istemciler için vardır. Üzerine yeni bir şey inşa etmeyin.

mcp.run()

server.py
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}."


if __name__ == "__main__":
    mcp.run()
  • run() senkrondur. Sunucunun ömrü boyunca bloke kalır.
  • Argüman verilmezse aktarım stdio olur.
  • if __name__ == "__main__": altında durur, çünkü sunucunuzu yükleyen her şey (mcp dev, mcp run, mcp install, testleriniz) bu dosyayı içe aktarır. Bu koruma, bir içe aktarmanın çalışan bir sunucuya dönüşmesini engeller.

stdio

Yapılandırılacak hiçbir şey yok. Host, dosyanızı bir alt süreç olarak başlatır, istekleri stdin'ine yazar ve yanıtları stdout'undan okur.

Kendiniz çalıştırın, sonucunu görürsünüz:

python server.py

Hiçbir şey yazdırmaz ve geri dönmez. Bir host'un ilk sözü söylemesini stdin'de bekliyordur.

Bu aynı zamanda stdout'un iletişim hattının ta kendisi olduğu anlamına gelir. Hizmet verirken SDK bu hattı özel bir dosya tanımlayıcısına taşır ve stdout'a flush edilen çıktıyı (miras aldığı stdout'a yazan bir alt süreç, flush edilmiş bir print()) akışı bozamayacağı stderr'e yönlendirir. Hizmet başlamadan önce stdout'a flush edilen çıktı (echo yapan bir sarmalayıcı betik, import sırasında tamponlanmadan yapılan bir print) yine hatta düşer; yorumlayıcı çıkışta boşaltana kadar tamponda kalan bir print() de öyle. Gerçekten istediğiniz çıktı için doğru araç logging modülüdür: işleyicisi her kaydı oluştuğu anda stderr'e flush eder. Ayrıntıların tamamı Log tutma sayfasında.

Deneyin

uv run mcp dev server.py

Inspector, gerçek bir host'un yaptığının aynısını yapar: server.py dosyasını bir alt süreç olarak başlatır ve ona stdio üzerinden bağlanır.

Ona hiç port vermediniz. Zaten yok.

Streamable HTTP

Aynı sunucuyu bunun yerine bir porta koymak için aktarımı (ve seçeneklerini) run() içinde belirtin:

server.py
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}."


if __name__ == "__main__":
    mcp.run(transport="streamable-http", port=3001)

Bu tek satır bir Starlette uygulaması kurar ve onu uvicorn ile sunar. İstemciler http://127.0.0.1:3001/mcp adresine bağlanır.

Her aktarımın kendi anahtar sözcük argümanları vardır ve hepsi run() üzerindedir:

  • host / port: nerede dinleneceği. Varsayılanlar 127.0.0.1 ve 8000.
  • streamable_http_path: MCP endpoint'inin bulunduğu yol. Varsayılan /mcp.
  • json_response=True: her POST'a SSE akışı yerine tek bir JSON gövdesiyle yanıt verir. Bu gövdede yanıttan başka hiçbir şeye yer yoktur; bu yüzden istek sırasında istemciye geri çağrı yapan bir araç (ctx.elicit(), örnekleme (sampling)) bu ayakta NoBackChannelError fırlatır ve sürmekte olan çağrıya bağlı bildirimler (ctx.report_progress() ile bildirilen ilerleme, çağrıya özel log mesajları) düşürülür; bağımsız GET akışı ilgisiz olanları taşımaya devam eder.
  • stateless_http=True: istek başına yeni bir aktarım, oturum takibi yok.
  • max_request_body_size: bayt cinsinden kabul edilen en büyük POST gövdesi. Varsayılan olarak 4 MiB; daha büyük istekler, ayrıştırma veya oturum oluşturma öncesinde HTTP 413 alır. Bunu yalnızca meşru MCP mesajları bu boyutu aştığında yükseltin.
  • event_store, retry_interval, transport_security: kaldığı yerden devam edebilme ve DNS rebinding koruması. localhost dışında bir yere dağıtım yapana kadar bekleyebilirler; transport_security konusunu Dağıtım ve ölçekleme ele alır.

Warning

Aktarım seçenekleri run()'a gider, MCPServer(...)'a değil. Kurucu, sunucunuzun ne olduğunu tanımlar: ad, sürüm, talimatlar. run() ise nasıl sunulduğunu tanımlar. Bunu tersine çevirirseniz, daha MCP devreye bile girmeden Python yanıt verir:

TypeError: MCPServer.__init__() got an unexpected keyword argument 'port'

run() kısa yoldur. Daha fazlasına ihtiyaç duyduğunuz an (sunucunuzun mevcut bir uygulamanın içine mount edilmesi, tek süreçte iki sunucu, tarayıcı istemcileri için CORS) ASGI uygulamasını kendiniz kurar ve herhangi bir ASGI sunucusuna teslim edersiniz. Bu da Mevcut bir uygulamaya ekleme sayfasının konusu.

Sunucu ayarları

Çalıştırmayla ilgili birkaç şey aktarımla ilgili değildir. Bunlar kurucu argümanlarıdır:

server.py
from mcp.server import MCPServer

mcp = MCPServer("Bookshop", log_level="DEBUG")


@mcp.tool()
def search_books(query: str) -> str:
    """Search the catalog by title or author."""
    return f"Found 3 books matching {query!r}."


if __name__ == "__main__":
    mcp.run()
  • log_level: MCPServer(...) kurulduğu anda logging.basicConfig() fonksiyonuna verilir. Bu, kök logger'ı yapılandırır; dolayısıyla yalnızca SDK'nınkilerin değil, kendi logger'larınızın düzeyini de belirler. Varsayılan "INFO".
  • debug: HTTP aktarımlarının kurduğu Starlette uygulamasına iletilir. Varsayılan False.

Her ikisi de çalışma zamanında geri okuyabileceğiniz mcp.settings üzerine yerleşir.

mcp komutu

[cli] ekstrası tüm bunların etrafına küçük bir komut satırı aracı kurar.

mcp dev, sunucunuzu MCP Inspector altında çalıştırır:

uv run mcp dev server.py
uv run mcp dev server.py --with pandas --with numpy
uv run mcp dev server.py --with-editable .

--with, kurduğu ortama paket ekler; --with-editable kendi paketinizi o ortama kurar. PATH değişkeninizde npx bulunmalıdır: Inspector bir Node.js uygulamasıdır.

mcp run dosyayı içe aktarır, sunucu nesnesini (modül düzeyinde bir mcp, server veya app) bulur ve üzerinde run() çağırır:

uv run mcp run server.py
uv run mcp run server.py:bookshop

: soneki, nesnenin adı mcp, server veya app olmadığında onu belirtir.

if __name__ == "__main__": bloğunuz burada hiç çalışmaz: mcp run, run()'ı kendisi çağırır ve ilettiği tek seçenek --transport seçeneğidir.

mcp install sunucuyu Claude Desktop'a kaydeder; böylece uygulama onu sizin için başlatır:

uv run mcp install server.py --name "Bookshop"
uv run mcp install server.py -v API_KEY=abc123 -f .env

-v KEY=VALUE ve -f .env, ortam değişkenlerini bu kayda işler. Claude Desktop sunucunuzu kendi sürecinde başlatır. Kabuğunuzun ortamı orada yoktur.

Claude Desktop, mcp install komutunun bildiği tek host'tur. Diğer tüm host'lar (Claude Code, Cursor, VS Code) aynı başlatma komutunu kendi yapılandırma dosyalarında alır; her biri Gerçek bir host'a bağlanma sayfasında var.

mcp version kurulu SDK sürümünü yazdırır.

Tip

mcp dev ve mcp run yalnızca MCPServer'ı anlar. Düşük seviyeli Server ile geliştiriyorsanız onu kendiniz çalıştırırsınız. Bkz. Düşük seviyeli Server.

Özet

  • Aktarım, baytların sunucunuza nasıl ulaştığıdır: yerel bir alt süreç için stdio, bir port için streamable-http. SSE'nin yerini yenisi aldı.
  • mcp.run() aktarımı seçer. Argümansız stdio'dur ve bloke kalır.
  • Her aktarım seçeneği (host, port, streamable_http_path, ...) run()'a verilen bir argümandır, asla MCPServer(...)'a değil.
  • run()if __name__ == "__main__": altında tutun. Sunucunuzu yükleyen her şey önce dosyayı içe aktarır.
  • log_level= ve debug= kurucu argümanlarıdır; mcp.settings üzerine yerleşirler.
  • Inspector için mcp dev, bir dosyayı çalıştırmak için mcp run, Claude Desktop için mcp install, sürüm için mcp version.
  • Aktarım, sunucunuzun ne olduğunu asla değiştirmez: bu sayfadaki üç dosya da birebir aynı aracı sunar.

Sınır run()'ın kendisi olduğunda (sunucunuz zaten var olan bir uygulamanın içindeyse) adres Mevcut bir uygulamaya ekleme. Gerçek bir ana bilgisayar adı ve birden fazla worker Dağıtım ve ölçekleme sayfasında. İstemcilerinizden bazıları hâlâ 2025-11-25 veya daha eski bir spesifikasyon sürümündeyse, iyi haber Eski nesil istemcilere hizmet verme sayfasında.