Skip to main content
Glama

Puch AI MCP Starter

by VipulGhodke
mcp_starter.cpython-311.pyc34.1 kB
� <��h�s� �f �ddlZddlmZddlZddlmZddlmZddlm Z m Z ddl m Z m Z ddlmZddlmZmZmZmZdd lmZmZddlZddlZddlZddlZe��ej�d ��Zej�d ��Zej�d d ��Z e� Jd���e� Jd���Gd�d��Z!Gd�d��Z"e"��Z#Gd�de ��Z$Gd�de��Z%ede$e�����Z e j&de'fd���Z(e%ddd���Z)e%d d!�"��Z*e �&e*�+���#�� dQd$ee'ed%�#��fd&ee'dzed'�#��fd(ee'dzed)�#��fde'fd*���Z,e �&d+�#��d,ee'ed-�#��fde'fd.���Z-e �&d/�#�� dRd0ee'ed1�#��fd2ee'dzed3�#��fde'fd4���Z.e �&d5�#��d$ee'ed%�#��fd6ee'ed7�#��fd8ee'ed9�#��fde'fd:���Z/e �&d;�#��d$ee'ed%�#��fde'fd<���Z0e �&d=�#�� dSd$ee'ed%�#��fd?ee1dzed@�#��fde'fdA���Z2e �&dB�#�� dRd$ee'ed%�#��fd(ee'dzedC�#��fde'fdD���Z3e �&dE�#��d$ee'ed%�#��fd6ee'ed7�#��fd8ee'ed9�#��fde'fdF���Z4e �&dG�#��d$ee'ed%�#��fde'fdH���Z5e �&dI�#��d$ee'ed%�#��fdJee'edK�#��fde'fdL���Z6e �&dM�#��d$ee'ed%�#��fde'fdN���Z7dO�Z8e9dPkrej:e8����dSdS)T�N)� Annotated)� load_dotenv)�FastMCP)�BearerAuthProvider� RSAKeyPair)� ErrorData�McpError)� AccessToken)� TextContent� ImageContent�INVALID_PARAMS�INTERNAL_ERROR)� BaseModel�Field� AUTH_TOKEN� MY_NUMBER� BACKEND_URLzhttp://localhost:8090z'Please set AUTH_TOKEN in your .env filez&Please set MY_NUMBER in your .env filec�<�eZdZdefd�Zd�Zedefd���ZdS)� UserProfile�user_idc��||_d|_d|_d|_d|_d|_d|_d|_d|_dS)Nr��) r�xp�hearts� streak_count� last_active�learning_language�current_difficulty�correct_streak�hearts_last_refill��selfrs �ZC:\Users\Anushka\OneDrive\Desktop\puch_hackathon\mcpServer\mcp-bearer-token\mcp_starter.py�__init__zUserProfile.__init__sM���� ������ �������!%���"#������"&�����c ��|j|j|j|j|jr|j���nd|j|j|jd�S)N)rrrrrrrr ) rrrrr� isoformatrrr �r#s r$�to_dictzUserProfile.to_dict(sX���|��'��k� �-�;?�;K�U�4�+�5�5�7�7�7�QU�!%�!7�"&�"9�"�1�  �  � r&�datac�f�||d��}|�dd��|_|�dd��|_|�dd��|_|�dd��|_|�d d��|_|�d ��|_|�d ��r*tj�|d ��|_ |�d ��r*tj�|d ��|_ |S) Nrrrrrrrrr rrr!) �getrrrrr r�datetime� fromisoformatrr!)�clsr+�profiles r$� from_dictzUserProfile.from_dict4s���#�d�9�o�&�&���X�X�d�A�&�&�� ����(�A�.�.���#�x�x���:�:���%)�X�X�.B�A�%F�%F��"�!%���*:�A�!>�!>���$(�H�H�-@�$A�$A��!� �8�8�M� "� "� W�"*�"3�"A�"A�$�}�BU�"V�"V�G� � �8�8�(� )� )� e�)1�):�)H�)H��Nb�Ic�)d�)d�G� &��r&N) �__name__� __module__� __qualname__�strr%r*� classmethod�dictr2�r&r$rrse������ '�� '� '� '� '�  �  �  ���T�����[���r&rc��eZdZd�Zd�Zdedefd�Zddeded efd �Z ded ed ede fd �Z de d ede fd�Z defd�Zdefd�ZdS)�StandaloneGamificationc�F�i|_|���|_dS�N)�users�_create_default_exercises� exercisesr)s r$r%zStandaloneGamification.__init__Fs ���� ��7�7�9�9����r&c ���ddddddd�ddd d ddd�d d d ddgd�d�ddddddd�ddddddd�gddddddd�ddddddd�dd dddgd �d�d!dd"d#ddd�d$dd%d&ddd�gd'ddd(ddd�d)dd d*ddd�d+d d,d-dgd.�d�gd/�}|S)0z:Create a set of built-in exercises for different languages�es_1� translatezTranslate: Hello�holarN)�id�type�prompt� answer_key� difficulty�choices�es_2zTranslate: Thank you�gracias�es_3�mcqzSelect 'Good morning'� buenos días)z buenas nochesrO�adiós�es_4� fill_blankuFill: ¿Cómo ____?uestás��es_5zTranslate: GoodbyerP�de_1zTranslate: Good morningz guten morgen�de_2zauf wiedersehen�de_3zSelect 'Hello'�hallo)utschüssrX�bitte�de_4zFill: Wie ____ du?uheißt�de_5zTranslate: PleaserY�fr_1�bonjour�fr_2�merci�fr_3zSelect 'Good evening'�bonsoir)r]raz au revoir)�es�de�frr9)r#r@s r$r?z0StandaloneGamification._create_default_exercisesJs��� !�'�0�"(�"#�#� ��!�'�4�"+�"#�#� ��!�!�5�"0�"#�J�J�J� ��!�(�3�"*�"#�#� ��!�'�2�"*�"#�#� ��C)�X!�'�7�"0�"#�#� ��!�'�2�"3�"#�#� ��!�!�.�")�"#�=�=�=� ��!�(�2�"*�"#�#� ��!�'�1�")�"#�#� ��C)�X!�'�0�"+�"#�#� ��!�'�4�")�"#�#� ��!�!�5�"+�"#�B�B�B� ��#�ko �o � �`�r&r�returnc�\�||jvrt|��|j|<|j|Sr=)r>rr"s r$�get_user_profilez'StandaloneGamification.get_user_profile�s0�� �$�*� $� $�"-�g�"6�"6�D�J�w� ��z�'�"�"r&Nr�language�limitc���|�|��}|s |jpd}||jvrgS|j|���}t j|��|d|�S)Nrb)rgrr@�copy�random�shuffle)r#rrhrir1� availables r$�get_available_exercisesz.StandaloneGamification.get_available_exercises�ss���'�'��0�0��� 9��0�8�D�H� �4�>� )� )��I��N�8�,�1�1�3�3� ���y�!�!�!���%�� � r&� exercise_id�answerc��|�|��}d}|j���D]}|D]}|d|kr|}n�|rn�|sddiS|�||��}|rRd} |xj| z c_|xjdz c_|jdkr$t d|jdz��|_d|_nCd} td|j dz ��|_ d|_td|jdz ��|_|� |��|| |rd n d |d ��|j|j |j |jd �S) NrE�errorzExercise not found� r�rr�Correct!zIncorrect. The answer was: rH)� is_correct� awarded_xp�feedback�new_xprrr) rgr@�values� _grade_answerrr �minr�maxr�_update_streakr) r#rrprqr1�exercise�lang_exercises�exrwrxs r$� submit_answerz$StandaloneGamification.submit_answer�s����'�'��0�0����"�n�3�3�5�5� � �N�$� � ���d�8�{�*�*�!�H��E�+�� ��� �� 3��1�2� 2��'�'��&�9�9� � � P��J� �J�J�*� $�J�J� � "� "�a� '� "� "��%��*�*�-0��G�4N�QR�4R�-S�-S��*�)*��&���J� ��G�N�Q�$6�7�7�G�N�%&�G� "�),�Q��0J�Q�0N�)O�)O�G� &� ���G�$�$�$�%�$�&0�l� � �6l�T\�]i�Tj�6l�6l��j��n�#�0�")�"<� � � r&r�c��|������}|d������}||krdS|ddkrs|drk t|��dz }d|cxkrt|d��kr'nn$|d|���|kSn#t$rYnwxYwdS) zGrade the user's answerrHTrFrNrJrrF)�strip�lower�int�len� ValueError)r#r�rq� user_answer�correct_answer� choice_indexs r$r|z$StandaloneGamification._grade_answers����l�l�n�n�*�*�,�,� �!�,�/�5�5�7�7�=�=�?�?�� �.� (� (��4� �F� �u� $� $��)�)<� $� �"�;�/�/�!�3� �� �?�?�?�?�s�8�I�+>�'?�'?�?�?�?�?�?�#�I�.�|�<�B�B�D�D��V�V���� � � ��� �����us�0AC � C�Cr1c���tj���}|j|krdS|j�d|_n3||jz j}|dkr|xjdz c_n |dkrd|_||_dS)zUpdate the user's streakNr)r.�date�todayrr�days)r#r1r��deltas r$rz%StandaloneGamification._update_streaks���� �#�#�%�%�� � �%� '� '� �F� � � &�#$�G� � ��W�0�0�6�E���z�z��$�$��)�$�$�$�����'(��$�#����r&c��|�|��}tj���}|jdkrdS|j� ||_dSt ||jz ���dz��}td|jz |dz��}|dkr?td|j|z��|_|tj|dz���z |_dSdS)zRegenerate hearts over timerN�<�r)�minutes) rgr.�nowrr!r�� total_secondsr}� timedelta)r#rr1r��minutes_passed� hearts_to_adds r$�maybe_regen_heartsz)StandaloneGamification.maybe_regen_hearts&s����'�'��0�0����#�#�%�%�� �>�Q� � � �F� � %� -�),�G� &� �F��c�G�$>�>�M�M�O�O�SU�U�V�V���A���.��"�0D�E�E� � �1� � � ��G�N�]�$B�C�C�G�N�),�x�/A�>�\^�K^�/`�/`�/`�)`�G� &� &� &� � r&)Nr)r3r4r5r%r?r6rrgr�ror8r��boolr|rr�r9r&r$r;r;Es������:�:�:�r�r�r�h#��#� �#�#�#�#� !� !�s� !�c� !�QT� !� !� !� !�. �S�. �s�. �C�. �D�. �. �. �. �`�d��C��D�����($�k�$�$�$�$�$a�#�a�a�a�a�a�ar&r;c�:��eZdZdef�fd� Zdededzfd�Z�xZS)�SimpleBearerAuthProvider�tokenc���tj��}t���|jddd���||_dS)N)� public_key�jwks_uri�issuer�audience)r�generate�superr%r�r�)r#r��k� __class__s �r$r%z!SimpleBearerAuthProvider.__init__?s@��� � � !� !�� �����A�L�4��W[��\�\�\��� � � r&reNc��HK�||jkrt|ddgd���SdS)Nz puch-client�*)r�� client_id�scopes� expires_at)r�r )r#r�s r$�load_access_tokenz*SimpleBearerAuthProvider.load_access_tokenDs?���� �D�J� � ���'��u�� ��� � �tr&)r3r4r5r6r%r r�� __classcell__)r�s@r$r�r�>sk��������c������� �S��[�4�5G��������r&r�c�8�eZdZUeed<eed<dZedzed<dS)�RichToolDescription� description�use_whenN� side_effects)r3r4r5r6�__annotations__r�r9r&r$r�r�Os;������������M�M�M�#�L�#��*�#�#�#�#�#r&r�zChatLingo MCP Server)�authrec��K�tSr=)rr9r&r$�validater�`s ���� �r&z0Convert an image to black and white and save it.zeUse this tool when the user provides an image URL and requests it to be converted to black and white.zBThe image will be processed and saved in a black and white format.)r�r�r�zlChatLingo tools: start a session, submit an answer, check your daily goals and streak, and review due vocab.zcUse to drive a structured language learning flow with XP, hearts, streaks, and adaptive difficulty.)r�r�)r�rzUser identifier� lesson_idz&Optional lesson id to focus session onrz3Optional target learning language, e.g., 'de', 'es'c��4K�t||����d{V��S)N)rr)� start_session)rr�rs r$� session_startr�ys.�����w�BS�T�T�T� T� T� T� T� T� T�Tr&zSAnalyze a user-provided image (base64) for OCR/metadata; returns suggested replies.�puch_image_datazBase64-encoded image to analyzec ��K�tj��4�d{V��}|�t�d�d|i����d{V��}|jdkr+t t td|j��������ddd �d d d �d d d �g} |�t�d�ddt|��id�����d{V��}n#t$rYnwxYw|jdzd|�d�zcddd���d{V��S#1�d{V��swxYwYdS)Nz/media/image/analyze� image_b64��json��Backend error: ��code�message�Next�next��titlerE�Explain�explainz Try another� try_another� /media/event�image_analyze_tool�size�� event_type�meta� �<suggested_replies>�</suggested_replies>� �httpx� AsyncClient�postr� status_coder rr�textr�� Exception)r��client�resp� suggestions�_s r$� image_analyzer��s\����� �"�"�\�\�\�\�\�\�\�f��[�[�� 0� 0� 0���/�!� � � � � � � � �� � �s� "� "��9�.�B_�TX�T]�B_�B_�`�`�`�a�a� a��F� +� +��y� 1� 1�#�=� 9� 9� � �  ��k�k�[�">�">�">�Th�sy�{~�@O�|P�|P�sQ�FR�FR�k�S�S�S�S�S�S�S�S�A�A��� � � � �D� �����y�6�!�$[�+�$[�$[�$[�[�#\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\����\�\�\�\�\�\s6�A,C4� 7C�C4� C� C4� C�C4�4 C>�C>zNTranscribe a voice note (base64 audio) and return text with suggested actions.�puch_audio_datazBase64-encoded audio data� mime_typez'Optional audio MIME type e.g. audio/oggc��K�tj��4�d{V��}|�t�d�||d�����d{V��}|jdkr+t t td|j��������ddd �d d d �d d d �g} |�t�d�dt|��|d�d�����d{V��}n#t$rYnwxYw|jdzd|�d�zcddd���d{V��S#1�d{V��swxYwYdS)Nz/media/audio/transcribe)� audio_b64r�r�r�r�r�z Play again� play_againr��Slower�slowerr�r�r��audio_transcribe_tool)r�r�r�r�r�r�r�)r�r�r�r�r�r�s r$�transcribe_audior��sn���� � �"�"�\�\�\�\�\�\�\�f��[�[�� 3� 3� 3�.�Y�G�G�!� � � � � � � � �� � �s� "� "��9�.�B_�TX�T]�B_�B_�`�`�`�a�a� a�"�,� 7� 7��h� /� /��F� +� +� � �  ��k�k�[�">�">�">�Tk�B�CR�S�S�bk�vl�vl�Fm�Fm�k�n�n�n�n�n�n�n�n�A�A��� � � � �D� �����y�6�!�$[�+�$[�$[�$[�[�!\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\�\����\�\�\�\�\�\s6�A-C6� 8C�C6� C� C6�C�C6�6 D�Dz>Submit an answer for grading and XP/streak updates via backendrpz Exercise idrqz User's answerc��K�tj��4�d{V��}|�t�d�|||d�����d{V��}|jdkr+t t td|j�������� |� ��}n#t$rd}YnwxYw|rt|t��s1ddd �d d d �d d d �g}|jdzd|�d�zcddd���d{V��St|�d����}|�d��p|rdnd}|�d��} |�d��} |�d��} |r8dg} t| t��r| dkr| �d| �d���n|g} d�| ��} ddd �d d d �d d d �g}|| | | d�}| dzd|�d�zdzd|�d�z cddd���d{V��S#1�d{V��swxYwYdS) Nz/sessions/submit)rrprqr�r�r�r�r��next_exr�r�r��Repeat�repeatr�r�r�rwryrvz Incorrect.rxrru Correct! 🎉r�+� XP� )�correctrxr�streakz <result_meta>z</result_meta>)r�r�r�rr�r rrr�r�r�� isinstancer8r�r-r��append�join)rrprqr�r�r+r�rwry�awardedrr��parts�summaryr�s r$�submit_answer_backendr��s����� � �"�"�3 �3 �3 �3 �3 �3 �3 �f��[�[�� ,� ,� ,�$�[�F�S�S�!� � � � � � � � �� � �s� "� "��9�.�B_�TX�T]�B_�B_�`�`�`�a�a� a� ��9�9�;�;�D�D��� � � ��D�D�D� ����� `�:�d�D�1�1� `�!� �2�2�#�9�5�5�"�(�3�3��K� �9�v�%�(_�k�(_�(_�(_�_�)3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �,�$�(�(�<�0�0�1�1� ��8�8�J�'�'�W�*�,V�J�J�,���(�(�<�(�(�����(�#�#�����.�)�)�� � �$�%�E��'�3�'�'� /�G�a�K�K�� � �-��-�-�-�.�.�.���J�E��(�(�5�/�/���I� .� .��y� 1� 1��h� /� /� � �&�W��Z`�a�a�� �� �2�d�2�2�2� 3�� �F�K�E�E�E�  F� �[3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 �3 ����3 �3 �3 �3 �3 �3 s=�A G8�=B�G8� B!�G8� B!�!8G8�,C9G8�8 H�HzFFetch daily goals and gamification status (xp, hearts, streak, quests)c��|K�tj��4�d{V��}|�t�d�d|i����d{V��}|jdkr+t t td|j��������ddd �d d d �d d d �g}|jdzd|�d�zcddd���d{V��S#1�d{V��swxYwYdS)Nz/gamification/statusr��paramsr�r�r�z Daily goal� daily_goalr�z Start sessionr�z Due cards� due_cardsr�r�r�� r�r�r-rr�r rrr�)rr�r�r�s r$�gamification_statusr�s������ �"�"� \� \� \� \� \� \� \�f��Z�Z�;� D� D� D�i�Y`�Ma�Z�b�b�b�b�b�b�b�b�� � �s� "� "��9�.�B_�TX�T]�B_�B_�`�`�`�a�a� a�"�,� 7� 7�%�_� =� =�!�� 5� 5� � � �y�6�!�$[�+�$[�$[�$[�[� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \���� \� \� \� \� \� \s�A<B+�+ B5�8B5z$Get due SRS vocab items for the user�rizOptional limit of due itemsc��~K�tj��4�d{V��}|�t�d�||d�����d{V��}|jdkr+t t td|j��������ddd �d d d �d d d �g}|jdzd|�d�zcddd���d{V��S#1�d{V��swxYwYdS)Nz/srs/due)rrir�r�r�r�z Start review� start_reviewr��Skip�skip�Back�backr�r�r�r)rrir�r�r�s r$�srs_duer s����� � �"�"� \� \� \� \� \� \� \�f��Z�Z�;� 8� 8� 8�W�_d�Ae�Ae�Z�f�f�f�f�f�f�f�f�� � �s� "� "��9�.�B_�TX�T]�B_�B_�`�`�`�a�a� a�$�N� ;� ;��F� +� +��F� +� +� � � �y�6�!�$[�+�$[�$[�$[�[� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \� \���� \� \� \� \� \� \s�A=B,�, B6�9B6z9Start a language learning session with built-in exercisesz-Target learning language: 'es', 'de', or 'fr'c��K�t�|��}|r||_|jsddd�ddd�ddd�g}d|�d �St�||jd � ��}|sd d d�ddd�g}d|�d �S|d}|ddkrI|drAd�d�t |d��D����}|d�d|�d�}n#|ddkr |d�d�}n |d�d�}ddd�dd d�ddd�g}|d!|dd"�}d#|j����d$|j�d%|j�d&|j �d'|j �d(|�d)|�d*|�d �S)+Nz Learn Spanish� set_lang_esr�z Learn German� set_lang_dez Learn French� set_lang_fruOWelcome to ChatLingo! 🎉 Here's how it works: - Earn XP for correct answers and build your streak - Hearts represent your lives; wrong answers cost a heart - Hearts regenerate every 15 minutes - Difficulty adapts to your performance Please choose a language to learn: - Spanish (es) - German (de) - French (fr) <suggested_replies>r�r�ri�Change Language� change_lang� View Profile� view_profilezBNo exercises available for this language yet. <suggested_replies>rrFrNrJ� c�(�g|]\}}|dz�d|����S�rz. r9��.0�i�choices r$� <listcomp>z!start_session.<locals>.<listcomp>B�.��!e�!e�!e���F�Q�q�S�"4�"4�F�"4�"4�!e�!e�!er&rGr��5 Reply with the number (1, 2, 3) or the answer text.rR�* Fill in the blank with the correct word.� Type your answer.� Submit Answerr�r� skip_exerciserE�rprF�🌍 Language: � 💪 Difficulty: �/5 ❤️ Hearts: � /5 ⭐ XP: � 🔥 Streak: � days **Exercise:** � <exercise_meta>�%</exercise_meta> <suggested_replies>� � gamificationrgrror�� enumerate�upperrrrr) rrr1r�r@r�� choices_textrGr�s r$r�r�s����� �+�+�G�4�4�G��6�$5��!� � $� �%�]� ;� ;�$�M� :� :�$�M� :� :� � � D�#.� D� D� D� ��4�4�W�g�>W�_`�4�a�a�I� � �'�}� =� =�$�N� ;� ;� � �  D�"-� D� D� D� � ��|�H����5� � �X�i�%8� ��y�y�!e�!e�i�PX�Yb�Pc�Fd�Fd�!e�!e�!e�f�f� ��X�&�q�q�L�q�q�q��� �&� �\� )� )��X�&�T�T�T����X�&�=�=�=��"��9�9���0�0� ��7�7��K� $�D�>�8�F�3C� D� D�D� @�'�3�9�9�;�;� @� @�#�6� @� @�!�.� @� @��:� @� @� �,�  @� @� !�  @� @� �  @� @�*� @� @� @� r&z2Submit an answer for grading and XP/streak updatesc ��XK�t�|||��}d|vrddd�ddd�g}d|d�d|�d �St�|��}|d r d |d �d �}n d|d��}ddd�ddd�ddd�g}|�d|j�d|j�d|j�d|j�d|�d � S)Nrs� Start Sessionr�r�rrzError: � <suggested_replies>r�rwu🎉 Correct! +rxr�u❌ ryz Next Exercise� next_exerciser�change_languageu+ 📊 **Your Progress:** 💪 Difficulty: r%r&r'z days <suggested_replies>)r,r�rgrrrr)rrprq�resultr�r1r�s r$r�r�\sT���� � '� '���f� E� E�F��&���%�_� =� =�$�N� ;� ;� � �c����b�b��b�b�b�b��+�+�G�4�4�G� �l��.�=�F�<�$8�=�=�=���-�� �+�-�-��"��9�9� ��7�7�#�+<�=�=��K� � @� @�#�6� @� @�"�.� @� @��:�  @� @�  �,�  @� @� *�  @� @� @�r&z+View your gamification profile and progressc��\K�t�|��}t�|��|jdzdz}d|jdzz }ddd�ddd�dd d�g}d |�d |j�d |�d |j�d|j�d|j�d|jr|j���nd�d|�d�S)N�drr1r�r�z Daily Goalr�rr4u#👤 **Your Profile** 🏆 Level: u ⭐ XP: z (Next level in u XP) ❤️ Hearts: u/5 🔥 Streak: u days 💪 Difficulty: u/5 🌍 Learning: zNot setr2r�) r,rgr�rrrrrr.)rr1�level� xp_to_nextr�s r$rr�s:�����+�+�G�4�4�G��#�#�G�,�,�,��Z�3� �!� #�E��� �S�(�)�J�"��9�9��l�3�3�#�+<�=�=��K� @�� @� @��:� @� @�/9� @� @�"�.� @� @� �,�  @� @� $�6�  @� @� @G�?X�g�'�3�9�9�;�;�;�^g�  @� @�*� @� @� @� r&z$Set or change your learning languagerhz"Language code: 'es', 'de', or 'fr'c��K�t�|��}||_ddd�ddd�g}d|����d|�d�S) Nr1r�r�rru🌍 Language set to z\! Ready to start learning? Begin a session to get your first exercise. <suggested_replies>r�)r,rgrr.)rrhr1r�s r$� set_languager;�sz���� �+�+�G�4�4�G� (�G��"��9�9� ��7�7��K�  @���� 0� 0� @� @�)� @� @� @�r&zGet your next exercisec��K�t�|��}|jsddd�ddd�g}d|�d�St�||jd� ��}|sd d d�ddd�g}d |�d�S|d }|ddkrI|drAd�d�t |d��D����}|d�d|�d�}n#|ddkr |d�d�}n |d�d�}ddd�ddd�ddd�g}|d|dd�}d|j����d |j�d!|j�d"|j �d#|j �d$|�d%|�d&|�d�S)'Nz Set Languager;r�rrz:Please set a learning language first. <suggested_replies>r�rrrr4zCNo more exercises available for this language. <suggested_replies>rrFrNrJrc�(�g|]\}}|dz�d|����Srr9rs r$rz!next_exercise.<locals>.<listcomp>�rr&rGr�rrRrrr r�rr!rEr"r#r$r%r&r'r(r)r*r+)rr1r�r@r�r/rGr�s r$r3r3�sa�����+�+�G�4�4�G� � $� �$�N� ;� ;�$�N� ;� ;� � �  D�"-� D� D� D� � �4�4�W�g�>W�_`�4�a�a�I� � �'�/@� A� A�$�N� ;� ;� � �  D�"-� D� D� D� � ��|�H����5� � �X�i�%8� ��y�y�!e�!e�i�PX�Yb�Pc�Fd�Fd�!e�!e�!e�f�f� ��X�&�q�q�L�q�q�q��� �&� �\� )� )��X�&�T�T�T����X�&�=�=�=��"��9�9���0�0� ��7�7��K� $�D�>�8�F�3C� D� D�D� @�'�3�9�9�;�;� @� @�#�6� @� @�!�.� @� @��:� @� @� �,�  @� @� !�  @� @� �  @� @�*� @� @� @� r&c���K�td��td��td��td��t�ddd����d{V��dS) Nu/🚀 Starting MCP server on http://0.0.0.0:8086u)🎮 ChatLingo Gamification System Ready!u@📚 Available languages: Spanish (es), German (de), French (fr)u)💡 Use start_session to begin learning!zstreamable-httpz0.0.0.0i�)�host�port)�print�mcp� run_asyncr9r&r$�mainrD�ss���� � ;�<�<�<� � 5�6�6�6� � L�M�M�M� � 5�6�6�6� �-�-�)� ��-� E� E�E�E�E�E�E�E�E�E�Er&�__main__)NNr=)r);�asyncio�typingr�os�dotenvr�fastmcpr�$fastmcp.server.auth.providers.bearerrrrBrr �mcp.server.auth.providerr � mcp.typesr r r r�pydanticrrr�r.rlr��environr-�TOKENrrrr;r,r�r��toolr6r��$MAKE_IMG_BLACK_AND_WHITE_DESCRIPTION�DuolingoToolDescription�model_dump_jsonr�r�r�r�rr�r r�r�rr;r3rDr3�runr9r&r$�<module>rVs������������� � � � �������������O�O�O�O�O�O�O�O�#�#�#�#�#�#�#�#�0�0�0�0�0�0�O�O�O�O�O�O�O�O�O�O�O�O�%�%�%�%�%�%�%�%� � � � ����� � � � � � � � � � � � � � � ���|�$�$�� �J�N�N�;� '� '� ��j�n�n�]�,C�D�D� � ���C�������F����'�'�'�'�'�'�'�'�Rsa�sa�sa�sa�sa�sa�sa�sa�l&�%�'�'� ������1����"$�$�$�$�$�)�$�$�$��g�� !� !�%� (� (������������ ���(;�':�B� t�U�(�(�(�$�.�-�~� r����� ���-�=�=�?�?��@�@�ei�y}�U�U� �s�E�E�.?�@�@�@�@� A�U���t��U�U�7_�%`�%`�%`�`�a�U�!��t��U�U�?t�-u�-u�-u�!u�v�U� � U�U�U�A�@�U����k��l�l�\��s�E�E�6W�$X�$X�$X�X�Y�\��\�\�\�m�l�\�.���f��g�g�dh�\�\��s�E�E�6Q�$R�$R�$R�R�S�\���t��U�U�7`�%a�%a�%a�a�b�\� �\�\�\�h�g�\�.���V��W�W�8 � �s�E�E�.?�@�@�@�@� A�8 ��3���-� @� @� @�@�A�8 � �c�5�5�_�=�=�=�=� >�8 � � 8 �8 �8 �X�W�8 �v���^��_�_� \� �s�E�E�.?�@�@�@�@� A� \�� \� \� \�`�_� \����<��=�=�VX� \� \� �s�E�E�.?�@�@�@�@� A� \� �S�4�Z���3P�!Q�!Q�!Q�Q� R� \� � \� \� \�>�=� \� ���Q��R�R�tx�H�H� �s�E�E�.?�@�@�@�@� A�H� ��t��U�U�?n�-o�-o�-o�!o�p�H� �H�H�H�S�R�H�T���J��K�K�#� �s�E�E�.?�@�@�@�@� A�#��3���-� @� @� @�@�A�#� �c�5�5�_�=�=�=�=� >�#� � #�#�#�L�K�#�J���C��D�D�� �s�E�E�.?�@�@�@�@� A������E�D��6���<��=�=�� �s�E�E�.?�@�@�@�@� A����U�U�/S�T�T�T�T�U�� ����>�=��$���.��/�/�7� �s�E�E�.?�@�@�@�@� A�7��7�7�7�0�/�7�tF�F�F� �z����G�K�����������r&

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VipulGhodke/mcpServer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server