Skip to content

Commit 52143f9

Browse files
committed
Move Skills client API into extensions
1 parent 7ff625f commit 52143f9

9 files changed

Lines changed: 20 additions & 17 deletions

File tree

‎docs/advanced/extensions.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ after connecting to get the API bound to that connection. Run the
198198
import anyio
199199

200200
from mcp import Client
201-
from mcp.client.skills import Skills
201+
from mcp.client.extensions.skills import Skills
202202

203203

204204
async def main() -> None:

‎docs/advanced/skills.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ get the verbs tied to that connection:
5656
--8<-- "docs_src/skills/tutorial001_client.py"
5757
```
5858

59-
`client.extension(Skills)` hands you a `BoundSkills` with the SEP-2640 methods:
59+
`client.extension(Skills)` hands you a `SkillsClient` with the SEP-2640 methods:
6060

6161
* `list_skills` and `read_directory` follow `nextCursor` to completion, so a single call gives you
6262
every page's skills or resources.

‎docs_src/skills/tutorial001_client.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import anyio
22

33
from mcp import Client
4-
from mcp.client.skills import Skills
4+
from mcp.client.extensions.skills import Skills
55

66

77
async def main() -> None:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from mcp.client.extensions.skills import Skills, SkillsClient
2+
3+
__all__ = ["Skills", "SkillsClient"]
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
for skill in await client.extension(Skills).list_skills():
1010
print(skill.uri, skill.frontmatter["description"])
1111
12-
`client.extension(Skills)` returns a `BoundSkills`. Its catalog verbs — `list_skills`,
12+
`client.extension(Skills)` returns a `SkillsClient`. Its catalog verbs — `list_skills`,
1313
`get_skill`, and `read_directory` — check that the server advertises the
1414
extension and validate its response; `list_skills` and `read_directory` follow
1515
`nextCursor` to completion, so one call returns every page's results.
@@ -36,25 +36,25 @@
3636
validate_directory_result,
3737
)
3838

39-
__all__ = ["BoundSkills", "Skills"]
39+
__all__ = ["Skills", "SkillsClient"]
4040

4141

4242
class Skills(ClientExtension):
4343
"""The client-side Skills extension: register, then access its typed verbs.
4444
4545
Pass an instance to `Client(extensions=[Skills()])` — this advertises
4646
`io.modelcontextprotocol/skills` under the client's capabilities — and call
47-
`client.extension(Skills)` once connected for a `BoundSkills` handle.
47+
`client.extension(Skills)` once connected for a `SkillsClient` handle.
4848
"""
4949

5050
identifier = EXTENSION_ID
5151

52-
def bind(self, session: ClientSession) -> BoundSkills:
52+
def bind(self, session: ClientSession) -> SkillsClient:
5353
"""Return the SEP-2640 verbs bound to `session`."""
54-
return BoundSkills(session)
54+
return SkillsClient(session)
5555

5656

57-
class BoundSkills:
57+
class SkillsClient:
5858
"""The SEP-2640 verbs bound to one connected session.
5959
6060
Obtain it from `client.extension(Skills)`. The catalog verbs — `list_skills`,

‎src/mcp/shared/skills.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Wire types and SEP-2640 conformance checks for the Skills extension.
22
3-
Shared by the server (`mcp.server.skills`) and client (`mcp.client.skills`)
3+
Shared by the server (`mcp.server.skills`) and client (`mcp.client.extensions.skills`)
44
surfaces, mirroring how `mcp.shared.extension` hosts the identifier grammar
55
both tiers need. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640.
66
"""
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Tests for the client-side Skills extension (SEP-2640, `mcp.client.skills`)."""
1+
"""Tests for the client-side Skills extension (SEP-2640, `mcp.client.extensions.skills`)."""
22

33
import hashlib
44
from collections.abc import AsyncIterator
@@ -9,8 +9,8 @@
99
from mcp_types import INVALID_PARAMS, Resource
1010

1111
from mcp.client.client import Client
12-
from mcp.client.skills import BoundSkills
13-
from mcp.client.skills import Skills as ClientSkills
12+
from mcp.client.extensions.skills import Skills as ClientSkills
13+
from mcp.client.extensions.skills import SkillsClient
1414
from mcp.server.context import ServerRequestContext
1515
from mcp.server.extension import Extension, MethodBinding
1616
from mcp.server.mcpserver import MCPServer
@@ -82,7 +82,7 @@ async def handler(ctx: ServerRequestContext[Any, Any], params: ListSkillsParams)
8282
class _NonConformantGetSkill(Extension):
8383
"""A server that advertises the extension but answers `skills/get` with the wrong skill -
8484
the case the SDK's own `Skills` extension already rules out server-side, so this
85-
exercises `mcp.client.skills.get_skill`'s own defense-in-depth check."""
85+
exercises `mcp.client.extensions.skills.SkillsClient.get_skill`'s own defense-in-depth check."""
8686

8787
identifier = EXTENSION_ID
8888

@@ -138,7 +138,7 @@ def _server(*, with_directory_read: bool = False) -> MCPServer:
138138

139139

140140
@asynccontextmanager
141-
async def _skills(server: MCPServer) -> AsyncIterator[BoundSkills]:
141+
async def _skills(server: MCPServer) -> AsyncIterator[SkillsClient]:
142142
"""Register the client `Skills` extension, connect, and yield the bound verbs."""
143143
extension = ClientSkills()
144144
async with Client(server, extensions=[extension]) as client:

‎tests/docs_src/test_skills.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from docs_src.skills import tutorial001
77
from mcp import Client
8-
from mcp.client.skills import Skills
8+
from mcp.client.extensions.skills import Skills
99
from mcp.shared.exceptions import MCPError
1010

1111
pytestmark = pytest.mark.anyio

‎tests/shared/test_skills.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""SEP-2640 conformance checks in `mcp.shared.skills`: types and validation.
22
33
Server- and client-side end-to-end wiring live in `tests/server/test_skills.py` and
4-
`tests/client/test_skills.py`; this file pins the pure functions both depend on.
4+
`tests/client/extensions/test_skills.py`; this file pins the pure functions both depend on.
55
"""
66

77
from typing import Any

0 commit comments

Comments
 (0)