python-sdk/examples/stories at main · modelcontextprotocol/python-sdk · GitHub
https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/stories • 376 KB fetched
Open original page
python-sdk/examples/stories at main · modelcontextprotocol/python-sdk · GitHub
Skip to content
Navigation Menu
Sign in Appearance settings
* Platform
* AI CODE CREATION
* GitHub Copilot Write better code with AI
* GitHub Copilot app Direct agents from issue to merge
* MCP Registry Integrate external tools
* DEVELOPER WORKFLOWS
* Actions Automate any workflow
* Codespaces Instant dev environments
* Issues Plan and track work
* Code Review Manage code changes
* Code Quality Enforce quality at merge
* APPLICATION SECURITY
* GitHub Advanced Security Find and fix vulnerabilities
* Code security Secure your code as you build
* Secret protection Stop leaks before they start
* EXPLORE
* Why GitHub
* Documentation
* Blog
* Changelog
* Marketplace
View all features
* Solutions
* BY COMPANY SIZE
* Enterprises
* Small and medium teams
* Startups
* Nonprofits
* BY USE CASE
* App Modernization
* DevSecOps
* DevOps
* CI/CD
* View all use cases
* BY INDUSTRY
* Healthcare
* Financial services
* Manufacturing
* Government
* View all industries
View all solutions
* Resources
* EXPLORE BY TOPIC
* AI
* Software Development
* DevOps
* Security
* View all topics
* EXPLORE BY TYPE
* Customer stories
* Events & webinars
* Ebooks & reports
* Business insights
* GitHub Skills
* SUPPORT & SERVICES
* Documentation
* Customer support
* Community forum
* Trust center
* Partners
View all resources
* Open Source
* COMMUNITY
* GitHub Sponsors Fund open source developers
* PROGRAMS
* Security Lab
* Maintainer Community
* GitHub Stars
* Archive Program
* REPOSITORIES
* Topics
* Trending
* Collections
* Enterprise
* ENTERPRISE SOLUTIONS
* Enterprise platform AI-powered developer platform
* AVAILABLE ADD-ONS
* GitHub Advanced Security Enterprise-grade security features
* Copilot for Business Enterprise-grade AI features
* Premium Support Enterprise-grade 24/7 support
* Pricing
Search /
Sign in
Sign up Appearance settings
You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
Uh oh!
There was an error while loading. Please reload this page .
modelcontextprotocol
/
python-sdk
Public
*
Notifications
You must be signed in to change notification settings
*
Fork
3.9k
*
Star
24.3k
*
Code
*
Issues
229
*
Pull requests
184
*
Actions
*
Projects
*
Security and quality
6
*
Insights
Additional navigation options
*
Code
*
Issues
*
Pull requests
*
Actions
*
Projects
*
Security and quality
*
Insights
Files Expand file tree
main
Breadcrumbs
* python-sdk
* / examples
/ stories
/
Copy path
Directory actions
More options
More options
Directory actions
More options
More options
Latest commit
History
History
History
main
Breadcrumbs
* python-sdk
* / examples
/ stories
/
Copy path
Top
Folders and files
Name Name Last commit message
Last commit date
parent directory
..
_shared
_shared
apps
apps
bearer_auth
bearer_auth
caching
caching
custom_methods
custom_methods
dual_era
dual_era
error_handling
error_handling
events
events
extensions
extensions
identity_assertion
identity_assertion
json_response
json_response
legacy_elicitation
legacy_elicitation
legacy_routing
legacy_routing
lifespan
lifespan
middleware
middleware
mrtr
mrtr
oauth
oauth
oauth_client_credentials
oauth_client_credentials
pagination
pagination
parallel_calls
parallel_calls
prompts
prompts
reconnect
reconnect
refund_desk
refund_desk
resources
resources
roots
roots
sampling
sampling
schema_validators
schema_validators
serve_one
serve_one
skills
skills
sse_polling
sse_polling
standalone_get
standalone_get
starlette_mount
starlette_mount
stateless_legacy
stateless_legacy
stickynotes
stickynotes
streaming
streaming
subscriptions
subscriptions
tasks
tasks
tools
tools
README.md
README.md
__init__.py
__init__.py
_harness.py
_harness.py
_hosting.py
_hosting.py
manifest.toml
manifest.toml
View all files
README.md
Outline
Story examples
One feature per folder. Each story is a small, self-verifying program: a
server.py (plus, where the wire contract is worth seeing by hand, a
server_lowlevel.py ) and a client.py whose main() makes assertions and
exits non-zero on failure. The code you read here is the same code CI runs —
there is no separate test double.
Canonical shape
Every client.py starts from this skeleton — copy it, then replace the body
with the story's assertions:
"""One line: what this client proves."""
from mcp . client import Client
from stories . _harness import Target , run_client
async def main ( target : Target , * , mode : str = "auto" ) -> None :
async with Client ( target , mode = mode ) as client :
... # the story's assertions
if __name__ == "__main__" :
run_client ( main )
There are exactly two main shapes. A story that opens one connection
takes main(target: Target, ...) . A story that opens more than one sets
multi_connection = true in manifest.toml , takes
main(targets: TargetFactory, ...) , and calls targets() once per fresh
connection — a Client cannot be re-entered after exit. Nothing else changes
shape.
Story files import from stories._harness only these names: run_client ,
target_from_args , Target , TargetFactory — plus AuthBuilder for the
auth stories. Everything else a story uses comes from public mcp.* modules.
The repetition this produces across stories is deliberate, not a refactor
waiting to happen: each client.py is a standalone, compiled doc page, so
when a public API changes, N red example files flag N doc pages. Don't pull
the Client(target, mode=mode) line (or anything around it) into a shared
helper. A story that can't be the canonical shape says why in its module
docstring's first line.
How to read a story
Start with the story's README, then server.py , then client.py . Every
client.py exports async def main(target, *, mode="auto") — or
main(targets, ...) for the stories that open more than one connection — and
constructs the Client itself, so the body opens with the one line a client
example exists to teach: async with Client(target, mode=mode) as client: .
The run_client(main) call in the __main__ block is only argv plumbing
(stdio vs --http , which mode to pass); it never hides how the client
connects.
Running a story
From the repository root:
# stdio (default — the client spawns the server as a subprocess)
uv run python -m stories.tools.client
# HTTP, self-hosted — the client spawns the server on a real uvicorn socket on a
# port it owns, waits for it, runs, then terminates it. Nothing to background or kill.
uv run python -m stories.tools.client --http
# the same self-hosted run against the story's lowlevel-API server variant
uv run python -m stories.tools.client --http --server server_lowlevel
# HTTP against a server you run yourself
uv run python -m stories.tools.server --http --port 8000 # separate terminal
uv run python -m stories.tools.client --http http://127.0.0.1:8000/mcp
--http takes two forms. Bare --http is the canonical HTTP run — it is
complete on its own, and it is what every per-story README shows. --http <url> connects to a server you started yourself; the per-story READMEs spell
that out only where hosting is the lesson (the HTTP-hosting and auth stories).
--server <stem> swaps in a sibling server module on stdio and on the
self-hosted --http run; with --http <url> you already picked the server
when you started it. The auth stories ( bearer_auth/ , oauth/ ,
oauth_client_credentials/ ) self-host on their fixed :8000 instead of a
free port because their issuer/PRM metadata bake it in — :8000 must be
free, and the run refuses to start (rather than silently testing whatever is
there) if it is not.
The full matrix (every story × transport × era × server-variant) runs under
pytest:
uv run --frozen pytest tests/examples/ # everything
uv run --frozen pytest tests/examples/ -k tools # one story
manifest.toml declares each story's transports, era, status,
and variants; tests/examples/ expands it.
Layout
_hosting.py adapts a story's build_server() / build_app() to argv (stdio
vs --http serving); _harness.py is the client-side mirror — it picks the
target that main() connects to (a stdio subprocess by default, a self-hosted
HTTP subprocess under bare --http , your URL under --http <url> ). They
isolate the parts of the SDK's hosting surface
that are still moving — don't copy them into your own project ; copy the
server.py / client.py bodies instead. _shared/ holds an in-process OAuth
authorization server reused by the auth stories.
Stories
The status column is the feature's standing in the protocol, from
manifest.toml : current , legacy (a 2025 handshake-era
mechanism with a 2026-era replacement), or deprecated (deprecated by
SEP-2577; functional through the deprecation window). Each non- current story's README
opens with a banner saying what replaces it.
story
what it shows
status
— start here —
tools
@mcp.tool() , schema inference, structured output, annotations
current
prompts
@mcp.prompt() , list/get, argument completion
current
resources
@mcp.resource() , list/read, URI templates
current
lifespan
startup/shutdown lifespan, per-request state injection
current
dual_era
one server factory serving both protocol eras; era-neutral accessors
current
— feature stories —
streaming
progress notifications, in-flight logging, cancellation
current
mrtr
InputRequiredResult round-trip: the Client auto-loop, a manual session-level loop, and the default requestState sealing (a tampered echo gets one frozen error)
current
legacy_elicitation
server pauses a tool to ask the user (form + url) via a push request
legacy
refund_desk
resolver DI: Annotated[T, Resolve(fn)] params filled server-side, hidden from the input schema
current
sampling
server asks the client's LLM mid-tool (push request)
deprecated
stickynotes
capstone: tools mutate state → resources + list_changed + elicit guard
current
custom_methods
vendor-prefixed JSON-RPC via add_request_handler / send_request
current
schema_validators
tool input schema from pydantic / TypedDict / dataclass / dict
current
middleware
server-side request/response middleware
current
parallel_calls
two clients rendezvous in one tool; per-call progress attribution
current
roots
client-declared roots, server reads them via ctx
deprecated
pagination
manual cursor loop over list endpoints
current
error_handling
is_error results vs MCPError ; ToolError
current
serve_one
building a Connection by hand and calling serve_one directly
current
— HTTP hosting —
stateless_legacy
streamable_http_app(stateless_http=True) ; the one-liner deploy
current
json_response
json_response=True mode; raw 2026 POST envelope on the wire
current
legacy_routing
classify_inbound_request() era routing in front of a sessionful 1.x deploy
current
starlette_mount
mounting streamable_http_app() under a Starlette/FastAPI sub-path
current
sse_polling
SEP-1699 closeSSE() + Last-Event-ID resume via EventStore
legacy
standalone_get
server-initiated list_changed over the sessionful GET stream
legacy
subscriptions
subscriptions/listen streams: ctx.notify_* , SubscriptionBus , ListenHandler
current
reconnect
explicit discover() , persist DiscoverResult , zero-RTT reconnect
current
bearer_auth
TokenVerifier + AuthSettings bearer gate, PRM metadata, get_access_token()
current
oauth
full authorization_code grant against an in-process AS
current
oauth_client_credentials
client_credentials grant; minimal in-process token endpoint
current
identity_assertion
SEP-990 enterprise IdP flow: present an ID-JAG under the jwt-bearer grant
current
— deferred (README only) —
caching
CacheableResult ttl/scope hints; client honouring
not yet implemented
tasks
io.modelcontextprotocol/tasks extension
not yet implemented
apps
MCP Apps: ui:// resource + _meta.ui
not yet implemented — #2896
skills
SEP-2640 skills extension
not yet implemented — #2896
events
io.modelcontextprotocol/events extension
not yet implemented
The TypeScript SDK's repl , client-quickstart , and server-quickstart
examples are intentionally not ported (interactive / external network deps);
its hono example maps to starlette_mount/ .
Footer
(c) 2026 GitHub, Inc.
Footer navigation
*
Terms
*
Privacy
*
Security
*
Status
*
Community
*
Docs
*
Contact
*
Manage cookies
*
Do not share my personal information
You can’t perform that action at this time.
Links found on this page
- Skip to content [direct]
- Sign in [direct]
- GitHub Copilot Write better code with AI [direct]
- GitHub Copilot app Direct agents from issue to merge [direct]
- MCP Registry Integrate external tools [direct]
- Actions Automate any workflow [direct]
- Codespaces Instant dev environments [direct]
- Issues Plan and track work [direct]
- Code Review Manage code changes [direct]
- Code Quality Enforce quality at merge [direct]
- GitHub Advanced Security Find and fix vulnerabilities [direct]
- Code security Secure your code as you build [direct]
- Secret protection Stop leaks before they start [direct]
- Why GitHub [direct]
- Documentation [direct]
- Blog [direct]
- Changelog [direct]
- Marketplace [direct]
- View all features [direct]
- Enterprises [direct]
- Small and medium teams [direct]
- Startups [direct]
- Nonprofits [direct]
- App Modernization [direct]
- DevSecOps [direct]
- DevOps [direct]
- CI/CD [direct]
- View all use cases [direct]
- Healthcare [direct]
- Financial services [direct]
- Manufacturing [direct]
- Government [direct]
- View all industries [direct]
- View all solutions [direct]
- AI [direct]
- Software Development [direct]
- DevOps [direct]
- Security [direct]
- View all topics [direct]
- Customer stories [direct]
- Events & webinars [direct]
- Ebooks & reports [direct]
- Business insights [direct]
- GitHub Skills [direct]
- Customer support [direct]
- Community forum [direct]
- Trust center [direct]
- Partners [direct]
- View all resources [direct]
- GitHub Sponsors Fund open source developers [direct]
- Security Lab [direct]
- Maintainer Community [direct]
- GitHub Stars [direct]
- Archive Program [direct]
- Topics [direct]
- Trending [direct]
- Collections [direct]
- Copilot for Business Enterprise-grade AI features [direct]
- Premium Support Enterprise-grade 24/7 support [direct]
- Pricing [direct]
- Sign up [direct]
- modelcontextprotocol [direct]
- python-sdk [direct]
- Notifications [direct]
- Issues
229 [direct]
- Pull requests
184 [direct]
- Actions [direct]
- Projects [direct]
- Security and quality
6 [direct]
- Insights [direct]
- python-sdk [direct]
- examples [direct]
- History [direct]
- _shared [direct]
- apps [direct]
- bearer_auth [direct]
- caching [direct]
- custom_methods [direct]
- dual_era [direct]
- error_handling [direct]