diff --git a/README.md b/README.md
index d76d3d267..6aea45102 100644
--- a/README.md
+++ b/README.md
@@ -877,13 +877,13 @@ The MCP protocol defines three core primitives that servers can implement:
MCP servers declare capabilities during initialization:
-| Capability | Feature Flag | Description |
-|-------------|------------------------------|------------------------------------|
-| `prompts` | `listChanged` | Prompt template management |
-| `resources` | `subscribe`
`listChanged`| Resource exposure and updates |
-| `tools` | `listChanged` | Tool discovery and execution |
-| `logging` | - | Server logging configuration |
-| `completion`| - | Argument completion suggestions |
+| Capability | Feature Flag | Description |
+|--------------|------------------------------|------------------------------------|
+| `prompts` | `listChanged` | Prompt template management |
+| `resources` | `subscribe`
`listChanged`| Resource exposure and updates |
+| `tools` | `listChanged` | Tool discovery and execution |
+| `logging` | - | Server logging configuration |
+| `completions`| - | Argument completion suggestions |
## Documentation
diff --git a/src/mcp/server/lowlevel/server.py b/src/mcp/server/lowlevel/server.py
index b98e3dd1a..5386040be 100644
--- a/src/mcp/server/lowlevel/server.py
+++ b/src/mcp/server/lowlevel/server.py
@@ -186,6 +186,7 @@ def get_capabilities(
resources_capability = None
tools_capability = None
logging_capability = None
+ completions_capability = None
# Set prompt capabilities if handler exists
if types.ListPromptsRequest in self.request_handlers:
@@ -209,12 +210,17 @@ def get_capabilities(
if types.SetLevelRequest in self.request_handlers:
logging_capability = types.LoggingCapability()
+ # Set completions capabilities if handler exists
+ if types.CompleteRequest in self.request_handlers:
+ completions_capability = types.CompletionsCapability()
+
return types.ServerCapabilities(
prompts=prompts_capability,
resources=resources_capability,
tools=tools_capability,
logging=logging_capability,
experimental=experimental_capabilities,
+ completions=completions_capability,
)
@property
diff --git a/src/mcp/types.py b/src/mcp/types.py
index 4f5af27b9..5ad0ec463 100644
--- a/src/mcp/types.py
+++ b/src/mcp/types.py
@@ -267,6 +267,12 @@ class LoggingCapability(BaseModel):
model_config = ConfigDict(extra="allow")
+class CompletionsCapability(BaseModel):
+ """Capability for completions operations."""
+
+ model_config = ConfigDict(extra="allow")
+
+
class ServerCapabilities(BaseModel):
"""Capabilities that a server may support."""
@@ -280,6 +286,10 @@ class ServerCapabilities(BaseModel):
"""Present if the server offers any resources to read."""
tools: ToolsCapability | None = None
"""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")
diff --git a/tests/server/test_session.py b/tests/server/test_session.py
index 1375df12f..c6bca7395 100644
--- a/tests/server/test_session.py
+++ b/tests/server/test_session.py
@@ -11,8 +11,13 @@
from mcp.shared.session import RequestResponder
from mcp.types import (
ClientNotification,
+ Completion,
+ CompletionArgument,
+ CompletionsCapability,
InitializedNotification,
+ PromptReference,
PromptsCapability,
+ ResourceReference,
ResourcesCapability,
ServerCapabilities,
)
@@ -88,6 +93,7 @@ async def test_server_capabilities():
caps = server.get_capabilities(notification_options, experimental_capabilities)
assert caps.prompts is None
assert caps.resources is None
+ assert caps.completions is None
# Add a prompts handler
@server.list_prompts()
@@ -97,6 +103,7 @@ async def list_prompts():
caps = server.get_capabilities(notification_options, experimental_capabilities)
assert caps.prompts == PromptsCapability(listChanged=False)
assert caps.resources is None
+ assert caps.completions is None
# Add a resources handler
@server.list_resources()
@@ -106,6 +113,21 @@ async def list_resources():
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 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