<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Python on Thomas</title>
        <link>https://blog.thomasplantain.fr/tags/python/</link>
        <description>Recent content in Python on Thomas</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>fr-fr</language>
        <lastBuildDate>Tue, 24 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.thomasplantain.fr/tags/python/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>MCP pour les nuls</title>
        <link>https://blog.thomasplantain.fr/post/mcp/</link>
        <pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate>
        
        <guid>https://blog.thomasplantain.fr/post/mcp/</guid>
        <description>&lt;img src="https://blog.thomasplantain.fr/img/mcp/mcp_bg.avif" alt="Featured image of post MCP pour les nuls" /&gt;&lt;h2 id=&#34;mcp-kesako-&#34;&gt;MCP Kesako ?
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Protocole de communication entre un agent IA et un service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://modelcontextprotocol.io/docs/getting-started/intro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MCP Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le service permet à un agent d&amp;rsquo;avoir accès à des données structurées (format JSON) qui ne sont pas déjà présentes dans son modèle LLM.
Il existe deux protocoles de communication, io et http. Dans mon cas, je souhaite utiliser http, dans l&amp;rsquo;idée de créer un serveur MCP accessible à tous.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.thomasplantain.fr/img/mcp/mcp-simple-diagram.avif&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;copilot&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Pour accélérer le développement, je vais utiliser la librairie Python fastMCP :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fastMCP: &lt;a class=&#34;link&#34; href=&#34;https://gofastmcp.com/getting-started/welcome&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://gofastmcp.com/getting-started/welcome&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prototype-du-service-mcp&#34;&gt;Prototype du service MCP
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Mon cas d&amp;rsquo;utilisation : je veux mettre en place un service qui donne les détails d&amp;rsquo;une carte de crédit si on lui donne le numéro en paramètre, ou la liste des transactions d&amp;rsquo;un compte.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dans ce premier post, je ne vais pas aborder la sécurité ni l&amp;rsquo;observabilité, mais je souhaite en parler bientôt dans un post dédié, notamment via une API Gateway.&lt;/p&gt;
&lt;h3 id=&#34;pour-commencer&#34;&gt;Pour commencer
&lt;/h3&gt;&lt;p&gt;Dans un environnement Python :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install fastmcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;serveur-mcp-card-details&#34;&gt;Serveur MCP Card Details
&lt;/h3&gt;&lt;p&gt;J&amp;rsquo;ai créé deux services : le détail d&amp;rsquo;une carte et la liste des transactions d&amp;rsquo;un compte, avec des données fictives.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; fastmcp &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; FastMCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; starlette.requests &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Request
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; starlette.responses &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; PlainTextResponse
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mcp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; FastMCP(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;My MCP Server&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@mcp.custom_route&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/health&amp;#34;&lt;/span&gt;, methods&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;health_check&lt;/span&gt;(request: Request) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; PlainTextResponse:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; PlainTextResponse(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@mcp.tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;card_details&lt;/span&gt;(card_number: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; dict:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Dummy implementation for demonstration purposes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;card_number&amp;#34;&lt;/span&gt;: card_number,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;card_type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Visa&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;expiry_date&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;12/25&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cardholder_name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@mcp.tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;transaction_list&lt;/span&gt;(account_id: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; list:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Dummy implementation for demonstration purposes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;transaction_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;txn_001&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;100.0&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;currency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;USD&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;completed&amp;#34;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;transaction_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;txn_002&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;50.0&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;currency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;USD&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pending&amp;#34;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;transaction_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;txn_003&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;75.0&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;currency&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;USD&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; __name__ &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mcp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;run(transport&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;, port&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8000&lt;/span&gt;)    
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour lancer le serveur qui va écouter sur le port 8000, j&amp;rsquo;exécute :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python my_server.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;configuration-de-copilot&#34;&gt;Configuration de Copilot
&lt;/h2&gt;&lt;p&gt;Une fois que le serveur MCP tourne dans la console, je configure mon GitHub Copilot pour qu&amp;rsquo;il ajoute le serveur dans sa liste :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.thomasplantain.fr/img/mcp/mcp_copilot_config.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;copilot&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Une fois la configuration faite, on peut voir le serveur et les deux fonctionnalités (&lt;code&gt;card_details&lt;/code&gt; et &lt;code&gt;transaction_list&lt;/code&gt;) :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.thomasplantain.fr/img/mcp/mcp_tools.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;tools&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;utilisation-du-service&#34;&gt;Utilisation du service
&lt;/h3&gt;&lt;p&gt;Les deux fonctionnalités sont maintenant accessibles dans le chat de Copilot :
&lt;img src=&#34;https://blog.thomasplantain.fr/img/mcp/mcp_copilot.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;chat&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;prochaines-étapes&#34;&gt;Prochaines étapes
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Mettre en place une API Gateway
&lt;ul&gt;
&lt;li&gt;Authentification&lt;/li&gt;
&lt;li&gt;Observabilité&lt;/li&gt;
&lt;li&gt;Limitation, quotas&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
