Embed code snippets for README from executable examples (#1055)

This commit is contained in:
Inna Harper 2025-07-04 17:25:54 +01:00 • committed by GitHub
commit adf327164a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1139 additions and 1131 deletions

View file

@ -20,6 +20,6 @@ def desktop() -> list[str]:
@mcp.tool()
def add(a: int, b: int) -> int:
def sum(a: int, b: int) -> int:
"""Add two numbers"""
return a + b

View file

@ -6,7 +6,7 @@ mcp = FastMCP("Demo")
# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
def sum(a: int, b: int) -> int:
"""Add two numbers"""
return a + b

View file

@ -90,7 +90,7 @@ def get_weather_alerts(region: str) -> list[WeatherAlert]:
WeatherAlert(
severity="high",
title="Heat Wave Warning",
description="Temperatures expected to exceed 40°C",
description="Temperatures expected to exceed 40 degrees",
affected_areas=["Los Angeles", "San Diego", "Riverside"],
valid_until=datetime(2024, 7, 15, 18, 0),
),

View file

@ -0,0 +1,18 @@
[project]
name = "mcp-snippets"
version = "0.1.0"
description = "MCP Example Snippets"
requires-python = ">=3.10"
dependencies = [
"mcp",
]
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
packages = ["servers"]
[project.scripts]
server = "servers:run_server"

View file

@ -0,0 +1,36 @@
"""MCP Snippets.
This package contains simple examples of MCP server features.
Each server demonstrates a single feature and can be run as a standalone server.
To run a server, use the command:
uv run server basic_tool sse
"""
import importlib
import sys
from typing import Literal, cast
def run_server():
"""Run a server by name with optional transport.
Usage: server <server-name> [transport]
Example: server basic_tool sse
"""
if len(sys.argv) < 2:
print("Usage: server <server-name> [transport]")
print("Available servers: basic_tool, basic_resource, basic_prompt, tool_progress,")
print(" sampling, elicitation, completion, notifications")
print("Available transports: stdio (default), sse, streamable-http")
sys.exit(1)
server_name = sys.argv[1]
transport = sys.argv[2] if len(sys.argv) > 2 else "stdio"
try:
module = importlib.import_module(f".{server_name}", package=__name__)
module.mcp.run(cast(Literal["stdio", "sse", "streamable-http"], transport))
except ImportError:
print(f"Error: Server '{server_name}' not found")
sys.exit(1)

View file

@ -0,0 +1,18 @@
from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.prompts import base
mcp = FastMCP(name="Prompt Example")
@mcp.prompt(title="Code Review")
def review_code(code: str) -> str:
return f"Please review this code:\n\n{code}"
@mcp.prompt(title="Debug Assistant")
def debug_error(error: str) -> list[base.Message]:
return [
base.UserMessage("I'm seeing this error:"),
base.UserMessage(error),
base.AssistantMessage("I'll help debug that. What have you tried so far?"),
]

View file

@ -0,0 +1,20 @@
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(name="Resource Example")
@mcp.resource("file://documents/{name}")
def read_document(name: str) -> str:
"""Read a document by name."""
# This would normally read from disk
return f"Content of {name}"
@mcp.resource("config://settings")
def get_settings() -> str:
"""Get application settings."""
return """{
"theme": "dark",
"language": "en",
"debug": false
}"""

View file

@ -0,0 +1,16 @@
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(name="Tool Example")
@mcp.tool()
def sum(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
@mcp.tool()
def get_weather(city: str, unit: str = "celsius") -> str:
"""Get weather for a city."""
# This would normally call a weather API
return f"Weather in {city}: 22degrees{unit[0].upper()}"

View file

@ -0,0 +1,49 @@
from mcp.server.fastmcp import FastMCP
from mcp.types import (
Completion,
CompletionArgument,
CompletionContext,
PromptReference,
ResourceTemplateReference,
)
mcp = FastMCP(name="Example")
@mcp.resource("github://repos/{owner}/{repo}")
def github_repo(owner: str, repo: str) -> str:
"""GitHub repository resource."""
return f"Repository: {owner}/{repo}"
@mcp.prompt(description="Code review prompt")
def review_code(language: str, code: str) -> str:
"""Generate a code review."""
return f"Review this {language} code:\n{code}"
@mcp.completion()
async def handle_completion(
ref: PromptReference | ResourceTemplateReference,
argument: CompletionArgument,
context: CompletionContext | None,
) -> Completion | None:
"""Provide completions for prompts and resources."""
# Complete programming languages for the prompt
if isinstance(ref, PromptReference):
if ref.name == "review_code" and argument.name == "language":
languages = ["python", "javascript", "typescript", "go", "rust"]
return Completion(
values=[lang for lang in languages if lang.startswith(argument.value)],
hasMore=False,
)
# Complete repository names for GitHub resources
if isinstance(ref, ResourceTemplateReference):
if ref.uri == "github://repos/{owner}/{repo}" and argument.name == "repo":
if context and context.arguments and context.arguments.get("owner") == "modelcontextprotocol":
repos = ["python-sdk", "typescript-sdk", "specification"]
return Completion(values=repos, hasMore=False)
return None

View file

@ -0,0 +1,41 @@
from pydantic import BaseModel, Field
from mcp.server.fastmcp import Context, FastMCP
mcp = FastMCP(name="Elicitation Example")
class BookingPreferences(BaseModel):
"""Schema for collecting user preferences."""
checkAlternative: bool = Field(description="Would you like to check another date?")
alternativeDate: str = Field(
default="2024-12-26",
description="Alternative date (YYYY-MM-DD)",
)
@mcp.tool()
async def book_table(
date: str,
time: str,
party_size: int,
ctx: Context,
) -> str:
"""Book a table with date availability check."""
# Check if date is available
if date == "2024-12-25":
# Date unavailable - ask user for alternative
result = await ctx.elicit(
message=(f"No tables available for {party_size} on {date}. Would you like to try another date?"),
schema=BookingPreferences,
)
if result.action == "accept" and result.data:
if result.data.checkAlternative:
return f"[SUCCESS] Booked for {result.data.alternativeDate}"
return "[CANCELLED] No booking made"
return "[CANCELLED] Booking cancelled"
# Date available
return f"[SUCCESS] Booked for {date} at {time}"

View file

@ -0,0 +1,18 @@
from mcp.server.fastmcp import Context, FastMCP
mcp = FastMCP(name="Notifications Example")
@mcp.tool()
async def process_data(data: str, ctx: Context) -> str:
"""Process data with logging."""
# Different log levels
await ctx.debug(f"Debug: Processing '{data}'")
await ctx.info("Info: Starting processing")
await ctx.warning("Warning: This is experimental")
await ctx.error("Error: (This is just a demo)")
# Notify about resource changes
await ctx.session.send_resource_list_changed()
return f"Processed: {data}"

View file

@ -0,0 +1,24 @@
from mcp.server.fastmcp import Context, FastMCP
from mcp.types import SamplingMessage, TextContent
mcp = FastMCP(name="Sampling Example")
@mcp.tool()
async def generate_poem(topic: str, ctx: Context) -> str:
"""Generate a poem using LLM sampling."""
prompt = f"Write a short poem about {topic}"
result = await ctx.session.create_message(
messages=[
SamplingMessage(
role="user",
content=TextContent(type="text", text=prompt),
)
],
max_tokens=100,
)
if result.content.type == "text":
return result.content.text
return str(result.content)

View file

@ -0,0 +1,20 @@
from mcp.server.fastmcp import Context, FastMCP
mcp = FastMCP(name="Progress Example")
@mcp.tool()
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
"""Execute a task with progress updates."""
await ctx.info(f"Starting: {task_name}")
for i in range(steps):
progress = (i + 1) / steps
await ctx.report_progress(
progress=progress,
total=1.0,
message=f"Step {i + 1}/{steps}",
)
await ctx.debug(f"Completed step {i + 1}")
return f"Task '{task_name}' completed"