refactor: use snake case instead of camel case in types (#1894)
This commit is contained in:
parent
7080fcf1e6
commit
e94b386a13
127 changed files with 1063 additions and 1057 deletions
40
README.md
40
README.md
|
|
@ -442,7 +442,7 @@ def validated_tool() -> Annotated[CallToolResult, ValidationModel]:
|
|||
"""Return CallToolResult with structured output validation."""
|
||||
return CallToolResult(
|
||||
content=[TextContent(type="text", text="Validated response")],
|
||||
structuredContent={"status": "success", "data": {"result": 42}},
|
||||
structured_content={"status": "success", "data": {"result": 42}},
|
||||
_meta={"internal": "metadata"},
|
||||
)
|
||||
|
||||
|
|
@ -757,8 +757,8 @@ async def run():
|
|||
# List available resource templates
|
||||
templates = await session.list_resource_templates()
|
||||
print("Available resource templates:")
|
||||
for template in templates.resourceTemplates:
|
||||
print(f" - {template.uriTemplate}")
|
||||
for template in templates.resource_templates:
|
||||
print(f" - {template.uri_template}")
|
||||
|
||||
# List available prompts
|
||||
prompts = await session.list_prompts()
|
||||
|
|
@ -767,20 +767,20 @@ async def run():
|
|||
print(f" - {prompt.name}")
|
||||
|
||||
# Complete resource template arguments
|
||||
if templates.resourceTemplates:
|
||||
template = templates.resourceTemplates[0]
|
||||
print(f"\nCompleting arguments for resource template: {template.uriTemplate}")
|
||||
if templates.resource_templates:
|
||||
template = templates.resource_templates[0]
|
||||
print(f"\nCompleting arguments for resource template: {template.uri_template}")
|
||||
|
||||
# Complete without context
|
||||
result = await session.complete(
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate),
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uri_template),
|
||||
argument={"name": "owner", "value": "model"},
|
||||
)
|
||||
print(f"Completions for 'owner' starting with 'model': {result.completion.values}")
|
||||
|
||||
# Complete with context - repo suggestions based on owner
|
||||
result = await session.complete(
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate),
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uri_template),
|
||||
argument={"name": "repo", "value": ""},
|
||||
context_arguments={"owner": "modelcontextprotocol"},
|
||||
)
|
||||
|
|
@ -910,7 +910,7 @@ async def connect_service(service_name: str, ctx: Context[ServerSession, None])
|
|||
mode="url",
|
||||
message=f"Authorization required to connect to {service_name}",
|
||||
url=f"https://{service_name}.example.com/oauth/authorize?elicit={elicitation_id}",
|
||||
elicitationId=elicitation_id,
|
||||
elicitation_id=elicitation_id,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -1706,7 +1706,7 @@ async def handle_list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="query_db",
|
||||
description="Query the database",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {"query": {"type": "string", "description": "SQL query to execute"}},
|
||||
"required": ["query"],
|
||||
|
|
@ -1867,12 +1867,12 @@ async def list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="get_weather",
|
||||
description="Get current weather for a city",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string", "description": "City name"}},
|
||||
"required": ["city"],
|
||||
},
|
||||
outputSchema={
|
||||
output_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"temperature": {"type": "number", "description": "Temperature in Celsius"},
|
||||
|
|
@ -1970,7 +1970,7 @@ async def list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="advanced_tool",
|
||||
description="Tool with full control including _meta field",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {"message": {"type": "string"}},
|
||||
"required": ["message"],
|
||||
|
|
@ -1986,7 +1986,7 @@ async def handle_call_tool(name: str, arguments: dict[str, Any]) -> types.CallTo
|
|||
message = str(arguments.get("message", ""))
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=f"Processed: {message}")],
|
||||
structuredContent={"result": "success", "message": message},
|
||||
structured_content={"result": "success", "message": message},
|
||||
_meta={"hidden": "data for client applications only"},
|
||||
)
|
||||
|
||||
|
|
@ -2062,7 +2062,7 @@ async def list_resources_paginated(request: types.ListResourcesRequest) -> types
|
|||
# Determine next cursor
|
||||
next_cursor = str(end) if end < len(ITEMS) else None
|
||||
|
||||
return types.ListResourcesResult(resources=page_items, nextCursor=next_cursor)
|
||||
return types.ListResourcesResult(resources=page_items, next_cursor=next_cursor)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/pagination_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/pagination_example.py)_
|
||||
|
|
@ -2103,8 +2103,8 @@ async def list_all_resources() -> None:
|
|||
print(f"Fetched {len(result.resources)} resources")
|
||||
|
||||
# Check if there are more pages
|
||||
if result.nextCursor:
|
||||
cursor = result.nextCursor
|
||||
if result.next_cursor:
|
||||
cursor = result.next_cursor
|
||||
else:
|
||||
break
|
||||
|
||||
|
|
@ -2167,7 +2167,7 @@ async def handle_sampling_message(
|
|||
text="Hello, world! from model",
|
||||
),
|
||||
model="gpt-3.5-turbo",
|
||||
stopReason="endTurn",
|
||||
stop_reason="endTurn",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -2205,7 +2205,7 @@ async def run():
|
|||
result_unstructured = result.content[0]
|
||||
if isinstance(result_unstructured, types.TextContent):
|
||||
print(f"Tool result: {result_unstructured.text}")
|
||||
result_structured = result.structuredContent
|
||||
result_structured = result.structured_content
|
||||
print(f"Structured tool result: {result_structured}")
|
||||
|
||||
|
||||
|
|
@ -2306,7 +2306,7 @@ async def display_resources(session: ClientSession):
|
|||
print(f"Resource: {display_name} ({resource.uri})")
|
||||
|
||||
templates_response = await session.list_resource_templates()
|
||||
for template in templates_response.resourceTemplates:
|
||||
for template in templates_response.resource_templates:
|
||||
display_name = get_display_name(template)
|
||||
print(f"Resource Template: {display_name}")
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class Server:
|
|||
|
||||
for item in tools_response:
|
||||
if item[0] == "tools":
|
||||
tools.extend(Tool(tool.name, tool.description, tool.inputSchema, tool.title) for tool in item[1])
|
||||
tools.extend(Tool(tool.name, tool.description, tool.input_schema, tool.title) for tool in item[1])
|
||||
|
||||
return tools
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ async def run(url: str) -> None:
|
|||
arguments={},
|
||||
ttl=60000,
|
||||
)
|
||||
task_id = result.task.taskId
|
||||
task_id = result.task.task_id
|
||||
print(f"Task created: {task_id}")
|
||||
|
||||
status = None
|
||||
# Poll until done (respects server's pollInterval hint)
|
||||
async for status in session.experimental.poll_task(task_id):
|
||||
print(f" Status: {status.status} - {status.statusMessage or ''}")
|
||||
print(f" Status: {status.status} - {status.status_message or ''}")
|
||||
|
||||
# Check final status
|
||||
if status and status.status != "completed":
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ async def sampling_callback(context, params) -> CreateMessageResult:
|
|||
```python
|
||||
# Call a tool as a task (returns immediately with task reference)
|
||||
result = await session.experimental.call_tool_as_task("tool_name", {"arg": "value"})
|
||||
task_id = result.task.taskId
|
||||
task_id = result.task.task_id
|
||||
|
||||
# Get result - this delivers elicitation/sampling requests and blocks until complete
|
||||
final = await session.experimental.get_task_result(task_id, CallToolResult)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ async def run(url: str) -> None:
|
|||
print("Calling confirm_delete tool...")
|
||||
|
||||
elicit_task = await session.experimental.call_tool_as_task("confirm_delete", {"filename": "important.txt"})
|
||||
elicit_task_id = elicit_task.task.taskId
|
||||
elicit_task_id = elicit_task.task.task_id
|
||||
print(f"Task created: {elicit_task_id}")
|
||||
|
||||
# Poll until terminal, calling tasks/result on input_required
|
||||
|
|
@ -112,7 +112,7 @@ async def run(url: str) -> None:
|
|||
print("Calling write_haiku tool...")
|
||||
|
||||
sampling_task = await session.experimental.call_tool_as_task("write_haiku", {"topic": "autumn leaves"})
|
||||
sampling_task_id = sampling_task.task.taskId
|
||||
sampling_task_id = sampling_task.task.task_id
|
||||
print(f"Task created: {sampling_task_id}")
|
||||
|
||||
# Poll until terminal, calling tasks/result on input_required
|
||||
|
|
|
|||
|
|
@ -20,5 +20,5 @@ class EchoResponse(BaseModel):
|
|||
def echo(text: str) -> Annotated[CallToolResult, EchoResponse]:
|
||||
"""Echo the input text with structure and metadata"""
|
||||
return CallToolResult(
|
||||
content=[TextContent(type="text", text=text)], structuredContent={"text": text}, _meta={"some": "metadata"}
|
||||
content=[TextContent(type="text", text=text)], structured_content={"text": text}, _meta={"some": "metadata"}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ icon_path = Path(__file__).parent / "mcp.png"
|
|||
icon_data = base64.standard_b64encode(icon_path.read_bytes()).decode()
|
||||
icon_data_uri = f"data:image/png;base64,{icon_data}"
|
||||
|
||||
icon_data = Icon(src=icon_data_uri, mimeType="image/png", sizes=["64x64"])
|
||||
icon_data = Icon(src=icon_data_uri, mime_type="image/png", sizes=["64x64"])
|
||||
|
||||
# Create server with icons in implementation
|
||||
mcp = FastMCP("Icons Demo Server", website_url="https://github.com/modelcontextprotocol/python-sdk", icons=[icon_data])
|
||||
|
|
@ -40,9 +40,9 @@ def prompt_with_icon(text: str) -> str:
|
|||
|
||||
@mcp.tool(
|
||||
icons=[
|
||||
Icon(src=icon_data_uri, mimeType="image/png", sizes=["16x16"]),
|
||||
Icon(src=icon_data_uri, mimeType="image/png", sizes=["32x32"]),
|
||||
Icon(src=icon_data_uri, mimeType="image/png", sizes=["64x64"]),
|
||||
Icon(src=icon_data_uri, mime_type="image/png", sizes=["16x16"]),
|
||||
Icon(src=icon_data_uri, mime_type="image/png", sizes=["32x32"]),
|
||||
Icon(src=icon_data_uri, mime_type="image/png", sizes=["64x64"]),
|
||||
]
|
||||
)
|
||||
def multi_icon_tool(action: str) -> str:
|
||||
|
|
|
|||
|
|
@ -161,32 +161,32 @@ if __name__ == "__main__":
|
|||
# Test get_weather
|
||||
result = await client.call_tool("get_weather", {"city": "London"})
|
||||
print("\nWeather in London:")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Test get_weather_summary
|
||||
result = await client.call_tool("get_weather_summary", {"city": "Paris"})
|
||||
print("\nWeather summary for Paris:")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Test get_weather_metrics
|
||||
result = await client.call_tool("get_weather_metrics", {"cities": ["Tokyo", "Sydney", "Mumbai"]})
|
||||
print("\nWeather metrics:")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Test get_weather_alerts
|
||||
result = await client.call_tool("get_weather_alerts", {"region": "California"})
|
||||
print("\nWeather alerts for California:")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Test get_temperature
|
||||
result = await client.call_tool("get_temperature", {"city": "Berlin", "unit": "fahrenheit"})
|
||||
print("\nTemperature in Berlin:")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Test get_weather_stats
|
||||
result = await client.call_tool("get_weather_stats", {"city": "Seattle", "days": 30})
|
||||
print("\nWeather stats for Seattle (30 days):")
|
||||
print(json.dumps(result.structuredContent, indent=2))
|
||||
print(json.dumps(result.structured_content, indent=2))
|
||||
|
||||
# Also show the text content for comparison
|
||||
print("\nText content for last result:")
|
||||
|
|
@ -204,11 +204,11 @@ if __name__ == "__main__":
|
|||
print(f"\nTool: {tool.name}")
|
||||
print(f"Description: {tool.description}")
|
||||
print("Input Schema:")
|
||||
print(json.dumps(tool.inputSchema, indent=2))
|
||||
print(json.dumps(tool.input_schema, indent=2))
|
||||
|
||||
if tool.outputSchema:
|
||||
if tool.output_schema:
|
||||
print("Output Schema:")
|
||||
print(json.dumps(tool.outputSchema, indent=2))
|
||||
print(json.dumps(tool.output_schema, indent=2))
|
||||
else:
|
||||
print("Output Schema: None (returns unstructured content)")
|
||||
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@ def test_simple_text() -> str:
|
|||
@mcp.tool()
|
||||
def test_image_content() -> list[ImageContent]:
|
||||
"""Tests image content response"""
|
||||
return [ImageContent(type="image", data=TEST_IMAGE_BASE64, mimeType="image/png")]
|
||||
return [ImageContent(type="image", data=TEST_IMAGE_BASE64, mime_type="image/png")]
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def test_audio_content() -> list[AudioContent]:
|
||||
"""Tests audio content response"""
|
||||
return [AudioContent(type="audio", data=TEST_AUDIO_BASE64, mimeType="audio/wav")]
|
||||
return [AudioContent(type="audio", data=TEST_AUDIO_BASE64, mime_type="audio/wav")]
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
|
|
@ -115,7 +115,7 @@ def test_embedded_resource() -> list[EmbeddedResource]:
|
|||
type="resource",
|
||||
resource=TextResourceContents(
|
||||
uri="test://embedded-resource",
|
||||
mimeType="text/plain",
|
||||
mime_type="text/plain",
|
||||
text="This is an embedded resource content.",
|
||||
),
|
||||
)
|
||||
|
|
@ -127,12 +127,12 @@ def test_multiple_content_types() -> list[TextContent | ImageContent | EmbeddedR
|
|||
"""Tests response with multiple content types (text, image, resource)"""
|
||||
return [
|
||||
TextContent(type="text", text="Multiple content types test:"),
|
||||
ImageContent(type="image", data=TEST_IMAGE_BASE64, mimeType="image/png"),
|
||||
ImageContent(type="image", data=TEST_IMAGE_BASE64, mime_type="image/png"),
|
||||
EmbeddedResource(
|
||||
type="resource",
|
||||
resource=TextResourceContents(
|
||||
uri="test://mixed-content-resource",
|
||||
mimeType="application/json",
|
||||
mime_type="application/json",
|
||||
text='{"test": "data", "value": 123}',
|
||||
),
|
||||
),
|
||||
|
|
@ -164,7 +164,7 @@ async def test_tool_with_progress(ctx: Context[ServerSession, None]) -> str:
|
|||
await ctx.report_progress(progress=100, total=100, message="Completed step 100 of 100")
|
||||
|
||||
# Return progress token as string
|
||||
progress_token = ctx.request_context.meta.progressToken if ctx.request_context and ctx.request_context.meta else 0
|
||||
progress_token = ctx.request_context.meta.progress_token if ctx.request_context and ctx.request_context.meta else 0
|
||||
return str(progress_token)
|
||||
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ def test_prompt_with_embedded_resource(resourceUri: str) -> list[UserMessage]:
|
|||
type="resource",
|
||||
resource=TextResourceContents(
|
||||
uri=resourceUri,
|
||||
mimeType="text/plain",
|
||||
mime_type="text/plain",
|
||||
text="Embedded resource content for testing.",
|
||||
),
|
||||
),
|
||||
|
|
@ -386,7 +386,7 @@ def test_prompt_with_embedded_resource(resourceUri: str) -> list[UserMessage]:
|
|||
def test_prompt_with_image() -> list[UserMessage]:
|
||||
"""A prompt that includes image content"""
|
||||
return [
|
||||
UserMessage(role="user", content=ImageContent(type="image", data=TEST_IMAGE_BASE64, mimeType="image/png")),
|
||||
UserMessage(role="user", content=ImageContent(type="image", data=TEST_IMAGE_BASE64, mime_type="image/png")),
|
||||
UserMessage(role="user", content=TextContent(type="text", text="Please analyze the image above.")),
|
||||
]
|
||||
|
||||
|
|
@ -427,7 +427,7 @@ async def _handle_completion(
|
|||
"""Handle completion requests"""
|
||||
# Basic completion support - returns empty array for conformance
|
||||
# Real implementations would provide contextual suggestions
|
||||
return Completion(values=[], total=0, hasMore=False)
|
||||
return Completion(values=[], total=0, has_more=False)
|
||||
|
||||
|
||||
# CLI
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ SAMPLE_TOOLS = [
|
|||
name=f"tool_{i}",
|
||||
title=f"Tool {i}",
|
||||
description=f"This is sample tool number {i}",
|
||||
inputSchema={"type": "object", "properties": {"input": {"type": "string"}}},
|
||||
input_schema={"type": "object", "properties": {"input": {"type": "string"}}},
|
||||
)
|
||||
for i in range(1, 26) # 25 tools total
|
||||
]
|
||||
|
|
@ -71,7 +71,7 @@ def main(port: int, transport: str) -> int:
|
|||
start_idx = int(cursor)
|
||||
except (ValueError, TypeError):
|
||||
# Invalid cursor, return empty
|
||||
return types.ListToolsResult(tools=[], nextCursor=None)
|
||||
return types.ListToolsResult(tools=[], next_cursor=None)
|
||||
|
||||
# Get the page of tools
|
||||
page_tools = SAMPLE_TOOLS[start_idx : start_idx + page_size]
|
||||
|
|
@ -81,7 +81,7 @@ def main(port: int, transport: str) -> int:
|
|||
if start_idx + page_size < len(SAMPLE_TOOLS):
|
||||
next_cursor = str(start_idx + page_size)
|
||||
|
||||
return types.ListToolsResult(tools=page_tools, nextCursor=next_cursor)
|
||||
return types.ListToolsResult(tools=page_tools, next_cursor=next_cursor)
|
||||
|
||||
# Paginated list_resources - returns 10 resources per page
|
||||
@app.list_resources()
|
||||
|
|
@ -100,7 +100,7 @@ def main(port: int, transport: str) -> int:
|
|||
start_idx = int(cursor)
|
||||
except (ValueError, TypeError):
|
||||
# Invalid cursor, return empty
|
||||
return types.ListResourcesResult(resources=[], nextCursor=None)
|
||||
return types.ListResourcesResult(resources=[], next_cursor=None)
|
||||
|
||||
# Get the page of resources
|
||||
page_resources = SAMPLE_RESOURCES[start_idx : start_idx + page_size]
|
||||
|
|
@ -110,7 +110,7 @@ def main(port: int, transport: str) -> int:
|
|||
if start_idx + page_size < len(SAMPLE_RESOURCES):
|
||||
next_cursor = str(start_idx + page_size)
|
||||
|
||||
return types.ListResourcesResult(resources=page_resources, nextCursor=next_cursor)
|
||||
return types.ListResourcesResult(resources=page_resources, next_cursor=next_cursor)
|
||||
|
||||
# Paginated list_prompts - returns 7 prompts per page
|
||||
@app.list_prompts()
|
||||
|
|
@ -129,7 +129,7 @@ def main(port: int, transport: str) -> int:
|
|||
start_idx = int(cursor)
|
||||
except (ValueError, TypeError):
|
||||
# Invalid cursor, return empty
|
||||
return types.ListPromptsResult(prompts=[], nextCursor=None)
|
||||
return types.ListPromptsResult(prompts=[], next_cursor=None)
|
||||
|
||||
# Get the page of prompts
|
||||
page_prompts = SAMPLE_PROMPTS[start_idx : start_idx + page_size]
|
||||
|
|
@ -139,7 +139,7 @@ def main(port: int, transport: str) -> int:
|
|||
if start_idx + page_size < len(SAMPLE_PROMPTS):
|
||||
next_cursor = str(start_idx + page_size)
|
||||
|
||||
return types.ListPromptsResult(prompts=page_prompts, nextCursor=next_cursor)
|
||||
return types.ListPromptsResult(prompts=page_prompts, next_cursor=next_cursor)
|
||||
|
||||
# Implement call_tool handler
|
||||
@app.call_tool()
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ def main(port: int, transport: str) -> int:
|
|||
name=name,
|
||||
title=SAMPLE_RESOURCES[name]["title"],
|
||||
description=f"A sample text resource named {name}",
|
||||
mimeType="text/plain",
|
||||
mime_type="text/plain",
|
||||
)
|
||||
for name in SAMPLE_RESOURCES.keys()
|
||||
]
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ def main(
|
|||
types.Tool(
|
||||
name="start-notification-stream",
|
||||
description=("Sends a stream of notifications with configurable count and interval"),
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"required": ["interval", "count", "caller"],
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ def main(
|
|||
types.Tool(
|
||||
name="start-notification-stream",
|
||||
description=("Sends a stream of notifications with configurable count and interval"),
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"required": ["interval", "count", "caller"],
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -31,17 +31,17 @@ async def list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="confirm_delete",
|
||||
description="Asks for confirmation before deleting (demonstrates elicitation)",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {"filename": {"type": "string"}},
|
||||
},
|
||||
execution=types.ToolExecution(taskSupport=types.TASK_REQUIRED),
|
||||
execution=types.ToolExecution(task_support=types.TASK_REQUIRED),
|
||||
),
|
||||
types.Tool(
|
||||
name="write_haiku",
|
||||
description="Asks LLM to write a haiku (demonstrates sampling)",
|
||||
inputSchema={"type": "object", "properties": {"topic": {"type": "string"}}},
|
||||
execution=types.ToolExecution(taskSupport=types.TASK_REQUIRED),
|
||||
input_schema={"type": "object", "properties": {"topic": {"type": "string"}}},
|
||||
execution=types.ToolExecution(task_support=types.TASK_REQUIRED),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ async def handle_confirm_delete(arguments: dict[str, Any]) -> types.CreateTaskRe
|
|||
|
||||
result = await task.elicit(
|
||||
message=f"Are you sure you want to delete '{filename}'?",
|
||||
requestedSchema={
|
||||
requested_schema={
|
||||
"type": "object",
|
||||
"properties": {"confirm": {"type": "boolean"}},
|
||||
"required": ["confirm"],
|
||||
|
|
@ -121,7 +121,7 @@ async def handle_call_tool(name: str, arguments: dict[str, Any]) -> types.CallTo
|
|||
else:
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=f"Unknown tool: {name}")],
|
||||
isError=True,
|
||||
is_error=True,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ async def list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="long_running_task",
|
||||
description="A task that takes a few seconds to complete with status updates",
|
||||
inputSchema={"type": "object", "properties": {}},
|
||||
execution=types.ToolExecution(taskSupport=types.TASK_REQUIRED),
|
||||
input_schema={"type": "object", "properties": {}},
|
||||
execution=types.ToolExecution(task_support=types.TASK_REQUIRED),
|
||||
)
|
||||
]
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ async def handle_call_tool(name: str, arguments: dict[str, Any]) -> types.CallTo
|
|||
else:
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=f"Unknown tool: {name}")],
|
||||
isError=True,
|
||||
is_error=True,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def main(port: int, transport: str) -> int:
|
|||
name="fetch",
|
||||
title="Website Fetcher",
|
||||
description="Fetches a website and returns its content",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"required": ["url"],
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ def main(port: int, log_level: str, retry_interval: int) -> int:
|
|||
"Process a batch of items with periodic checkpoints. "
|
||||
"Demonstrates SSE polling where server closes stream periodically."
|
||||
),
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ async def list_tools() -> list[types.Tool]:
|
|||
types.Tool(
|
||||
name="get_weather",
|
||||
description="Get weather information (simulated)",
|
||||
inputSchema={
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string", "description": "City name"}},
|
||||
"required": ["city"],
|
||||
},
|
||||
outputSchema={
|
||||
output_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"temperature": {"type": "number"},
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ async def run():
|
|||
# List available resource templates
|
||||
templates = await session.list_resource_templates()
|
||||
print("Available resource templates:")
|
||||
for template in templates.resourceTemplates:
|
||||
print(f" - {template.uriTemplate}")
|
||||
for template in templates.resource_templates:
|
||||
print(f" - {template.uri_template}")
|
||||
|
||||
# List available prompts
|
||||
prompts = await session.list_prompts()
|
||||
|
|
@ -38,20 +38,20 @@ async def run():
|
|||
print(f" - {prompt.name}")
|
||||
|
||||
# Complete resource template arguments
|
||||
if templates.resourceTemplates:
|
||||
template = templates.resourceTemplates[0]
|
||||
print(f"\nCompleting arguments for resource template: {template.uriTemplate}")
|
||||
if templates.resource_templates:
|
||||
template = templates.resource_templates[0]
|
||||
print(f"\nCompleting arguments for resource template: {template.uri_template}")
|
||||
|
||||
# Complete without context
|
||||
result = await session.complete(
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate),
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uri_template),
|
||||
argument={"name": "owner", "value": "model"},
|
||||
)
|
||||
print(f"Completions for 'owner' starting with 'model': {result.completion.values}")
|
||||
|
||||
# Complete with context - repo suggestions based on owner
|
||||
result = await session.complete(
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uriTemplate),
|
||||
ref=ResourceTemplateReference(type="ref/resource", uri=template.uri_template),
|
||||
argument={"name": "repo", "value": ""},
|
||||
context_arguments={"owner": "modelcontextprotocol"},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ async def display_resources(session: ClientSession):
|
|||
print(f"Resource: {display_name} ({resource.uri})")
|
||||
|
||||
templates_response = await session.list_resource_templates()
|
||||
for template in templates_response.resourceTemplates:
|
||||
for template in templates_response.resource_templates:
|
||||
display_name = get_display_name(template)
|
||||
print(f"Resource Template: {display_name}")
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue