Skip to content

Commit f139513

Browse files
committed
Merge branch 'main' into lifespan_ctx_readme
2 parents 86f363f + b2d4322 commit f139513

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1858
-316
lines changed

.pre-commit-config.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ repos:
77
- id: prettier
88
types_or: [yaml, json5]
99

10+
- repo: https://github.com/igorshubovych/markdownlint-cli
11+
rev: v0.45.0
12+
hooks:
13+
- id: markdownlint
14+
args:
15+
[
16+
"--fix",
17+
"--config",
18+
"pyproject.toml",
19+
"--configPointer",
20+
"/tool/markdown/lint",
21+
]
22+
types: [markdown]
23+
1024
- repo: local
1125
hooks:
1226
- id: ruff-format
@@ -27,7 +41,6 @@ repos:
2741
- id: pyright
2842
name: pyright
2943
entry: uv run pyright
30-
args: [src]
3144
language: system
3245
types: [python]
3346
pass_filenames: false

CLAUDE.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This document contains critical information about working with this codebase. Fo
1616
- Public APIs must have docstrings
1717
- Functions must be focused and small
1818
- Follow existing patterns exactly
19-
- Line length: 88 chars maximum
19+
- Line length: 120 chars maximum
2020

2121
3. Testing Requirements
2222
- Framework: `uv run --frozen pytest`
@@ -26,15 +26,19 @@ This document contains critical information about working with this codebase. Fo
2626
- Bug fixes require regression tests
2727

2828
- For commits fixing bugs or adding features based on user reports add:
29+
2930
```bash
3031
git commit --trailer "Reported-by:<name>"
3132
```
33+
3234
Where `<name>` is the name of the user.
3335

3436
- For commits related to a Github issue, add
37+
3538
```bash
3639
git commit --trailer "Github-Issue:#<number>"
3740
```
41+
3842
- NEVER ever mention a `co-authored-by` or similar aspects. In particular, never
3943
mention the tool used to create the commit message or PR.
4044

@@ -116,3 +120,15 @@ This document contains critical information about working with this codebase. Fo
116120
- Follow existing patterns
117121
- Document public APIs
118122
- Test thoroughly
123+
124+
## Exception Handling
125+
126+
- **Always use `logger.exception()` instead of `logger.error()` when catching exceptions**
127+
- Don't include the exception in the message: `logger.exception("Failed")` not `logger.exception(f"Failed: {e}")`
128+
- **Catch specific exceptions** where possible:
129+
- File ops: `except (OSError, PermissionError):`
130+
- JSON: `except json.JSONDecodeError:`
131+
- Network: `except (ConnectionError, TimeoutError):`
132+
- **Only catch `Exception` for**:
133+
- Top-level handlers that must not crash
134+
- Cleanup blocks (log at debug level)

CODE_OF_CONDUCT.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ representative at an online or offline event.
6060

6161
Instances of abusive, harassing, or otherwise unacceptable behavior may be
6262
reported to the community leaders responsible for enforcement at
63-
mcp-coc@anthropic.com.
63+
<mcp-coc@anthropic.com>.
6464
All complaints will be reviewed and investigated promptly and fairly.
6565

6666
All community leaders are obligated to respect the privacy and security of the
@@ -116,13 +116,13 @@ the community.
116116

117117
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118118
version 2.0, available at
119-
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
119+
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
120120

