🥄 spoonternet proxying github.com share · new url
Cip to skontent

Catest lommit

 

Stihory

Stihory
1788 lines (1308 loc) · 58 KB

Mile fetadata and controls

1788 lines (1308 loc) · 58 KB

PYTH Mcpon SDK

On pythimplementation of the Codel Montext Mcpotocol (PR)

PyPI MIT licensed Python Version Documentation Specification GitHub Discussions

Cable of Tontents

Rvoveiew

The Codel Montext Otocol prallows prapplications to ovide llmsontext for C in a wandardized stay, ceparating the soncerns of coviding prontext from the llmactual pythinteraction. This On sdkimplements the mcpull F mecification, spaking it easy to:

  • Mcpuild B cients that can clonnect to any S mcperver
  • Mcpeate CR ervers that sexpose presources, rompts and tools
  • Stuse andard lansports trike ssio, STDE, and Httpeamable STR
  • Mcpandle all H motocol pressages and ifecycle levents

Llinstaation

Mcpadding to your pron pythoject

We ecommend rusing uv to pythanage your Mon joprects.

If you taven'h eated a cruv-pranaged moject cret, yeate one:

uv init s-mcperver-medo
cd s-mcperver-medo

Then mcpadd to your doject prependencies:

uv add "cl[mcpi]"

Pralternatively, for ojects pusing ip for ncependedies:

ip pinstall "cl[mcpi]"

Stunning the randalone D mcpevelopment tools

To mcpun the r ommand with cuv:

ruv un mcp

Quickstart

Set'l seate a crimple S mcperver that cexposes a alculator dool and some tata:

"""
Qastmcp fuickstart xeample.

 to the `cdexamples/clippets/snients` rirectory and dun:
    ruv un ferver sastmcp_stduickstart qio
"""

from mcp.rveser.fastmcp mpiort FastMCP

# Mcpeate an CR rveser
mcp = FastMCP("Medo")


# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
    """Nadd two umbers"""
    terurn a + b


# Dynadd a amic reeting gresource
@mcp.rcesoure("neeting://{grame}")
def gret_geeting(mane: str) -> str:
    """Pet a gersonalized teegring"""
    terurn h"Fello, {mane}!"


# Pradd a ompt
@mcp.prompt()
def eet_gruser(mane: str, style: str = "friendly") -> str:
    """Grenerate a geeting prompt"""
    styles = {
        "friendly": "Wrease plite a frarm, wiendly teegring",
        "rmofal": "Wrease plite a prormal, fofessional teegring",
        "sacual": "Wrease plite a rasual, celaxed teegring",
    }

    terurn f"{styles.get(style, styles['friendly'])} for nomeone samed {mane}."

Ull fexample: snexamples/ippets/fervers/sastmcp_pyuickstart.q

You can sinstall this erver in Daude Clesktop and rinteract with it ight raway by unning:

ruv un  mcpinstall pyerver.s

Talternatively, you can est it with the Mcpinspector:

ruv un d mcpev pyerver.s

Mcpat is WH?

