docs: restructure into topical sections and add the four most-asked-for pages (#3044)
This commit is contained in:
parent
080f2a869d
commit
220d362112
9 changed files with 2403 additions and 343 deletions
0
docs_src/troubleshooting/__init__.py
Normal file
0
docs_src/troubleshooting/__init__.py
Normal file
22
docs_src/troubleshooting/tutorial001.py
Normal file
22
docs_src/troubleshooting/tutorial001.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from mcp.server import MCPServer
|
||||
from mcp.server.mcpserver.exceptions import ResourceNotFoundError
|
||||
|
||||
mcp = MCPServer("Weather")
|
||||
|
||||
FORECASTS = {"London": "Rain.", "Cairo": "Sun."}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def forecast(city: str) -> str:
|
||||
"""Today's forecast for one city."""
|
||||
if city not in FORECASTS:
|
||||
raise ValueError(f"No forecast for {city!r}.")
|
||||
return FORECASTS[city]
|
||||
|
||||
|
||||
@mcp.resource("weather://{city}")
|
||||
def report(city: str) -> str:
|
||||
"""The full report for one city."""
|
||||
if city not in FORECASTS:
|
||||
raise ResourceNotFoundError(f"No forecast for {city!r}.")
|
||||
return f"{city}: {FORECASTS[city]}"
|
||||
15
docs_src/troubleshooting/tutorial002.py
Normal file
15
docs_src/troubleshooting/tutorial002.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from mcp.server import MCPServer
|
||||
|
||||
mcp = MCPServer("Weather")
|
||||
|
||||
|
||||
@mcp.tool(name="forecast")
|
||||
def forecast_today(city: str) -> str:
|
||||
"""Today's forecast for one city."""
|
||||
return f"{city}: Rain."
|
||||
|
||||
|
||||
@mcp.tool(name="forecast") # Same name. This registration is dropped.
|
||||
def forecast_hourly(city: str, hours: int) -> str:
|
||||
"""The next few hours for one city."""
|
||||
return f"{city}: Rain for {hours}h."
|
||||
12
docs_src/troubleshooting/tutorial003.py
Normal file
12
docs_src/troubleshooting/tutorial003.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from mcp.server import MCPServer
|
||||
|
||||
mcp = MCPServer("Weather")
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def forecast(city: str) -> str:
|
||||
"""Today's forecast for one city."""
|
||||
return f"{city}: Rain."
|
||||
|
||||
|
||||
app = mcp.streamable_http_app()
|
||||
18
docs_src/troubleshooting/tutorial004.py
Normal file
18
docs_src/troubleshooting/tutorial004.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from mcp.server import MCPServer
|
||||
from mcp.server.transport_security import TransportSecuritySettings
|
||||
|
||||
mcp = MCPServer("Weather")
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def forecast(city: str) -> str:
|
||||
"""Today's forecast for one city."""
|
||||
return f"{city}: Rain."
|
||||
|
||||
|
||||
app = mcp.streamable_http_app(
|
||||
transport_security=TransportSecuritySettings(
|
||||
allowed_hosts=["mcp.example.com", "mcp.example.com:*"],
|
||||
allowed_origins=["https://app.example.com"],
|
||||
)
|
||||
)
|
||||
16
docs_src/troubleshooting/tutorial005.py
Normal file
16
docs_src/troubleshooting/tutorial005.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from starlette.applications import Starlette
|
||||
from starlette.routing import Mount
|
||||
|
||||
from mcp.server import MCPServer
|
||||
|
||||
mcp = MCPServer("Weather")
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def forecast(city: str) -> str:
|
||||
"""Today's forecast for one city."""
|
||||
return f"{city}: Rain."
|
||||
|
||||
|
||||
# The mount works. The MCP app's own lifespan never runs.
|
||||
app = Starlette(routes=[Mount("/", app=mcp.streamable_http_app())])
|
||||
19
docs_src/troubleshooting/tutorial006.py
Normal file
19
docs_src/troubleshooting/tutorial006.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
from mcp.server import MCPServer
|
||||
from mcp.server.mcpserver import Context
|
||||
|
||||
mcp = MCPServer("Bistro")
|
||||
|
||||
|
||||
class Confirmation(BaseModel):
|
||||
confirm: bool
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def book_table(date: str, ctx: Context) -> str:
|
||||
"""Book a table at the bistro."""
|
||||
result = await ctx.elicit(f"Book a table for {date}?", schema=Confirmation)
|
||||
if result.action == "accept" and result.data.confirm:
|
||||
return f"Booked for {date}."
|
||||
return "No booking made."
|
||||
25
docs_src/troubleshooting/tutorial007.py
Normal file
25
docs_src/troubleshooting/tutorial007.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
from typing import Annotated
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from mcp.server import MCPServer
|
||||
from mcp.server.mcpserver import Elicit, Resolve
|
||||
|
||||
mcp = MCPServer("Bistro")
|
||||
|
||||
|
||||
class Confirmation(BaseModel):
|
||||
confirm: bool
|
||||
|
||||
|
||||
async def ask_to_confirm(date: str) -> Elicit[Confirmation]:
|
||||
"""Resolver: ask the user to confirm the booking."""
|
||||
return Elicit(f"Book a table for {date}?", Confirmation)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def book_table(date: str, answer: Annotated[Confirmation, Resolve(ask_to_confirm)]) -> str:
|
||||
"""Book a table at the bistro."""
|
||||
if answer.confirm:
|
||||
return f"Booked for {date}."
|
||||
return "No booking made."
|
||||
23
docs_src/troubleshooting/tutorial008.py
Normal file
23
docs_src/troubleshooting/tutorial008.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
from mcp.server import MCPServer
|
||||
from mcp.server.mcpserver import Context
|
||||
|
||||
mcp = MCPServer("Bistro")
|
||||
|
||||
|
||||
class Confirmation(BaseModel):
|
||||
confirm: bool
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def book_table(date: str, ctx: Context) -> str:
|
||||
"""Book a table at the bistro."""
|
||||
result = await ctx.elicit(f"Book a table for {date}?", schema=Confirmation)
|
||||
if result.action == "accept" and result.data.confirm:
|
||||
return f"Booked for {date}."
|
||||
return "No booking made."
|
||||
|
||||
|
||||
# Stateless HTTP: every request is its own world. No channel back to the client.
|
||||
app = mcp.streamable_http_app(stateless_http=True)
|
||||
Loading…
Reference in a new issue