chore: add markdownlint on pre-commit hook and lint md files (#996)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
This commit is contained in:
parent
f55831ee79
commit
6d092af6fd
12 changed files with 85 additions and 28 deletions
|
|
@ -7,6 +7,20 @@ repos:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
types_or: [yaml, json5]
|
types_or: [yaml, json5]
|
||||||
|
|
||||||
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||||
|
rev: v0.45.0
|
||||||
|
hooks:
|
||||||
|
- id: markdownlint
|
||||||
|
args:
|
||||||
|
[
|
||||||
|
"--fix",
|
||||||
|
"--config",
|
||||||
|
"pyproject.toml",
|
||||||
|
"--configPointer",
|
||||||
|
"/tool/markdown/lint",
|
||||||
|
]
|
||||||
|
types: [markdown]
|
||||||
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,19 @@ This document contains critical information about working with this codebase. Fo
|
||||||
- Bug fixes require regression tests
|
- Bug fixes require regression tests
|
||||||
|
|
||||||
- For commits fixing bugs or adding features based on user reports add:
|
- For commits fixing bugs or adding features based on user reports add:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git commit --trailer "Reported-by:<name>"
|
git commit --trailer "Reported-by:<name>"
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `<name>` is the name of the user.
|
Where `<name>` is the name of the user.
|
||||||
|
|
||||||
- For commits related to a Github issue, add
|
- For commits related to a Github issue, add
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git commit --trailer "Github-Issue:#<number>"
|
git commit --trailer "Github-Issue:#<number>"
|
||||||
```
|
```
|
||||||
|
|
||||||
- NEVER ever mention a `co-authored-by` or similar aspects. In particular, never
|
- NEVER ever mention a `co-authored-by` or similar aspects. In particular, never
|
||||||
mention the tool used to create the commit message or PR.
|
mention the tool used to create the commit message or PR.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ representative at an online or offline event.
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
reported to the community leaders responsible for enforcement at
|
reported to the community leaders responsible for enforcement at
|
||||||
mcp-coc@anthropic.com.
|
<mcp-coc@anthropic.com>.
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
|
@ -116,7 +116,7 @@ the community.
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
version 2.0, available at
|
version 2.0, available at
|
||||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
enforcement ladder](https://github.com/mozilla/diversity).
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
@ -124,5 +124,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
[homepage]: https://www.contributor-covenant.org
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
https://www.contributor-covenant.org/faq. Translations are available at
|
<https://www.contributor-covenant.org/faq>. Translations are available at
|
||||||
https://www.contributor-covenant.org/translations.
|
<https://www.contributor-covenant.org/translations>.
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ Thank you for your interest in contributing to the MCP Python SDK! This document
|
||||||
3. Fork the repository
|
3. Fork the repository
|
||||||
4. Clone your fork: `git clone https://github.com/YOUR-USERNAME/python-sdk.git`
|
4. Clone your fork: `git clone https://github.com/YOUR-USERNAME/python-sdk.git`
|
||||||
5. Install dependencies:
|
5. Install dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv sync --frozen --all-extras --dev
|
uv sync --frozen --all-extras --dev
|
||||||
```
|
```
|
||||||
|
|
@ -25,22 +26,26 @@ uv sync --frozen --all-extras --dev
|
||||||
3. Make your changes
|
3. Make your changes
|
||||||
|
|
||||||
4. Ensure tests pass:
|
4. Ensure tests pass:
|
||||||
```bash
|
|
||||||
|
```bash
|
||||||
uv run pytest
|
uv run pytest
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Run type checking:
|
5. Run type checking:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run pyright
|
uv run pyright
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Run linting:
|
6. Run linting:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run ruff check .
|
uv run ruff check .
|
||||||
uv run ruff format .
|
uv run ruff format .
|
||||||
```
|
```
|
||||||
|
|
||||||
7. Update README snippets if you modified example code:
|
7. Update README snippets if you modified example code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run scripts/update_readme_snippets.py
|
uv run scripts/update_readme_snippets.py
|
||||||
```
|
```
|
||||||
|
|
|
||||||
34
README.md
34
README.md
|
|
@ -95,6 +95,7 @@ If you haven't created a uv-managed project yet, create one:
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, for projects using pip for dependencies:
|
Alternatively, for projects using pip for dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install "mcp[cli]"
|
pip install "mcp[cli]"
|
||||||
```
|
```
|
||||||
|
|
@ -134,11 +135,13 @@ def get_greeting(name: str) -> str:
|
||||||
```
|
```
|
||||||
|
|
||||||
You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
|
You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run mcp install server.py
|
uv run mcp install server.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can test it with the MCP Inspector:
|
Alternatively, you can test it with the MCP Inspector:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run mcp dev server.py
|
uv run mcp dev server.py
|
||||||
```
|
```
|
||||||
|
|
@ -232,6 +235,7 @@ def get_settings() -> str:
|
||||||
"debug": false
|
"debug": false
|
||||||
}"""
|
}"""
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/basic_resource.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_resource.py)_
|
_Full example: [examples/snippets/servers/basic_resource.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_resource.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
|
|
@ -258,15 +262,17 @@ def get_weather(city: str, unit: str = "celsius") -> str:
|
||||||
# This would normally call a weather API
|
# This would normally call a weather API
|
||||||
return f"Weather in {city}: 22degrees{unit[0].upper()}"
|
return f"Weather in {city}: 22degrees{unit[0].upper()}"
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_
|
_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
#### Structured Output
|
#### Structured Output
|
||||||
|
|
||||||
Tools will return structured results by default, if their return type
|
Tools will return structured results by default, if their return type
|
||||||
annotation is compatible. Otherwise, they will return unstructured results.
|
annotation is compatible. Otherwise, they will return unstructured results.
|
||||||
|
|
||||||
Structured output supports these return types:
|
Structured output supports these return types:
|
||||||
|
|
||||||
- Pydantic models (BaseModel subclasses)
|
- Pydantic models (BaseModel subclasses)
|
||||||
- TypedDicts
|
- TypedDicts
|
||||||
- Dataclasses and other classes with type hints
|
- Dataclasses and other classes with type hints
|
||||||
|
|
@ -278,17 +284,17 @@ Classes without type hints cannot be serialized for structured output. Only
|
||||||
classes with properly annotated attributes will be converted to Pydantic models
|
classes with properly annotated attributes will be converted to Pydantic models
|
||||||
for schema generation and validation.
|
for schema generation and validation.
|
||||||
|
|
||||||
Structured results are automatically validated against the output schema
|
Structured results are automatically validated against the output schema
|
||||||
generated from the annotation. This ensures the tool returns well-typed,
|
generated from the annotation. This ensures the tool returns well-typed,
|
||||||
validated data that clients can easily process.
|
validated data that clients can easily process.
|
||||||
|
|
||||||
**Note:** For backward compatibility, unstructured results are also
|
**Note:** For backward compatibility, unstructured results are also
|
||||||
returned. Unstructured results are provided for backward compatibility
|
returned. Unstructured results are provided for backward compatibility
|
||||||
with previous versions of the MCP specification, and are quirks-compatible
|
with previous versions of the MCP specification, and are quirks-compatible
|
||||||
with previous versions of FastMCP in the current version of the SDK.
|
with previous versions of FastMCP in the current version of the SDK.
|
||||||
|
|
||||||
**Note:** In cases where a tool function's return type annotation
|
**Note:** In cases where a tool function's return type annotation
|
||||||
causes the tool to be classified as structured _and this is undesirable_,
|
causes the tool to be classified as structured _and this is undesirable_,
|
||||||
the classification can be suppressed by passing `structured_output=False`
|
the classification can be suppressed by passing `structured_output=False`
|
||||||
to the `@tool` decorator.
|
to the `@tool` decorator.
|
||||||
|
|
||||||
|
|
@ -407,6 +413,7 @@ def debug_error(error: str) -> list[base.Message]:
|
||||||
base.AssistantMessage("I'll help debug that. What have you tried so far?"),
|
base.AssistantMessage("I'll help debug that. What have you tried so far?"),
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)_
|
_Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
|
|
@ -456,6 +463,7 @@ async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str
|
||||||
|
|
||||||
return f"Task '{task_name}' completed"
|
return f"Task '{task_name}' completed"
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_
|
_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
|
|
@ -464,6 +472,7 @@ _Full example: [examples/snippets/servers/tool_progress.py](https://github.com/m
|
||||||
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:
|
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:
|
||||||
|
|
||||||
Client usage:
|
Client usage:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from mcp.client.session import ClientSession
|
from mcp.client.session import ClientSession
|
||||||
from mcp.types import ResourceTemplateReference
|
from mcp.types import ResourceTemplateReference
|
||||||
|
|
@ -542,6 +551,7 @@ async def handle_completion(
|
||||||
|
|
||||||
return None
|
return None
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)_
|
_Full example: [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
### Elicitation
|
### Elicitation
|
||||||
|
|
@ -592,10 +602,12 @@ async def book_table(
|
||||||
# Date available
|
# Date available
|
||||||
return f"[SUCCESS] Booked for {date} at {time}"
|
return f"[SUCCESS] Booked for {date} at {time}"
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)_
|
_Full example: [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
The `elicit()` method returns an `ElicitationResult` with:
|
The `elicit()` method returns an `ElicitationResult` with:
|
||||||
|
|
||||||
- `action`: "accept", "decline", or "cancel"
|
- `action`: "accept", "decline", or "cancel"
|
||||||
- `data`: The validated response (only when accepted)
|
- `data`: The validated response (only when accepted)
|
||||||
- `validation_error`: Any validation error message
|
- `validation_error`: Any validation error message
|
||||||
|
|
@ -631,6 +643,7 @@ async def generate_poem(topic: str, ctx: Context) -> str:
|
||||||
return result.content.text
|
return result.content.text
|
||||||
return str(result.content)
|
return str(result.content)
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/sampling.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/sampling.py)_
|
_Full example: [examples/snippets/servers/sampling.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/sampling.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
|
|
@ -659,6 +672,7 @@ async def process_data(data: str, ctx: Context) -> str:
|
||||||
|
|
||||||
return f"Processed: {data}"
|
return f"Processed: {data}"
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/notifications.py)_
|
_Full example: [examples/snippets/servers/notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/notifications.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
|
|
@ -697,6 +711,7 @@ mcp = FastMCP(
|
||||||
For a complete example with separate Authorization Server and Resource Server implementations, see [`examples/servers/simple-auth/`](examples/servers/simple-auth/).
|
For a complete example with separate Authorization Server and Resource Server implementations, see [`examples/servers/simple-auth/`](examples/servers/simple-auth/).
|
||||||
|
|
||||||
**Architecture:**
|
**Architecture:**
|
||||||
|
|
||||||
- **Authorization Server (AS)**: Handles OAuth flows, user authentication, and token issuance
|
- **Authorization Server (AS)**: Handles OAuth flows, user authentication, and token issuance
|
||||||
- **Resource Server (RS)**: Your MCP server that validates tokens and serves protected resources
|
- **Resource Server (RS)**: Your MCP server that validates tokens and serves protected resources
|
||||||
- **Client**: Discovers AS through RFC 9728, obtains tokens, and uses them with the MCP server
|
- **Client**: Discovers AS through RFC 9728, obtains tokens, and uses them with the MCP server
|
||||||
|
|
@ -748,6 +763,7 @@ if __name__ == "__main__":
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it with:
|
Run it with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python server.py
|
python server.py
|
||||||
# or
|
# or
|
||||||
|
|
@ -827,10 +843,12 @@ app.mount("/math", math.mcp.streamable_http_app())
|
||||||
```
|
```
|
||||||
|
|
||||||
For low level server with Streamable HTTP implementations, see:
|
For low level server with Streamable HTTP implementations, see:
|
||||||
|
|
||||||
- Stateful server: [`examples/servers/simple-streamablehttp/`](examples/servers/simple-streamablehttp/)
|
- Stateful server: [`examples/servers/simple-streamablehttp/`](examples/servers/simple-streamablehttp/)
|
||||||
- Stateless server: [`examples/servers/simple-streamablehttp-stateless/`](examples/servers/simple-streamablehttp-stateless/)
|
- Stateless server: [`examples/servers/simple-streamablehttp-stateless/`](examples/servers/simple-streamablehttp-stateless/)
|
||||||
|
|
||||||
The streamable HTTP transport supports:
|
The streamable HTTP transport supports:
|
||||||
|
|
||||||
- Stateful and stateless operation modes
|
- Stateful and stateless operation modes
|
||||||
- Resumability with event stores
|
- Resumability with event stores
|
||||||
- JSON or SSE response formats
|
- JSON or SSE response formats
|
||||||
|
|
@ -1003,6 +1021,7 @@ async def query_db(name: str, arguments: dict) -> list:
|
||||||
```
|
```
|
||||||
|
|
||||||
The lifespan API provides:
|
The lifespan API provides:
|
||||||
|
|
||||||
- A way to initialize resources when the server starts and clean them up when it stops
|
- A way to initialize resources when the server starts and clean them up when it stops
|
||||||
- Access to initialized resources through the request context in handlers
|
- Access to initialized resources through the request context in handlers
|
||||||
- Type-safe context passing between lifespan and request handlers
|
- 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]:
|
||||||
```
|
```
|
||||||
|
|
||||||
Tools can return data in three ways:
|
Tools can return data in three ways:
|
||||||
|
|
||||||
1. **Content only**: Return a list of content blocks (default behavior before spec revision 2025-06-18)
|
1. **Content only**: Return a list of content blocks (default behavior before spec revision 2025-06-18)
|
||||||
2. **Structured data only**: Return a dictionary that will be serialized to JSON (Introduced in spec revision 2025-06-18)
|
2. **Structured data only**: Return a dictionary that will be serialized to JSON (Introduced in spec revision 2025-06-18)
|
||||||
3. **Both**: Return a tuple of (content, structured_data) preferred option to use for backwards compatibility
|
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):
|
||||||
```
|
```
|
||||||
|
|
||||||
The `get_display_name()` function implements the proper precedence rules for displaying names:
|
The `get_display_name()` function implements the proper precedence rules for displaying names:
|
||||||
|
|
||||||
- For tools: `title` > `annotations.title` > `name`
|
- For tools: `title` > `annotations.title` > `name`
|
||||||
- For other objects: `title` > `name`
|
- For other objects: `title` > `name`
|
||||||
|
|
||||||
|
|
@ -1312,7 +1333,6 @@ async def main():
|
||||||
|
|
||||||
For a complete working example, see [`examples/clients/simple-auth-client/`](examples/clients/simple-auth-client/).
|
For a complete working example, see [`examples/clients/simple-auth-client/`](examples/clients/simple-auth-client/).
|
||||||
|
|
||||||
|
|
||||||
### MCP Primitives
|
### MCP Primitives
|
||||||
|
|
||||||
The MCP protocol defines three core primitives that servers can implement:
|
The MCP protocol defines three core primitives that servers can implement:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# Security Policy
|
# Security Policy
|
||||||
|
|
||||||
Thank you for helping us keep the SDKs and systems they interact with secure.
|
Thank you for helping us keep the SDKs and systems they interact with secure.
|
||||||
|
|
||||||
## Reporting Security Issues
|
## Reporting Security Issues
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ The client will open your browser for authentication. After completing OAuth, yo
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
```
|
```markdown
|
||||||
🔐 Simple MCP Auth Client
|
🔐 Simple MCP Auth Client
|
||||||
Connecting to: http://localhost:3001
|
Connecting to: http://localhost:3001
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,12 @@ This example demonstrates how to integrate the Model Context Protocol (MCP) into
|
||||||
```plaintext
|
```plaintext
|
||||||
LLM_API_KEY=your_api_key_here
|
LLM_API_KEY=your_api_key_here
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** The current implementation is configured to use the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) with the `llama-3.2-90b-vision-preview` model. If you plan to use a different LLM provider, you'll need to modify the `LLMClient` class in `main.py` to use the appropriate endpoint URL and model parameters.
|
**Note:** The current implementation is configured to use the Groq API endpoint (`https://api.groq.com/openai/v1/chat/completions`) with the `llama-3.2-90b-vision-preview` model. If you plan to use a different LLM provider, you'll need to modify the `LLMClient` class in `main.py` to use the appropriate endpoint URL and model parameters.
|
||||||
|
|
||||||
3. **Configure servers:**
|
3. **Configure servers:**
|
||||||
|
|
||||||
The `servers_config.json` follows the same structure as Claude Desktop, allowing for easy integration of multiple servers.
|
The `servers_config.json` follows the same structure as Claude Desktop, allowing for easy integration of multiple servers.
|
||||||
Here's an example:
|
Here's an example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
@ -46,9 +47,11 @@ This example demonstrates how to integrate the Model Context Protocol (MCP) into
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Environment variables are supported as well. Pass them as you would with the Claude Desktop App.
|
Environment variables are supported as well. Pass them as you would with the Claude Desktop App.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
|
|
@ -72,7 +75,7 @@ This example demonstrates how to integrate the Model Context Protocol (MCP) into
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Interact with the assistant:**
|
2. **Interact with the assistant:**
|
||||||
|
|
||||||
The assistant will automatically detect available tools and can respond to queries based on the tools provided by the configured servers.
|
The assistant will automatically detect available tools and can respond to queries based on the tools provided by the configured servers.
|
||||||
|
|
||||||
3. **Exit the session:**
|
3. **Exit the session:**
|
||||||
|
|
@ -86,6 +89,7 @@ This example demonstrates how to integrate the Model Context Protocol (MCP) into
|
||||||
- **Server Integration**: Supports any MCP-compatible server, tested with various server implementations including Uvicorn and Node.js.
|
- **Server Integration**: Supports any MCP-compatible server, tested with various server implementations including Uvicorn and Node.js.
|
||||||
|
|
||||||
### Class Structure
|
### Class Structure
|
||||||
|
|
||||||
- **Configuration**: Manages environment variables and server configurations
|
- **Configuration**: Manages environment variables and server configurations
|
||||||
- **Server**: Handles MCP server initialization, tool discovery, and execution
|
- **Server**: Handles MCP server initialization, tool discovery, and execution
|
||||||
- **Tool**: Represents individual tools with their properties and formatting
|
- **Tool**: Represents individual tools with their properties and formatting
|
||||||
|
|
@ -107,5 +111,3 @@ This example demonstrates how to integrate the Model Context Protocol (MCP) into
|
||||||
- If it's a direct response → return to user
|
- If it's a direct response → return to user
|
||||||
- Tool results are sent back to LLM for interpretation
|
- Tool results are sent back to LLM for interpretation
|
||||||
- Final response is presented to user
|
- Final response is presented to user
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ This example demonstrates OAuth 2.0 authentication with the Model Context Protoc
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Running the Servers
|
## Running the Servers
|
||||||
|
|
||||||
### Step 1: Start Authorization Server
|
### Step 1: Start Authorization Server
|
||||||
|
|
@ -18,6 +17,7 @@ uv run mcp-simple-auth-as --port=9000
|
||||||
```
|
```
|
||||||
|
|
||||||
**What it provides:**
|
**What it provides:**
|
||||||
|
|
||||||
- OAuth 2.0 flows (registration, authorization, token exchange)
|
- OAuth 2.0 flows (registration, authorization, token exchange)
|
||||||
- Simple credential-based authentication (no external provider needed)
|
- Simple credential-based authentication (no external provider needed)
|
||||||
- Token introspection endpoint for Resource Servers (`/introspect`)
|
- Token introspection endpoint for Resource Servers (`/introspect`)
|
||||||
|
|
@ -38,7 +38,6 @@ uv run mcp-simple-auth-rs --port=8001 --auth-server=http://localhost:9000 --tra
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Step 3: Test with Client
|
### Step 3: Test with Client
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -47,15 +46,16 @@ cd examples/clients/simple-auth-client
|
||||||
MCP_SERVER_PORT=8001 MCP_TRANSPORT_TYPE=streamable_http uv run mcp-simple-auth-client
|
MCP_SERVER_PORT=8001 MCP_TRANSPORT_TYPE=streamable_http uv run mcp-simple-auth-client
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
### RFC 9728 Discovery
|
### RFC 9728 Discovery
|
||||||
|
|
||||||
**Client → Resource Server:**
|
**Client → Resource Server:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8001/.well-known/oauth-protected-resource
|
curl http://localhost:8001/.well-known/oauth-protected-resource
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"resource": "http://localhost:8001",
|
"resource": "http://localhost:8001",
|
||||||
|
|
@ -64,9 +64,11 @@ curl http://localhost:8001/.well-known/oauth-protected-resource
|
||||||
```
|
```
|
||||||
|
|
||||||
**Client → Authorization Server:**
|
**Client → Authorization Server:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:9000/.well-known/oauth-authorization-server
|
curl http://localhost:9000/.well-known/oauth-authorization-server
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"issuer": "http://localhost:9000",
|
"issuer": "http://localhost:9000",
|
||||||
|
|
@ -75,7 +77,6 @@ curl http://localhost:9000/.well-known/oauth-authorization-server
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Legacy MCP Server as Authorization Server (Backwards Compatibility)
|
## Legacy MCP Server as Authorization Server (Backwards Compatibility)
|
||||||
|
|
||||||
For backwards compatibility with older MCP implementations, a legacy server is provided that acts as an Authorization Server (following the old spec where MCP servers could optionally provide OAuth):
|
For backwards compatibility with older MCP implementations, a legacy server is provided that acts as an Authorization Server (following the old spec where MCP servers could optionally provide OAuth):
|
||||||
|
|
@ -88,6 +89,7 @@ uv run mcp-simple-auth-legacy --port=8002
|
||||||
```
|
```
|
||||||
|
|
||||||
**Differences from the new architecture:**
|
**Differences from the new architecture:**
|
||||||
|
|
||||||
- **MCP server acts as AS:** The MCP server itself provides OAuth endpoints (old spec behavior)
|
- **MCP server acts as AS:** The MCP server itself provides OAuth endpoints (old spec behavior)
|
||||||
- **No separate RS:** The server handles both authentication and MCP tools
|
- **No separate RS:** The server handles both authentication and MCP tools
|
||||||
- **Local token validation:** Tokens are validated internally without introspection
|
- **Local token validation:** Tokens are validated internally without introspection
|
||||||
|
|
@ -103,6 +105,7 @@ MCP_SERVER_PORT=8002 MCP_TRANSPORT_TYPE=streamable_http uv run mcp-simple-auth-c
|
||||||
```
|
```
|
||||||
|
|
||||||
The client will:
|
The client will:
|
||||||
|
|
||||||
1. Try RFC 9728 discovery at `/.well-known/oauth-protected-resource` (404 on legacy server)
|
1. Try RFC 9728 discovery at `/.well-known/oauth-protected-resource` (404 on legacy server)
|
||||||
2. Fall back to direct OAuth discovery at `/.well-known/oauth-authorization-server`
|
2. Fall back to direct OAuth discovery at `/.well-known/oauth-authorization-server`
|
||||||
3. Complete authentication with the MCP server acting as its own AS
|
3. Complete authentication with the MCP server acting as its own AS
|
||||||
|
|
@ -112,6 +115,7 @@ This ensures existing MCP servers (which could optionally act as Authorization S
|
||||||
## Manual Testing
|
## Manual Testing
|
||||||
|
|
||||||
### Test Discovery
|
### Test Discovery
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test Resource Server discovery endpoint (new architecture)
|
# Test Resource Server discovery endpoint (new architecture)
|
||||||
curl -v http://localhost:8001/.well-known/oauth-protected-resource
|
curl -v http://localhost:8001/.well-known/oauth-protected-resource
|
||||||
|
|
@ -121,6 +125,7 @@ curl -v http://localhost:9000/.well-known/oauth-authorization-server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test Token Introspection
|
### Test Token Introspection
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# After getting a token through OAuth flow:
|
# After getting a token through OAuth flow:
|
||||||
curl -X POST http://localhost:9000/introspect \
|
curl -X POST http://localhost:9000/introspect \
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ A stateless MCP server example demonstrating the StreamableHttp transport withou
|
||||||
- Task lifecycle scoped to individual requests
|
- Task lifecycle scoped to individual requests
|
||||||
- Suitable for deployment in multi-node environments
|
- Suitable for deployment in multi-node environments
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Start the server:
|
Start the server:
|
||||||
|
|
@ -35,7 +34,6 @@ The server exposes a tool named "start-notification-stream" that accepts three a
|
||||||
- `count`: Number of notifications to send (e.g., 5)
|
- `count`: Number of notifications to send (e.g., 5)
|
||||||
- `caller`: Identifier string for the caller
|
- `caller`: Identifier string for the caller
|
||||||
|
|
||||||
|
|
||||||
## Client
|
## Client
|
||||||
|
|
||||||
You can connect to this server using an HTTP client. For now, only the TypeScript SDK has streamable HTTP client examples, or you can use [Inspector](https://github.com/modelcontextprotocol/inspector) for testing.
|
You can connect to this server using an HTTP client. For now, only the TypeScript SDK has streamable HTTP client examples, or you can use [Inspector](https://github.com/modelcontextprotocol/inspector) for testing.
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,14 @@ This server includes resumability support through the InMemoryEventStore. This e
|
||||||
- Reconnect to the server after a disconnection
|
- Reconnect to the server after a disconnection
|
||||||
- Resume event streaming from where they left off using the Last-Event-ID header
|
- Resume event streaming from where they left off using the Last-Event-ID header
|
||||||
|
|
||||||
|
|
||||||
The server will:
|
The server will:
|
||||||
|
|
||||||
- Generate unique event IDs for each SSE message
|
- Generate unique event IDs for each SSE message
|
||||||
- Store events in memory for later replay
|
- Store events in memory for later replay
|
||||||
- Replay missed events when a client reconnects with a Last-Event-ID header
|
- Replay missed events when a client reconnects with a Last-Event-ID header
|
||||||
|
|
||||||
Note: The InMemoryEventStore is designed for demonstration purposes only. For production use, consider implementing a persistent storage solution.
|
Note: The InMemoryEventStore is designed for demonstration purposes only. For production use, consider implementing a persistent storage solution.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Client
|
## Client
|
||||||
|
|
||||||
You can connect to this server using an HTTP client, for now only Typescript SDK has streamable HTTP client examples or you can use [Inspector](https://github.com/modelcontextprotocol/inspector)
|
You can connect to this server using an HTTP client, for now only Typescript SDK has streamable HTTP client examples or you can use [Inspector](https://github.com/modelcontextprotocol/inspector)
|
||||||
|
|
|
||||||
|
|
@ -129,3 +129,13 @@ filterwarnings = [
|
||||||
# pywin32 internal deprecation warning
|
# pywin32 internal deprecation warning
|
||||||
"ignore:getargs.*The 'u' format is deprecated:DeprecationWarning"
|
"ignore:getargs.*The 'u' format is deprecated:DeprecationWarning"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.markdown.lint]
|
||||||
|
default=true
|
||||||
|
MD004=false # ul-style - Unordered list style
|
||||||
|
MD007.indent=2 # ul-indent - Unordered list indentation
|
||||||
|
MD013=false # line-length - Line length
|
||||||
|
MD029=false # ol-prefix - Ordered list item prefix
|
||||||
|
MD033=false # no-inline-html Inline HTML
|
||||||
|
MD041=false # first-line-heading/first-line-h1
|
||||||
|
MD059=false # descriptive-link-text
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue