| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| from mcp.server import Server, ServerRequestContext | ||
| from mcp.types import CallToolRequestParams, CallToolResult, ListToolsResult, PaginatedRequestParams, TextContent, Tool | ||
|
|
||
| FIND_BOOK = Tool( | ||
| name="find_book", | ||
| description="Find one book by ISBN, or by title and author.", | ||
| input_schema={ | ||
| "type": "object", | ||
| "properties": { | ||
| "isbn": {"type": "string", "pattern": "^[0-9]{13}$"}, | ||
| "title": {"type": "string"}, | ||
| "author": {"type": "string"}, | ||
| }, | ||
| "oneOf": [{"required": ["isbn"]}, {"required": ["title", "author"]}], | ||
| "additionalProperties": False, | ||
| }, | ||
| ) | ||
|
|
||
|
|
||
| async def list_tools(ctx: ServerRequestContext, params: PaginatedRequestParams | None) -> ListToolsResult: | ||
| return ListToolsResult(tools=[FIND_BOOK]) | ||
|
|
||
|
|
||
| async def call_tool(ctx: ServerRequestContext, params: CallToolRequestParams) -> CallToolResult: | ||
| args = params.arguments or {} | ||
| found = f"ISBN {args['isbn']}" if "isbn" in args else f"{args['title']!r} by {args['author']}" | ||
| return CallToolResult(content=[TextContent(type="text", text=f"Found {found} on shelf C-3.")]) | ||
|
|
||
|
|
||
| server = Server("Bookshop", on_list_tools=list_tools, on_call_tool=call_tool) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| from mcp.server import MCPServer | ||
| from mcp.types import EmbeddedResource, TextResourceContents | ||
|
|
||
| mcp = MCPServer("Brand kit") | ||
|
|
||
|
|
||
| @mcp.resource("brand://guidelines", mime_type="text/markdown") | ||
| def guidelines() -> str: | ||
| """How to use the brand assets.""" | ||
| return "# Brand guidelines\n\nUse the primary colour for calls to action.\n" | ||
|
|
||
|
|
||
| @mcp.tool() | ||
| def brand_guidelines() -> EmbeddedResource: | ||
| """The brand guidelines as a Markdown document.""" | ||
| return EmbeddedResource( | ||
| resource=TextResourceContents(uri="brand://guidelines", mime_type="text/markdown", text=guidelines()) | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| from pathlib import Path | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality🟡 [quality] New docs examples/claims added without the chapter behavioral tests every existing tutorial has sweep:docs_src/(media/tutorial005|prompts/tutorial00[4-6]|lowlevel/tutorial007)\.py [also at: docs_src/media/tutorial005.py:1 - [quality] Five new docs_src tutorials (media/tutorial005, prompts/tutorial004-006, lowlevel/tutorial007) and the two new] Extended reasoning...Repo convention (tests/docs_src/test_media.py, test_prompts.py, test_lowlevel.py all open with "every claim the page makes, proved against the real SDK" and import/exercise every prior tutorial: media 001-004, prompts 001-003, lowlevel 001-006) is that each docs_src tutorial gets a behavioral test; the five new modules (docs_src/media/tutorial005.py, docs_src/prompts/tutorial004-006.py, docs_src/lowlevel/tutorial007.py) are only covered by the test_shape.py import-only floor, and likewise tests/docs_src/test_deprecated.py's header says each prose claim on docs/deprecated.md is executed, yet the two new sections' claims (legacy ping both directions with the printed '2025-11-25' output, roots list_changed end-to-end via on_roots_list_changed, the notification being 'silently dropped' on modern connections) have no test. Concrete cost: the rendered JSON/output blocks and behavioral assertions on these pages can silently drift from real SDK behavior — exactly the drift these chapter tests exist to prevent — and future refactors won't fail CI when they break the examples' runtime behavi Verification: nit — Convention is real and violated. tests/docs_src/test_media.py:1, test_prompts.py:1 and test_lowlevel.py:1 all open with "every claim the page makes, proved against the real SDK", and their imports stop just short of the new files: test_media.py:9 from docs_src.media import tutorial001, tutorial002, tutorial003, tutorial004 (no 005), test_prompts.py:9 `from docs_src.prompts import tutoria
Sorry, something went wrong.
claude[bot] reacted with thumbs up emoji
claude[bot] reacted with thumbs down emoji
All reactions
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIntentional for this PR: it is scoped to the narrative coverage the tier audit needs and adds no tests. The new docs_src modules are still import-checked by test_shape.py, type-checked by pyright and the fences ruff-linted by test_examples.py; behavioural chapter tests for them can follow separately if we want them.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| from mcp.server import MCPServer | ||
| from mcp.server.mcpserver import Message, UserMessage | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality🟡 [quality] nit: New prompt examples import Message/UserMessage from mcp.server.mcpserver, contradicting the same page's prose and every existing docs_src example sweep:from mcp\.server\.mcpserver import .*(UserMessage|Message) Extended reasoning...docs/servers/prompts.md line 88 (the bullet under tutorial002, unchanged by this PR) states "UserMessage and AssistantMessage come from mcp.server.mcpserver.prompts.base", and every pre-existing docs_src example imports them from that path (docs_src/prompts/tutorial002.py:2, docs_src/mrtr/tutorial004.py:2). The two new examples rendered on the very same page a few sections later import the same symbols from the top-level re-export instead (docs_src/prompts/tutorial004.py:4 from mcp.server.mcpserver import Message, UserMessage; docs_src/prompts/tutorial005.py:4). Concrete cost: the prompts page now contradicts itself about where these classes live — a reader who follows the earlier bullet and then copies tutorial004 sees two different canonical import paths for the same names on one page, and the docs_src corpus loses its single established spelling. Fix in one sweep: change the two new files to from mcp.server.mcpserver.prompts.base import ... (or, if the top-level spelling is now preferred, update the line-88 prose and the older examples in a follow-up). Verification: nit — Factually accurate quality finding. docs_src/prompts/tutorial004.py:4 (from mcp.server.mcpserver import Message, UserMessage) and tutorial005.py:4 import from the top-level re-export, while the same rendered page states at docs/servers/prompts.md:88 that "UserMessage and AssistantMessage come from mcp.server.mcpserver.prompts.base", and all pre-existing examples import from that pa
Sorry, something went wrong.
claude[bot] reacted with thumbs up emoji
claude[bot] reacted with thumbs down emoji
All reactions
|
||
| from mcp.types import EmbeddedResource, TextResourceContents | ||
|
|
||
| mcp = MCPServer("Code Helper") | ||
|
|
||
| STYLE_GUIDE_FILE = Path(__file__).parent / "style-guide.md" # or the path to your file on disk | ||
|
|
||
|
|
||
| @mcp.resource("style://python", mime_type="text/markdown") | ||
| def style_guide() -> str: | ||
| """The team's Python style guide.""" | ||
| return STYLE_GUIDE_FILE.read_text(encoding="utf-8") | ||
|
|
||
|
|
||
| @mcp.prompt() | ||
| def review_code(code: str) -> list[Message]: | ||
| """Review a piece of code against the team style guide.""" | ||
| guide = TextResourceContents(uri="style://python", mime_type="text/markdown", text=style_guide()) | ||
| return [ | ||
| UserMessage(EmbeddedResource(resource=guide)), | ||
| UserMessage(f"Review this code against the style guide above:\n\n{code}"), | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| from pathlib import Path | ||
|
|
||
| from mcp.server import MCPServer | ||
| from mcp.server.mcpserver import Image, Message, UserMessage | ||
|
|
||
| mcp = MCPServer("Code Helper") | ||
|
|
||
| DIAGRAM_FILE = Path(__file__).parent / "architecture.png" # or the path to your file on disk | ||
|
|
||
|
|
||
| @mcp.prompt() | ||
| def explain_component(component: str) -> list[Message]: | ||
| """Explain one component using the architecture diagram.""" | ||
| return [ | ||
| UserMessage(Image(path=DIAGRAM_FILE)), | ||
| UserMessage(f"Where does {component} sit in this architecture, and what does it talk to?"), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| from contextlib import suppress | ||
|
|
||
| from mcp.server import MCPServer | ||
| from mcp.server.mcpserver import Context | ||
| from mcp.server.mcpserver.prompts import Prompt | ||
|
|
||
| mcp = MCPServer("Code Helper") | ||
|
|
||
|
|
||
| @mcp.prompt() | ||
| def review_code(code: str) -> str: | ||
| """Review a piece of code.""" | ||
| return f"Please review this code:\n\n{code}" | ||
|
|
||
|
|
||
| @mcp.tool() | ||
| async def save_template(name: str, instruction: str, ctx: Context) -> str: | ||
| """Save an instruction as a prompt the user can pick from the menu.""" | ||
|
|
||
| def template(code: str) -> str: | ||
| return f"{instruction}\n\n{code}" | ||
|
|
||
| with suppress(ValueError): # replace an existing entry of the same name | ||
| mcp.remove_prompt(name) | ||
| mcp.add_prompt(Prompt.from_function(template, name=name, description=instruction)) | ||
|
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
|
||
| await ctx.notify_prompts_changed() | ||
| await ctx.session.send_prompt_list_changed() | ||
| return f"Saved '{name}' to the prompt menu." | ||
|
Comment thread
claude[bot] marked this conversation as resolved.
|
||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality🟣 Pre-existing: new "Changing the list at runtime" section claims ctx.session.send_prompt_list_changed() notifies pre-2026 clients, but MCPServer advertises prompts.listChanged: false in every legacy handshake, so spec-compliant legacy clients ignore the notification the tutorial teaches
Extended reasoning...docs/servers/prompts.md:183 (and the recap at line 195, backed by docs_src/prompts/tutorial006.py:27) states "await ctx.session.send_prompt_list_changed() sends it to the calling client when that client is pre-2026". The notification is indeed written to the legacy standalone stream, but the server never declared it would send it: every MCPServer path builds the InitializeResult capabilities via create_initialization_options() with a default NotificationOptions() (src/mcp/server/mcpserver/server.py:1024 and :1115, src/mcp/server/runner.py:431 for the streamable-HTTP manager path), and Server.get_capabilities then sets PromptsCapability(list_changed=False) for handshake-era versions (src/mcp/server/lowlevel/server.py:588-595) — notification_options is only honored for modern versions via the subscriptions/listen derivation. The MCP spec makes prompts.listChanged the opt-in that tells a client to expect and handle notifications/prompts/list_changed, so a spec-compliant pre-2026 host that checks the negotiated capability ignores the notification (or never wires up a
Verification: pre-existing — the capability mismatch is real but lives in src/ code this docs-only PR did not touch. New docs/servers/prompts.md:183 teaches "await ctx.session.send_prompt_list_changed() sends it to the calling client when that client is pre-2026" (tutorial006.py:27 calls it), yet every MCPServer legacy handshake advertises prompts.listChanged: false: src/mcp/server/mcpserver/server.py:1024
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.