mirror of
https://github.com/aljazceru/mcp-python-sdk.git
synced 2025-12-19 14:54:24 +01:00
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
This commit is contained in:
committed by
GitHub
parent
dfbe56d2b2
commit
df2d3a57c2
@@ -652,9 +652,9 @@ class Context(BaseModel, Generic[ServerSessionT, LifespanContextT]):
|
|||||||
Returns:
|
Returns:
|
||||||
The resource content as either text or bytes
|
The resource content as either text or bytes
|
||||||
"""
|
"""
|
||||||
assert self._fastmcp is not None, (
|
assert (
|
||||||
"Context is not available outside of a request"
|
self._fastmcp is not None
|
||||||
)
|
), "Context is not available outside of a request"
|
||||||
return await self._fastmcp.read_resource(uri)
|
return await self._fastmcp.read_resource(uri)
|
||||||
|
|
||||||
async def log(
|
async def log(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from mcp.shared.session import BaseSession
|
|||||||
from mcp.types import RequestId, RequestParams
|
from mcp.types import RequestId, RequestParams
|
||||||
|
|
||||||
SessionT = TypeVar("SessionT", bound=BaseSession[Any, Any, Any, Any, Any])
|
SessionT = TypeVar("SessionT", bound=BaseSession[Any, Any, Any, Any, Any])
|
||||||
LifespanContextT = TypeVar("LifespanContextT", default=None)
|
LifespanContextT = TypeVar("LifespanContextT")
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from typing import Generic
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from mcp.shared.context import RequestContext
|
from mcp.shared.context import LifespanContextT, RequestContext
|
||||||
from mcp.shared.session import (
|
from mcp.shared.session import (
|
||||||
BaseSession,
|
BaseSession,
|
||||||
ReceiveNotificationT,
|
ReceiveNotificationT,
|
||||||
@@ -60,7 +60,8 @@ def progress(
|
|||||||
SendResultT,
|
SendResultT,
|
||||||
ReceiveRequestT,
|
ReceiveRequestT,
|
||||||
ReceiveNotificationT,
|
ReceiveNotificationT,
|
||||||
]
|
],
|
||||||
|
LifespanContextT,
|
||||||
],
|
],
|
||||||
total: float | None = None,
|
total: float | None = None,
|
||||||
) -> Generator[
|
) -> Generator[
|
||||||
|
|||||||
50
tests/issues/test_355_type_error.py
Normal file
50
tests/issues/test_355_type_error.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from collections.abc import AsyncIterator
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from mcp.server.fastmcp import Context, FastMCP
|
||||||
|
|
||||||
|
|
||||||
|
class Database: # Replace with your actual DB type
|
||||||
|
@classmethod
|
||||||
|
async def connect(cls):
|
||||||
|
return cls()
|
||||||
|
|
||||||
|
async def disconnect(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def query(self):
|
||||||
|
return "Hello, World!"
|
||||||
|
|
||||||
|
|
||||||
|
# Create a named server
|
||||||
|
mcp = FastMCP("My App")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AppContext:
|
||||||
|
db: Database
|
||||||
|
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
|
||||||
|
"""Manage application lifecycle with type-safe context"""
|
||||||
|
# Initialize on startup
|
||||||
|
db = await Database.connect()
|
||||||
|
try:
|
||||||
|
yield AppContext(db=db)
|
||||||
|
finally:
|
||||||
|
# Cleanup on shutdown
|
||||||
|
await db.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
# Pass lifespan to server
|
||||||
|
mcp = FastMCP("My App", lifespan=app_lifespan)
|
||||||
|
|
||||||
|
|
||||||
|
# Access type-safe lifespan context in tools
|
||||||
|
@mcp.tool()
|
||||||
|
def query_db(ctx: Context) -> str:
|
||||||
|
"""Tool that uses initialized resources"""
|
||||||
|
db = ctx.request_context.lifespan_context.db
|
||||||
|
return db.query()
|
||||||
Reference in New Issue
Block a user