+
    Q(i                       R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
 ^ RIt]
'       d   ^ RIHt ] ! R R4      4       t] ! R	 R
4      4       t] ! R R4      4       tR R ltR R ltRR/R R lltRR/R R lltR# )zIClient utilities for discovering and downloading skills from MCP servers.)annotationsN)	dataclass)Path)TYPE_CHECKING)Clientc                  :    ] tR t^t$ RtR]R&   R]R&   R]R&   RtR# )SkillSummaryz8Summary information about a skill available on a server.strnamedescriptionuri N__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r       ^/Users/agent/.openclaw/workspace/venv/lib/python3.14/site-packages/fastmcp/utilities/skills.pyr   r      s    B
I	Hr   r   c                  :    ] tR t^t$ RtR]R&   R]R&   R]R&   RtR# )		SkillFilez(Information about a file within a skill.r	   pathintsizehashr   Nr   r   r   r   r   r      s    2
I
I
Ir   r   c                  0    ] tR t^#t$ RtR]R&   R]R&   RtR# )SkillManifestz-Full manifest of a skill including all files.r	   r
   zlist[SkillFile]filesr   Nr   r   r   r   r   r   #   s    7
Ir   r   c                    V ^8  d   QhRRRR/# )   clientr   returnzlist[SkillSummary]r   )formats   "r   __annotate__r&   +   s     ) )f )); )r   c           	       "   V P                  4       G Rj  xL
 p. pV F  p\        VP                  4      pVP                  R4      '       g   K1  VP	                  R4      '       g   KJ  V\        R4      R pVP                  R^4      ^ ,          pTP                  \        TVP                  ;'       g    RVR7      4       K  	  V#  L5i)a8  List all available skills from an MCP server.

Discovers skills by finding resources with URIs matching the
`skill://{name}/SKILL.md` pattern.

Args:
    client: Connected FastMCP client

Returns:
    List of SkillSummary objects with name, description, and URI

Example:
    ```python
    from fastmcp import Client
    from fastmcp.utilities.skills import list_skills

    async with Client("http://skills-server/mcp") as client:
        skills = await list_skills(client)
        for skill in skills:
            print(f"{skill.name}: {skill.description}")
    ```
Nskill://z	/SKILL.md/ )r
   r   r   )
list_resourcesr	   r   
startswithendswithlenrsplitappendr   r   )r#   	resourcesskillsresourcer   	path_partr
   s   &      r   list_skillsr5   +   s     . ++--IF(,,>>*%%#,,{*C*CC
O-.I##C+A.DMM ( 4 4 : :  M% .s"   C	C4C	C	)A
C	4C	c               $    V ^8  d   QhRRRRRR/# )r"   r#   r   
skill_namer	   r$   r   r   )r%   s   "r   r&   r&   W   s&     %T %TV %T %T %Tr   c                  "   RV R2pV P                  V4      G Rj  xL
 pV'       g   \        RV 24      hV^ ,          p\        V\        P                  P
                  4      '       d#    \        P                  ! VP                  4      pM\        RV 24      h \        VR,          VR,           Uu. uF&  p\        VR	,          VR
