blob: 6479d3418a3a5e07c1ec37144c99d2504db0fb8e [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Static managers used to verify MCP list pagination across transports."""
from __future__ import annotations
import json
import logging
from dataclasses import dataclass
from typing import Any
from mcp.types import (
GetPromptResult,
Prompt,
PromptMessage,
Resource,
TextContent,
Tool,
)
from doris_mcp_server import __version__
from doris_mcp_server.protocol import create_doris_mcp_server
RESOURCE_URIS = [
"doris://table/alpha",
"doris://table/bravo",
"doris://table/charlie",
"doris://table/delta",
"doris://table/echo",
]
TOOL_NAMES = ["alpha", "bravo", "charlie", "delta", "echo"]
PROMPT_NAMES = ["alpha", "bravo", "charlie", "delta", "echo"]
@dataclass
class PaginationManagers:
resources: PaginationResourcesManager
tools: PaginationToolsManager
prompts: PaginationPromptsManager
class PaginationResourcesManager:
def __init__(self) -> None:
self.resources = [
Resource(
uri=uri,
name=uri.rsplit("/", 1)[-1],
mime_type="application/json",
)
for uri in reversed(RESOURCE_URIS)
]
async def list_resources(self) -> list[Resource]:
return list(self.resources)
async def read_resource(self, uri: str) -> str:
return json.dumps({"uri": uri})
class PaginationToolsManager:
def __init__(self) -> None:
self.tools = [
Tool(
name=name,
description=f"{name} test tool",
input_schema={"type": "object", "properties": {}},
)
for name in reversed(TOOL_NAMES)
]
async def list_tools(self) -> list[Tool]:
return list(self.tools)
async def call_tool(self, name: str, arguments: dict[str, Any]) -> str:
return json.dumps({"name": name, "arguments": arguments})
class PaginationPromptsManager:
def __init__(self) -> None:
self.prompts = [
Prompt(name=name, description=f"{name} test prompt")
for name in reversed(PROMPT_NAMES)
]
async def list_prompts(self) -> list[Prompt]:
return list(self.prompts)
async def get_prompt(
self,
name: str,
arguments: dict[str, Any],
) -> GetPromptResult:
return GetPromptResult(
description=name,
messages=[
PromptMessage(
role="user",
content=TextContent(
type="text",
text=json.dumps(arguments, sort_keys=True),
),
)
],
)
def create_pagination_server(
*,
page_size: int = 2,
state_handle_secret: str | None = None,
state_handle_ttl_seconds: int = 300,
):
resources = PaginationResourcesManager()
tools = PaginationToolsManager()
prompts = PaginationPromptsManager()
server = create_doris_mcp_server(
resources_manager=resources,
tools_manager=tools,
prompts_manager=prompts,
name="doris-mcp-pagination-test",
version=__version__,
logger=logging.getLogger(__name__),
list_page_size=page_size,
state_handle_secret=state_handle_secret,
state_handle_ttl_seconds=state_handle_ttl_seconds,
)
return server, PaginationManagers(
resources=resources,
tools=tools,
prompts=prompts,
)