fix: Expose completions capability (#865)
This commit is contained in:
parent
3d67e723e5
commit
906ceea388
4 changed files with 41 additions and 7 deletions
14
README.md
14
README.md
|
|
@ -1327,13 +1327,13 @@ The MCP protocol defines three core primitives that servers can implement:
|
||||||
|
|
||||||
MCP servers declare capabilities during initialization:
|
MCP servers declare capabilities during initialization:
|
||||||
|
|
||||||
| Capability | Feature Flag | Description |
|
| Capability | Feature Flag | Description |
|
||||||
|-------------|------------------------------|------------------------------------|
|
|--------------|------------------------------|------------------------------------|
|
||||||
| `prompts` | `listChanged` | Prompt template management |
|
| `prompts` | `listChanged` | Prompt template management |
|
||||||
| `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates |
|
| `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates |
|
||||||
| `tools` | `listChanged` | Tool discovery and execution |
|
| `tools` | `listChanged` | Tool discovery and execution |
|
||||||
| `logging` | - | Server logging configuration |
|
| `logging` | - | Server logging configuration |
|
||||||
| `completion`| - | Argument completion suggestions |
|
| `completions`| - | Argument completion suggestions |
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ class Server(Generic[LifespanResultT, RequestT]):
|
||||||
resources_capability = None
|
resources_capability = None
|
||||||
tools_capability = None
|
tools_capability = None
|
||||||
logging_capability = None
|
logging_capability = None
|
||||||
|
completions_capability = None
|
||||||
|
|
||||||
# Set prompt capabilities if handler exists
|
# Set prompt capabilities if handler exists
|
||||||
if types.ListPromptsRequest in self.request_handlers:
|
if types.ListPromptsRequest in self.request_handlers:
|
||||||
|
|
@ -209,12 +210,17 @@ class Server(Generic[LifespanResultT, RequestT]):
|
||||||
if types.SetLevelRequest in self.request_handlers:
|
if types.SetLevelRequest in self.request_handlers:
|
||||||
logging_capability = types.LoggingCapability()
|
logging_capability = types.LoggingCapability()
|
||||||
|
|
||||||
|
# Set completions capabilities if handler exists
|
||||||
|
if types.CompleteRequest in self.request_handlers:
|
||||||
|
completions_capability = types.CompletionsCapability()
|
||||||
|
|
||||||
return types.ServerCapabilities(
|
return types.ServerCapabilities(
|
||||||
prompts=prompts_capability,
|
prompts=prompts_capability,
|
||||||
resources=resources_capability,
|
resources=resources_capability,
|
||||||
tools=tools_capability,
|
tools=tools_capability,
|
||||||
logging=logging_capability,
|
logging=logging_capability,
|
||||||
experimental=experimental_capabilities,
|
experimental=experimental_capabilities,
|
||||||
|
completions=completions_capability,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,12 @@ class LoggingCapability(BaseModel):
|
||||||
model_config = ConfigDict(extra="allow")
|
model_config = ConfigDict(extra="allow")
|
||||||
|
|
||||||
|
|
||||||
|
class CompletionsCapability(BaseModel):
|
||||||
|
"""Capability for completions operations."""
|
||||||
|
|
||||||
|
model_config = ConfigDict(extra="allow")
|
||||||
|
|
||||||
|
|
||||||
class ServerCapabilities(BaseModel):
|
class ServerCapabilities(BaseModel):
|
||||||
"""Capabilities that a server may support."""
|
"""Capabilities that a server may support."""
|
||||||
|
|
||||||
|
|
@ -299,6 +305,8 @@ class ServerCapabilities(BaseModel):
|
||||||
"""Present if the server offers any resources to read."""
|
"""Present if the server offers any resources to read."""
|
||||||
tools: ToolsCapability | None = None
|
tools: ToolsCapability | None = None
|
||||||
"""Present if the server offers any tools to call."""
|
"""Present if the server offers any tools to call."""
|
||||||
|
completions: CompletionsCapability | None = None
|
||||||
|
"""Present if the server offers autocompletion suggestions for prompts and resources."""
|
||||||
model_config = ConfigDict(extra="allow")
|
model_config = ConfigDict(extra="allow")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,13 @@ from mcp.shared.message import SessionMessage
|
||||||
from mcp.shared.session import RequestResponder
|
from mcp.shared.session import RequestResponder
|
||||||
from mcp.types import (
|
from mcp.types import (
|
||||||
ClientNotification,
|
ClientNotification,
|
||||||
|
Completion,
|
||||||
|
CompletionArgument,
|
||||||
|
CompletionsCapability,
|
||||||
InitializedNotification,
|
InitializedNotification,
|
||||||
|
PromptReference,
|
||||||
PromptsCapability,
|
PromptsCapability,
|
||||||
|
ResourceReference,
|
||||||
ResourcesCapability,
|
ResourcesCapability,
|
||||||
ServerCapabilities,
|
ServerCapabilities,
|
||||||
)
|
)
|
||||||
|
|
@ -80,6 +85,7 @@ async def test_server_capabilities():
|
||||||
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
||||||
assert caps.prompts is None
|
assert caps.prompts is None
|
||||||
assert caps.resources is None
|
assert caps.resources is None
|
||||||
|
assert caps.completions is None
|
||||||
|
|
||||||
# Add a prompts handler
|
# Add a prompts handler
|
||||||
@server.list_prompts()
|
@server.list_prompts()
|
||||||
|
|
@ -89,6 +95,7 @@ async def test_server_capabilities():
|
||||||
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
||||||
assert caps.prompts == PromptsCapability(listChanged=False)
|
assert caps.prompts == PromptsCapability(listChanged=False)
|
||||||
assert caps.resources is None
|
assert caps.resources is None
|
||||||
|
assert caps.completions is None
|
||||||
|
|
||||||
# Add a resources handler
|
# Add a resources handler
|
||||||
@server.list_resources()
|
@server.list_resources()
|
||||||
|
|
@ -98,6 +105,19 @@ async def test_server_capabilities():
|
||||||
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
||||||
assert caps.prompts == PromptsCapability(listChanged=False)
|
assert caps.prompts == PromptsCapability(listChanged=False)
|
||||||
assert caps.resources == ResourcesCapability(subscribe=False, listChanged=False)
|
assert caps.resources == ResourcesCapability(subscribe=False, listChanged=False)
|
||||||
|
assert caps.completions is None
|
||||||
|
|
||||||
|
# Add a complete handler
|
||||||
|
@server.completion()
|
||||||
|
async def complete(ref: PromptReference | ResourceReference, argument: CompletionArgument):
|
||||||
|
return Completion(
|
||||||
|
values=["completion1", "completion2"],
|
||||||
|
)
|
||||||
|
|
||||||
|
caps = server.get_capabilities(notification_options, experimental_capabilities)
|
||||||
|
assert caps.prompts == PromptsCapability(listChanged=False)
|
||||||
|
assert caps.resources == ResourcesCapability(subscribe=False, listChanged=False)
|
||||||
|
assert caps.completions == CompletionsCapability()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue