Skip to content

Commit c3dbc22

Browse files
author
Robin1987China
committed
fix: check_capability now validates elicitation sub-capabilities (form/url)
Schema has ElicitationCapability.form and .url sub-fields but check_capability only validated the top-level elicitation key. A client that supports URL elicitation but not form elicitation would incorrectly return True when the caller checks for form. Fix matches the existing sampling sub-capability pattern.
1 parent a527142 commit c3dbc22

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

src/mcp/server/connection.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,13 @@ def check_capability(self, capability: ClientCapabilities) -> bool:
337337
return False
338338
if capability.sampling.tools is not None and have.sampling.tools is None:
339339
return False
340-
if capability.elicitation is not None and have.elicitation is None:
341-
return False
340+
if capability.elicitation is not None:
341+
if have.elicitation is None:
342+
return False
343+
if capability.elicitation.form is not None and have.elicitation.form is None:
344+
return False
345+
if capability.elicitation.url is not None and have.elicitation.url is None:
346+
return False
342347
if capability.experimental is not None:
343348
if have.experimental is None:
344349
return False

tests/server/test_connection.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
CreateMessageRequestParams,
2828
ElicitationCapability,
2929
EmptyResult,
30+
FormElicitationCapability,
3031
Implementation,
3132
ListRootsRequest,
3233
ListRootsResult,
@@ -37,6 +38,7 @@
3738
SamplingCapability,
3839
SamplingContextCapability,
3940
SamplingToolsCapability,
41+
UrlElicitationCapability,
4042
)
4143

4244
_CLIENT_INFO = Implementation(name="t", version="0")
@@ -365,6 +367,28 @@ def test_connection_check_capability_false_when_no_client_params_recorded():
365367
(ClientCapabilities(experimental={"a": {}}), ClientCapabilities(experimental={"b": {}}), False),
366368
(ClientCapabilities(experimental={"a": {"x": 1}}), ClientCapabilities(experimental={"a": {"x": 2}}), False),
367369
(ClientCapabilities(experimental={"a": {}}), ClientCapabilities(experimental={"a": {}}), True),
370+
# Elicitation sub-capability checks (form / url)
371+
(ClientCapabilities(elicitation=None), ClientCapabilities(elicitation=ElicitationCapability()), False),
372+
(
373+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability())),
374+
ClientCapabilities(elicitation=ElicitationCapability(url=UrlElicitationCapability())),
375+
False,
376+
),
377+
(
378+
ClientCapabilities(elicitation=ElicitationCapability(url=UrlElicitationCapability())),
379+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability())),
380+
False,
381+
),
382+
(
383+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability(), url=UrlElicitationCapability())),
384+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability())),
385+
True,
386+
),
387+
(
388+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability())),
389+
ClientCapabilities(elicitation=ElicitationCapability(form=FormElicitationCapability())),
390+
True,
391+
),
368392
],
369393
)
370394
def test_check_capability_per_field_branches(have: ClientCapabilities, want: ClientCapabilities, expected: bool):

0 commit comments

Comments
 (0)