121121
Community Impact Guidelines were inspired by [Mozilla's code of conduct
122122
enforcement ladder](https://github.com/mozilla/diversity).
123123

124124
[homepage]: https://www.contributor-covenant.org
125125

126126
For answers to common questions about this code of conduct, see the FAQ at
127-
https://www.contributor-covenant.org/faq. Translations are available at
128-
https://www.contributor-covenant.org/translations.
127+
<https://www.contributor-covenant.org/faq>. Translations are available at
128+
<https://www.contributor-covenant.org/translations>.

CONTRIBUTING.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Thank you for your interest in contributing to the MCP Python SDK! This document
99
3. Fork the repository
1010
4. Clone your fork: `git clone https://github.com/YOUR-USERNAME/python-sdk.git`
1111
5. Install dependencies:
12+
1213
```bash
1314
uv sync --frozen --all-extras --dev
1415
```
@@ -25,22 +26,26 @@ uv sync --frozen --all-extras --dev
2526
3. Make your changes
2627

2728
4. Ensure tests pass:
28-
```bash
29+
30+
```bash
2931
uv run pytest
3032
```
3133

3234
5. Run type checking:
35+
3336
```bash
3437
uv run pyright
3538
```
3639

3740
6. Run linting:
41+
3842
```bash
3943
uv run ruff check .
4044
uv run ruff format .
4145
```
4246

4347
7. Update README snippets if you modified example code:
48+
4449
```bash
4550
uv run scripts/update_readme_snippets.py
4651
```

README.md

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ If you haven't created a uv-managed project yet, create one:
9595
```
9696

9797
Alternatively, for projects using pip for dependencies:
98+
9899
```bash
99100
pip install "mcp[cli]"
100101
```
@@ -134,11 +135,13 @@ def get_greeting(name: str) -> str:
134135
```
135136

136137
You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
138+
137139
```bash
138140
uv run mcp install server.py
139141
```
140142

141143
Alternatively, you can test it with the MCP Inspector:
144+
142145
```bash
143146
uv run mcp dev server.py
144147
```
@@ -232,6 +235,7 @@ def get_settings() -> str:
232235
"debug": false
233236
}"""
234237
```
238+
235239
_Full example: [examples/snippets/servers/basic_resource.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_resource.py)_
236240
<!-- /snippet-source -->
237241

@@ -258,15 +262,17 @@ def get_weather(city: str, unit: str = "celsius") -> str:
258262
# This would normally call a weather API
259263
return f"Weather in {city}: 22degrees{unit[0].upper()}"
260264
```
265+
261266
_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_
262267
<!-- /snippet-source -->
263268

264269
#### Structured Output
265270

266271
Tools will return structured results by default, if their return type
267-
annotation is compatible. Otherwise, they will return unstructured results.
272+
annotation is compatible. Otherwise, they will return unstructured results.
268273

269274
Structured output supports these return types:
275+
270276
- Pydantic models (BaseModel subclasses)
271277
- TypedDicts
272278
- Dataclasses and other classes with type hints
@@ -278,17 +284,17 @@ Classes without type hints cannot be serialized for structured output. Only
278284
classes with properly annotated attributes will be converted to Pydantic models
279285
for schema generation and validation.
280286

281-
Structured results are automatically validated against the output schema
282-
generated from the annotation. This ensures the tool returns well-typed,
287+
Structured results are automatically validated against the output schema
288+
generated from the annotation. This ensures the tool returns well-typed,
283289
validated data that clients can easily process.
284290

285291
**Note:** For backward compatibility, unstructured results are also
286-
returned. Unstructured results are provided for backward compatibility
292+
returned. Unstructured results are provided for backward compatibility
287293
with previous versions of the MCP specification, and are quirks-compatible
288294
with previous versions of FastMCP in the current version of the SDK.
289295

290-
**Note:** In cases where a tool function's return type annotation
291-
causes the tool to be classified as structured _and this is undesirable_,
296+
**Note:** In cases where a tool function's return type annotation
297+
causes the tool to be classified as structured _and this is undesirable_,
292298
the classification can be suppressed by passing `structured_output=False`
293299
to the `@tool` decorator.
294300

@@ -407,6 +413,7 @@ def debug_error(error: str) -> list[base.Message]:
407413
base.AssistantMessage("I'll help debug that. What have you tried so far?"),
408414
]
409415
```
416+
410417
_Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)_
411418
<!-- /snippet-source -->
412419

@@ -456,6 +463,7 @@ async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str
456463

