add server and context

This commit is contained in:
Jeremiah Lowin 2025-04-05 17:40:28 -04:00
commit 9a4eb1a1c9
6 changed files with 101 additions and 36 deletions

View file

@ -1,7 +1,10 @@
"""FastMCP - A more ergonomic interface for MCP servers."""
"""FastMCP - An ergonomic MCP interface."""
from importlib.metadata import version
from mcp.server.fastmcp import FastMCP, Context, Image
from fastmcp.server import FastMCP, Context
__version__ = version("fastmcp")
__all__ = ["FastMCP", "Context", "Image"]
__all__ = [
"FastMCP",
"Context",
]

View file

@ -1,11 +0,0 @@
from typing import Any
import mcp.server.fastmcp
from fastmcp.utilities.logging import get_logger
logger = get_logger(__name__)
class FastMCP(mcp.server.fastmcp.FastMCP):
def __init__(self, name: str | None = None, **settings: Any):
super().__init__(name=name or "FastMCP", **settings)

View file

@ -0,0 +1,5 @@
from .server import FastMCP
from .context import Context
__all__ = ["FastMCP", "Context"]

View file

@ -0,0 +1,60 @@
from typing import Any
import mcp.server.fastmcp
from mcp.server.fastmcp.utilities.logging import get_logger
from mcp.server.session import ServerSessionT
from mcp.shared.context import LifespanContextT, RequestContext
from mcp.types import (
CreateMessageResult,
ImageContent,
SamplingMessage,
TextContent,
)
logger = get_logger(__name__)
class Context(mcp.server.fastmcp.Context[ServerSessionT, LifespanContextT]):
def __init__(
self,
*,
request_context: RequestContext[ServerSessionT, LifespanContextT] | None = None,
fastmcp: mcp.server.fastmcp.FastMCP | None = None,
**kwargs: Any,
):
super().__init__(request_context=request_context, fastmcp=fastmcp, **kwargs)
async def sample(
self,
message: str,
system_prompt: str | None = None,
temperature: float | None = None,
max_tokens: int | None = None,
) -> TextContent | ImageContent:
"""
Send a sampling request to the client and await the response.
Call this method at any time to have the server request an LLM
completion from the client. The client must be appropriately configured,
or the request will error.
"""
if max_tokens is None:
max_tokens = 512
assert self._request_context is not None
assert self._request_context.session is not None
sampling_message = SamplingMessage(
content=TextContent(text=message, type="text"),
role="user",
)
result: CreateMessageResult = await self.request_context.session.create_message(
messages=[sampling_message],
system_prompt=system_prompt,
temperature=temperature,
max_tokens=max_tokens,
)
return result.content

View file

@ -0,0 +1,24 @@
from typing import Any
import mcp.server.fastmcp
from fastmcp.server.context import Context
from fastmcp.utilities.logging import get_logger
logger = get_logger(__name__)
class FastMCP(mcp.server.fastmcp.FastMCP):
def __init__(self, name: str | None = None, **settings: Any):
super().__init__(name=name or "FastMCP", **settings)
def get_context(self) -> Context:
"""
Returns a Context object. Note that the context will only be valid
during a request; outside a request, most methods will error.
"""
try:
request_context = self._mcp_server.request_context
except LookupError:
request_context = None
return Context(request_context=request_context, fastmcp=self)

View file

@ -1,8 +1,8 @@
from pydantic import Field
from typing import Literal
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import Literal
LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
class Settings(BaseSettings):
@ -18,24 +18,8 @@ class Settings(BaseSettings):
extra="ignore",
)
# Server settings
debug: bool = False
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"
log_level: LOG_LEVEL = "INFO"
# HTTP settings
host: str = "0.0.0.0"
port: int = 8000
# resource settings
warn_on_duplicate_resources: bool = True
# tool settings
warn_on_duplicate_tools: bool = True
# prompt settings
warn_on_duplicate_prompts: bool = True
dependencies: list[str] = Field(
default_factory=list,
description="List of dependencies to install in the server environment",
)
# Client settings
client_log_level: LOG_LEVEL | None = None