,          VR,          R7      NK(  	  upR7      #  L  \        P                   d   p\        RT 24      ThRp?ii ; iu upi   \        \        3 d   p\        RT 24      ThRp?ii ; i5i)zGet the manifest for a specific skill.

Args:
    client: Connected FastMCP client
    skill_name: Name of the skill

Returns:
    SkillManifest with file listing

Raises:
    ValueError: If manifest cannot be read or parsed
r(   z
/_manifestNz#Could not read manifest for skill: z!Invalid manifest JSON for skill: z&Unexpected manifest format for skill: skillr    r   r   r   )r   r   r   )r
   r    z#Invalid manifest format for skill: )read_resource
ValueError
isinstancemcptypesTextResourceContentsjsonloadstextJSONDecodeErrorr   r   KeyError	TypeError)r#   r7   manifest_uriresultcontentmanifest_dataefs   &&      r   get_skill_manifestrL   W   sD     j\4L''55F>zlKLLQiG'39999::	V JJw||4M A*NOO	Tw' 'w//A qyqyqyI/
 	
 6 ## 	V@MNTUU	V
 i  T>zlKLRSSTso   EC(EAE, C* ED 4,D
 D 'E*D?DDED E ,D;;E  E	overwriteFc          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r"   r#   r   r7   r	   
target_dir
str | PathrM   boolr$   r   r   )r%   s   "r   r&   r&      sA     T TTT T
 T 
Tr   c                 "   \        V4      P                  4       P                  4       pW!,          pVP                  4       '       d   V'       g   \	        RV R24      h\        W4      G Rj  xL
 pVP                  RRR7       VP                   EFg  p\        VP                  4      P                  4       '       d   K/  WFP                  ,          P                  4       pVP                  V4      '       g   Kh  RV RVP                   2pV P                  V4      G Rj  xL
 p	V	'       g   K  V	^ ,          p
VP                  P                  RRR7       \        V
\        P                  P                   4      '       d   VP#                  V
P$                  4       EK  \        V
\        P                  P&                  4      '       d3   VP)                  \*        P,                  ! V
P.                  4      4       EKg  EKj  	  V#  EL L5i)a  Download a skill and all its files to a local directory.

Creates a subdirectory named after the skill containing all files.

Args:
    client: Connected FastMCP client
    skill_name: Name of the skill to download
    target_dir: Directory where skill folder will be created
    overwrite: If True, overwrite existing skill directory. If False
        (default), raise FileExistsError if directory exists.

Returns:
    Path to the downloaded skill directory

Raises:
    ValueError: If skill cannot be found or downloaded
    FileExistsError: If skill directory exists and overwrite=False

Example:
    ```python
    from fastmcp import Client
    from fastmcp.utilities.skills import download_skill

    async with Client("http://skills-server/mcp") as client:
        skill_path = await download_skill(
            client,
            "pdf-processing",
            "~/.claude/skills"
        )
        print(f"Downloaded to: {skill_path}")
    ```
z Skill directory already exists: z . Use overwrite=True to replace.NT)parentsexist_okr(   r)   )r   
expanduserresolveexistsFileExistsErrorrL   mkdirr    r   is_absoluteis_relative_tor:   parentr<   r=   r>   r?   
write_textrB   BlobResourceContentswrite_bytesbase64	b64decodeblob)r#   r7   rO   rM   	skill_dirmanifest	file_info	file_pathfile_urirG   rH   s   &&&$       r   download_skillrh      s    N j!,,.668J'I ).yk :- -
 	
 (;;H OOD4O0 ^^		++--/88:	''	22j\9>>*:;++H55) 	td; gsyy==>>  .!?!?@@!!&"2"27<<"@A 5 $8 E < 6s2   AHH-G?.B1HH H,CHHc               (    V ^8  d   QhRRRRRRRR/# )	r"   r#   r   rO   rP   rM   rQ   r$   z
list[Path]r   )r%   s   "r   r&   r&      s0     ' ''' 	'
 'r   c                  "   \        V 4      G Rj  xL
 p. pV F4  p \        WP                  WR7      G Rj  xL
 pVP                  V4       K6  	  V#  LB L  \         d     KL  i ; i5i)a%  Download all available skills from a server.

Args:
    client: Connected FastMCP client
    target_dir: Directory where skill folders will be created
    overwrite: If True, overwrite existing files

Returns:
    List of paths to downloaded skill directories

Example:
    ```python
    from fastmcp import Client
    from fastmcp.utilities.skills import sync_skills

    async with Client("http://skills-server/mcp") as client:
        paths = await sync_skills(client, "~/.claude/skills")
        print(f"Downloaded {len(paths)} skills")
    ```
N)rM   )r5   rh   r
   r0   rX   )r#   rO   rM   r2   
downloadedr9   r   s   &&$    r   sync_skillsrl      su     4 v&&FJ	'

J D d#   '
  		sB   A*AA*AAAA*AA'#A*&A''A*)r   
__future__r   r`   r@   dataclassesr   pathlibr   typingr   	mcp.typesr=   fastmcp.clientr   r   r   r   r5   rL   rh   rl   r   r   r   <module>rs      s    O "   !    %         )X%TPT
 Tn' 	' 'r   