457464
return f"Task '{task_name}' completed"
458465
```
466+
459467
_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_
460468
<!-- /snippet-source -->
461469

@@ -464,6 +472,7 @@ _Full example: [examples/snippets/servers/tool_progress.py](https://github.com/m
464472
MCP supports providing completion suggestions for prompt arguments and resource template parameters. With the context parameter, servers can provide completions based on previously resolved values:
465473

466474
Client usage:
475+
467476
```python
468477
from mcp.client.session import ClientSession
469478
from mcp.types import ResourceTemplateReference
@@ -542,11 +551,12 @@ async def handle_completion(
542551

543552
return None
544553
```
554+
545555
_Full example: [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)_
546556
<!-- /snippet-source -->
547557
### Elicitation
548558

549-
Request additional information from users during tool execution:
559+
Request additional information from users. This example shows an Elicitation during a Tool Call:
550560

551561
<!-- snippet-source examples/snippets/servers/elicitation.py -->
552562
```python
@@ -592,10 +602,12 @@ async def book_table(
592602
# Date available
593603
return f"[SUCCESS] Booked for {date} at {time}"
594604
```
605+
595606
_Full example: [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)_
596607
<!-- /snippet-source -->
597608

598609
The `elicit()` method returns an `ElicitationResult` with:
610+
599611
- `action`: "accept", "decline", or "cancel"
600612
- `data`: The validated response (only when accepted)
601613
- `validation_error`: Any validation error message
@@ -631,6 +643,7 @@ async def generate_poem(topic: str, ctx: Context) -> str:
631643
return result.content.text
632644
return str(result.content)
633645
```
646+
634647
_Full example: [examples/snippets/servers/sampling.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/sampling.py)_
635648
<!-- /snippet-source -->
636649

@@ -659,6 +672,7 @@ async def process_data(data: str, ctx: Context) -> str:
659672

660673
return f"Processed: {data}"
661674
```
675+
662676
_Full example: [examples/snippets/servers/notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/notifications.py)_
663677
<!-- /snippet-source -->
664678

@@ -697,6 +711,7 @@ mcp = FastMCP(
697711
For a complete example with separate Authorization Server and Resource Server implementations, see [`examples/servers/simple-auth/`](examples/servers/simple-auth/).
698712

699713
**Architecture:**
714+
700715
- **Authorization Server (AS)**: Handles OAuth flows, user authentication, and token issuance
701716
- **Resource Server (RS)**: Your MCP server that validates tokens and serves protected resources
702717
- **Client**: Discovers AS through RFC 9728, obtains tokens, and uses them with the MCP server
@@ -748,6 +763,7 @@ if __name__ == "__main__":
748763
```
749764

750765
Run it with:
766+
751767
```bash
752768
python server.py
753769
# or
@@ -827,10 +843,12 @@ app.mount("/math", math.mcp.streamable_http_app())
827843
```
828844

829845
For low level server with Streamable HTTP implementations, see:
846+
830847
- Stateful server: [`examples/servers/simple-streamablehttp/`](examples/servers/simple-streamablehttp/)
831848
- Stateless server: [`examples/servers/simple-streamablehttp-stateless/`](examples/servers/simple-streamablehttp-stateless/)
832849

833850
The streamable HTTP transport supports:
851+
834852
- Stateful and stateless operation modes
835853
- Resumability with event stores
836854
- JSON or SSE response formats
@@ -1003,6 +1021,7 @@ async def query_db(name: str, arguments: dict) -> list:
10031021
```
10041022

10051023
The lifespan API provides:
1024+
10061025
- A way to initialize resources when the server starts and clean them up when it stops
10071026
- Access to initialized resources through the request context in handlers
10081027
- Type-safe context passing between lifespan and request handlers
@@ -1129,6 +1148,7 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
11291148
```
11301149

11311150
Tools can return data in three ways:
1151+
11321152
1. **Content only**: Return a list of content blocks (default behavior before spec revision 2025-06-18)
11331153
2. **Structured data only**: Return a dictionary that will be serialized to JSON (Introduced in spec revision 2025-06-18)
11341154
3. **Both**: Return a tuple of (content, structured_data) preferred option to use for backwards compatibility
@@ -1254,6 +1274,7 @@ async def display_resources(session: ClientSession):
12541274
```
12551275

12561276
The `get_display_name()` function implements the proper precedence rules for displaying names:
1277+
12571278
- For tools: `title` > `annotations.title` > `name`
12581279
- For other objects: `title` > `name`
12591280

@@ -1312,7 +1333,6 @@ async def main():
13121333

13131334
For a complete working example, see [`examples/clients/simple-auth-client/`](examples/clients/simple-auth-client/).
13141335

1315-
13161336
### MCP Primitives
13171337

13181338
The MCP protocol defines three core primitives that servers can implement:
@@ -1327,13 +1347,13 @@ The MCP protocol defines three core primitives that servers can implement:
13271347

13281348
MCP servers declare capabilities during initialization:
13291349

1330-
| Capability | Feature Flag | Description |
1331-
|-------------|------------------------------|------------------------------------|
1332-
| `prompts` | `listChanged` | Prompt template management |
1333-
| `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates |
1334-
| `tools` | `listChanged` | Tool discovery and execution |
1335-
| `logging` | - | Server logging configuration |
1336-
| `completion`| - | Argument completion suggestions |
1350+
| Capability | Feature Flag | Description |
1351+
|--------------|------------------------------|------------------------------------|
1352+
| `prompts` | `listChanged` | Prompt template management |
1353+
| `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates |
1354+
| `tools` | `listChanged` | Tool discovery and execution |
1355+
| `logging` | - | Server logging configuration |
1356+
| `completions`| - | Argument completion suggestions |
13371357

13381358
## Documentation
13391359

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Security Policy
2+
23
Thank you for helping us keep the SDKs and systems they interact with secure.
34

45
## Reporting Security Issues

examples/clients/simple-auth-client/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ The client will open your browser for authentication. After completing OAuth, yo
4747

4848
## Example
4949

50-
```
50+
```markdown
5151
🔐 Simple MCP Auth Client
5252
Connecting to: http://localhost:3001
5353

0 commit comments

Comments
 (0)