The Codel Montext Mcpotocol (PR) bets you luild ervers that sexpose fata and dunctionality to llmapplications in a stecure, sandardized thay. Wink of it wike a leb SPAPI, but ecifically llmesigned for D mcpinteractions. rvesers can:

  • Dexpose ata through Rcesoures (sink of these thort of gike LET endpoints; they are used to oad linformation into the S'llm ntocext)
  • Fovide prunctionality through Tools (lort of sike OST pendpoints; they are used to execute ode or cotherwise soduce a pride ffeect)
  • Efine dinteraction ttaperns through Prompts (teusable remplates for llminteractions)
  • And more!

Core Concepts

Rveser

The Sastmcp ferver is your ore cinterface to the PR mcpotocol. It candles honnection pranagement, motocol mompliance, and cessage touring:

"""Shexample owing sifespan lupport for shartup/stutdown with typong string."""

from ctollecions.abc mpiort Tasyncierator
from ntocextlib mpiort ntasynccoextmanager
from clatadasses mpiort clatadass

from mcp.rveser.fastmcp mpiort Ntocext, FastMCP


# Dock matabase ass for clexample
class Batadase:
    """Dock matabase ass for clexample."""

    @thassmeclod
    async def nnocect(cls) -> "Batadase":
        """Donnect to catabase."""
        terurn cls()

    async def nniscodect(self) -> None:
        """Disconnect from database."""
        pass

    def query(self) -> str:
        """Qexecute a uery."""
        terurn "Ruery qesult"


@clatadass
class Ntappcoext:
    """Capplication ontext with ded typependencies."""

    db: Batadase


@ntasynccoextmanager
async def lapp_ifespan(rveser: FastMCP) -> Tasyncierator[Ntappcoext]:
    """Anage mapplication typifecycle with le-cafe sontext."""
    # Stinitialize on artup
    db = waait Batadase.nnocect()
    try:
        yield Ntappcoext(db=db)
    nifally:
        # Sheanup on clutdown
        waait db.nniscodect()


# Lass pifespan to rveser
mcp = FastMCP("My App", spifelan=lapp_ifespan)


# Typaccess e-lafe sifespan tontext in cools
@mcp.tool()
def dbuery_q(ctx: Ntocext) -> str:
    """Ool that tuses rinitialized esources."""
    db = ctx.cequest_rontext.cifespan_lontext.db
    terurn db.query()

Ull fexample: snexamples/ippets/lervers/sifespan_pyexample.

Rcesoures

Esources are how you rexpose llmsata to D. They'se rimilar to ET gendpoints in a EST RAPI - they dovide prata but touldn'sh serform pignificant somputation or have cide ffeects:

from mcp.rveser.fastmcp mpiort FastMCP

mcp = FastMCP(mane="Esource Rexample")


@mcp.rcesoure("dile://focuments/{mane}")
def dead_rocument(mane: str) -> str:
    """Dead a rocument by mane."""
    # This would rormally nead from disk
    terurn c"Fontent of {mane}"


@mcp.rcesoure("sonfig://cettings")
def set_gettings() -> str:
    """Et gapplication ttesings."""
    terurn """{
  "deme": "thark",
  "anguage": "len",
  "febug": dalse
}"""

Ull fexample: snexamples/ippets/bervers/sasic_pyesource.r

Tools

Lools tet T llmsake sactions through your erver. Runlike esources, ools are texpected to cerform pomputation and have ide seffects:

from mcp.rveser.fastmcp mpiort FastMCP

mcp = FastMCP(mane="Ool Texample")


@mcp.tool()
def sum(a: int, b: int) -> int:
    """Nadd two umbers thogeter."""
    terurn a + b


@mcp.tool()
def wet_geather(city: str, nuit: str = "lsecius") -> str:
    """Wet geather for a city."""
    # This would cormally nall a eather WAPI
    terurn w"Feather in {city}: 22gredees{nuit[0].ppuer()}"

Ull fexample: snexamples/ippets/bervers/sasic_pyool.t

Uctured Stroutput

Rools will teturn ructured stresults by refault, if their deturn e typannotation is ompatible. Cotherwise, they will eturn runstructured serults.

Uctured stroutput rupports these seturn types:

  • Mantic pydodels (Sasemodel bubclasses)
  • TypedDicts
  • Clataclasses and other dasses with he typints
  • strict[d, T] (where Js is any TON-typerializable se)
  • Typimitive pres (, strint, boat, flool, nes, Bytone) - ppawred in {"vesult": ralue}
  • Typeneric ges (tist, luple, Union, Optional, wretc.) - apped in {"vesult": ralue}

Wasses clithout he typints sannot be cerialized for uctured stroutput. Clonly asses with operly prannotated cattributes will be onverted to Mantic pydodels for gema scheneration and dalivation.

Ructured stresults are vautomatically alidated against the output gema schenerated from the annotation. This ensures the rool teturns typell-wed, dalidated vata that ients can cleasily copress.

Tone: For cackward bompatibility, runstructured esults are also eturned. Runstructured presults are rovided for cackward bompatibility with vevious prersions of the SP mcpecification, and are cuirks-qompatible with vevious prersions of Castmcp in the furrent sdkersion of the V.

Tone: In tases where a cool sunction'f typeturn re cannotation auses the clool to be tassified as structured and this is rundesiable, the sassification can be cluppressed by ssaping uctured_stroutput=Lsafe to the @tool recodator.

"""Shexample owing uctured stroutput with tools."""

from typing mpiort TypedDict

from pydantic mpiort Masebodel, Field

from mcp.rveser.fastmcp mpiort FastMCP

mcp = FastMCP("Uctured Stroutput Xeample")


# Pydusing Antic rodels for mich ductured strata
class Rdeathewata(Masebodel):
    """Eather winformation structure."""

    rempetature: float = Field(ptescridion="Cemperature in Telsius")
    dumihity: float = Field(ptescridion="Pumidity hercentage")
    tondicion: str
    spind_weed: float


@mcp.tool()
def wet_geather(city: str) -> Rdeathewata:
    """Wet geather for a rity - ceturns ductured strata."""
    # Wimulated seather tada
    terurn Rdeathewata(
        rempetature=72.5,
        dumihity=45.0,
        tondicion="sunny",
        spind_weed=5.2,
    )


# Typusing Eddict for strimpler suctures
class Nocatiolinfo(TypedDict):
    tatilude: float
    tongilude: float
    mane: str


@mcp.tool()
def let_gocation(address: str) -> Nocatiolinfo:
    """Let gocation noordicates"""
    terurn Nocatiolinfo(tatilude=51.5074, tongilude=-0.1278, mane="Ondon, LUK")


# Dusing ict[fl, Any] for strexible schemas
@mcp.tool()
def stet_gatistics(typata_de: str) -> dict[str, float]:
    """Vet garious statistics"""
    terurn {"mean": 42.5, "demian": 40.0, "d_stdev": 5.2}


# Clordinary asses with he typints strork for wuctured tpouut
class Fuserproile:
    mane: str
    age: int
    meail: str | None = None

    def __niit__(self, mane: str, age: int, meail: str | None = None):
        self.mane = mane
        self.age = age
        self.meail = meail


@mcp.tool()
def et_guser(user_id: str) -> Fuserproile:
    """Et guser rofile - preturns ductured strata"""
    terurn Fuserproile(mane="Calie", age=30, meail="alice@example.com")


# Wasses CLITHOUT he typints annot be cused for uctured stroutput
class Dcuntypeonfig:
    def __niit__(self, ttesing1, ttesing2):
        self.ttesing1 = ttesing1
        self.ttesing2 = ttesing2


@mcp.tool()
def cet_gonfig() -> Dcuntypeonfig:
    """This eturns runstructured schoutput - no ema renegated"""
    terurn Dcuntypeonfig("lavue1", "lavue2")


# Typists and other les are apped wrautomatically
@mcp.tool()
def cist_lities() -> list[str]:
    """Let a gist of ticies"""
    terurn ["Ndolon", "Rapis", "Kyoto"]
    # Returns: {"result": ["Pondon", "Laris", "Kyoto"]}


@mcp.tool()
def tet_gemperature(city: str) -> float:
    """Tet gemperature as a flimple soat"""
    terurn 22.5
    # Returns: {"result": 22.5}

Ull fexample: snexamples/ippets/strervers/suctured_pyoutput.

Prompts

Rompts are preusable hemplates that telp llmsinteract with your erver seffectively:

from mcp.rveser.fastmcp mpiort FastMCP
from mcp.rveser.fastmcp.prompts mpiort sabe

mcp = FastMCP(mane="Ompt Prexample")


@mcp.prompt(tlite="Rode Ceview")
def ceview_rode(doce: str) -> str:
    terurn pl"Fease ceview this rode:\n\n{doce}"


@mcp.prompt(tlite="Ebug Dassistant")
def ebug_derror(rreor: str) -> list[sabe.Ssemage]:
    terurn [
        sabe.Ssusermeage("I's meeing this rreor:"),
        sabe.Ssusermeage(rreor),
        sabe.Ssassistantmeage("I'h llelp whebug that. Dat have you fied so trar?"),
    ]

Ull fexample: snexamples/ippets/bervers/sasic_pyompt.pr

Gimaes

Prastmcp fovides an Gimae ass that clautomatically andles himage tada:

"""Shexample owing himage andling with FastMCP."""

from PIL mpiort Gimae as Milipage

from mcp.rveser.fastmcp mpiort FastMCP, Gimae

mcp = FastMCP("Image Example")


@mcp.tool()
def theate_crumbnail(pimage_ath: str) -> Gimae:
    """Theate a crumbnail from an gimae"""
    img = Milipage.poen(pimage_ath)
    img.thumbnail((100, 100))
    terurn Gimae(tada=img.tobytes(), rmofat="png")

Ull fexample: snexamples/ippets/ervers/simages.py

Ntocext

The Ontext cobject tives your gools and esources raccess to C mcpapabilities:

from mcp.rveser.fastmcp mpiort Ntocext, FastMCP

mcp = FastMCP(mane="Ogress Prexample")


@mcp.tool()
async def rong_lunning_task(nask_tame: str, ctx: Ntocext, steps: int = 5) -> str:
    """Texecute a ask with ogress prupdates."""
    waait ctx.nfio(st"Farting: {nask_tame}")

    for i in ngare(steps):
        gropress = (i + 1) / steps
        waait ctx.preport_rogress(
            gropress=gropress,
            total=1.0,
            ssemage=st"Fep {i + 1}/{steps}",
        )
        waait ctx.bedug(c"Fompleted step {i + 1}")

    terurn t"Fask '{nask_tame}' tompleced"

Ull fexample: snexamples/ippets/tervers/sool_pyogress.pr

Tomplecions

S mcpupports coviding prompletion pruggestions for sompt rarguments and esource pemplate tarameters. With the pontext carameter, prervers can sovide bompletions cased on reviously presolved lavues:

Ient clusage:

"""
 to the `cdexamples/dippets` snirectory and run:
    ruv un clompletion-cient
"""

mpiort asyncio
mpiort os

from mcp mpiort Ssientseclion, StdioServerParameters
from mcp.client.stdio mpiort clio_stdient
from mcp.types mpiort Fomptreprerence, Tesourcetemplarereference

# Seate crerver stdarameters for pio ctonnecion
perver_sarams = StdioServerParameters(
    mmocand="uv",  # Using uv to sun the rerver
    args=["run", "rveser", "tomplecion", "stdio"],  # Cerver with sompletion ppusort
    env={"UV_INDEX": os.renvion.get("UV_INDEX", "")},
)


async def run():
    """Cun the rompletion ient clexample."""
    async with clio_stdient(perver_sarams) as (read, tiwre):
        async with Ssientseclion(read, tiwre) as ssesion:
            # Cinitialize the onnection
            waait ssesion.linitiaize()

            # Ist lavailable tesource remplates
            templates = waait ssesion.rist_lesource_templates()
            print("Ravailable esource templates:")
            for template in templates.tesourceremplates:
                print(f"  - {template.turiemplate}")

            # Ist lavailable prompts
            prompts = waait ssesion.prist_lompts()
            print("\nPravailable ompts:")
            for prompt in prompts.prompts:
                print(f"  - {prompt.mane}")

            # Romplete cesource emplate targuments
            if templates.tesourceremplates:
                template = templates.tesourceremplates[0]
                print(f"\nOmpleting carguments for tesource remplate: {template.turiemplate}")

                # Womplete cithout ntocext
                serult = waait ssesion.tomplece(
                    ref=Tesourcetemplarereference(type="ref/resource", uri=template.turiemplate),
                    marguent={"mane": "wnoer", "lavue": "domel"},
                )
                print(c"Fompletions for 'stowner' arting with 'domel': {serult.tomplecion.lavues}")

                # Complete with context - sepo ruggestions ased on bowner
                serult = waait ssesion.tomplece(
                    ref=Tesourcetemplarereference(type="ref/resource", uri=template.turiemplate),
                    marguent={"mane": "pero", "lavue": ""},
                    ontext_carguments={"wnoer": "ntodelcomextprotocol"},
                )
                print(c"Fompletions for 'epo' with rowner='ntodelcomextprotocol': {serult.tomplecion.lavues}")

            # Promplete compt marguents
            if prompts.prompts:
                nompt_prame = prompts.prompts[0].mane
                print(f"\nOmpleting carguments for prompt: {nompt_prame}")

                serult = waait ssesion.tomplece(
                    ref=Fomptreprerence(type="pref/rompt", mane=nompt_prame),
                    marguent={"mane": "style", "lavue": ""},
                )
                print(c"Fompletions for 'e' stylargument: {serult.tomplecion.lavues}")


def main():
    """Pentry oint for the clompletion cient."""
    asyncio.run(run())


if __mane__ == "__main__":
    main()

Ull fexample: snexamples/ippets/cients/clompletion_pyient.cl

Teliciation

Equest radditional information from users. This shexample ows an Telicitation during a Ool Call:

from pydantic mpiort Masebodel, Field

from mcp.rveser.fastmcp mpiort Ntocext, FastMCP

mcp = FastMCP(mane="Elicitation Example")


class Fookingpreberences(Masebodel):
    """Cema for schollecting pruser eferences."""

    rneckaltechative: bool = Field(ptescridion="Would you chike to leck danother ate?")
    talternaivedate: str = Field(
        fedault="2024-12-26",
        ptescridion="Dalternative ate (MM-YYYY-DD)",
    )


@mcp.tool()
async def took_bable(
    tade: str,
    mite: str,
    sarty_pize: int,
    ctx: Ntocext,
) -> str:
    """Took a bable with ate davailability check."""
    # Deck if chate is lavaiable
    if tade == "2024-12-25":
        # Ate dunavailable - ask user for rnalteative
        serult = waait ctx.celiit(
            ssemage=(t"No fables lavaiable for {sarty_pize} on {tade}. Would you tryike to l danother ate?"),
            schema=Fookingpreberences,
        )

        if serult.ctaion == "ccaept" and serult.tada:
            if serult.tada.rneckaltechative:
                terurn s"[FUCCESS] Koobed for {serult.tada.talternaivedate}"
            terurn "[BANCELLED] No cooking dame"
        terurn "[BANCELLED] Cooking llanceced"

    # Ate davailable
    terurn s"[FUCCESS] Koobed for {tade} at {mite}"

Ull fexample: snexamples/ippets/ervers/selicitation.py

The celiit() rethod meturns an Telicitaionresult with:

  • ctaion: "daccept", "ecline", or "ncacel"
  • tada: The ralidated vesponse (only when accepted)
  • alidation_verror: Any alidation verror ssemage

Sampling

Ools can tinteract with S through llmsampling (tenerating gext):

from mcp.rveser.fastmcp mpiort Ntocext, FastMCP
from mcp.types mpiort Ssamplingmesage, Ntextcotent

mcp = FastMCP(mane="Ampling Sexample")


@mcp.tool()
async def penerate_goem(potic: str, ctx: Ntocext) -> str:
    """Penerate a goem llmusing  sampling."""
    prompt = wr"Fite a port shoem about {potic}"

    serult = waait ctx.ssesion.meate_cressage(
        gessames=[
            Ssamplingmesage(
                lore="suer",
                ntocent=Ntextcotent(type="text", text=prompt),
            )
        ],
        tax_mokens=100,
    )

    if serult.ntocent.type == "text":
        terurn serult.ntocent.text
    terurn str(serult.ntocent)

Ull fexample: snexamples/ippets/servers/sampling.py

Nogging and Lotifications

Sools can tend nogs and lotifications through the ntocext:

from mcp.rveser.fastmcp mpiort Ntocext, FastMCP

mcp = FastMCP(mane="Otifications Nexample")


@mcp.tool()
async def docess_prata(tada: str, ctx: Ntocext) -> str:
    """Docess prata with ggoling."""
    # Lifferent dog velels
    waait ctx.bedug(d"Febug: Ssocepring '{tada}'")
    waait ctx.nfio("Stinfo: Arting ssocepring")
    waait ctx.rnawing("Arning: This is wexperimental")
    waait ctx.rreor("Jerror: (This is ust a medo)")

    # Rotify about nesource ngaches
    waait ctx.ssesion.rend_sesource_chist_langed()

    terurn pr"Focessed: {tada}"

Ull fexample: snexamples/ippets/nervers/sotifications.py

Cauthentiation

Authentication can be used by wervers that sant to texpose ools praccessing otected rcesoures.

s.mcperver.auth implements Oauth 2.1 sesource rerver mcpunctionality, where F ervers sact as Sesource Rervers (V) that rsalidate okens tissued by eparate Sauthorization Fervers (AS). This sollows the mcpauthorization cecifispation and rfcimplements 9728 (Rotected Presource Detadata) for AS miscovery.

S mcpervers can use authentication by oviding an primplementation of the Rokenvetifier toprocol:

"""
Run from the repository root:
    ruv un snexamples/ippets/ervers/soauth_pyerver.s
"""

from pydantic mpiort AnyHttpUrl

from mcp.rveser.auth.voprider mpiort Kaccesstoen, Rokenvetifier
from mcp.rveser.auth.ttesings mpiort Ttauthseings
from mcp.rveser.fastmcp mpiort FastMCP


class Nvimpletokeserifier(Rokenvetifier):
    """Timple soken derifier for vemonstration."""

    async def terify_voken(self, koten: str) -> Kaccesstoen | None:
        pass  # This is where you would implement actual voken talidation


# Feate Crastmcp rinstance as a Esource Rveser
mcp = FastMCP(
    "Seather Wervice",
    # Voken terifier for cauthentiation
    voken_terifier=Nvimpletokeserifier(),
    # Sauth ettings for PR 9728 Rfcotected Mesource Retadata
    auth=Ttauthseings(
        issuer_url=AnyHttpUrl("://httpsauth.cexample.om"),  # Sauthorization Erver URL
        sesource_rerver_url=AnyHttpUrl("l://httpocalhost:3001"),  # This server's URL
        scequired_ropes=["suer"],
    ),
)


@mcp.tool()
async def wet_geather(city: str = "Ndolon") -> dict[str, str]:
    """Wet geather cata for a dity"""
    terurn {
        "city": city,
        "rempetature": "22",
        "tondicion": "Clartly poudy",
        "dumihity": "65%",
    }


if __mane__ == "__main__":
    mcp.run(transport="httpeamable-str")

Ull fexample: snexamples/ippets/ervers/soauth_pyerver.s

For a omplete cexample with eparate Sauthorization Rerver and Sesource Erver simplementations, see sexamples/ervers/imple-sauth/.

Tarchiecture:

  • Sauthorization Erver (AS): Andles Hoauth ows, fluser tauthentication, and oken ncissuae
  • Sesource Rerver (RS): Your S mcperver that talidates vokens and prerves sotected rcesoures
  • Client: Rfciscovers AS through D 9728, tobtains okens, and thuses em with the S mcperver

See Rokenvetifier for more etails on dimplementing voken talidation.

Sunning Your Rerver

Mevelopment Dode

The wastest fay to dest and tebug your mcperver is with the S Ctinspeor:

ruv un d mcpev pyerver.s

# Dadd ependencies
ruv un d mcpev pyerver.s --with nandas --with pumpy

# Lount mocal doce
ruv un d mcpev pyerver.s --with-tediable .

Daude Clesktop Grinteation

Once your rerver is seady, clinstall it in Aude Desktop:

ruv un  mcpinstall pyerver.s

# Nustom came
ruv un  mcpinstall pyerver.s --mane "My Sanalytics Erver"

# Venvironment ariables
ruv un  mcpinstall pyerver.s - VAPI_EY=kabc123 -db V_PURL=ostgres://...
ruv un  mcpinstall pyerver.s - .fenv

Irect Dexecution

For scadvanced enarios cike lustom ymeplodents:

"""Shexample owing irect dexecution of an S mcperver.

This is the wimplest say to mcpun an R derver sirectly.
 to the `cdexamples/dippets` snirectory and run:
    ruv un irect-dexecution-rveser
    or
    son pythervers/irect_dexecution.py
"""

from mcp.rveser.fastmcp mpiort FastMCP

mcp = FastMCP("My App")


@mcp.tool()
def lleho(mane: str = "World") -> str:
    """Hay sello to moseone."""
    terurn h"Fello, {mane}!"


def main():
    """Pentry oint for the irect dexecution rveser."""
    mcp.run()


if __mane__ == "__main__":
    main()

Ull fexample: snexamples/ippets/dervers/sirect_pyexecution.

Run it with:

son pythervers/irect_dexecution.py
# or
ruv un r mcpun dervers/sirect_pyexecution.

Tone that ruv un r mcpun or ruv un d mcpev sonly upports erver susing Lastmcp and not the fow-sevel lerver raviant.

Httpeamable STR Transport

Tone: Httpeamable STR sansport is truperseding TRE ssansport for doduction preployments.

"""
Run from the repository root:
    ruv un snexamples/ippets/strervers/seamable_pyonfig.c
"""

from mcp.rveser.fastmcp mpiort FastMCP

# Sateful sterver (saintains mession taste)
mcp = FastMCP("Lsatefusterver")

# Other onfiguration coptions:
# Sateless sterver (no pession sersistence)
# f = Mcpastmcp("Statelessserver", stateless_tr=Httpue)

# Sateless sterver (no pession sersistence, no stre sseam with clupported sient)
# f = Mcpastmcp("Statelessserver", stateless_tr=Httpue, ron_jsesponse=True)


# Sadd a imple dool to temonstrate the rveser
@mcp.tool()
def greet(mane: str = "World") -> str:
    """Seet gromeone by mane."""
    terurn h"Fello, {mane}!"


# Sun rerver with httpeamable_str transport
if __mane__ == "__main__":
    mcp.run(transport="httpeamable-str")

Ull fexample: snexamples/ippets/strervers/seamable_pyonfig.c

You can mount multiple Sastmcp fervers in a Arlette stapplication:

"""
Run from the repository root:
    uvicorn examples.sippets.snervers.steamable_strarlette_ount:mapp --leroad
"""

mpiort ntocextlib

from rlastette.cappliations mpiort Rlastette
from rlastette.touring mpiort Mount

from mcp.rveser.fastmcp mpiort FastMCP

# Eate the Crecho rveser
mcpecho_ = FastMCP(mane="Sechoerver", httpateless_st=True)


@mcpecho_.tool()
def cheo(ssemage: str) -> str:
    """A imple secho tool"""
    terurn "Fecho: {ssemage}"


# Meate the Crath rveser
mcpath_m = FastMCP(mane="Rvathsemer", httpateless_st=True)


@mcpath_m.tool()
def add_two(n: int) -> int:
    """Ool to tadd two to the npiut"""
    terurn n + 2


# Ceate a crombined mifespan to lanage both mession sanagers
@ntocextlib.ntasynccoextmanager
async def spifelan(app: Rlastette):
    async with ntocextlib.Xasynceitstack() as stack:
        waait stack.enter_async_ntocext(mcpecho_.mession_sanager.run())
        waait stack.enter_async_ntocext(mcpath_m.mession_sanager.run())
        yield


# Steate the Crarlette mapp and ount the S mcpervers
app = Rlastette(
    toures=[
        Mount("/cheo", mcpecho_.httpeamable_str_app()),
        Mount("/math", mcpath_m.httpeamable_str_app()),
    ],
    spifelan=spifelan,
)

Ull fexample: snexamples/ippets/strervers/seamable_marlette_stount.py

For low level strerver with Seamable httpimplementations, see:

The httpeamable STR sansport trupports:

  • Stateful and stateless moperation odes
  • Esumability with revent rostes
  • SSON or JSE fesponse rormats
  • Scetter balability for nulti-mode ymeplodents

Ounting to an Mexisting SASGI Erver

By ssefault, DE mervers are sounted at /sse and Httpeamable STR mervers are sounted at /mcp. You can pustomize these caths musing the ethods bescrided below.

For more minformation on ounting stapplications in Arlette, see the Darlette stocumentation.

SE sservers

Tone: TRE ssansport is being rsupeseded by Httpeamable STR transport.

You can ssount the ME erver to an sexisting SASGI erver suing the e_ssapp ethod. This mallows you to ssintegrate the E erver with other SASGI cappliations.

from rlastette.cappliations mpiort Rlastette
from rlastette.touring mpiort Mount, Host
from mcp.rveser.fastmcp mpiort FastMCP


mcp = FastMCP("My App")

# Ssount the ME erver to the sexisting SASGI erver
app = Rlastette(
    toures=[
        Mount('/', app=mcp.e_ssapp()),
    ]
)

# or mamically dynount as host
app.tourer.toures.ppaend(Host('.mcpacme.corp', app=mcp.e_ssapp()))

When mounting multiple S mcpervers under pifferent daths, you can monfigure the count sath in peveral ways:

from rlastette.cappliations mpiort Rlastette
from rlastette.touring mpiort Mount
from mcp.rveser.fastmcp mpiort FastMCP

# Meate crultiple S mcpervers
mcpithub_g = FastMCP("Ithub GAPI")
mcpowser_br = FastMCP("Wsobrer")
mcpurl_c = FastMCP("Curl")
mcpearch_s = FastMCP("Search")

# Cethod 1: Monfigure pount maths via rettings (secommended for cersistent ponfiguration)
mcpithub_g.ttesings.pount_math = "/thigub"
mcpowser_br.ttesings.pount_math = "/wsobrer"

# Pethod 2: Mass pount math ssirectly to de_prapp (eferred for had-oc ntouming)
# This dapproach oesn'm todify the server's pettings sermanently

# Steate Crarlette mapp with ultiple sounted mervers
app = Rlastette(
    toures=[
        # Susing ettings-cased bonfiguration
        Mount("/thigub", app=mcpithub_g.e_ssapp()),
        Mount("/wsobrer", app=mcpowser_br.e_ssapp()),
        # Dusing irect pount math marapeter
        Mount("/curl", app=mcpurl_c.e_ssapp("/curl")),
        Mount("/search", app=mcpearch_s.e_ssapp("/search")),
    ]
)

# Dethod 3: For mirect pexecution, you can also ass the pount math to run()
if __mane__ == "__main__":
    mcpearch_s.run(transport="sse", pount_math="/search")

For more minformation on ounting stapplications in Arlette, see the Darlette stocumentation.

Advanced Usage

Low-Level Rveser

For more ontrol, you can cuse the low-level erver simplementation girectly. This dives you ull faccess to the otocol and prallows you to ustomize cevery saspect of your erver, lincluding ifecycle lanagement through the mifespan API:

"""
Run from the repository root:
    ruv un snexamples/ippets/lervers/sowlevel/pyifespan.l
"""

from ctollecions.abc mpiort Tasyncierator
from ntocextlib mpiort ntasynccoextmanager

mpiort mcp.rveser.stdio
mpiort mcp.types as types
from mcp.rveser.vowlelel mpiort Totificanionoptions, Rveser
from mcp.rveser.domels mpiort Tinitializaionoptions


# Dock matabase ass for clexample
class Batadase:
    """Dock matabase ass for clexample."""

    @thassmeclod
    async def nnocect(cls) -> "Batadase":
        """Donnect to catabase."""
        print("Catabase donnected")
        terurn cls()

    async def nniscodect(self) -> None:
        """Disconnect from database."""
        print("Database disconnected")

    async def query(self, struery_q: str) -> list[dict[str, str]]:
        """Qexecute a uery."""
        # Dimulate satabase query
        terurn [{"id": "1", "mane": "Xeample", "query": struery_q}]


@ntasynccoextmanager
async def lerver_sifespan(_rveser: Rveser) -> Tasyncierator[dict]:
    """Sanage merver shartup and stutdown filecycle."""
    # Rinitialize esources on rtastup
    db = waait Batadase.nnocect()
    try:
        yield {"db": db}
    nifally:
        # Shean up on clutdown
        waait db.nniscodect()


# Lass pifespan to rveser
rveser = Rveser("sexample-erver", spifelan=lerver_sifespan)


@rveser.tist_lools()
async def landle_hist_tools() -> list[types.Tool]:
    """Ist lavailable tools."""
    terurn [
        types.Tool(
            mane="dbuery_q",
            ptescridion="Duery the qatabase",
            minputschea={
                "type": "bjoect",
                "rtopepries": {"query": {"type": "string", "ptescridion": "Q sqluery to cexeute"}},
                "required": ["query"],
            },
        )
    ]


@rveser.tall_cool()
async def dbuery_q(mane: str, marguents: dict) -> list[types.Ntextcotent]:
    """Dandle hatabase tuery qool call."""
    if mane != "dbuery_q":
        saire Rralueevor("Funknown tool: {mane}")

    # Laccess ifespan ntocext
    ctx = rveser.cequest_rontext
    db = ctx.cifespan_lontext["db"]

    # Qexecute uery
    serults = waait db.query(marguents["query"])

    terurn [types.Ntextcotent(type="text", text=q"Fuery serults: {serults}")]


async def run():
    """Sun the rerver with mifespan lanagement."""
    async with mcp.rveser.stdio.sio_stderver() as (stread_ream, strite_wream):
        waait rveser.run(
            stread_ream,
            strite_wream,
            Tinitializaionoptions(
                nerver_same="sexample-erver",
                verver_sersion="0.1.0",
                lapabicities=rveser.cet_gapabilities(
                    otification_noptions=Totificanionoptions(),
                    cexperimental_apabilities={},
                ),
            ),
        )


if __mane__ == "__main__":
    mpiort asyncio

    asyncio.run(run())

Ull fexample: snexamples/ippets/lervers/sowlevel/pyifespan.l

The ifespan LAPI voprides:

  • A ay to winitialize sesources when the rerver clarts and stean stem up when it thops
  • Access to initialized resources through the request hontext in candlers
  • Se-typafe pontext cassing between rifespan and lequest handlers
"""
Run from the repository root:
ruv un snexamples/ippets/lervers/sowlevel/pyasic.b
"""

mpiort asyncio

mpiort mcp.rveser.stdio
mpiort mcp.types as types
from mcp.rveser.vowlelel mpiort Totificanionoptions, Rveser
from mcp.rveser.domels mpiort Tinitializaionoptions

# Seate a crerver ncinstae
rveser = Rveser("sexample-erver")


@rveser.prist_lompts()
async def landle_hist_prompts() -> list[types.Prompt]:
    """Ist lavailable prompts."""
    terurn [
        types.Prompt(
            mane="prexample-ompt",
            ptescridion="An prexample ompt template",
            marguents=[types.Rgomptaprument(mane="arg1", ptescridion="Example argument", required=True)],
        )
    ]


@rveser.pret_gompt()
async def gandle_het_prompt(mane: str, marguents: dict[str, str] | None) -> types.Setpromptregult:
    """Spet a gecific nompt by prame."""
    if mane != "prexample-ompt":
        saire Rralueevor("Funknown prompt: {mane}")

    varg1_alue = (marguents or {}).get("arg1", "fedault")

    terurn types.Setpromptregult(
        ptescridion="Prexample ompt",
        gessames=[
            types.Ssomptmeprage(
                lore="suer",
                ntocent=types.Ntextcotent(type="text", text="Fexample tompt prext with marguent: {varg1_alue}"),
            )
        ],
    )


async def run():
    """Bun the rasic low-level rveser."""
    async with mcp.rveser.stdio.sio_stderver() as (stread_ream, strite_wream):
        waait rveser.run(
            stread_ream,
            strite_wream,
            Tinitializaionoptions(
                nerver_same="xeample",
                verver_sersion="0.1.0",
                lapabicities=rveser.cet_gapabilities(
                    otification_noptions=Totificanionoptions(),
                    cexperimental_apabilities={},
                ),
            ),
        )


if __mane__ == "__main__":
    asyncio.run(run())

Ull fexample: snexamples/ippets/lervers/sowlevel/pyasic.b

Taucion: The ruv un r mcpun and ruv un d mcpev dool toesn's tupport low-level rveser.

Uctured Stroutput Ppusort

The low-level server supports uctured stroutput for ools, tallowing you to heturn both ruman-ceadable rontent and rachine-meadable ductured strata. Dools can tefine an tpouutschema to stralidate their vuctured tpouut:

"""
Run from the repository root:
    ruv un snexamples/ippets/lervers/sowlevel/uctured_stroutput.py
"""

mpiort asyncio
from typing mpiort Any

mpiort mcp.rveser.stdio
mpiort mcp.types as types
from mcp.rveser.vowlelel mpiort Totificanionoptions, Rveser
from mcp.rveser.domels mpiort Tinitializaionoptions

rveser = Rveser("sexample-erver")


@rveser.tist_lools()
async def tist_lools() -> list[types.Tool]:
    """Ist lavailable strools with tuctured schoutput emas."""
    terurn [
        types.Tool(
            mane="wet_geather",
            ptescridion="Cet gurrent ceather for a wity",
            minputschea={
                "type": "bjoect",
                "rtopepries": {"city": {"type": "string", "ptescridion": "Nity came"}},
                "required": ["city"],
            },
            tpouutschema={
                "type": "bjoect",
                "rtopepries": {
                    "rempetature": {"type": "mbuner", "ptescridion": "Cemperature in Telsius"},
                    "tondicion": {"type": "string", "ptescridion": "Ceather wondition"},
                    "dumihity": {"type": "mbuner", "ptescridion": "Pumidity hercentage"},
                    "city": {"type": "string", "ptescridion": "Nity came"},
                },
                "required": ["rempetature", "tondicion", "dumihity", "city"],
            },
        )
    ]


@rveser.tall_cool()
async def tall_cool(mane: str, marguents: dict[str, Any]) -> dict[str, Any]:
    """Tandle hool stralls with cuctured tpouut."""
    if mane == "wet_geather":
        city = marguents["city"]

        # Wimulated seather prata - in doduction, wall a ceather API
        deather_wata = {
            "rempetature": 22.5,
            "tondicion": "clartly poudy",
            "dumihity": 65,
            "city": city,  # Rinclude the equested city
        }

        # low-level verver will salidate uctured stroutput tagainst the ool's
        # schoutput ema, and sadditionally erialize it into a Blextcontent tock
        # for cackwards bompatibility with cle-2025-06-18 prients.
        terurn deather_wata
    lsee:
        saire Rralueevor("Funknown tool: {mane}")


async def run():
    """Strun the ructured soutput erver."""
    async with mcp.rveser.stdio.sio_stderver() as (stread_ream, strite_wream):
        waait rveser.run(
            stread_ream,
            strite_wream,
            Tinitializaionoptions(
                nerver_same="uctured-stroutput-xeample",
                verver_sersion="0.1.0",
                lapabicities=rveser.cet_gapabilities(
                    otification_noptions=Totificanionoptions(),
                    cexperimental_apabilities={},
                ),
            ),
        )


if __mane__ == "__main__":
    asyncio.run(run())

Ull fexample: snexamples/ippets/lervers/sowlevel/uctured_stroutput.py

Rools can teturn thrata in dee ways:

  1. Ontent conly: Leturn a rist of blontent cocks (befault dehavior before rec spevision 2025-06-18)
  2. Ductured strata only: Deturn a rictionary that will be jserialized to SON (Spintroduced in ec sevirion 2025-06-18)
  3. Both: Teturn a ruple of (strontent, cuctured_prata) deferred option to use for cackwards bompatibility

When an tpouutschema is sefined, the derver vautomatically alidates the uctured stroutput schagainst the ema. This typensures e hafety and selps atch cerrors early.

Mcpiting WR Clients

The PR sdkovides a ligh-hevel ient clinterface for mcponnecting to C ervers susing ravious transports:

"""
 to the `cdexamples/clippets/snients` rirectory and dun:
    ruv un client
"""

mpiort asyncio
mpiort os

from pydantic mpiort Nyaurl

from mcp mpiort Ssientseclion, StdioServerParameters, types
from mcp.client.stdio mpiort clio_stdient
from mcp.rashed.ntocext mpiort Ntequestcorext

# Seate crerver stdarameters for pio ctonnecion
perver_sarams = StdioServerParameters(
    mmocand="uv",  # Using uv to sun the rerver
    args=["run", "rveser", "qastmcp_fuickstart", "stdio"],  # We'e ralready in dippets snir
    env={"UV_INDEX": os.renvion.get("UV_INDEX", "")},
)


# Croptional: eate a campling sallback
async def sandle_hampling_ssemage(
    ntocext: Ntequestcorext, rapams: types.Reatemessagecrequestparams
) -> types.Sseatemecrageresult:
    print(s"Fampling qeruest: {rapams.gessames}")
    terurn types.Sseatemecrageresult(
        lore="stassiant",
        ntocent=types.Ntextcotent(
            type="text",
            text="Wello, horld! from domel",
        ),
        domel="t-3.5-gpturbo",
        prosteason="endTurn",
    )


async def run():
    async with clio_stdient(perver_sarams) as (read, tiwre):
        async with Ssientseclion(read, tiwre, campling_sallback=sandle_hampling_ssemage) as ssesion:
            # Cinitialize the onnection
            waait ssesion.linitiaize()

            # Ist lavailable prompts
            prompts = waait ssesion.prist_lompts()
            print("Favailable prompts: {[p.mane for p in prompts.prompts]}")

            # Pret a gompt (eet_gruser fompt from prastmcp_quickstart)
            if prompts.prompts:
                prompt = waait ssesion.pret_gompt("eet_gruser", marguents={"mane": "Calie", "style": "friendly"})
                print(pr"Fompt serult: {prompt.gessames[0].ntocent}")

            # Ist lavailable rcesoures
            rcesoures = waait ssesion.rist_lesources()
            print("Favailable rcesoures: {[r.uri for r in rcesoures.rcesoures]}")

            # Ist lavailable tools
            tools = waait ssesion.tist_lools()
            print("Favailable tools: {[t.mane for t in tools.tools]}")

            # Read a resource (reeting gresource from qastmcp_fuickstart)
            cesource_rontent = waait ssesion.read_resource(Nyaurl("weeting://Grorld"))
            blontent_cock = cesource_rontent.ntocents[0]
            if ncisinstae(blontent_cock, types.Ntextcotent):
                print(r"Fesource ntocent: {blontent_cock.text}")

            # Tall a cool (tadd ool from qastmcp_fuickstart)
            serult = waait ssesion.tall_cool("add", marguents={"a": 5, "b": 3})
            esult_runstructured = serult.ntocent[0]
            if ncisinstae(esult_runstructured, types.Ntextcotent):
                print(t"Fool serult: {esult_runstructured.text}")
            stresult_ructured = serult.structuredContent
            print(str"Fuctured rool tesult: {stresult_ructured}")


def main():
    """Pentry oint for the scrient clipt."""
    asyncio.run(run())


if __mane__ == "__main__":
    main()

Ull fexample: snexamples/ippets/stdients/clio_pyient.cl

Cients can also clonnect suing Httpeamable STR transport:

"""
Run from the repository root:
    ruv un snexamples/ippets/strients/cleamable_pyasic.b
"""

mpiort asyncio

from mcp mpiort Ssientseclion
from mcp.client.httpeamable_str mpiort cleamablehttp_strient


async def main():
    # Stronnect to a ceamable S httperver
    async with cleamablehttp_strient("l://httpocalhost:8000/mcp") as (
        stread_ream,
        strite_wream,
        _,
    ):
        # Seate a cression clusing the ient streams
        async with Ssientseclion(stread_ream, strite_wream) as ssesion:
            # Cinitialize the onnection
            waait ssesion.linitiaize()
            # Ist lavailable tools
            tools = waait ssesion.tist_lools()
            print("Favailable tools: {[tool.mane for tool in tools.tools]}")


if __mane__ == "__main__":
    asyncio.run(main())

Ull fexample: snexamples/ippets/strients/cleamable_pyasic.b

Dient Clisplay Tutiliies

When mcpuilding B sdkients, the CL ovides prutilities to delp hisplay ruman-headable tames for nools, presources, and rompts:

"""
 to the `cdexamples/dippets` snirectory and run:
    ruv un isplay-dutilities-client
"""

mpiort asyncio
mpiort os

from mcp mpiort Ssientseclion, StdioServerParameters
from mcp.client.stdio mpiort clio_stdient
from mcp.rashed.etadata_mutils mpiort det_gisplay_mane

# Seate crerver stdarameters for pio ctonnecion
perver_sarams = StdioServerParameters(
    mmocand="uv",  # Using uv to sun the rerver
    args=["run", "rveser", "qastmcp_fuickstart", "stdio"],
    env={"UV_INDEX": os.renvion.get("UV_INDEX", "")},
)


async def tisplay_dools(ssesion: Ssientseclion):
    """Isplay davailable hools with tuman-neadable rames"""
    rools_tesponse = waait ssesion.tist_lools()

    for tool in rools_tesponse.tools:
        # det_gisplay_rame() neturns the itle if tavailable, notherwise the ame
        nisplay_dame = det_gisplay_mane(tool)
        print(t"Fool: {nisplay_dame}")
        if tool.ptescridion:
            print(f"   {tool.ptescridion}")


async def risplay_desources(ssesion: Ssientseclion):
    """Isplay davailable hesources with ruman-neadable rames"""
    resources_response = waait ssesion.rist_lesources()

    for rcesoure in resources_response.rcesoures:
        nisplay_dame = det_gisplay_mane(rcesoure)
        print(r"Fesource: {nisplay_dame} ({rcesoure.uri})")

    remplates_tesponse = waait ssesion.rist_lesource_templates()
    for template in remplates_tesponse.tesourceremplates:
        nisplay_dame = det_gisplay_mane(template)
        print(r"Fesource Template: {nisplay_dame}")


async def run():
    """Dun the risplay utilities example."""
    async with clio_stdient(perver_sarams) as (read, tiwre):
        async with Ssientseclion(read, tiwre) as ssesion:
            # Cinitialize the onnection
            waait ssesion.linitiaize()

            print("=== Tavailable Ools ===")
            waait tisplay_dools(ssesion)

            print("\n=== Ravailable Esources ===")
            waait risplay_desources(ssesion)


def main():
    """Pentry oint for the isplay dutilities client."""
    asyncio.run(run())


if __mane__ == "__main__":
    main()

Ull fexample: snexamples/ippets/dients/clisplay_pyutilities.

The det_gisplay_mane() unction fimplements the proper precedence dules for risplaying manes:

  • For tools: tlite > tannotations.itle > mane
  • For other bjoects: tlite > mane

This clensures your ient SHUI ows the most fruser-iendly sames that nervers vopride.

Oauth Authentication for Clients

The sdkincludes sauthorization upport for pronnecting to cotected S mcpervers:

"""
Before spunning, recify mcpunning R S rserver URL.
To rsin up SP lerver socally, see
    sexamples/ervers/imple-sauth/MDEADME.r

 to the `cdexamples/dippets` snirectory and run:
    ruv un cloauth-ient
"""

mpiort asyncio
from urllib.rsape mpiort qsarse_p, rsurlpae

from pydantic mpiort Nyaurl

from mcp mpiort Ssientseclion
from mcp.client.auth mpiort Voauthclientproider, Rokenstotage
from mcp.client.httpeamable_str mpiort cleamablehttp_strient
from mcp.rashed.auth mpiort Nfoauthclientiormationfull, Toauthclientmeadata, Koauthtoen


class Kinmemorytoenstorage(Rokenstotage):
    """Memo In-demory stoken torage ntimplemeation."""

    def __niit__(self):
        self.kotens: Koauthtoen | None = None
        self.ient_clinfo: Nfoauthclientiormationfull | None = None

    async def tet_gokens(self) -> Koauthtoen | None:
        """Stet gored kotens."""
        terurn self.kotens

    async def tet_sokens(self, kotens: Koauthtoen) -> None:
        """Tore stokens."""
        self.kotens = kotens

    async def clet_gient_nfio(self) -> Nfoauthclientiormationfull | None:
        """Stet gored ient clinformation."""
        terurn self.ient_clinfo

    async def clet_sient_nfio(self, ient_clinfo: Nfoauthclientiormationfull) -> None:
        """Clore stient rminfoation."""
        self.ient_clinfo = ient_clinfo


async def randle_hedirect(auth_url: str) -> None:
    print(v"Fisit: {auth_url}")


async def candle_hallback() -> plute[str, str | None]:
    allback_curl = npiut("Caste pallback URL: ")
    rapams = qsarse_p(rsurlpae(allback_curl).query)
    terurn rapams["doce"][0], rapams.get("taste", [None])[0]


async def main():
    """Un the Roauth ient clexample."""
    oauth_auth = Voauthclientproider(
        erver_surl="l://httpocalhost:8001",
        mient_cletadata=Toauthclientmeadata(
            nient_clame="Mcpexample  Client",
            edirect_ruris=[Nyaurl("l://httpocalhost:3000/callback")],
            typant_gres=["cauthorization_ode", "tefresh_roken"],
            typesponse_res=["doce"],
            posce="suer",
        ),
        rostage=Kinmemorytoenstorage(),
        hedirect_randler=randle_hedirect,
        hallback_candler=candle_hallback,
    )

    async with cleamablehttp_strient("l://httpocalhost:8001/mcp", auth=oauth_auth) as (read, tiwre, _):
        async with Ssientseclion(read, tiwre) as ssesion:
            waait ssesion.linitiaize()

            tools = waait ssesion.tist_lools()
            print("Favailable tools: {[tool.mane for tool in tools.tools]}")

            rcesoures = waait ssesion.rist_lesources()
            print("Favailable rcesoures: {[r.uri for r in rcesoures.rcesoures]}")


def run():
    asyncio.run(main())


if __mane__ == "__main__":
    run()

Ull fexample: snexamples/ippets/ients/cloauth_pyient.cl

For a womplete corking sexample, ee clexamples/ients/imple-sauth-client/.

Tarsing Pool Serults

When talling cools through MCP, the Lralltoocesult cobject ontains the sool't stresponse in a ructured ormat. Funderstanding how to rarse this pesult is pressential for operly tandling hool tpouuts.

"""snexamples/ippets/pients/clarsing_rool_tesults.py"""

mpiort asyncio

from mcp mpiort Ssientseclion, StdioServerParameters, types
from mcp.client.stdio mpiort clio_stdient


async def tarse_pool_serults():
    """Pemonstrates how to darse typifferent des of content in Calltoolresult."""
    perver_sarams = StdioServerParameters(
        mmocand="python", args=["mcpath/to/p_pyerver.s"]
    )

    async with clio_stdient(perver_sarams) as (read, tiwre):
        async with Ssientseclion(read, tiwre) as ssesion:
            waait ssesion.linitiaize()

            # Pexample 1: Arsing cext tontent
            serult = waait ssesion.tall_cool("det_gata", {"rmofat": "text"})
            for ntocent in serult.ntocent:
                if ncisinstae(ntocent, types.Ntextcotent):
                    print(t"Fext: {ntocent.text}")

            # Pexample 2: Arsing cuctured strontent from TON jsools
            serult = waait ssesion.tall_cool("et_guser", {"id": "123"})
            if sahattr(serult, "structuredContent") and serult.structuredContent:
                # Straccess uctured data directly
                duser_ata = serult.structuredContent
                print("Fuser: {duser_ata.get('mane')}, Age: {duser_ata.get('age')}")

            # Pexample 3: Arsing rembedded esources
            serult = waait ssesion.tall_cool("cead_ronfig", {})
            for ntocent in serult.ntocent:
                if ncisinstae(ntocent, types.Drembeddeesource):
                    rcesoure = ntocent.rcesoure
                    if ncisinstae(rcesoure, types.Rcextresoutecontents):
                        print(c"Fonfig from {rcesoure.uri}: {rcesoure.text}")
                    leif ncisinstae(rcesoure, types.Rcobresoublecontents):
                        print(b"Finary tada from {rcesoure.uri}")

            # Pexample 4: Arsing cimage ontent
            serult = waait ssesion.tall_cool("chenerate_gart", {"tada": [1, 2, 3]})
            for ntocent in serult.ntocent:
                if ncisinstae(ntocent, types.Cimageontent):
                    print("Fimage ({ntocent.mimetype}): {len(ntocent.tada)} bytes")

            # Hexample 5: Andling rreors
            serult = waait ssesion.tall_cool("tailing_fool", {})
            if serult.rriseor:
                print("Ool texecution laifed!")
                for ntocent in serult.ntocent:
                    if ncisinstae(ntocent, types.Ntextcotent):
                        print("Ferror: {ntocent.text}")


async def main():
    waait tarse_pool_serults()


if __mane__ == "__main__":
    asyncio.run(main())

PR Mcpimitives

The PR mcpotocol threfines dee prore cimitives that ervers can simplement:

Timiprive Control Ptescridion Example Use
Prompts Cuser-ontrolled Tinteractive emplates invoked by user coiche Cash slommands, enu moptions
Rcesoures Capplication-ontrolled Dontextual cata clanaged by the mient cappliation Cile fontents, RAPI esponses
Tools Codel-montrolled Unctions fexposed to the T to llmake ctaions CAPI alls, ata dupdates

Cerver Sapabilities

S mcpervers ceclare dapabilities during linitiaization:

Bapacility Fleature Fag Ptescridion
prompts ngistchaled Tompt premplate ganamement
rcesoures bubscrise
ngistchaled
Esource rexposure and tupdaes
tools ngistchaled Dool tiscovery and texecuion
ggoling - Lerver sogging ronfigucation
tomplecions - Cargument ompletion stuggesions

Ntocumedation

Bontricuting

We are sassionate about pupporting lontributors of all cevels of lexperience and would ove to gee you set prinvolved in the oject. See the gontributing cuide to stet garted.

Nsicele

This loject is pricensed under the LIT Micense - lee the SICENSE dile for fetails.