[{"data":1,"prerenderedAt":13803},["ShallowReactive",2],{"posts_fr:/fr/blog":3,"navigation_fr":4,"page-fr":52,"posts-fr":61},null,[5],{"title":6,"path":7,"stem":8,"children":9,"page":51},"Fr","/fr","fr",[10],{"title":11,"path":12,"stem":13,"children":14,"page":51},"Blog","/fr/blog","fr/blog",[15,19,23,27,31,35,39,43,47],{"title":16,"path":17,"stem":18},"Serveurs MCP comme Serveurs de Ressources OAuth : Une Approche Simplifiée","/fr/blog/mcp-aouth","fr/blog/1. mcp-aouth",{"title":20,"path":21,"stem":22},"Pratiques de Sécurité pour MCP Utilisant JSON-RPC","/fr/blog/mcp-security","fr/blog/1. mcp-security",{"title":24,"path":25,"stem":26},"Serveurs MCP : Connecter l'IA aux Données en Temps Réel","/fr/blog/mcp-create","fr/blog/2. mcp-create",{"title":28,"path":29,"stem":30},"Agents MCP Tiny On-Premises : S'affranchir des Dépendances Cloud","/fr/blog/mcp-tiny-agents-on-premises","fr/blog/5. mcp-tiny-agents-on-premises",{"title":32,"path":33,"stem":34},"De l'Idée à l'API en 2 Jours : Construction de Bankly avec les Flux de Travail Agentiques","/fr/blog/overvibing","fr/blog/6. overvibing",{"title":36,"path":37,"stem":38},"Chatbot IA, Serveur MCP construit avec le Protocole de Flux de Travail Agentique pour démo sur Checkatrade.com","/fr/blog/mcp-in-chat-demo","fr/blog/8. mcp-in-chat-demo",{"title":40,"path":41,"stem":42},"DDD et les Frameworks Full-Stack","/fr/blog/architecture","fr/blog/architecture",{"title":44,"path":45,"stem":46},"Qualité : Comment protéger les Frontends alimentés par l'IA ?","/fr/blog/qa-front","fr/blog/qa-front",{"title":48,"path":49,"stem":50},"Consultation et Stratégie IT","/fr/blog/strategy","fr/blog/strategy",false,{"id":53,"title":54,"description":55,"extension":56,"headline":11,"image":3,"links":3,"meta":57,"ogTitle":3,"stem":13,"__hash__":60},"blog_fr/fr/blog.yml","Idées, Normes et Innovation.","Section interne dédiée au Développement, à la Technologie et aux Solutions d’Architecture.","yml",{"navigation":58},{"icon":59},"i-lucide-newspaper","N9iDva3ClRHwLuzkI06Ip3K3_22PQS7RW2221wJs0aU",[62,2212,3182,4638,6567,7749,10842,11874,13195],{"id":63,"title":16,"authors":64,"badge":71,"body":75,"date":2204,"description":2205,"extension":2206,"image":2207,"meta":2209,"navigation":320,"path":17,"seo":2210,"stem":18,"__hash__":2211},"posts_fr/fr/blog/1. mcp-aouth.md",[65],{"name":66,"description":67,"to":68,"avatar":69},"Michael Wybraniec","Freelance, MCP Servers, Full-Stack Development, Architecture","https://www.linkedin.com/in/one-front/",{"src":70},"https://media.licdn.com/dms/image/v2/D4D03AQF3mn-R1ERoNg/profile-displayphoto-crop_800_800/B4DZeoMSehHMAI-/0/1750873484401?e=1756339200&v=beta&t=D2AWIO__-FP4J-iWELIG6djNIvq0WOe8x9uBYpKvFZA",{"label":72,"color":73,"variant":74},"Architecture, Security","primary","soft",{"type":76,"value":77,"toc":2186},"minimark",[78,101,128,149,201,216,269,280,431,446,560,575,614,1182,1197,1203,1277,1292,1303,1436,1451,1560,1575,1733,1911,1943,1949,1958,2019,2028,2043,2169,2182],[79,80,81,86,87,86,91,86,95],"p",{},[82,83,85],"a",{"href":84},"/blog","Retour aux articles"," | ",[82,88,90],{"href":89},"/blog/architecture","Architecture MCP",[82,92,94],{"href":93},"/blog/mcp-security","Sécurité MCP",[82,96,100],{"href":97,"rel":98},"https://datatracker.ietf.org/doc/html/rfc8693",[99],"nofollow","RFC 8693 Token Exchange",[102,103,106],"div",{"className":104},[105],"text-justify",[79,107,108,109,113,114,117,118,123,124,127],{},"L'architecture d'autorisation du Model Context Protocol (MCP) peut être considérablement simplifiée en traitant les serveurs MCP comme des ",[110,111,112],"strong",{},"serveurs de ressources OAuth"," plutôt que comme des serveurs d'autorisation. Cette approche révolutionnaire, proposée par ",[110,115,116],{},"dasiths"," dans la ",[82,119,122],{"href":120,"rel":121},"https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/381",[99],"discussion GitHub",", permet aux développeurs de tirer parti des solutions d'identité existantes comme ",[110,125,126],{},"Okta, Auth0, Microsoft Entra ID"," tout en réduisant la complexité d'implémentation et en améliorant l'adoption en entreprise.",[102,129,134,141],{"className":130},[131,132,133],"flex","justify-between","items-center",[135,136,138],"h2",{"id":137},"le-problème-avec-lapproche-actuelle",[110,139,140],{},"Le Problème avec l'Approche Actuelle",[79,142,143],{},[82,144,146],{"href":145},"#top",[110,147,148],{},"⤴",[102,150,152,159],{"className":151},[105],[79,153,154,155,158],{},"L'implémentation actuelle du brouillon d'autorisation MCP traite chaque serveur MCP comme un ",[110,156,157],{},"serveur d'autorisation OAuth",". Cela signifie que chaque développeur de serveur MCP doit implémenter conformément aux spécifications :",[160,161,162,173,183,186],"ul",{},[163,164,165,172],"li",{},[110,166,167],{},[82,168,171],{"href":169,"rel":170},"https://datatracker.ietf.org/doc/html/rfc8414",[99],"RFC 8414"," - OAuth 2.0 Authorization Server Metadata",[163,174,175,182],{},[110,176,177],{},[82,178,181],{"href":179,"rel":180},"https://datatracker.ietf.org/doc/html/rfc7591",[99],"RFC 7591"," - OAuth 2.0 Dynamic Client Registration Protocol",[163,184,185],{},"Les endpoints d'autorisation et de tokens",[163,187,188,189,192,193,196,197,200],{},"La gestion des sessions utilisateurs\nCette approche crée une ",[110,190,191],{},"complexité inutile"," et constitue un obstacle majeur à l'adoption, comme l'a souligné ",[110,194,195],{},"gao-sun"," qui a testé cette implémentation avec ",[110,198,199],{},"Logto, Keycloak et Auth0",".",[102,202,204,210],{"className":203},[131,132,133],[135,205,207],{"id":206},"la-solution-serveur-de-ressources-oauth",[110,208,209],{},"La Solution : Serveur de Ressources OAuth",[79,211,212],{},[82,213,214],{"href":145},[110,215,148],{},[102,217,219,245],{"className":218},[105],[79,220,221,222,225,226,234,235,238,239,244],{},"En traitant le serveur MCP comme un ",[110,223,224],{},"serveur de ressources OAuth"," conformément au ",[110,227,228,233],{},[82,229,232],{"href":230,"rel":231},"https://datatracker.ietf.org/doc/html/rfc9728",[99],"RFC 9728"," - OAuth 2.0 Protected Resource Metadata",", nous déléguons l'authentification et l'autorisation à des fournisseurs d'identité existants. Cette approche transforme le serveur MCP en un service ",[110,236,237],{},"sans état"," en ce qui concerne les préoccupations d'authentification, utilisant le ",[110,240,241],{},[82,242,100],{"href":97,"rel":243},[99]," pour les scénarios de délégation.",[79,246,247,248,255,256,259,260,264,265,200],{},"Selon la ",[110,249,250],{},[82,251,254],{"href":252,"rel":253},"https://github.com/modelcontextprotocol/modelcontextprotocol/blob/63ccd1a416de4ffe7c24d8257f8f3c849e4ea0f8/docs/specification/draft/basic/authorization.mdx",[99],"spécification officielle MCP",", les serveurs MCP ",[110,257,258],{},"DOIVENT"," implémenter OAuth 2.0 Protected Resource Metadata pour indiquer l'emplacement des serveurs d'autorisation via l'en-tête ",[261,262,263],"code",{},"WWW-Authenticate"," lors du retour d'un ",[266,267,268],"em",{},"401 Unauthorized",[102,270,272,277],{"className":271},[105],[79,273,274],{},[110,275,276],{},"Diagramme 1 : Flux de découverte et d'autorisation MCP avec serveur de ressources OAuth",[79,278,279],{},"Ce diagramme illustre le processus complet de découverte des métadonnées et d'autorisation entre un client MCP, un serveur MCP agissant comme serveur de ressources OAuth, et un serveur d'autorisation externe. Le flux commence par une requête non autorisée et se termine par une communication MCP sécurisée avec un token d'accès valide.",[281,282,287],"pre",{"className":283,"code":284,"language":285,"meta":286,"style":286},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sequenceDiagram\n    participant C as Client MCP\n    participant M as Serveur MCP (Serveur de Ressources)\n    participant A as Serveur d'Autorisation\n\n    C->>M: Requête MCP sans token\n    M-->>C: HTTP 401 Unauthorized avec en-tête WWW-Authenticate\n    Note over C: Extraire resource_metadata\u003Cbr />du WWW-Authenticate\n\n    C->>M: GET /.well-known/oauth-protected-resource\n    M-->>C: Métadonnées de ressource avec URL serveur d'autorisation\n    Note over C: Valider métadonnées RS,\u003Cbr />construire URL métadonnées AS\n\n    C->>A: GET /.well-known/oauth-authorization-server\n    A-->>C: Métadonnées serveur d'autorisation\n\n    Note over C,A: Flux d'autorisation OAuth 2.1 se déroule ici\n\n    C->>A: Requête de token\n    A-->>C: Token d'accès\n\n    C->>M: Requête MCP avec token d'accès\n    M-->>C: Réponse MCP\n    Note over C,M: Communication MCP continue avec token valide\n","mermaid","",[261,288,289,297,303,309,315,322,328,334,340,345,351,357,363,368,374,380,385,391,396,402,408,413,419,425],{"__ignoreMap":286},[290,291,294],"span",{"class":292,"line":293},"line",1,[290,295,296],{},"sequenceDiagram\n",[290,298,300],{"class":292,"line":299},2,[290,301,302],{},"    participant C as Client MCP\n",[290,304,306],{"class":292,"line":305},3,[290,307,308],{},"    participant M as Serveur MCP (Serveur de Ressources)\n",[290,310,312],{"class":292,"line":311},4,[290,313,314],{},"    participant A as Serveur d'Autorisation\n",[290,316,318],{"class":292,"line":317},5,[290,319,321],{"emptyLinePlaceholder":320},true,"\n",[290,323,325],{"class":292,"line":324},6,[290,326,327],{},"    C->>M: Requête MCP sans token\n",[290,329,331],{"class":292,"line":330},7,[290,332,333],{},"    M-->>C: HTTP 401 Unauthorized avec en-tête WWW-Authenticate\n",[290,335,337],{"class":292,"line":336},8,[290,338,339],{},"    Note over C: Extraire resource_metadata\u003Cbr />du WWW-Authenticate\n",[290,341,343],{"class":292,"line":342},9,[290,344,321],{"emptyLinePlaceholder":320},[290,346,348],{"class":292,"line":347},10,[290,349,350],{},"    C->>M: GET /.well-known/oauth-protected-resource\n",[290,352,354],{"class":292,"line":353},11,[290,355,356],{},"    M-->>C: Métadonnées de ressource avec URL serveur d'autorisation\n",[290,358,360],{"class":292,"line":359},12,[290,361,362],{},"    Note over C: Valider métadonnées RS,\u003Cbr />construire URL métadonnées AS\n",[290,364,366],{"class":292,"line":365},13,[290,367,321],{"emptyLinePlaceholder":320},[290,369,371],{"class":292,"line":370},14,[290,372,373],{},"    C->>A: GET /.well-known/oauth-authorization-server\n",[290,375,377],{"class":292,"line":376},15,[290,378,379],{},"    A-->>C: Métadonnées serveur d'autorisation\n",[290,381,383],{"class":292,"line":382},16,[290,384,321],{"emptyLinePlaceholder":320},[290,386,388],{"class":292,"line":387},17,[290,389,390],{},"    Note over C,A: Flux d'autorisation OAuth 2.1 se déroule ici\n",[290,392,394],{"class":292,"line":393},18,[290,395,321],{"emptyLinePlaceholder":320},[290,397,399],{"class":292,"line":398},19,[290,400,401],{},"    C->>A: Requête de token\n",[290,403,405],{"class":292,"line":404},20,[290,406,407],{},"    A-->>C: Token d'accès\n",[290,409,411],{"class":292,"line":410},21,[290,412,321],{"emptyLinePlaceholder":320},[290,414,416],{"class":292,"line":415},22,[290,417,418],{},"    C->>M: Requête MCP avec token d'accès\n",[290,420,422],{"class":292,"line":421},23,[290,423,424],{},"    M-->>C: Réponse MCP\n",[290,426,428],{"class":292,"line":427},24,[290,429,430],{},"    Note over C,M: Communication MCP continue avec token valide\n",[102,432,434,440],{"className":433},[131,132,133],[135,435,437],{"id":436},"avantages-de-cette-approche",[110,438,439],{},"Avantages de Cette Approche",[79,441,442],{},[82,443,444],{"href":145},[110,445,148],{},[102,447,455,503],{"className":448},[449,450,451,452,453,454],"grid","grid-cols-1","md:grid-cols-2","items-start","w-full","gap-x-8",[102,456,458,465,472,483,489,492],{"className":457},[105],[459,460,462],"h4",{"id":461},"adoption-entreprise",[110,463,464],{},"🏢 Adoption Entreprise",[79,466,467,468,471],{},"Cette approche augmente considérablement l'",[110,469,470],{},"adoptabilité de MCP dans les scénarios d'entreprise"," où des serveurs d'autorisation OAuth sont déjà déployés. Les organisations peuvent :",[160,473,474,477,480],{},[163,475,476],{},"Utiliser leurs solutions d'identité existantes",[163,478,479],{},"Appliquer leurs politiques de sécurité établies",[163,481,482],{},"Intégrer MCP dans leur architecture de sécurité actuelle",[459,484,486],{"id":485},"réduction-de-complexité",[110,487,488],{},"⚡ Réduction de Complexité",[79,490,491],{},"Les développeurs de serveurs MCP n'ont plus besoin de :",[160,493,494,497,500],{},[163,495,496],{},"Implémenter des flux d'autorisation complexes",[163,498,499],{},"Gérer les sessions et tokens liés",[163,501,502],{},"Maintenir des bases de données d'utilisateurs",[102,504,506,512,533,539,546],{"className":505},[105],[459,507,509],{"id":508},"sécurité-renforcée",[110,510,511],{},"🔒 Sécurité Renforcée",[160,513,514,520,526],{},[163,515,516,519],{},[110,517,518],{},"Réduction de la surface d'attaque"," en cas de vulnérabilité",[163,521,522,525],{},[110,523,524],{},"Architecture sans état"," pour les préoccupations d'auth",[163,527,528,529,532],{},"Possibilité d'utiliser des ",[110,530,531],{},"flux d'échange de tokens"," pour agir au nom de l'utilisateur",[459,534,536],{"id":535},"flexibilité-client",[110,537,538],{},"🔄 Flexibilité Client",[79,540,541,542,545],{},"Les clients MCP peuvent tirer parti de ",[110,543,544],{},"n'importe quel flux OAuth supporté"," pour récupérer un token :",[160,547,548,551,554,557],{},[163,549,550],{},"Client credentials",[163,552,553],{},"Authorization code",[163,555,556],{},"Device code",[163,558,559],{},"Token exchange",[102,561,563,569],{"className":562},[131,132,133],[135,564,566],{"id":565},"scénario-dexemple-échange-de-tokens",[110,567,568],{},"Scénario d'Exemple : Échange de Tokens",[79,570,571],{},[82,572,573],{"href":145},[110,574,148],{},[102,576,578,603],{"className":577},[105],[79,579,580,581,584,585,587,588,225,591,598,599,602],{},"Considérons une organisation avec une ",[110,582,583],{},"multitude d'APIs REST"," développées au fil des années, comme mentionné par ",[110,586,116],{}," dans sa proposition. Ces APIs sont protégées par l'authentification ",[110,589,590],{},"JWT bearer",[110,592,593],{},[82,594,597],{"href":595,"rel":596},"https://datatracker.ietf.org/doc/html/rfc6750",[99],"RFC 6750"," et disposent de serveurs d'autorisation OAuth existants (",[110,600,601],{},"Okta, Auth0, Microsoft Entra ID, Keycloak",").",[79,604,605,606,609,610,613],{},"Le ",[110,607,608],{},"chemin le plus simple pour adopter MCP"," serait de tirer parti de leur solution d'auth existante et de traiter le serveur MCP comme un simple service de niveau intermédiaire qui doit consommer leurs APIs existantes en utilisant le ",[110,611,612],{},"Token Exchange Flow"," du RFC 8693.",[281,615,619],{"className":616,"code":617,"language":618,"meta":286,"style":286},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Exemple d'implémentation côté serveur MCP inspirée de MCP Auth par gao-sun\nclass MCPResourceServer {\n  async handleRequest(request: MCPRequest, accessToken: string) {\n    // 1. Valider le token avec le serveur d'autorisation (RFC 7662 Token Introspection)\n    const validation = await this.validateToken(accessToken);\n    \n    if (!validation.valid) {\n      throw new UnauthorizedError();\n    }\n    \n    // 2. Échange de token pour accéder aux APIs internes (RFC 8693)\n    const exchangedToken = await this.exchangeToken(\n      accessToken, \n      'urn:ietf:params:oauth:token-type:access_token',\n      'https://api.internal.company.com'\n    );\n    \n    // 3. Appel à l'API avec le token échangé\n    return await this.callInternalAPI(exchangedToken);\n  }\n  \n  // Métadonnées de ressource protégée (RFC 9728) - Endpoint /.well-known/oauth-protected-resource\n  async getResourceMetadata() {\n    return {\n      \"authorization_servers\": [\"https://auth.company.com\"],\n      \"scopes_supported\": [\"mcp:read\", \"mcp:write\", \"mcp:admin\"],\n      \"bearer_methods_supported\": [\"header\"],\n      \"resource_documentation\": \"https://docs.company.com/mcp-api\"\n    };\n  }\n  \n  // Gestion de l'en-tête WWW-Authenticate selon la spécification MCP\n  async handleUnauthorized(response: Response) {\n    response.status = 401;\n    response.headers.set('WWW-Authenticate', \n      'Bearer realm=\"MCP Server\", resource_metadata=\"https://mcp.company.com/.well-known/oauth-protected-resource\"'\n    );\n    response.headers.set('MCP-Protocol-Version', '2024-11-05');\n    return response;\n  }\n}\n","typescript",[261,620,621,627,641,679,684,717,722,747,763,768,772,777,796,806,821,831,838,842,847,868,873,878,883,894,900,929,973,998,1018,1024,1029,1034,1040,1062,1081,1108,1118,1125,1161,1171,1176],{"__ignoreMap":286},[290,622,623],{"class":292,"line":293},[290,624,626],{"class":625},"sHwdD","// Exemple d'implémentation côté serveur MCP inspirée de MCP Auth par gao-sun\n",[290,628,629,633,637],{"class":292,"line":299},[290,630,632],{"class":631},"spNyl","class",[290,634,636],{"class":635},"sBMFI"," MCPResourceServer",[290,638,640],{"class":639},"sMK4o"," {\n",[290,642,643,646,650,653,657,660,663,666,669,671,674,677],{"class":292,"line":305},[290,644,645],{"class":631},"  async",[290,647,649],{"class":648},"swJcz"," handleRequest",[290,651,652],{"class":639},"(",[290,654,656],{"class":655},"sHdIc","request",[290,658,659],{"class":639},":",[290,661,662],{"class":635}," MCPRequest",[290,664,665],{"class":639},",",[290,667,668],{"class":655}," accessToken",[290,670,659],{"class":639},[290,672,673],{"class":635}," string",[290,675,676],{"class":639},")",[290,678,640],{"class":639},[290,680,681],{"class":292,"line":311},[290,682,683],{"class":625},"    // 1. Valider le token avec le serveur d'autorisation (RFC 7662 Token Introspection)\n",[290,685,686,689,693,696,700,703,707,709,712,714],{"class":292,"line":317},[290,687,688],{"class":631},"    const",[290,690,692],{"class":691},"sTEyZ"," validation",[290,694,695],{"class":639}," =",[290,697,699],{"class":698},"s7zQu"," await",[290,701,702],{"class":639}," this.",[290,704,706],{"class":705},"s2Zo4","validateToken",[290,708,652],{"class":648},[290,710,711],{"class":691},"accessToken",[290,713,676],{"class":648},[290,715,716],{"class":639},";\n",[290,718,719],{"class":292,"line":324},[290,720,721],{"class":648},"    \n",[290,723,724,727,730,733,736,738,741,744],{"class":292,"line":330},[290,725,726],{"class":698},"    if",[290,728,729],{"class":648}," (",[290,731,732],{"class":639},"!",[290,734,735],{"class":691},"validation",[290,737,200],{"class":639},[290,739,740],{"class":691},"valid",[290,742,743],{"class":648},") ",[290,745,746],{"class":639},"{\n",[290,748,749,752,755,758,761],{"class":292,"line":336},[290,750,751],{"class":698},"      throw",[290,753,754],{"class":639}," new",[290,756,757],{"class":705}," UnauthorizedError",[290,759,760],{"class":648},"()",[290,762,716],{"class":639},[290,764,765],{"class":292,"line":342},[290,766,767],{"class":639},"    }\n",[290,769,770],{"class":292,"line":347},[290,771,721],{"class":648},[290,773,774],{"class":292,"line":353},[290,775,776],{"class":625},"    // 2. Échange de token pour accéder aux APIs internes (RFC 8693)\n",[290,778,779,781,784,786,788,790,793],{"class":292,"line":359},[290,780,688],{"class":631},[290,782,783],{"class":691}," exchangedToken",[290,785,695],{"class":639},[290,787,699],{"class":698},[290,789,702],{"class":639},[290,791,792],{"class":705},"exchangeToken",[290,794,795],{"class":648},"(\n",[290,797,798,801,803],{"class":292,"line":365},[290,799,800],{"class":691},"      accessToken",[290,802,665],{"class":639},[290,804,805],{"class":648}," \n",[290,807,808,811,815,818],{"class":292,"line":370},[290,809,810],{"class":639},"      '",[290,812,814],{"class":813},"sfazB","urn:ietf:params:oauth:token-type:access_token",[290,816,817],{"class":639},"'",[290,819,820],{"class":639},",\n",[290,822,823,825,828],{"class":292,"line":376},[290,824,810],{"class":639},[290,826,827],{"class":813},"https://api.internal.company.com",[290,829,830],{"class":639},"'\n",[290,832,833,836],{"class":292,"line":382},[290,834,835],{"class":648},"    )",[290,837,716],{"class":639},[290,839,840],{"class":292,"line":387},[290,841,721],{"class":648},[290,843,844],{"class":292,"line":393},[290,845,846],{"class":625},"    // 3. Appel à l'API avec le token échangé\n",[290,848,849,852,854,856,859,861,864,866],{"class":292,"line":398},[290,850,851],{"class":698},"    return",[290,853,699],{"class":698},[290,855,702],{"class":639},[290,857,858],{"class":705},"callInternalAPI",[290,860,652],{"class":648},[290,862,863],{"class":691},"exchangedToken",[290,865,676],{"class":648},[290,867,716],{"class":639},[290,869,870],{"class":292,"line":404},[290,871,872],{"class":639},"  }\n",[290,874,875],{"class":292,"line":410},[290,876,877],{"class":691},"  \n",[290,879,880],{"class":292,"line":415},[290,881,882],{"class":625},"  // Métadonnées de ressource protégée (RFC 9728) - Endpoint /.well-known/oauth-protected-resource\n",[290,884,885,887,890,892],{"class":292,"line":421},[290,886,645],{"class":631},[290,888,889],{"class":648}," getResourceMetadata",[290,891,760],{"class":639},[290,893,640],{"class":639},[290,895,896,898],{"class":292,"line":427},[290,897,851],{"class":698},[290,899,640],{"class":639},[290,901,903,906,909,912,914,917,919,922,924,927],{"class":292,"line":902},25,[290,904,905],{"class":639},"      \"",[290,907,908],{"class":648},"authorization_servers",[290,910,911],{"class":639},"\"",[290,913,659],{"class":639},[290,915,916],{"class":648}," [",[290,918,911],{"class":639},[290,920,921],{"class":813},"https://auth.company.com",[290,923,911],{"class":639},[290,925,926],{"class":648},"]",[290,928,820],{"class":639},[290,930,932,934,937,939,941,943,945,948,950,952,955,958,960,962,964,967,969,971],{"class":292,"line":931},26,[290,933,905],{"class":639},[290,935,936],{"class":648},"scopes_supported",[290,938,911],{"class":639},[290,940,659],{"class":639},[290,942,916],{"class":648},[290,944,911],{"class":639},[290,946,947],{"class":813},"mcp:read",[290,949,911],{"class":639},[290,951,665],{"class":639},[290,953,954],{"class":639}," \"",[290,956,957],{"class":813},"mcp:write",[290,959,911],{"class":639},[290,961,665],{"class":639},[290,963,954],{"class":639},[290,965,966],{"class":813},"mcp:admin",[290,968,911],{"class":639},[290,970,926],{"class":648},[290,972,820],{"class":639},[290,974,976,978,981,983,985,987,989,992,994,996],{"class":292,"line":975},27,[290,977,905],{"class":639},[290,979,980],{"class":648},"bearer_methods_supported",[290,982,911],{"class":639},[290,984,659],{"class":639},[290,986,916],{"class":648},[290,988,911],{"class":639},[290,990,991],{"class":813},"header",[290,993,911],{"class":639},[290,995,926],{"class":648},[290,997,820],{"class":639},[290,999,1001,1003,1006,1008,1010,1012,1015],{"class":292,"line":1000},28,[290,1002,905],{"class":639},[290,1004,1005],{"class":648},"resource_documentation",[290,1007,911],{"class":639},[290,1009,659],{"class":639},[290,1011,954],{"class":639},[290,1013,1014],{"class":813},"https://docs.company.com/mcp-api",[290,1016,1017],{"class":639},"\"\n",[290,1019,1021],{"class":292,"line":1020},29,[290,1022,1023],{"class":639},"    };\n",[290,1025,1027],{"class":292,"line":1026},30,[290,1028,872],{"class":639},[290,1030,1032],{"class":292,"line":1031},31,[290,1033,877],{"class":691},[290,1035,1037],{"class":292,"line":1036},32,[290,1038,1039],{"class":625},"  // Gestion de l'en-tête WWW-Authenticate selon la spécification MCP\n",[290,1041,1043,1045,1048,1050,1053,1055,1058,1060],{"class":292,"line":1042},33,[290,1044,645],{"class":631},[290,1046,1047],{"class":648}," handleUnauthorized",[290,1049,652],{"class":639},[290,1051,1052],{"class":655},"response",[290,1054,659],{"class":639},[290,1056,1057],{"class":635}," Response",[290,1059,676],{"class":639},[290,1061,640],{"class":639},[290,1063,1065,1068,1070,1073,1075,1079],{"class":292,"line":1064},34,[290,1066,1067],{"class":691},"    response",[290,1069,200],{"class":639},[290,1071,1072],{"class":691},"status",[290,1074,695],{"class":639},[290,1076,1078],{"class":1077},"sbssI"," 401",[290,1080,716],{"class":639},[290,1082,1084,1086,1088,1091,1093,1096,1098,1100,1102,1104,1106],{"class":292,"line":1083},35,[290,1085,1067],{"class":691},[290,1087,200],{"class":639},[290,1089,1090],{"class":691},"headers",[290,1092,200],{"class":639},[290,1094,1095],{"class":705},"set",[290,1097,652],{"class":648},[290,1099,817],{"class":639},[290,1101,263],{"class":813},[290,1103,817],{"class":639},[290,1105,665],{"class":639},[290,1107,805],{"class":648},[290,1109,1111,1113,1116],{"class":292,"line":1110},36,[290,1112,810],{"class":639},[290,1114,1115],{"class":813},"Bearer realm=\"MCP Server\", resource_metadata=\"https://mcp.company.com/.well-known/oauth-protected-resource\"",[290,1117,830],{"class":639},[290,1119,1121,1123],{"class":292,"line":1120},37,[290,1122,835],{"class":648},[290,1124,716],{"class":639},[290,1126,1128,1130,1132,1134,1136,1138,1140,1142,1145,1147,1149,1152,1155,1157,1159],{"class":292,"line":1127},38,[290,1129,1067],{"class":691},[290,1131,200],{"class":639},[290,1133,1090],{"class":691},[290,1135,200],{"class":639},[290,1137,1095],{"class":705},[290,1139,652],{"class":648},[290,1141,817],{"class":639},[290,1143,1144],{"class":813},"MCP-Protocol-Version",[290,1146,817],{"class":639},[290,1148,665],{"class":639},[290,1150,1151],{"class":639}," '",[290,1153,1154],{"class":813},"2024-11-05",[290,1156,817],{"class":639},[290,1158,676],{"class":648},[290,1160,716],{"class":639},[290,1162,1164,1166,1169],{"class":292,"line":1163},39,[290,1165,851],{"class":698},[290,1167,1168],{"class":691}," response",[290,1170,716],{"class":639},[290,1172,1174],{"class":292,"line":1173},40,[290,1175,872],{"class":639},[290,1177,1179],{"class":292,"line":1178},41,[290,1180,1181],{"class":639},"}\n",[102,1183,1185,1191],{"className":1184},[131,132,133],[135,1186,1188],{"id":1187},"types-de-grants-oauth-supportés",[110,1189,1190],{},"Types de Grants OAuth Supportés",[79,1192,1193],{},[82,1194,1195],{"href":145},[110,1196,148],{},[102,1198,1200],{"className":1199},[105],[79,1201,1202],{},"Selon le type de client et le cas d'usage, différents grants OAuth peuvent être utilisés avec cette approche :",[1204,1205,1206,1223],"table",{},[1207,1208,1209],"thead",{},[1210,1211,1212,1218],"tr",{},[1213,1214,1215],"th",{},[110,1216,1217],{},"Type de Grant",[1213,1219,1220],{},[110,1221,1222],{},"Type de Client / Cas d'Usage",[1224,1225,1226,1237,1247,1257,1267],"tbody",{},[1210,1227,1228,1234],{},[1229,1230,1231],"td",{},[110,1232,1233],{},"Authorization Code",[1229,1235,1236],{},"Applications web traditionnelles avec backend et applications natives (mobile/desktop) pour SSO via navigateur système",[1210,1238,1239,1244],{},[1229,1240,1241],{},[110,1242,1243],{},"Client Credentials",[1229,1245,1246],{},"Clients comme services web agissant en leur propre nom",[1210,1248,1249,1254],{},[1229,1250,1251],{},[110,1252,1253],{},"Device Code",[1229,1255,1256],{},"Appareils sans navigateur ou avec saisie contrainte (Smart TV, console média, imprimante, etc.)",[1210,1258,1259,1264],{},[1229,1260,1261],{},[110,1262,1263],{},"Token Exchange",[1229,1265,1266],{},"Applications et services obtenant un token d'accès dans des scénarios de délégation et d'impersonation",[1210,1268,1269,1274],{},[1229,1270,1271],{},[110,1272,1273],{},"JWT Bearer",[1229,1275,1276],{},"Client possédant un JWT d'un domaine de sécurité l'échangeant contre un token OAuth 2.0 dans un autre domaine",[102,1278,1280,1286],{"className":1279},[131,132,133],[135,1281,1283],{"id":1282},"flux-dautorisation-complet",[110,1284,1285],{},"Flux d'Autorisation Complet",[79,1287,1288],{},[82,1289,1290],{"href":145},[110,1291,148],{},[102,1293,1295,1300],{"className":1294},[105],[79,1296,1297],{},[110,1298,1299],{},"Diagramme 2 : Flux d'autorisation OAuth 2.1 complet avec interaction utilisateur",[79,1301,1302],{},"Ce diagramme détaille le processus d'autorisation OAuth 2.1 incluant l'interaction avec l'agent utilisateur (navigateur). Il montre comment un client MCP obtient l'autorisation de l'utilisateur via le navigateur, utilise PKCE pour la sécurité, et échange le code d'autorisation contre un token d'accès pour établir une communication sécurisée avec le serveur MCP.",[281,1304,1306],{"className":283,"code":1305,"language":285,"meta":286,"style":286},"sequenceDiagram\n    participant B as Agent Utilisateur (Navigateur)\n    participant C as Client MCP\n    participant M as Serveur MCP (Serveur de Ressources)\n    participant A as Serveur d'Autorisation\n\n    C->>M: Requête MCP sans token\n    M->>C: HTTP 401 Unauthorized avec en-tête WWW-Authenticate\n    Note over C: Extraire l'URL resource_metadata du WWW-Authenticate\n\n    C->>A: GET /.well-known/oauth-authorization-server\n    A->>C: Réponse métadonnées serveur d'autorisation\n\n    alt Enregistrement client dynamique\n        C->>A: POST /register\n        A->>C: Identifiants Client\n    end\n\n    Note over C: Générer paramètres PKCE\n    C->>B: Ouvrir navigateur avec URL d'autorisation + code_challenge\n    B->>A: Requête d'autorisation\n    Note over A: L'utilisateur autorise\n    A->>B: Redirection vers callback avec code d'autorisation\n    B->>C: Callback code d'autorisation\n    C->>A: Requête token + code_verifier\n    A->>C: Token d'accès (+ token de rafraîchissement)\n    C->>M: Requête MCP avec token d'accès\n    M-->>C: Réponse MCP\n",[261,1307,1308,1312,1317,1321,1325,1329,1333,1337,1342,1347,1351,1355,1360,1364,1369,1374,1379,1384,1388,1393,1398,1403,1408,1413,1418,1423,1428,1432],{"__ignoreMap":286},[290,1309,1310],{"class":292,"line":293},[290,1311,296],{},[290,1313,1314],{"class":292,"line":299},[290,1315,1316],{},"    participant B as Agent Utilisateur (Navigateur)\n",[290,1318,1319],{"class":292,"line":305},[290,1320,302],{},[290,1322,1323],{"class":292,"line":311},[290,1324,308],{},[290,1326,1327],{"class":292,"line":317},[290,1328,314],{},[290,1330,1331],{"class":292,"line":324},[290,1332,321],{"emptyLinePlaceholder":320},[290,1334,1335],{"class":292,"line":330},[290,1336,327],{},[290,1338,1339],{"class":292,"line":336},[290,1340,1341],{},"    M->>C: HTTP 401 Unauthorized avec en-tête WWW-Authenticate\n",[290,1343,1344],{"class":292,"line":342},[290,1345,1346],{},"    Note over C: Extraire l'URL resource_metadata du WWW-Authenticate\n",[290,1348,1349],{"class":292,"line":347},[290,1350,321],{"emptyLinePlaceholder":320},[290,1352,1353],{"class":292,"line":353},[290,1354,373],{},[290,1356,1357],{"class":292,"line":359},[290,1358,1359],{},"    A->>C: Réponse métadonnées serveur d'autorisation\n",[290,1361,1362],{"class":292,"line":365},[290,1363,321],{"emptyLinePlaceholder":320},[290,1365,1366],{"class":292,"line":370},[290,1367,1368],{},"    alt Enregistrement client dynamique\n",[290,1370,1371],{"class":292,"line":376},[290,1372,1373],{},"        C->>A: POST /register\n",[290,1375,1376],{"class":292,"line":382},[290,1377,1378],{},"        A->>C: Identifiants Client\n",[290,1380,1381],{"class":292,"line":387},[290,1382,1383],{},"    end\n",[290,1385,1386],{"class":292,"line":393},[290,1387,321],{"emptyLinePlaceholder":320},[290,1389,1390],{"class":292,"line":398},[290,1391,1392],{},"    Note over C: Générer paramètres PKCE\n",[290,1394,1395],{"class":292,"line":404},[290,1396,1397],{},"    C->>B: Ouvrir navigateur avec URL d'autorisation + code_challenge\n",[290,1399,1400],{"class":292,"line":410},[290,1401,1402],{},"    B->>A: Requête d'autorisation\n",[290,1404,1405],{"class":292,"line":415},[290,1406,1407],{},"    Note over A: L'utilisateur autorise\n",[290,1409,1410],{"class":292,"line":421},[290,1411,1412],{},"    A->>B: Redirection vers callback avec code d'autorisation\n",[290,1414,1415],{"class":292,"line":427},[290,1416,1417],{},"    B->>C: Callback code d'autorisation\n",[290,1419,1420],{"class":292,"line":902},[290,1421,1422],{},"    C->>A: Requête token + code_verifier\n",[290,1424,1425],{"class":292,"line":931},[290,1426,1427],{},"    A->>C: Token d'accès (+ token de rafraîchissement)\n",[290,1429,1430],{"class":292,"line":975},[290,1431,418],{},[290,1433,1434],{"class":292,"line":1000},[290,1435,424],{},[102,1437,1439,1445],{"className":1438},[131,132,133],[135,1440,1442],{"id":1441},"considérations-de-sécurité",[110,1443,1444],{},"Considérations de Sécurité",[79,1446,1447],{},[82,1448,1449],{"href":145},[110,1450,148],{},[102,1452,1454,1489],{"className":1453},[449,450,451,452,453,454],[102,1455,1457,1463],{"className":1456},[105],[459,1458,1460],{"id":1459},"bonnes-pratiques",[110,1461,1462],{},"🔐 Bonnes Pratiques",[160,1464,1465,1471,1477,1483],{},[163,1466,1467,1470],{},[110,1468,1469],{},"PKCE requis"," pour tous les clients et serveurs d'autorisation MCP",[163,1472,1473,1476],{},[110,1474,1475],{},"Stockage sécurisé des tokens"," suivant les meilleures pratiques OAuth 2.0",[163,1478,1479,1482],{},[110,1480,1481],{},"Validation des URI de redirection"," pour prévenir les vulnérabilités de redirection ouverte",[163,1484,1485,1488],{},[110,1486,1487],{},"HTTPS obligatoire"," pour tous les endpoints d'autorisation",[102,1490,1492,1498],{"className":1491},[105],[459,1493,1495],{"id":1494},"️-gestion-derreurs",[110,1496,1497],{},"⚠️ Gestion d'Erreurs",[1204,1499,1500,1519],{},[1207,1501,1502],{},[1210,1503,1504,1509,1514],{},[1213,1505,1506],{},[110,1507,1508],{},"Code de Statut",[1213,1510,1511],{},[110,1512,1513],{},"Description",[1213,1515,1516],{},[110,1517,1518],{},"Usage",[1224,1520,1521,1534,1547],{},[1210,1522,1523,1528,1531],{},[1229,1524,1525],{},[110,1526,1527],{},"401",[1229,1529,1530],{},"Non autorisé",[1229,1532,1533],{},"Autorisation requise ou token invalide",[1210,1535,1536,1541,1544],{},[1229,1537,1538],{},[110,1539,1540],{},"403",[1229,1542,1543],{},"Interdit",[1229,1545,1546],{},"Scopes invalides ou permissions insuffisantes",[1210,1548,1549,1554,1557],{},[1229,1550,1551],{},[110,1552,1553],{},"400",[1229,1555,1556],{},"Requête incorrecte",[1229,1558,1559],{},"Requête d'autorisation malformée",[102,1561,1563,1569],{"className":1562},[131,132,133],[135,1564,1566],{"id":1565},"impact-sur-lécosystème-mcp",[110,1567,1568],{},"Impact sur l'Écosystème MCP",[79,1570,1571],{},[82,1572,1573],{"href":145},[110,1574,148],{},[102,1576,1578,1584,1589,1598,1611,1618,1624,1661,1666,1693,1699],{"className":1577},[105],[79,1579,1580,1581,1583],{},"Cette approche révolutionnaire simplifie considérablement l'intégration des serveurs d'autorisation, permettant de se connecter directement aux fournisseurs comme ",[110,1582,601],{}," et autres sans avoir à développer un serveur d'autorisation from scratch.",[79,1585,1586],{},[110,1587,1588],{},"Moins de code boilerplate. Plus de développement. MCP devient plus adapté aux entreprises.",[79,1590,1591,1592,1594,1595],{},"Comme l'a annoncé ",[110,1593,116],{}," : ",[266,1596,1597],{},"\"Big thank you to everyone who spent their valuable time providing input, reviewing the PR and waiting patiently while this change was discussed over the past 4 weeks. It was a massive community effort.\"",[79,1599,1600,1601,1607,1608,200],{},"Cette nouvelle spécification est maintenant disponible dans le ",[110,1602,1603],{},[82,1604,1606],{"href":252,"rel":1605},[99],"draft officiel MCP - Section Authorization"," et incluse dans la spécification du ",[110,1609,1610],{},"18 juin 2025",[1612,1613,1615],"h3",{"id":1614},"exigences-de-la-spécification-mcp",[110,1616,1617],{},"Exigences de la Spécification MCP",[79,1619,1620,1621,1623],{},"Selon la spécification officielle, les serveurs MCP agissant comme serveurs de ressources ",[110,1622,258],{}," :",[1625,1626,1627,1636,1645,1653],"ol",{},[163,1628,1629,729,1632,676],{},[110,1630,1631],{},"Implémenter OAuth 2.0 Protected Resource Metadata",[82,1633,1635],{"href":230,"rel":1634},[99],"RFC9728",[163,1637,1638,264,1643],{},[110,1639,1640,1641],{},"Utiliser l'en-tête ",[261,1642,263],{},[266,1644,268],{},[163,1646,1647],{},[110,1648,1649,1650],{},"Supporter l'endpoint ",[261,1651,1652],{},"/.well-known/oauth-protected-resource",[163,1654,1655,1660],{},[110,1656,1657,1658],{},"Inclure le champ ",[261,1659,908],{}," avec au moins un serveur d'autorisation",[79,1662,1663,1664,1623],{},"Les clients MCP ",[110,1665,258],{},[1625,1667,1668,1676,1685],{},[163,1669,1670,1675],{},[110,1671,1672,1673],{},"Parser les en-têtes ",[261,1674,263],{}," et répondre aux réponses HTTP 401",[163,1677,1678,729,1681,676],{},[110,1679,1680],{},"Suivre le protocole OAuth 2.0 Authorization Server Metadata",[82,1682,1684],{"href":169,"rel":1683},[99],"RFC8414",[163,1686,1687,1692],{},[110,1688,1689,1690],{},"Inclure l'en-tête ",[261,1691,1144],{}," dans les requêtes",[1612,1694,1696],{"id":1695},"mises-à-jour-des-sdks-en-cours",[110,1697,1698],{},"Mises à jour des SDKs en cours :",[160,1700,1701,1711,1721],{},[163,1702,1703,1710],{},[110,1704,1705],{},[82,1706,1709],{"href":1707,"rel":1708},"https://github.com/modelcontextprotocol/python-sdk/pull/686",[99],"Python SDK"," - Support pour la nouvelle spécification d'autorisation",[163,1712,1713,1720],{},[110,1714,1715],{},[82,1716,1719],{"href":1717,"rel":1718},"https://github.com/modelcontextprotocol/csharp-sdk/pull/377",[99],"C# SDK"," - Intégration ASP.NET Core native AuthN/AuthZ",[163,1722,1723,1730,1731],{},[110,1724,1725],{},[82,1726,1729],{"href":1727,"rel":1728},"https://github.com/gao-sun/mcp-auth",[99],"MCP Auth"," - Implémentation de référence par ",[110,1732,195],{},[281,1734,1738],{"className":1735,"code":1736,"language":1737,"meta":286,"style":286},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Exemple de métadonnées de ressource protégée (RFC 9728)\n{\n  \"authorization_servers\": [\n    \"https://auth.company.com\"\n  ],\n  \"resource_metadata\": {\n    \"resource\": \"https://mcp.company.com\",\n    \"authorization_servers\": [\"https://auth.company.com\"],\n    \"scopes_supported\": [\"mcp:read\", \"mcp:write\", \"mcp:admin\"],\n    \"bearer_methods_supported\": [\"header\"],\n    \"resource_documentation\": \"https://docs.company.com/mcp-api\"\n  }\n}\n","json",[261,1739,1740,1745,1749,1763,1772,1777,1790,1810,1831,1867,1887,1903,1907],{"__ignoreMap":286},[290,1741,1742],{"class":292,"line":293},[290,1743,1744],{"class":625},"// Exemple de métadonnées de ressource protégée (RFC 9728)\n",[290,1746,1747],{"class":292,"line":299},[290,1748,746],{"class":639},[290,1750,1751,1754,1756,1758,1760],{"class":292,"line":305},[290,1752,1753],{"class":639},"  \"",[290,1755,908],{"class":631},[290,1757,911],{"class":639},[290,1759,659],{"class":639},[290,1761,1762],{"class":639}," [\n",[290,1764,1765,1768,1770],{"class":292,"line":311},[290,1766,1767],{"class":639},"    \"",[290,1769,921],{"class":813},[290,1771,1017],{"class":639},[290,1773,1774],{"class":292,"line":317},[290,1775,1776],{"class":639},"  ],\n",[290,1778,1779,1781,1784,1786,1788],{"class":292,"line":324},[290,1780,1753],{"class":639},[290,1782,1783],{"class":631},"resource_metadata",[290,1785,911],{"class":639},[290,1787,659],{"class":639},[290,1789,640],{"class":639},[290,1791,1792,1794,1797,1799,1801,1803,1806,1808],{"class":292,"line":330},[290,1793,1767],{"class":639},[290,1795,1796],{"class":635},"resource",[290,1798,911],{"class":639},[290,1800,659],{"class":639},[290,1802,954],{"class":639},[290,1804,1805],{"class":813},"https://mcp.company.com",[290,1807,911],{"class":639},[290,1809,820],{"class":639},[290,1811,1812,1814,1816,1818,1820,1822,1824,1826,1828],{"class":292,"line":336},[290,1813,1767],{"class":639},[290,1815,908],{"class":635},[290,1817,911],{"class":639},[290,1819,659],{"class":639},[290,1821,916],{"class":639},[290,1823,911],{"class":639},[290,1825,921],{"class":813},[290,1827,911],{"class":639},[290,1829,1830],{"class":639},"],\n",[290,1832,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853,1855,1857,1859,1861,1863,1865],{"class":292,"line":342},[290,1834,1767],{"class":639},[290,1836,936],{"class":635},[290,1838,911],{"class":639},[290,1840,659],{"class":639},[290,1842,916],{"class":639},[290,1844,911],{"class":639},[290,1846,947],{"class":813},[290,1848,911],{"class":639},[290,1850,665],{"class":639},[290,1852,954],{"class":639},[290,1854,957],{"class":813},[290,1856,911],{"class":639},[290,1858,665],{"class":639},[290,1860,954],{"class":639},[290,1862,966],{"class":813},[290,1864,911],{"class":639},[290,1866,1830],{"class":639},[290,1868,1869,1871,1873,1875,1877,1879,1881,1883,1885],{"class":292,"line":347},[290,1870,1767],{"class":639},[290,1872,980],{"class":635},[290,1874,911],{"class":639},[290,1876,659],{"class":639},[290,1878,916],{"class":639},[290,1880,911],{"class":639},[290,1882,991],{"class":813},[290,1884,911],{"class":639},[290,1886,1830],{"class":639},[290,1888,1889,1891,1893,1895,1897,1899,1901],{"class":292,"line":353},[290,1890,1767],{"class":639},[290,1892,1005],{"class":635},[290,1894,911],{"class":639},[290,1896,659],{"class":639},[290,1898,954],{"class":639},[290,1900,1014],{"class":813},[290,1902,1017],{"class":639},[290,1904,1905],{"class":292,"line":359},[290,1906,872],{"class":639},[290,1908,1909],{"class":292,"line":365},[290,1910,1181],{"class":639},[281,1912,1916],{"className":1913,"code":1914,"language":1915,"meta":286,"style":286},"language-http shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// En-tête WWW-Authenticate pour découverte (RFC 9728)\nHTTP/1.1 401 Unauthorized\nWWW-Authenticate: Bearer realm=\"MCP Server\",\n                  resource_metadata=\"https://mcp.company.com/.well-known/oauth-protected-resource\"\nMCP-Protocol-Version: 2024-11-05\n","http",[261,1917,1918,1923,1928,1933,1938],{"__ignoreMap":286},[290,1919,1920],{"class":292,"line":293},[290,1921,1922],{},"// En-tête WWW-Authenticate pour découverte (RFC 9728)\n",[290,1924,1925],{"class":292,"line":299},[290,1926,1927],{},"HTTP/1.1 401 Unauthorized\n",[290,1929,1930],{"class":292,"line":305},[290,1931,1932],{},"WWW-Authenticate: Bearer realm=\"MCP Server\",\n",[290,1934,1935],{"class":292,"line":311},[290,1936,1937],{},"                  resource_metadata=\"https://mcp.company.com/.well-known/oauth-protected-resource\"\n",[290,1939,1940],{"class":292,"line":317},[290,1941,1942],{},"MCP-Protocol-Version: 2024-11-05\n",[1612,1944,1946],{"id":1945},"flux-de-découverte-officiel-mcp",[110,1947,1948],{},"Flux de Découverte Officiel MCP",[79,1950,247,1951,1957],{},[110,1952,1953],{},[82,1954,1956],{"href":252,"rel":1955},[99],"spécification MCP 2.3.4",", le processus de découverte suit ce flux précis :",[1625,1959,1960,1966,1978,1987,1995,2000,2007,2013],{},[163,1961,1962,1965],{},[110,1963,1964],{},"Client MCP"," fait une requête sans token",[163,1967,1968,1971,1972,1975,1976],{},[110,1969,1970],{},"Serveur MCP"," répond avec ",[261,1973,1974],{},"HTTP 401"," et en-tête ",[261,1977,263],{},[163,1979,1980,1983,1984,1986],{},[110,1981,1982],{},"Client"," extrait l'URL ",[261,1985,1783],{}," de l'en-tête",[163,1988,1989,1991,1992,1994],{},[110,1990,1982],{}," récupère ",[261,1993,1652],{}," du serveur MCP",[163,1996,1997,1999],{},[110,1998,1982],{}," utilise ces métadonnées pour construire l'URL du serveur d'autorisation",[163,2001,2002,1991,2004],{},[110,2003,1982],{},[261,2005,2006],{},"/.well-known/oauth-authorization-server",[163,2008,2009,2012],{},[110,2010,2011],{},"Flux OAuth 2.1"," standard se déroule",[163,2014,2015,2018],{},[110,2016,2017],{},"Communication MCP"," reprend avec le token valide",[79,2020,2021,2022,2024,2025,2027],{},"Cette approche, validée par ",[110,2023,195],{}," avec des tests sur ",[110,2026,199],{},", est maintenant la méthode recommandée dans l'écosystème MCP.",[102,2029,2031,2037],{"className":2030},[131,132,133],[135,2032,2034],{"id":2033},"conclusion",[110,2035,2036],{},"Conclusion",[79,2038,2039],{},[82,2040,2041],{"href":145},[110,2042,148],{},[102,2044,2046,2058,2063,2090,2096,2134,2140,2147,2161],{"className":2045},[105],[79,2047,2048,2049,2051,2052,2054,2055,2057],{},"L'adoption de l'approche ",[110,2050,224],{}," pour les serveurs MCP marque un tournant décisif dans l'évolution de l'écosystème MCP vers une architecture plus mature et adaptée aux entreprises. Cette nouvelle spécification, fruit d'un effort communautaire de 4 semaines dirigé par ",[110,2053,116],{}," et validé par ",[110,2056,195],{},", transforme radicalement la façon dont nous concevons l'authentification et l'autorisation dans MCP.",[79,2059,2060],{},[110,2061,2062],{},"Pourquoi agir maintenant ?",[160,2064,2065,2072,2078,2084],{},[163,2066,2067,2068,2071],{},"✅ ",[110,2069,2070],{},"Spécification officialisée"," dans MCP 2.3.4 (18 juin 2025)",[163,2073,2067,2074,2077],{},[110,2075,2076],{},"SDKs en cours de mise à jour"," (Python, C#, JavaScript)",[163,2079,2067,2080,2083],{},[110,2081,2082],{},"Implémentations de référence disponibles"," (MCP Auth par gao-sun)",[163,2085,2067,2086,2089],{},[110,2087,2088],{},"Support confirmé"," pour Okta, Auth0, Microsoft Entra ID, Keycloak",[1612,2091,2093],{"id":2092},"prochaines-étapes-recommandées",[110,2094,2095],{},"🚀 Prochaines Étapes Recommandées",[1625,2097,2098,2109,2119,2125],{},[163,2099,2100,1594,2103,2106,2107],{},[110,2101,2102],{},"Explorez l'implémentation de référence",[82,2104,1729],{"href":1727,"rel":2105},[99]," par ",[110,2108,195],{},[163,2110,2111,1594,2114],{},[110,2112,2113],{},"Consultez la spécification officielle",[82,2115,2118],{"href":2116,"rel":2117},"https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/draft/basic/authorization.mdx",[99],"MCP Authorization Draft",[163,2120,2121,2124],{},[110,2122,2123],{},"Testez avec votre fournisseur d'identité"," existant (Okta, Auth0, etc.)",[163,2126,2127,1594,2130],{},[110,2128,2129],{},"Rejoignez la discussion communautaire",[82,2131,2133],{"href":120,"rel":2132},[99],"GitHub Discussions",[1612,2135,2137],{"id":2136},"besoin-daide-pour-implémenter-mcp-dans-votre-organisation",[110,2138,2139],{},"💡 Besoin d'Aide pour Implémenter MCP dans Votre Organisation ?",[79,2141,2142,2143,2146],{},"En tant qu'",[110,2144,2145],{},"architecte spécialisé en MCP et OAuth",", je peux vous accompagner dans :",[160,2148,2149,2152,2155,2158],{},[163,2150,2151],{},"Migration vers l'architecture serveur de ressources OAuth",[163,2153,2154],{},"Intégration avec vos systèmes d'identité existants",[163,2156,2157],{},"Formation de vos équipes sur les meilleures pratiques MCP",[163,2159,2160],{},"Audit de sécurité et architecture review",[79,2162,2163],{},[110,2164,2165],{},[82,2166,2168],{"href":2167},"/contact","Contactez-moi pour discuter de votre projet MCP →",[102,2170,2176],{"className":2171},[2172,2173,2174,2175],"text-md","text-center","mt-10","font-bold",[79,2177,2178],{},[82,2179,2180],{"href":145},[110,2181,148],{},[2183,2184,2185],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":286,"searchDepth":299,"depth":299,"links":2187},[2188,2189,2190,2191,2192,2193,2194,2195,2200],{"id":137,"depth":299,"text":140},{"id":206,"depth":299,"text":209},{"id":436,"depth":299,"text":439},{"id":565,"depth":299,"text":568},{"id":1187,"depth":299,"text":1190},{"id":1282,"depth":299,"text":1285},{"id":1441,"depth":299,"text":1444},{"id":1565,"depth":299,"text":1568,"children":2196},[2197,2198,2199],{"id":1614,"depth":305,"text":1617},{"id":1695,"depth":305,"text":1698},{"id":1945,"depth":305,"text":1948},{"id":2033,"depth":299,"text":2036,"children":2201},[2202,2203],{"id":2092,"depth":305,"text":2095},{"id":2136,"depth":305,"text":2139},"2025-06-27","Traiter le serveur MCP comme un serveur de ressources OAuth plutôt qu'un serveur d'autorisation permet une architecture plus simple, sans état et adaptée aux entreprises.","md",{"src":2208},"/blog/mcp/mcp-cover.png",{},{"title":16,"description":2205},"Fw37KPtU629WGmkjjPlU_Be2Pl4UELIht35YqKmB8iM",{"id":2213,"title":20,"authors":2214,"badge":2219,"body":2221,"date":3176,"description":3177,"extension":2206,"image":3178,"meta":3179,"navigation":320,"path":21,"seo":3180,"stem":22,"__hash__":3181},"posts_fr/fr/blog/1. mcp-security.md",[2215],{"name":66,"description":2216,"to":68,"avatar":2217},"Freelance, Serveurs MCP, Développement Full-Stack, Architecture",{"src":2218},"https://media.licdn.com/dms/image/v2/D4D03AQEGvIVcrTTS2g/profile-displayphoto-shrink_800_800/B4DZbtSf7LIEAc-/0/1747737772225?e=1753315200&v=beta&t=EOviZQkM396PoGctVjDCdlG8U3vN5UKWiIeNQ8IFUgQ",{"label":2220,"color":73,"variant":74},"Sécurité",{"type":76,"value":2222,"toc":3163},[2223,2229,2250,2265,2271,2275,2332,2336,2393,2397,2437,2452,2654,2669,2772,2787,2830,2875,2890,2934,2949,3118,3133,3151,3160],[79,2224,2225],{},[82,2226,2228],{"href":2227},"/blog/","Retour au Blog",[102,2230,2232],{"className":2231},[105],[79,2233,2234,2235,2238,2239,2242,2243,2246,2247,200],{},"Le Protocole de Contexte de Modèle (MCP) est un framework pour la communication structurée entre clients et serveurs utilisant JSON-RPC 2.0. Il permet l'échange de messages à granularité fine dans des systèmes distribués ou modulaires, y compris ceux impliquant des modèles d'IA, des agents modulaires ou l'orchestration de services. Lors de l'utilisation de protocoles légers comme JSON-RPC 2.0 pour la communication MCP, les développeurs font face à plusieurs défis de sécurité. Cet article décrit les ",[110,2236,2237],{},"problèmes critiques",", les ",[110,2240,2241],{},"meilleures solutions"," et les ",[110,2244,2245],{},"outils pratiques pour développeurs"," pour assurer des ",[110,2248,2249],{},"systèmes MCP robustes et sécurisés",[102,2251,2253,2259],{"className":2252},[131,132,133],[135,2254,2256],{"id":2255},"guide-visuel-de-larchitecture-de-sécurité-mcp",[110,2257,2258],{},"Guide Visuel de l'Architecture de Sécurité MCP",[79,2260,2261],{},[82,2262,2263],{"href":145},[110,2264,148],{},[102,2266,2268],{"className":2267},[105],[79,2269,2270],{},"Ce guide fournit un aperçu visuel et pratique de la sécurisation des systèmes MCP, incluant la signature de messages, la gestion de sessions et les modèles d'architecture du monde réel. Il s'adresse aux développeurs et architectes construisant des systèmes modulaires, basés sur des agents ou distribués d'IA.",[1612,2272,2274],{"id":2273},"flux-de-signature-et-vérification-de-messages","Flux de Signature et Vérification de Messages",[281,2276,2278],{"className":283,"code":2277,"language":285,"meta":286,"style":286},"sequenceDiagram\n  participant Client\n  participant Serveur\n\n  Client->>Client: Sérialiser méthode + paramètres\n  Client->>Client: Signer payload avec clé privée\n  Client->>Serveur: Envoyer JSON-RPC + signature + clé publique\n\n  Serveur->>Serveur: Canonicaliser méthode + paramètres\n  Serveur->>Serveur: Vérifier signature avec clé publique\n  Serveur-->>Client: Traiter ou rejeter\n",[261,2279,2280,2284,2289,2294,2298,2303,2308,2313,2317,2322,2327],{"__ignoreMap":286},[290,2281,2282],{"class":292,"line":293},[290,2283,296],{},[290,2285,2286],{"class":292,"line":299},[290,2287,2288],{},"  participant Client\n",[290,2290,2291],{"class":292,"line":305},[290,2292,2293],{},"  participant Serveur\n",[290,2295,2296],{"class":292,"line":311},[290,2297,321],{"emptyLinePlaceholder":320},[290,2299,2300],{"class":292,"line":317},[290,2301,2302],{},"  Client->>Client: Sérialiser méthode + paramètres\n",[290,2304,2305],{"class":292,"line":324},[290,2306,2307],{},"  Client->>Client: Signer payload avec clé privée\n",[290,2309,2310],{"class":292,"line":330},[290,2311,2312],{},"  Client->>Serveur: Envoyer JSON-RPC + signature + clé publique\n",[290,2314,2315],{"class":292,"line":336},[290,2316,321],{"emptyLinePlaceholder":320},[290,2318,2319],{"class":292,"line":342},[290,2320,2321],{},"  Serveur->>Serveur: Canonicaliser méthode + paramètres\n",[290,2323,2324],{"class":292,"line":347},[290,2325,2326],{},"  Serveur->>Serveur: Vérifier signature avec clé publique\n",[290,2328,2329],{"class":292,"line":353},[290,2330,2331],{},"  Serveur-->>Client: Traiter ou rejeter\n",[1612,2333,2335],{"id":2334},"initialisation-sécurisée-de-session","Initialisation Sécurisée de Session",[281,2337,2339],{"className":283,"code":2338,"language":285,"meta":286,"style":286},"sequenceDiagram\n  participant Coordinateur\n  participant Agent A\n  participant Agent B\n\n  Agent A->>Coordinateur: Demander démarrage de session\n  Coordinateur->>Agent A: Envoyer UUID de session + token\n  Agent A->>Agent B: Partager contexte avec token\n  Agent B->>Coordinateur: Vérifier session + rejoindre\n\n  Note over Coordinateur: Le coordinateur suit les rôles, tours et état\n",[261,2340,2341,2345,2350,2355,2360,2364,2369,2374,2379,2384,2388],{"__ignoreMap":286},[290,2342,2343],{"class":292,"line":293},[290,2344,296],{},[290,2346,2347],{"class":292,"line":299},[290,2348,2349],{},"  participant Coordinateur\n",[290,2351,2352],{"class":292,"line":305},[290,2353,2354],{},"  participant Agent A\n",[290,2356,2357],{"class":292,"line":311},[290,2358,2359],{},"  participant Agent B\n",[290,2361,2362],{"class":292,"line":317},[290,2363,321],{"emptyLinePlaceholder":320},[290,2365,2366],{"class":292,"line":324},[290,2367,2368],{},"  Agent A->>Coordinateur: Demander démarrage de session\n",[290,2370,2371],{"class":292,"line":330},[290,2372,2373],{},"  Coordinateur->>Agent A: Envoyer UUID de session + token\n",[290,2375,2376],{"class":292,"line":336},[290,2377,2378],{},"  Agent A->>Agent B: Partager contexte avec token\n",[290,2380,2381],{"class":292,"line":342},[290,2382,2383],{},"  Agent B->>Coordinateur: Vérifier session + rejoindre\n",[290,2385,2386],{"class":292,"line":347},[290,2387,321],{"emptyLinePlaceholder":320},[290,2389,2390],{"class":292,"line":353},[290,2391,2392],{},"  Note over Coordinateur: Le coordinateur suit les rôles, tours et état\n",[1612,2394,2396],{"id":2395},"routage-de-contexte-mcp","Routage de Contexte MCP",[281,2398,2400],{"className":283,"code":2399,"language":285,"meta":286,"style":286},"graph TD\n  A[Client] -->|JSON-RPC| B[Coordinateur]\n  B -->|Routage de Session| C1[Agent A]\n  B -->|Routage de Session| C2[Agent B]\n  C1 -->|Message de Contexte| C2\n  C2 -->|Réponse| C1\n  B -->|Observabilité| D[Stockage de Logs Signés]\n",[261,2401,2402,2407,2412,2417,2422,2427,2432],{"__ignoreMap":286},[290,2403,2404],{"class":292,"line":293},[290,2405,2406],{},"graph TD\n",[290,2408,2409],{"class":292,"line":299},[290,2410,2411],{},"  A[Client] -->|JSON-RPC| B[Coordinateur]\n",[290,2413,2414],{"class":292,"line":305},[290,2415,2416],{},"  B -->|Routage de Session| C1[Agent A]\n",[290,2418,2419],{"class":292,"line":311},[290,2420,2421],{},"  B -->|Routage de Session| C2[Agent B]\n",[290,2423,2424],{"class":292,"line":317},[290,2425,2426],{},"  C1 -->|Message de Contexte| C2\n",[290,2428,2429],{"class":292,"line":324},[290,2430,2431],{},"  C2 -->|Réponse| C1\n",[290,2433,2434],{"class":292,"line":330},[290,2435,2436],{},"  B -->|Observabilité| D[Stockage de Logs Signés]\n",[102,2438,2440,2446],{"className":2439},[131,132,133],[135,2441,2443],{"id":2442},"problèmes-critiques-de-sécurité-dans-mcp-basé-sur-json-rpc",[110,2444,2445],{},"Problèmes Critiques de Sécurité dans MCP Basé sur JSON-RPC",[79,2447,2448],{},[82,2449,2450],{"href":145},[110,2451,148],{},[1204,2453,2454,2470],{},[1207,2455,2456],{},[1210,2457,2458,2461,2464,2467],{},[1213,2459,2460],{},"Zone",[1213,2462,2463],{},"Problème Critique",[1213,2465,2466],{},"Pourquoi C'est Important dans MCP",[1213,2468,2469],{},"Solution",[1224,2471,2472,2486,2500,2514,2528,2542,2556,2570,2584,2598,2612,2626,2640],{},[1210,2473,2474,2477,2480,2483],{},[1229,2475,2476],{},"🗭 Coordination",[1229,2478,2479],{},"Pas de routage natif multi-parties",[1229,2481,2482],{},"MCP implique souvent l'orchestration de plusieurs services ou agents",[1229,2484,2485],{},"Implémenter un service coordinateur pour gérer le routage, les rôles et les relais de messages",[1210,2487,2488,2491,2494,2497],{},[1229,2489,2490],{},"🔐 Identité",[1229,2492,2493],{},"Pas de couche d'identité/auth/session",[1229,2495,2496],{},"Vous devez authentifier et vérifier l'origine du message",[1229,2498,2499],{},"Utiliser DIDs, mTLS ou couches d'identité basées sur signature avec tokens de session",[1210,2501,2502,2505,2508,2511],{},[1229,2503,2504],{},"⚠️ Erreurs",[1229,2506,2507],{},"Mauvaise observabilité et sémantique d'erreurs",[1229,2509,2510],{},"Difficile de tracer les échecs dans les flux de modèles contextuels",[1229,2512,2513],{},"Ajouter logs signés, codes d'erreur structurés et tableaux de bord de trace",[1210,2515,2516,2519,2522,2525],{},[1229,2517,2518],{},"📦 Types de Données",[1229,2520,2521],{},"Pas de support pour données binaires/complexes",[1229,2523,2524],{},"Les paramètres et réponses du modèle peuvent ne pas s'adapter facilement au JSON",[1229,2526,2527],{},"Utiliser encodage base64, CBOR ou attacher payloads structurés en dehors des champs JSON-RPC centraux",[1210,2529,2530,2533,2536,2539],{},[1229,2531,2532],{},"🧪 Tests",[1229,2534,2535],{},"Pas de simulation ou d'outils étape par étape",[1229,2537,2538],{},"Besoin de replay de protocole et de débogage",[1229,2540,2541],{},"Construire des harnais de test déterministes avec replay de protocole et mocking d'agents",[1210,2543,2544,2547,2550,2553],{},[1229,2545,2546],{},"🧱 Persistance",[1229,2548,2549],{},"Pas de session/mémoire entre appels",[1229,2551,2552],{},"La continuité du contexte entre appels de modèle nécessite état et rôles suivis",[1229,2554,2555],{},"Utiliser Redis ou stockage de session en mémoire pour persister l'état de rôle, tour et message",[1210,2557,2558,2561,2564,2567],{},[1229,2559,2560],{},"💨 Agents Malveillants",[1229,2562,2563],{},"N'importe quel acteur peut injecter logique ou contexte nuisible",[1229,2565,2566],{},"Les agents malveillants peuvent faire dérailler ou empoisonner l'exécution du modèle",[1229,2568,2569],{},"Utiliser sandboxing (ex. VM2/WASM), validation de comportement et listes autorisées pour flux de contexte",[1210,2571,2572,2575,2578,2581],{},[1229,2573,2574],{},"🦮 Dérive de Session",[1229,2576,2577],{},"Les agents peuvent désynchroniser données de contexte/tour",[1229,2579,2580],{},"Conduit à conditions de course, hallucinations ou écrasement de contexte",[1229,2582,2583],{},"Utiliser snapshots de session signés, compteurs de tour et outils de replay du coordinateur",[1210,2585,2586,2589,2592,2595],{},[1229,2587,2588],{},"🔄 Attaques de Replay",[1229,2590,2591],{},"Réutilisation de messages valides entre contextes",[1229,2593,2594],{},"Non détecté, peut manipuler le comportement ou la sortie de l'agent",[1229,2596,2597],{},"Tokens horodatés, validation de nonce ou chaînes de hash pour assurer la fraîcheur",[1210,2599,2600,2603,2606,2609],{},[1229,2601,2602],{},"🛨️ Atténuation d'Agents Malveillants",[1229,2604,2605],{},"Agents compromis agissant dans une session valide",[1229,2607,2608],{},"Menace l'intégrité du système",[1229,2610,2611],{},"Appliquer règles de comportement, utiliser sandboxes sécurisés et valider modèles d'entrée/sortie",[1210,2613,2614,2617,2620,2623],{},[1229,2615,2616],{},"🌐 Identité Décentralisée (DIDs)",[1229,2618,2619],{},"Manque de résolution d'identité globale fiable",[1229,2621,2622],{},"Nécessaire pour délégation de confiance sécurisée entre agents",[1229,2624,2625],{},"Adopter DIDs W3C et résoudre clés via Documents DID ou registres de clés",[1210,2627,2628,2631,2634,2637],{},[1229,2629,2630],{},"📡 Gestion Sécurisée de Sessions",[1229,2632,2633],{},"Les sessions peuvent être piratées, perdues ou incohérentes",[1229,2635,2636],{},"Critique pour état du modèle, contexte et protection replay",[1229,2638,2639],{},"Suivre sessions via coordinateur, assigner IDs uniques, utiliser clés par session",[1210,2641,2642,2645,2648,2651],{},[1229,2643,2644],{},"🔄 Protection Replay et Course",[1229,2646,2647],{},"Requêtes dupliquées ou réordonnées peuvent causer erreurs",[1229,2649,2650],{},"Les agents peuvent mal se comporter ou retraiter anciennes données",[1229,2652,2653],{},"Utiliser nonces, timestamps et compteurs de tour dans chaque message",[102,2655,2657,2663],{"className":2656},[131,132,133],[135,2658,2660],{"id":2659},"tableau-de-vue-densemble-des-capacités",[110,2661,2662],{},"Tableau de Vue d'Ensemble des Capacités",[79,2664,2665],{},[82,2666,2667],{"href":145},[110,2668,148],{},[1204,2670,2671,2693],{},[1207,2672,2673],{},[1210,2674,2675,2678,2681,2684,2687,2690],{},[1213,2676,2677],{},"Capacité",[1213,2679,2680],{},"Contrôlé Par",[1213,2682,2683],{},"Direction",[1213,2685,2686],{},"Effets Secondaires",[1213,2688,2689],{},"Approbation Nécessaire",[1213,2691,2692],{},"Cas d'Usage Typiques",[1224,2694,2695,2715,2734,2753],{},[1210,2696,2697,2700,2703,2706,2709,2712],{},[1229,2698,2699],{},"Outils",[1229,2701,2702],{},"Modèle (LLM)",[1229,2704,2705],{},"Client → Serveur",[1229,2707,2708],{},"Oui (potentiellement)",[1229,2710,2711],{},"Oui",[1229,2713,2714],{},"Actions, appels API, manipulation de données",[1210,2716,2717,2720,2723,2725,2728,2731],{},[1229,2718,2719],{},"Ressources",[1229,2721,2722],{},"Application",[1229,2724,2705],{},[1229,2726,2727],{},"Non (lecture seule)",[1229,2729,2730],{},"Généralement non",[1229,2732,2733],{},"Récupération de données, collecte de contexte",[1210,2735,2736,2739,2742,2745,2748,2750],{},[1229,2737,2738],{},"Prompts",[1229,2740,2741],{},"Utilisateur",[1229,2743,2744],{},"Serveur → Client",[1229,2746,2747],{},"Non",[1229,2749,2747],{},[1229,2751,2752],{},"Flux guidés, modèles spécialisés",[1210,2754,2755,2758,2761,2764,2767,2769],{},[1229,2756,2757],{},"Échantillonnage",[1229,2759,2760],{},"Serveur",[1229,2762,2763],{},"Serveur → Client → Serveur",[1229,2765,2766],{},"Indirectement",[1229,2768,2711],{},[1229,2770,2771],{},"Tâches multi-étapes, comportements agentiques",[102,2773,2775,2781],{"className":2774},[131,132,133],[135,2776,2778],{"id":2777},"architecture-de-référence-du-monde-réel",[110,2779,2780],{},"Architecture de Référence du Monde Réel",[79,2782,2783],{},[82,2784,2785],{"href":145},[110,2786,148],{},[160,2788,2789,2795,2801,2807,2813,2819,2824],{},[163,2790,2791,2794],{},[110,2792,2793],{},"Frontend",": Nuxt 3 (avec Nuxt Content & Tailwind)",[163,2796,2797,2800],{},[110,2798,2799],{},"Backend",": Node.js / Fastify / Express",[163,2802,2803,2806],{},[110,2804,2805],{},"Coordinateur MCP",": Routage personnalisé + logique de contexte (sans état + conscient de session)",[163,2808,2809,2812],{},[110,2810,2811],{},"Agents",": Microservices indépendants ou modules basés sur WASM",[163,2814,2815,2818],{},[110,2816,2817],{},"Transport",": JSON-RPC 2.0 sur HTTPS (ou mTLS)",[163,2820,2821,2823],{},[110,2822,2220],{},": Validation de signature, DIDs et clés de chiffrement par session",[163,2825,2826,2829],{},[110,2827,2828],{},"Logs",": Logs signés en ajout seul + tableau de bord d'observabilité (Grafana / OpenTelemetry)",[281,2831,2833],{"className":283,"code":2832,"language":285,"meta":286,"style":286},"graph LR\n  FE[Client Nuxt3] -->|JSON-RPC| COORD[Coordinateur MCP]\n  COORD --> A1[Agent A]\n  COORD --> A2[Agent B]\n  COORD --> REDIS[(Stockage de Session)]\n  COORD --> LOG[Logs Signés]\n  A1 --> RES1[(API Externe)]\n  A2 --> RES2[(LLM ou Outil)]\n",[261,2834,2835,2840,2845,2850,2855,2860,2865,2870],{"__ignoreMap":286},[290,2836,2837],{"class":292,"line":293},[290,2838,2839],{},"graph LR\n",[290,2841,2842],{"class":292,"line":299},[290,2843,2844],{},"  FE[Client Nuxt3] -->|JSON-RPC| COORD[Coordinateur MCP]\n",[290,2846,2847],{"class":292,"line":305},[290,2848,2849],{},"  COORD --> A1[Agent A]\n",[290,2851,2852],{"class":292,"line":311},[290,2853,2854],{},"  COORD --> A2[Agent B]\n",[290,2856,2857],{"class":292,"line":317},[290,2858,2859],{},"  COORD --> REDIS[(Stockage de Session)]\n",[290,2861,2862],{"class":292,"line":324},[290,2863,2864],{},"  COORD --> LOG[Logs Signés]\n",[290,2866,2867],{"class":292,"line":330},[290,2868,2869],{},"  A1 --> RES1[(API Externe)]\n",[290,2871,2872],{"class":292,"line":336},[290,2873,2874],{},"  A2 --> RES2[(LLM ou Outil)]\n",[102,2876,2878,2884],{"className":2877},[131,132,133],[135,2879,2881],{"id":2880},"outils-et-solutions-pour-développeurs",[110,2882,2883],{},"Outils et Solutions pour Développeurs",[79,2885,2886],{},[82,2887,2888],{"href":145},[110,2889,148],{},[160,2891,2892,2898,2904,2910,2916,2922,2928],{},[163,2893,2067,2894,2897],{},[110,2895,2896],{},"Messages JSON-RPC Signés",": Créer JSON canonique, signer en utilisant EdDSA/ECDSA, envoyer avec clé publique ou DID.",[163,2899,2067,2900,2903],{},[110,2901,2902],{},"Snapshots de Session",": Stocker snapshots JSON par tour avec signatures.",[163,2905,2067,2906,2909],{},[110,2907,2908],{},"Détection de Replay",": Utiliser nonce + timestamps + chaînage de hash.",[163,2911,2067,2912,2915],{},[110,2913,2914],{},"Harnais de Test",": Construire outils de replay MCP avec agents simulés.",[163,2917,2067,2918,2921],{},[110,2919,2920],{},"Observabilité",": Utiliser OpenTelemetry ou agrégateurs de logs avec événements structurés.",[163,2923,2067,2924,2927],{},[110,2925,2926],{},"Validation de Signature",": Les bibliothèques client + agent doivent appliquer validation avant traitement.",[163,2929,2067,2930,2933],{},[110,2931,2932],{},"Service Résolveur DID",": Résoudre clés publiques liées aux DIDs d'agent.",[102,2935,2937,2943],{"className":2936},[131,132,133],[135,2938,2940],{"id":2939},"comment-signer-les-payloads-json-rpc",[110,2941,2942],{},"Comment Signer les Payloads JSON-RPC",[79,2944,2945],{},[82,2946,2947],{"href":145},[110,2948,148],{},[281,2950,2954],{"className":2951,"code":2952,"language":2953,"meta":286,"style":286},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { sign, verify } from 'crypto';\nconst method = 'agent.perform';\nconst params = { input: 'Exécuter test' };\nconst payload = JSON.stringify({ method, params });\nconst signature = sign('sha256', Buffer.from(payload), privateKey);\n\n// Envoyer: { method, params, signature, pubKey }\n","ts",[261,2955,2956,2987,3007,3033,3069,3109,3113],{"__ignoreMap":286},[290,2957,2958,2961,2964,2967,2969,2972,2975,2978,2980,2983,2985],{"class":292,"line":293},[290,2959,2960],{"class":698},"import",[290,2962,2963],{"class":639}," {",[290,2965,2966],{"class":691}," sign",[290,2968,665],{"class":639},[290,2970,2971],{"class":691}," verify",[290,2973,2974],{"class":639}," }",[290,2976,2977],{"class":698}," from",[290,2979,1151],{"class":639},[290,2981,2982],{"class":813},"crypto",[290,2984,817],{"class":639},[290,2986,716],{"class":639},[290,2988,2989,2992,2995,2998,3000,3003,3005],{"class":292,"line":299},[290,2990,2991],{"class":631},"const",[290,2993,2994],{"class":691}," method ",[290,2996,2997],{"class":639},"=",[290,2999,1151],{"class":639},[290,3001,3002],{"class":813},"agent.perform",[290,3004,817],{"class":639},[290,3006,716],{"class":639},[290,3008,3009,3011,3014,3016,3018,3021,3023,3025,3028,3030],{"class":292,"line":305},[290,3010,2991],{"class":631},[290,3012,3013],{"class":691}," params ",[290,3015,2997],{"class":639},[290,3017,2963],{"class":639},[290,3019,3020],{"class":648}," input",[290,3022,659],{"class":639},[290,3024,1151],{"class":639},[290,3026,3027],{"class":813},"Exécuter test",[290,3029,817],{"class":639},[290,3031,3032],{"class":639}," };\n",[290,3034,3035,3037,3040,3042,3045,3047,3050,3052,3055,3058,3060,3062,3065,3067],{"class":292,"line":311},[290,3036,2991],{"class":631},[290,3038,3039],{"class":691}," payload ",[290,3041,2997],{"class":639},[290,3043,3044],{"class":691}," JSON",[290,3046,200],{"class":639},[290,3048,3049],{"class":705},"stringify",[290,3051,652],{"class":691},[290,3053,3054],{"class":639},"{",[290,3056,3057],{"class":691}," method",[290,3059,665],{"class":639},[290,3061,3013],{"class":691},[290,3063,3064],{"class":639},"}",[290,3066,676],{"class":691},[290,3068,716],{"class":639},[290,3070,3071,3073,3076,3078,3080,3082,3084,3087,3089,3091,3094,3096,3099,3102,3104,3107],{"class":292,"line":317},[290,3072,2991],{"class":631},[290,3074,3075],{"class":691}," signature ",[290,3077,2997],{"class":639},[290,3079,2966],{"class":705},[290,3081,652],{"class":691},[290,3083,817],{"class":639},[290,3085,3086],{"class":813},"sha256",[290,3088,817],{"class":639},[290,3090,665],{"class":639},[290,3092,3093],{"class":691}," Buffer",[290,3095,200],{"class":639},[290,3097,3098],{"class":705},"from",[290,3100,3101],{"class":691},"(payload)",[290,3103,665],{"class":639},[290,3105,3106],{"class":691}," privateKey)",[290,3108,716],{"class":639},[290,3110,3111],{"class":292,"line":324},[290,3112,321],{"emptyLinePlaceholder":320},[290,3114,3115],{"class":292,"line":330},[290,3116,3117],{"class":625},"// Envoyer: { method, params, signature, pubKey }\n",[102,3119,3121,3127],{"className":3120},[131,132,133],[135,3122,3124],{"id":3123},"résumé",[110,3125,3126],{},"Résumé",[79,3128,3129],{},[82,3130,3131],{"href":145},[110,3132,148],{},[79,3134,3135,3136,3139,3140,3139,3143,3146,3147,3150],{},"Un système MCP sécurisé construit avec JSON-RPC nécessite des couches de protection : identité, intégrité des messages, sécurité du contexte et règles de protocole claires. Combiner ",[110,3137,3138],{},"DIDs",", ",[110,3141,3142],{},"signatures",[110,3144,3145],{},"contrôle de session"," et ",[110,3148,3149],{},"défenses contre agents malveillants"," assure que votre système modulaire reste sûr, observable et extensible.",[102,3152,3154],{"className":3153},[2172,2173,2174,2175],[79,3155,3156],{},[82,3157,3158],{"href":145},[110,3159,148],{},[2183,3161,3162],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":286,"searchDepth":299,"depth":299,"links":3164},[3165,3170,3171,3172,3173,3174,3175],{"id":2255,"depth":299,"text":2258,"children":3166},[3167,3168,3169],{"id":2273,"depth":305,"text":2274},{"id":2334,"depth":305,"text":2335},{"id":2395,"depth":305,"text":2396},{"id":2442,"depth":299,"text":2445},{"id":2659,"depth":299,"text":2662},{"id":2777,"depth":299,"text":2780},{"id":2880,"depth":299,"text":2883},{"id":2939,"depth":299,"text":2942},{"id":3123,"depth":299,"text":3126},"2025-06-26","Problèmes critiques de sécurité, meilleures solutions et outils pratiques pour des systèmes MCP robustes et sécurisés utilisant JSON-RPC.",{"src":2208},{},{"title":20,"description":3177},"v8QZCrRACbPHafMNqzDSLJTS3GEhRu0WnjMdQjJugMo",{"id":3183,"title":24,"authors":3184,"badge":3187,"body":3190,"date":4632,"description":4633,"extension":2206,"image":4634,"meta":4635,"navigation":320,"path":25,"seo":4636,"stem":26,"__hash__":4637},"posts_fr/fr/blog/2. mcp-create.md",[3185],{"name":66,"description":2216,"to":68,"avatar":3186},{"src":2218},{"label":3188,"color":3189,"variant":74},"MCP, Temps Réel","error",{"type":76,"value":3191,"toc":4620},[3192,3198,3213,3260,3275,3298,3313,3323,3416,3431,3838,3980,3995,4001,4168,4183,4201,4251,4266,4294,4309,4339,4425,4440,4446,4453,4576,4589,4598,4608,4617],[102,3193,3195],{"className":3194},[105],[79,3196,3197],{},"Les serveurs MCP révolutionnent la façon dont les modèles de langage interagissent avec les sources de données externes. Considérez-les comme des plugins sophistiqués qui étendent les capacités de l'IA au-delà de leurs données d'entraînement. Dans ce tutoriel complet, nous construirons un serveur MCP météorologique qui connecte Claude, GPT-4, ou tout autre LLM aux informations météorologiques en temps réel en utilisant Python et l'API Open-Meteo.",[102,3199,3201,3207],{"className":3200},[131,132,133],[135,3202,3204],{"id":3203},"quest-ce-quun-serveur-mcp",[110,3205,3206],{},"Qu'est-ce qu'un Serveur MCP ?",[79,3208,3209],{},[82,3210,3211],{"href":145},[110,3212,148],{},[102,3214,3216,3234],{"className":3215},[449,450,451,452,453,454],[102,3217,3218],{},[79,3219,3220,3229],{},[3221,3222],"img",{"alt":3223,"className":3224,"height":3226,"src":3227,"style":3228},"Diagramme d'Architecture MCP",[3225],"rounded-md",400,"/blog/mcp/llm-has-tools.png","padding: 20px; background-color: white",[82,3230,3233],{"href":3231,"rel":3232},"http://one-front/blog/mcp",[99],"Serveur MCP : Connecter l'IA aux Données en Temps Réel",[102,3235,3237,3240,3243],{"className":3236},[105],[79,3238,3239],{},"Les serveurs MCP étendent les capacités des modèles de langage en les connectant aux sources de données et services. Ce sont des applications agnostiques qui facilitent l'intégration avec n'importe quelle donnée ou service que vous pouvez imaginer. Pensez aux appels de fonction, mais les fonctions sont des plugins qui peuvent virtuellement tout faire.",[79,3241,3242],{},"Les serveurs MCP exposent trois primitives principales :",[160,3244,3245,3250,3255],{},[163,3246,3247,3249],{},[110,3248,2719],{}," (contrôlées par le client) : Exposition passive de données pour le contexte",[163,3251,3252,3254],{},[110,3253,2699],{}," (contrôlés par le modèle) : Fonctionnalité exécutable pour les actions",[163,3256,3257,3259],{},[110,3258,2738],{}," (contrôlés par l'utilisateur) : Workflows réutilisables et modèles",[102,3261,3263,3269],{"className":3262},[131,132,133],[135,3264,3266],{"id":3265},"pourquoi-les-données-météorologiques",[110,3267,3268],{},"Pourquoi les Données Météorologiques ?",[79,3270,3271],{},[82,3272,3273],{"href":145},[110,3274,148],{},[102,3276,3278,3281,3284],{"className":3277},[105],[79,3279,3280],{},"Les données météorologiques fournissent un excellent exemple pour le développement de serveurs MCP car elles démontrent l'intégration d'API du monde réel avec des applications pratiques. Les modèles de langage excellent à transformer les données météorologiques brutes (température, vitesse du vent, humidité) en descriptions en langage naturel et recommandations actionnables.",[79,3282,3283],{},"Nous utiliserons l'API Open-Meteo car elle est :",[160,3285,3286,3289,3292,3295],{},[163,3287,3288],{},"Gratuite pour un usage non commercial",[163,3290,3291],{},"Aucune clé API requise",[163,3293,3294],{},"Facilement configurable via les paramètres de requête",[163,3296,3297],{},"Parfaite pour l'intégration LLM",[102,3299,3301,3307],{"className":3300},[131,132,133],[135,3302,3304],{"id":3303},"configuration-du-projet",[110,3305,3306],{},"Configuration du Projet",[79,3308,3309],{},[82,3310,3311],{"href":145},[110,3312,148],{},[102,3314,3316],{"className":3315},[105],[79,3317,3318,3319,3322],{},"Avant de plonger dans le code, assurez-vous d'avoir les outils nécessaires installés. Nous utiliserons ",[261,3320,3321],{},"uv",", un gestionnaire de paquets Python basé sur Rust qui rend la gestion des dépendances transparente.",[281,3324,3328],{"className":3325,"code":3326,"language":3327,"meta":286,"style":286},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Créer le répertoire du projet\nmkdir mcp-server-weather\ncd mcp-server-weather\n\n# Initialiser le projet uv\nuv init\n\n# Créer et activer l'environnement virtuel\nuv venv\nsource .venv/bin/activate\n\n# Installer les dépendances\nuv add \"mcp[cli]\" httpx\n","bash",[261,3329,3330,3335,3343,3350,3354,3359,3366,3370,3375,3382,3390,3394,3399],{"__ignoreMap":286},[290,3331,3332],{"class":292,"line":293},[290,3333,3334],{"class":625},"# Créer le répertoire du projet\n",[290,3336,3337,3340],{"class":292,"line":299},[290,3338,3339],{"class":635},"mkdir",[290,3341,3342],{"class":813}," mcp-server-weather\n",[290,3344,3345,3348],{"class":292,"line":305},[290,3346,3347],{"class":705},"cd",[290,3349,3342],{"class":813},[290,3351,3352],{"class":292,"line":311},[290,3353,321],{"emptyLinePlaceholder":320},[290,3355,3356],{"class":292,"line":317},[290,3357,3358],{"class":625},"# Initialiser le projet uv\n",[290,3360,3361,3363],{"class":292,"line":324},[290,3362,3321],{"class":635},[290,3364,3365],{"class":813}," init\n",[290,3367,3368],{"class":292,"line":330},[290,3369,321],{"emptyLinePlaceholder":320},[290,3371,3372],{"class":292,"line":336},[290,3373,3374],{"class":625},"# Créer et activer l'environnement virtuel\n",[290,3376,3377,3379],{"class":292,"line":342},[290,3378,3321],{"class":635},[290,3380,3381],{"class":813}," venv\n",[290,3383,3384,3387],{"class":292,"line":347},[290,3385,3386],{"class":705},"source",[290,3388,3389],{"class":813}," .venv/bin/activate\n",[290,3391,3392],{"class":292,"line":353},[290,3393,321],{"emptyLinePlaceholder":320},[290,3395,3396],{"class":292,"line":359},[290,3397,3398],{"class":625},"# Installer les dépendances\n",[290,3400,3401,3403,3406,3408,3411,3413],{"class":292,"line":365},[290,3402,3321],{"class":635},[290,3404,3405],{"class":813}," add",[290,3407,954],{"class":639},[290,3409,3410],{"class":813},"mcp[cli]",[290,3412,911],{"class":639},[290,3414,3415],{"class":813}," httpx\n",[102,3417,3419,3425],{"className":3418},[131,132,133],[135,3420,3422],{"id":3421},"construction-du-serveur-mcp",[110,3423,3424],{},"Construction du Serveur MCP",[79,3426,3427],{},[82,3428,3429],{"href":145},[110,3430,148],{},[102,3432,3434,3826],{"className":3433},[449,450,451,452,453,454],[102,3435,3436],{},[281,3437,3439],{"className":1735,"code":3438,"language":1737,"meta":286,"style":286},"  [{\"type\": \"text\", \"text\": \"Prévisions pour 40.7128, -74.006 :\\n\\nAujourd'hui :\\nTempérature : 66°F\\nVent : 13 à 16 mph O\\nPrincipalement Ensoleillé\\n---\\nCe soir :\\nTempérature : 55°F\\nVent : 5 à 13 mph O\\nPartiellement Nuageux\\n---\\nLundi :\\nTempérature : 71°F\\nVent : 8 mph O\\nEnsoleillé\\n---\\nLundi Soir :\\nTempérature : 59°F\\nVent : 3 à 8 mph O\\nPrincipalement Dégagé\\n---\\nMardi :\\nTempérature : 77°F\\nVent : 3 à 7 mph SO\\nEnsoleillé\\n---\\nMardi Soir :\\nTempérature : 65°F\\nVent : 5 à 8 mph S\\nPrincipalement Dégagé\\n---\\nMercredi :\\nTempérature : 82°F\\nVent : 5 à 12 mph SO\\nEnsoleillé\\n---\\nMercredi Soir :\\nTempérature : 69°F\\nVent : 8 à 12 mph SO\\nPrincipalement Dégagé\\n---\\nJeudi :\\nTempérature : 85°F\\nVent : 7 à 12 mph SO\\nPrincipalement Ensoleillé\\n---\\nJeudi Soir :\\nTempérature : 72°F\\nVent : 7 à 12 mph SO\\nPartiellement Nuageux\\n---\\nVendredi :\\nTempérature : 82°F\\nVent : 7 à 12 mph SO\\nPossibilité d'Averses\\n---\\nVendredi Soir :\\nTempérature : 70°F\\nVent : 7 à 12 mph SO\\nPossibilité d'Averses\\n---\\nSamedi :\\nTempérature : 76°F\\nVent : 9 mph O\\nPossibilité d'Averses\\n---\\nSamedi Soir :\\nTempérature : 67°F\\nVent : 6 à 9 mph NO\\nPossibilité d'Averses\\n---\", \"uuid\": \"fb196843-938b-4a75-b1a5-b660892f9817\"}]\n",[261,3440,3441],{"__ignoreMap":286},[290,3442,3443,3446,3448,3451,3453,3455,3457,3460,3462,3464,3466,3468,3470,3472,3474,3477,3480,3483,3486,3489,3491,3494,3496,3499,3501,3504,3506,3509,3511,3514,3516,3519,3521,3524,3526,3528,3530,3533,3535,3538,3540,3543,3545,3548,3550,3552,3554,3557,3559,3562,3564,3567,3569,3572,3574,3576,3578,3581,3583,3586,3588,3591,3593,3595,3597,3599,3601,3604,3606,3609,3611,3614,3616,3618,3620,3622,3624,3627,3629,3632,3634,3637,3639,3641,3643,3645,3647,3650,3652,3655,3657,3660,3662,3664,3666,3668,3670,3673,3675,3678,3680,3683,3685,3687,3689,3691,3693,3696,3698,3701,3703,3705,3707,3709,3711,3713,3715,3718,3720,3722,3724,3726,3728,3731,3733,3735,3737,3740,3742,3745,3747,3749,3751,3753,3755,3757,3759,3762,3764,3767,3769,3772,3774,3776,3778,3780,3782,3785,3787,3790,3792,3795,3797,3799,3801,3803,3805,3807,3809,3812,3814,3816,3818,3821,3823],{"class":292,"line":293},[290,3444,3445],{"class":639},"  [{",[290,3447,911],{"class":639},[290,3449,3450],{"class":631},"type",[290,3452,911],{"class":639},[290,3454,659],{"class":639},[290,3456,954],{"class":639},[290,3458,3459],{"class":813},"text",[290,3461,911],{"class":639},[290,3463,665],{"class":639},[290,3465,954],{"class":639},[290,3467,3459],{"class":631},[290,3469,911],{"class":639},[290,3471,659],{"class":639},[290,3473,954],{"class":639},[290,3475,3476],{"class":813},"Prévisions pour 40.7128, -74.006 :",[290,3478,3479],{"class":691},"\\n\\n",[290,3481,3482],{"class":813},"Aujourd'hui :",[290,3484,3485],{"class":691},"\\n",[290,3487,3488],{"class":813},"Température : 66°F",[290,3490,3485],{"class":691},[290,3492,3493],{"class":813},"Vent : 13 à 16 mph O",[290,3495,3485],{"class":691},[290,3497,3498],{"class":813},"Principalement Ensoleillé",[290,3500,3485],{"class":691},[290,3502,3503],{"class":813},"---",[290,3505,3485],{"class":691},[290,3507,3508],{"class":813},"Ce soir :",[290,3510,3485],{"class":691},[290,3512,3513],{"class":813},"Température : 55°F",[290,3515,3485],{"class":691},[290,3517,3518],{"class":813},"Vent : 5 à 13 mph O",[290,3520,3485],{"class":691},[290,3522,3523],{"class":813},"Partiellement Nuageux",[290,3525,3485],{"class":691},[290,3527,3503],{"class":813},[290,3529,3485],{"class":691},[290,3531,3532],{"class":813},"Lundi :",[290,3534,3485],{"class":691},[290,3536,3537],{"class":813},"Température : 71°F",[290,3539,3485],{"class":691},[290,3541,3542],{"class":813},"Vent : 8 mph O",[290,3544,3485],{"class":691},[290,3546,3547],{"class":813},"Ensoleillé",[290,3549,3485],{"class":691},[290,3551,3503],{"class":813},[290,3553,3485],{"class":691},[290,3555,3556],{"class":813},"Lundi Soir :",[290,3558,3485],{"class":691},[290,3560,3561],{"class":813},"Température : 59°F",[290,3563,3485],{"class":691},[290,3565,3566],{"class":813},"Vent : 3 à 8 mph O",[290,3568,3485],{"class":691},[290,3570,3571],{"class":813},"Principalement Dégagé",[290,3573,3485],{"class":691},[290,3575,3503],{"class":813},[290,3577,3485],{"class":691},[290,3579,3580],{"class":813},"Mardi :",[290,3582,3485],{"class":691},[290,3584,3585],{"class":813},"Température : 77°F",[290,3587,3485],{"class":691},[290,3589,3590],{"class":813},"Vent : 3 à 7 mph SO",[290,3592,3485],{"class":691},[290,3594,3547],{"class":813},[290,3596,3485],{"class":691},[290,3598,3503],{"class":813},[290,3600,3485],{"class":691},[290,3602,3603],{"class":813},"Mardi Soir :",[290,3605,3485],{"class":691},[290,3607,3608],{"class":813},"Température : 65°F",[290,3610,3485],{"class":691},[290,3612,3613],{"class":813},"Vent : 5 à 8 mph S",[290,3615,3485],{"class":691},[290,3617,3571],{"class":813},[290,3619,3485],{"class":691},[290,3621,3503],{"class":813},[290,3623,3485],{"class":691},[290,3625,3626],{"class":813},"Mercredi :",[290,3628,3485],{"class":691},[290,3630,3631],{"class":813},"Température : 82°F",[290,3633,3485],{"class":691},[290,3635,3636],{"class":813},"Vent : 5 à 12 mph SO",[290,3638,3485],{"class":691},[290,3640,3547],{"class":813},[290,3642,3485],{"class":691},[290,3644,3503],{"class":813},[290,3646,3485],{"class":691},[290,3648,3649],{"class":813},"Mercredi Soir :",[290,3651,3485],{"class":691},[290,3653,3654],{"class":813},"Température : 69°F",[290,3656,3485],{"class":691},[290,3658,3659],{"class":813},"Vent : 8 à 12 mph SO",[290,3661,3485],{"class":691},[290,3663,3571],{"class":813},[290,3665,3485],{"class":691},[290,3667,3503],{"class":813},[290,3669,3485],{"class":691},[290,3671,3672],{"class":813},"Jeudi :",[290,3674,3485],{"class":691},[290,3676,3677],{"class":813},"Température : 85°F",[290,3679,3485],{"class":691},[290,3681,3682],{"class":813},"Vent : 7 à 12 mph SO",[290,3684,3485],{"class":691},[290,3686,3498],{"class":813},[290,3688,3485],{"class":691},[290,3690,3503],{"class":813},[290,3692,3485],{"class":691},[290,3694,3695],{"class":813},"Jeudi Soir :",[290,3697,3485],{"class":691},[290,3699,3700],{"class":813},"Température : 72°F",[290,3702,3485],{"class":691},[290,3704,3682],{"class":813},[290,3706,3485],{"class":691},[290,3708,3523],{"class":813},[290,3710,3485],{"class":691},[290,3712,3503],{"class":813},[290,3714,3485],{"class":691},[290,3716,3717],{"class":813},"Vendredi :",[290,3719,3485],{"class":691},[290,3721,3631],{"class":813},[290,3723,3485],{"class":691},[290,3725,3682],{"class":813},[290,3727,3485],{"class":691},[290,3729,3730],{"class":813},"Possibilité d'Averses",[290,3732,3485],{"class":691},[290,3734,3503],{"class":813},[290,3736,3485],{"class":691},[290,3738,3739],{"class":813},"Vendredi Soir :",[290,3741,3485],{"class":691},[290,3743,3744],{"class":813},"Température : 70°F",[290,3746,3485],{"class":691},[290,3748,3682],{"class":813},[290,3750,3485],{"class":691},[290,3752,3730],{"class":813},[290,3754,3485],{"class":691},[290,3756,3503],{"class":813},[290,3758,3485],{"class":691},[290,3760,3761],{"class":813},"Samedi :",[290,3763,3485],{"class":691},[290,3765,3766],{"class":813},"Température : 76°F",[290,3768,3485],{"class":691},[290,3770,3771],{"class":813},"Vent : 9 mph O",[290,3773,3485],{"class":691},[290,3775,3730],{"class":813},[290,3777,3485],{"class":691},[290,3779,3503],{"class":813},[290,3781,3485],{"class":691},[290,3783,3784],{"class":813},"Samedi Soir :",[290,3786,3485],{"class":691},[290,3788,3789],{"class":813},"Température : 67°F",[290,3791,3485],{"class":691},[290,3793,3794],{"class":813},"Vent : 6 à 9 mph NO",[290,3796,3485],{"class":691},[290,3798,3730],{"class":813},[290,3800,3485],{"class":691},[290,3802,3503],{"class":813},[290,3804,911],{"class":639},[290,3806,665],{"class":639},[290,3808,954],{"class":639},[290,3810,3811],{"class":631},"uuid",[290,3813,911],{"class":639},[290,3815,659],{"class":639},[290,3817,954],{"class":639},[290,3819,3820],{"class":813},"fb196843-938b-4a75-b1a5-b660892f9817",[290,3822,911],{"class":639},[290,3824,3825],{"class":639},"}]\n",[102,3827,3829,3832,3835],{"className":3828},[105],[79,3830,3831],{},"Ici vous pouvez voir une réponse de l'API get-weather d'un serveur MCP !",[79,3833,3834],{},"Commencez par créer l'échafaudage du serveur. Cela établit la fondation pour notre serveur MCP en utilisant FastMCP, qui simplifie la création et la gestion de serveurs.",[79,3836,3837],{},"FastMCP fournit une interface simplifiée pour définir les outils, ressources et prompts. En tirant parti de ses fonctionnalités intégrées, vous pouvez vous concentrer sur l'implémentation de la fonctionnalité sans vous soucier des détails de serveur de bas niveau.",[281,3839,3843],{"className":3840,"code":3841,"language":3842,"meta":286,"style":286},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from typing import Any\nimport httpx\nfrom mcp.server.fastmcp import FastMCP\n\n# Initialiser le serveur FastMCP\nmcp = FastMCP(\"weather\")\n\n# Constantes\nOPENMETEO_API_BASE = \"https://api.open-meteo.com/v1\"\nUSER_AGENT = \"weather-app/1.0\"\n\n# Fonction d'aide pour les requêtes API\nasync def make_openmeteo_request(url: str) -> dict[str, Any] | None:\n    \"\"\"Effectuer une requête vers l'API Open-Meteo avec gestion d'erreur appropriée.\"\"\"\n    headers = {\n        \"User-Agent\": USER_AGENT,\n        \"Accept\": \"application/json\"\n    }\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.get(url, headers=headers, timeout=30.0)\n            response.raise_for_status()\n            return response.json()\n        except Exception:\n            return None\n\nif __name__ == \"__main__\":\n    mcp.run(transport='stdio')\n","python",[261,3844,3845,3850,3855,3860,3864,3869,3874,3878,3883,3888,3893,3897,3902,3907,3912,3917,3922,3927,3931,3936,3941,3946,3951,3956,3961,3966,3970,3975],{"__ignoreMap":286},[290,3846,3847],{"class":292,"line":293},[290,3848,3849],{},"from typing import Any\n",[290,3851,3852],{"class":292,"line":299},[290,3853,3854],{},"import httpx\n",[290,3856,3857],{"class":292,"line":305},[290,3858,3859],{},"from mcp.server.fastmcp import FastMCP\n",[290,3861,3862],{"class":292,"line":311},[290,3863,321],{"emptyLinePlaceholder":320},[290,3865,3866],{"class":292,"line":317},[290,3867,3868],{},"# Initialiser le serveur FastMCP\n",[290,3870,3871],{"class":292,"line":324},[290,3872,3873],{},"mcp = FastMCP(\"weather\")\n",[290,3875,3876],{"class":292,"line":330},[290,3877,321],{"emptyLinePlaceholder":320},[290,3879,3880],{"class":292,"line":336},[290,3881,3882],{},"# Constantes\n",[290,3884,3885],{"class":292,"line":342},[290,3886,3887],{},"OPENMETEO_API_BASE = \"https://api.open-meteo.com/v1\"\n",[290,3889,3890],{"class":292,"line":347},[290,3891,3892],{},"USER_AGENT = \"weather-app/1.0\"\n",[290,3894,3895],{"class":292,"line":353},[290,3896,321],{"emptyLinePlaceholder":320},[290,3898,3899],{"class":292,"line":359},[290,3900,3901],{},"# Fonction d'aide pour les requêtes API\n",[290,3903,3904],{"class":292,"line":365},[290,3905,3906],{},"async def make_openmeteo_request(url: str) -> dict[str, Any] | None:\n",[290,3908,3909],{"class":292,"line":370},[290,3910,3911],{},"    \"\"\"Effectuer une requête vers l'API Open-Meteo avec gestion d'erreur appropriée.\"\"\"\n",[290,3913,3914],{"class":292,"line":376},[290,3915,3916],{},"    headers = {\n",[290,3918,3919],{"class":292,"line":382},[290,3920,3921],{},"        \"User-Agent\": USER_AGENT,\n",[290,3923,3924],{"class":292,"line":387},[290,3925,3926],{},"        \"Accept\": \"application/json\"\n",[290,3928,3929],{"class":292,"line":393},[290,3930,767],{},[290,3932,3933],{"class":292,"line":398},[290,3934,3935],{},"    async with httpx.AsyncClient() as client:\n",[290,3937,3938],{"class":292,"line":404},[290,3939,3940],{},"        try:\n",[290,3942,3943],{"class":292,"line":410},[290,3944,3945],{},"            response = await client.get(url, headers=headers, timeout=30.0)\n",[290,3947,3948],{"class":292,"line":415},[290,3949,3950],{},"            response.raise_for_status()\n",[290,3952,3953],{"class":292,"line":421},[290,3954,3955],{},"            return response.json()\n",[290,3957,3958],{"class":292,"line":427},[290,3959,3960],{},"        except Exception:\n",[290,3962,3963],{"class":292,"line":902},[290,3964,3965],{},"            return None\n",[290,3967,3968],{"class":292,"line":931},[290,3969,321],{"emptyLinePlaceholder":320},[290,3971,3972],{"class":292,"line":975},[290,3973,3974],{},"if __name__ == \"__main__\":\n",[290,3976,3977],{"class":292,"line":1000},[290,3978,3979],{},"    mcp.run(transport='stdio')\n",[102,3981,3983,3989],{"className":3982},[131,132,133],[135,3984,3986],{"id":3985},"création-des-outils-météorologiques",[110,3987,3988],{},"Création des Outils Météorologiques",[79,3990,3991],{},[82,3992,3993],{"href":145},[110,3994,148],{},[102,3996,3998],{"className":3997},[105],[79,3999,4000],{},"Les outils sont le cœur des serveurs MCP. Ils exposent des fonctionnalités exécutables que les modèles de langage peuvent invoquer. Notre outil météorologique récupérera les conditions actuelles et les prévisions basées sur les coordonnées géographiques.",[281,4002,4004],{"className":3840,"code":4003,"language":3842,"meta":286,"style":286},"@mcp.tool()\nasync def get_current_weather(latitude: float, longitude: float) -> str:\n    \"\"\"Obtenir la météo actuelle pour un emplacement.\n\n    Args:\n        latitude: Latitude de l'emplacement\n        longitude: Longitude de l'emplacement\n    \"\"\"\n    \n    url = f\"{OPENMETEO_API_BASE}/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,is_day,showers,cloud_cover,wind_speed_10m,wind_direction_10m,pressure_msl,snowfall,precipitation,relative_humidity_2m,apparent_temperature,rain,weather_code,surface_pressure,wind_gusts_10m\"\n    \n    data = await make_openmeteo_request(url)\n\n    if not data:\n        return \"Impossible de récupérer les données météorologiques actuelles pour cet emplacement.\"\n\n    return data\n\n@mcp.tool()\nasync def get_forecast(latitude: float, longitude: float, days: int = 7) -> str:\n    \"\"\"Obtenir les prévisions météorologiques pour un emplacement.\n\n    Args:\n        latitude: Latitude de l'emplacement\n        longitude: Longitude de l'emplacement  \n        days: Nombre de jours à prévoir (1-16)\n    \"\"\"\n    \n    url = f\"{OPENMETEO_API_BASE}/forecast?latitude={latitude}&longitude={longitude}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,weather_code&forecast_days={days}\"\n    \n    data = await make_openmeteo_request(url)\n    \n    if not data:\n        return \"Impossible de récupérer les données de prévision pour cet emplacement.\"\n    \n    return data\n",[261,4005,4006,4011,4016,4021,4025,4030,4035,4040,4045,4049,4054,4058,4063,4067,4072,4077,4081,4086,4090,4094,4099,4104,4108,4112,4116,4121,4126,4130,4134,4139,4143,4147,4151,4155,4160,4164],{"__ignoreMap":286},[290,4007,4008],{"class":292,"line":293},[290,4009,4010],{},"@mcp.tool()\n",[290,4012,4013],{"class":292,"line":299},[290,4014,4015],{},"async def get_current_weather(latitude: float, longitude: float) -> str:\n",[290,4017,4018],{"class":292,"line":305},[290,4019,4020],{},"    \"\"\"Obtenir la météo actuelle pour un emplacement.\n",[290,4022,4023],{"class":292,"line":311},[290,4024,321],{"emptyLinePlaceholder":320},[290,4026,4027],{"class":292,"line":317},[290,4028,4029],{},"    Args:\n",[290,4031,4032],{"class":292,"line":324},[290,4033,4034],{},"        latitude: Latitude de l'emplacement\n",[290,4036,4037],{"class":292,"line":330},[290,4038,4039],{},"        longitude: Longitude de l'emplacement\n",[290,4041,4042],{"class":292,"line":336},[290,4043,4044],{},"    \"\"\"\n",[290,4046,4047],{"class":292,"line":342},[290,4048,721],{},[290,4050,4051],{"class":292,"line":347},[290,4052,4053],{},"    url = f\"{OPENMETEO_API_BASE}/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,is_day,showers,cloud_cover,wind_speed_10m,wind_direction_10m,pressure_msl,snowfall,precipitation,relative_humidity_2m,apparent_temperature,rain,weather_code,surface_pressure,wind_gusts_10m\"\n",[290,4055,4056],{"class":292,"line":353},[290,4057,721],{},[290,4059,4060],{"class":292,"line":359},[290,4061,4062],{},"    data = await make_openmeteo_request(url)\n",[290,4064,4065],{"class":292,"line":365},[290,4066,321],{"emptyLinePlaceholder":320},[290,4068,4069],{"class":292,"line":370},[290,4070,4071],{},"    if not data:\n",[290,4073,4074],{"class":292,"line":376},[290,4075,4076],{},"        return \"Impossible de récupérer les données météorologiques actuelles pour cet emplacement.\"\n",[290,4078,4079],{"class":292,"line":382},[290,4080,321],{"emptyLinePlaceholder":320},[290,4082,4083],{"class":292,"line":387},[290,4084,4085],{},"    return data\n",[290,4087,4088],{"class":292,"line":393},[290,4089,321],{"emptyLinePlaceholder":320},[290,4091,4092],{"class":292,"line":398},[290,4093,4010],{},[290,4095,4096],{"class":292,"line":404},[290,4097,4098],{},"async def get_forecast(latitude: float, longitude: float, days: int = 7) -> str:\n",[290,4100,4101],{"class":292,"line":410},[290,4102,4103],{},"    \"\"\"Obtenir les prévisions météorologiques pour un emplacement.\n",[290,4105,4106],{"class":292,"line":415},[290,4107,321],{"emptyLinePlaceholder":320},[290,4109,4110],{"class":292,"line":421},[290,4111,4029],{},[290,4113,4114],{"class":292,"line":427},[290,4115,4034],{},[290,4117,4118],{"class":292,"line":902},[290,4119,4120],{},"        longitude: Longitude de l'emplacement  \n",[290,4122,4123],{"class":292,"line":931},[290,4124,4125],{},"        days: Nombre de jours à prévoir (1-16)\n",[290,4127,4128],{"class":292,"line":975},[290,4129,4044],{},[290,4131,4132],{"class":292,"line":1000},[290,4133,721],{},[290,4135,4136],{"class":292,"line":1020},[290,4137,4138],{},"    url = f\"{OPENMETEO_API_BASE}/forecast?latitude={latitude}&longitude={longitude}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,weather_code&forecast_days={days}\"\n",[290,4140,4141],{"class":292,"line":1026},[290,4142,721],{},[290,4144,4145],{"class":292,"line":1031},[290,4146,4062],{},[290,4148,4149],{"class":292,"line":1036},[290,4150,721],{},[290,4152,4153],{"class":292,"line":1042},[290,4154,4071],{},[290,4156,4157],{"class":292,"line":1064},[290,4158,4159],{},"        return \"Impossible de récupérer les données de prévision pour cet emplacement.\"\n",[290,4161,4162],{"class":292,"line":1083},[290,4163,721],{},[290,4165,4166],{"class":292,"line":1110},[290,4167,4085],{},[102,4169,4171,4177],{"className":4170},[131,132,133],[135,4172,4174],{"id":4173},"test-de-votre-serveur-mcp",[110,4175,4176],{},"Test de Votre Serveur MCP",[79,4178,4179],{},[82,4180,4181],{"href":145},[110,4182,148],{},[102,4184,4186,4195],{"className":4185},[449,450,451,452,453,454],[102,4187,4188],{},[79,4189,4190],{},[3221,4191],{"alt":4192,"className":4193,"height":3226,"src":4194,"style":3228},"Interface MCP Inspector",[3225],"/blog/mcp/mcp-inspector.png",[102,4196,4198],{"className":4197},[105],[79,4199,4200],{},"Le MCP Inspector fournit une interface web pour tester votre serveur avant de l'intégrer avec les modèles de langage. Cet outil est inestimable pour le débogage et la validation.",[281,4202,4204],{"className":3325,"code":4203,"language":3327,"meta":286,"style":286},"# Démarrer le serveur MCP en mode développement\nmcp dev server.py\n\n# Ouvrir le navigateur sur http://localhost:5173\n# Se connecter au serveur\n# Naviguer vers l'onglet Outils\n# Tester get_current_weather avec des coordonnées\n# Exemple : latitude=63.4463991, longitude=10.8127596\n",[261,4205,4206,4211,4222,4226,4231,4236,4241,4246],{"__ignoreMap":286},[290,4207,4208],{"class":292,"line":293},[290,4209,4210],{"class":625},"# Démarrer le serveur MCP en mode développement\n",[290,4212,4213,4216,4219],{"class":292,"line":299},[290,4214,4215],{"class":635},"mcp",[290,4217,4218],{"class":813}," dev",[290,4220,4221],{"class":813}," server.py\n",[290,4223,4224],{"class":292,"line":305},[290,4225,321],{"emptyLinePlaceholder":320},[290,4227,4228],{"class":292,"line":311},[290,4229,4230],{"class":625},"# Ouvrir le navigateur sur http://localhost:5173\n",[290,4232,4233],{"class":292,"line":317},[290,4234,4235],{"class":625},"# Se connecter au serveur\n",[290,4237,4238],{"class":292,"line":324},[290,4239,4240],{"class":625},"# Naviguer vers l'onglet Outils\n",[290,4242,4243],{"class":292,"line":330},[290,4244,4245],{"class":625},"# Tester get_current_weather avec des coordonnées\n",[290,4247,4248],{"class":292,"line":336},[290,4249,4250],{"class":625},"# Exemple : latitude=63.4463991, longitude=10.8127596\n",[102,4252,4254,4260],{"className":4253},[131,132,133],[135,4255,4257],{"id":4256},"principes-de-conception-clés",[110,4258,4259],{},"Principes de Conception Clés",[79,4261,4262],{},[82,4263,4264],{"href":145},[110,4265,148],{},[102,4267,4269,4272,4277],{"className":4268},[105],[79,4270,4271],{},"Lors de la construction de serveurs MCP, résistez à la tentation de formater les données retournées dans vos outils. Au lieu de cela, retournez les données brutes et laissez le modèle de langage les traiter et les formater de manière appropriée. Cette approche tire parti des capacités de langage naturel du LLM tout en maintenant l'intégrité des données.",[79,4273,4274],{},[110,4275,4276],{},"Meilleures Pratiques :",[160,4278,4279,4282,4285,4288,4291],{},[163,4280,4281],{},"Retourner des jeux de données complets plutôt que des résumés filtrés",[163,4283,4284],{},"Utiliser des noms d'outils descriptifs et de la documentation",[163,4286,4287],{},"Implémenter une gestion d'erreur appropriée pour les échecs d'API",[163,4289,4290],{},"Garder les outils focalisés sur des responsabilités uniques",[163,4292,4293],{},"Tirer parti d'async/await pour de meilleures performances",[102,4295,4297,4303],{"className":4296},[131,132,133],[135,4298,4300],{"id":4299},"extension-de-votre-serveur",[110,4301,4302],{},"Extension de Votre Serveur",[79,4304,4305],{},[82,4306,4307],{"href":145},[110,4308,148],{},[102,4310,4312,4315,4321,4327,4333],{"className":4311},[105],[79,4313,4314],{},"Une fois que vous avez un serveur météorologique de base fonctionnel, considérez l'ajout de ces améliorations :",[79,4316,4317,4320],{},[110,4318,4319],{},"Services de Localisation :"," Intégrer l'API de Géocodage Open-Meteo pour convertir les noms de villes en coordonnées, réduisant la dépendance au LLM pour la génération de coordonnées.",[79,4322,4323,4326],{},[110,4324,4325],{},"Données Historiques :"," Ajouter des outils pour accéder aux modèles météorologiques historiques et aux données climatiques.",[79,4328,4329,4332],{},[110,4330,4331],{},"Alertes et Avertissements :"," Implémenter la surveillance d'alertes météorologiques pour les conditions météorologiques sévères.",[79,4334,4335,4338],{},[110,4336,4337],{},"Emplacements Multiples :"," Supporter les requêtes par lot pour comparer la météo à travers plusieurs emplacements.",[281,4340,4342],{"className":3840,"code":4341,"language":3842,"meta":286,"style":286},"@mcp.tool()\nasync def get_location(city: str, country: str = \"\") -> str:\n    \"\"\"Obtenir les coordonnées d'une ville en utilisant le géocodage.\n    \n    Args:\n        city: Nom de la ville\n        country: Nom du pays optionnel pour désambiguïsation\n    \"\"\"\n    \n    query = f\"{city},{country}\" if country else city\n    url = f\"https://geocoding-api.open-meteo.com/v1/search?name={query}&count=1&language=fr&format=json\"\n    \n    data = await make_openmeteo_request(url)\n    \n    if not data or not data.get('results'):\n        return \"Emplacement non trouvé.\"\n    \n    return data['results'][0]\n",[261,4343,4344,4348,4353,4358,4362,4366,4371,4376,4380,4384,4389,4394,4398,4402,4406,4411,4416,4420],{"__ignoreMap":286},[290,4345,4346],{"class":292,"line":293},[290,4347,4010],{},[290,4349,4350],{"class":292,"line":299},[290,4351,4352],{},"async def get_location(city: str, country: str = \"\") -> str:\n",[290,4354,4355],{"class":292,"line":305},[290,4356,4357],{},"    \"\"\"Obtenir les coordonnées d'une ville en utilisant le géocodage.\n",[290,4359,4360],{"class":292,"line":311},[290,4361,721],{},[290,4363,4364],{"class":292,"line":317},[290,4365,4029],{},[290,4367,4368],{"class":292,"line":324},[290,4369,4370],{},"        city: Nom de la ville\n",[290,4372,4373],{"class":292,"line":330},[290,4374,4375],{},"        country: Nom du pays optionnel pour désambiguïsation\n",[290,4377,4378],{"class":292,"line":336},[290,4379,4044],{},[290,4381,4382],{"class":292,"line":342},[290,4383,721],{},[290,4385,4386],{"class":292,"line":347},[290,4387,4388],{},"    query = f\"{city},{country}\" if country else city\n",[290,4390,4391],{"class":292,"line":353},[290,4392,4393],{},"    url = f\"https://geocoding-api.open-meteo.com/v1/search?name={query}&count=1&language=fr&format=json\"\n",[290,4395,4396],{"class":292,"line":359},[290,4397,721],{},[290,4399,4400],{"class":292,"line":365},[290,4401,4062],{},[290,4403,4404],{"class":292,"line":370},[290,4405,721],{},[290,4407,4408],{"class":292,"line":376},[290,4409,4410],{},"    if not data or not data.get('results'):\n",[290,4412,4413],{"class":292,"line":382},[290,4414,4415],{},"        return \"Emplacement non trouvé.\"\n",[290,4417,4418],{"class":292,"line":387},[290,4419,721],{},[290,4421,4422],{"class":292,"line":393},[290,4423,4424],{},"    return data['results'][0]\n",[102,4426,4428,4434],{"className":4427},[131,132,133],[135,4429,4431],{"id":4430},"intégration-avec-les-modèles-de-langage",[110,4432,4433],{},"Intégration avec les Modèles de Langage",[79,4435,4436],{},[82,4437,4438],{"href":145},[110,4439,148],{},[102,4441,4443],{"className":4442},[105],[79,4444,4445],{},"Votre serveur MCP peut s'intégrer avec divers modèles de langage incluant Claude Desktop, GPT-4 à travers des clients compatibles, et d'autres applications compatibles MCP. Le serveur communique à travers l'entrée/sortie standard (stdio), le rendant universellement compatible.",[79,4447,4448,4449,4452],{},"Pour utiliser avec Claude Desktop, ajoutez votre configuration de serveur au fichier de paramètres MCP, typiquement situé à ",[261,4450,4451],{},"~/Library/Application Support/Claude/claude_desktop_config.json"," sur macOS.",[281,4454,4456],{"className":1735,"code":4455,"language":1737,"meta":286,"style":286},"{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"python\", \"server.py\"],\n      \"cwd\": \"/chemin/vers/votre/mcp-server-weather\"\n    }\n  }\n}\n",[261,4457,4458,4462,4475,4488,4507,4546,4564,4568,4572],{"__ignoreMap":286},[290,4459,4460],{"class":292,"line":293},[290,4461,746],{"class":639},[290,4463,4464,4466,4469,4471,4473],{"class":292,"line":299},[290,4465,1753],{"class":639},[290,4467,4468],{"class":631},"mcpServers",[290,4470,911],{"class":639},[290,4472,659],{"class":639},[290,4474,640],{"class":639},[290,4476,4477,4479,4482,4484,4486],{"class":292,"line":305},[290,4478,1767],{"class":639},[290,4480,4481],{"class":635},"weather",[290,4483,911],{"class":639},[290,4485,659],{"class":639},[290,4487,640],{"class":639},[290,4489,4490,4492,4495,4497,4499,4501,4503,4505],{"class":292,"line":311},[290,4491,905],{"class":639},[290,4493,4494],{"class":1077},"command",[290,4496,911],{"class":639},[290,4498,659],{"class":639},[290,4500,954],{"class":639},[290,4502,3321],{"class":813},[290,4504,911],{"class":639},[290,4506,820],{"class":639},[290,4508,4509,4511,4514,4516,4518,4520,4522,4525,4527,4529,4531,4533,4535,4537,4539,4542,4544],{"class":292,"line":317},[290,4510,905],{"class":639},[290,4512,4513],{"class":1077},"args",[290,4515,911],{"class":639},[290,4517,659],{"class":639},[290,4519,916],{"class":639},[290,4521,911],{"class":639},[290,4523,4524],{"class":813},"run",[290,4526,911],{"class":639},[290,4528,665],{"class":639},[290,4530,954],{"class":639},[290,4532,3842],{"class":813},[290,4534,911],{"class":639},[290,4536,665],{"class":639},[290,4538,954],{"class":639},[290,4540,4541],{"class":813},"server.py",[290,4543,911],{"class":639},[290,4545,1830],{"class":639},[290,4547,4548,4550,4553,4555,4557,4559,4562],{"class":292,"line":324},[290,4549,905],{"class":639},[290,4551,4552],{"class":1077},"cwd",[290,4554,911],{"class":639},[290,4556,659],{"class":639},[290,4558,954],{"class":639},[290,4560,4561],{"class":813},"/chemin/vers/votre/mcp-server-weather",[290,4563,1017],{"class":639},[290,4565,4566],{"class":292,"line":330},[290,4567,767],{"class":639},[290,4569,4570],{"class":292,"line":336},[290,4571,872],{"class":639},[290,4573,4574],{"class":292,"line":342},[290,4575,1181],{"class":639},[102,4577,4579,4583],{"className":4578},[131,132,133],[135,4580,4581],{"id":2033},[110,4582,2036],{},[79,4584,4585],{},[82,4586,4587],{"href":145},[110,4588,148],{},[102,4590,4592,4595],{"className":4591},[105],[79,4593,4594],{},"La construction de serveurs MCP ouvre de nouvelles possibilités pour l'intégration de l'IA avec les sources de données du monde réel. Ce serveur météorologique démontre les concepts fondamentaux qui s'appliquent à toute intégration d'API externe ou de service. Le Model Context Protocol représente un pas significatif vers des systèmes d'IA plus capables et connectés.",[79,4596,4597],{},"Le code source complet pour ce tutoriel est disponible dans le dépôt des fichiers d'exercice. Expérimentez avec différentes APIs, ajoutez de nouveaux outils, et explorez les possibilités infinies du développement de serveurs MCP.",[102,4599,4602],{"className":4600},[131,4601,133],"justify-end",[79,4603,4604],{},[82,4605,4607],{"href":68,"rel":4606},[99],"#OuverteAuxCollaborationsFreelance",[102,4609,4611],{"className":4610},[2172,2173,2174,2175],[79,4612,4613],{},[82,4614,4615],{"href":145},[110,4616,148],{},[2183,4618,4619],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":286,"searchDepth":299,"depth":299,"links":4621},[4622,4623,4624,4625,4626,4627,4628,4629,4630,4631],{"id":3203,"depth":299,"text":3206},{"id":3265,"depth":299,"text":3268},{"id":3303,"depth":299,"text":3306},{"id":3421,"depth":299,"text":3424},{"id":3985,"depth":299,"text":3988},{"id":4173,"depth":299,"text":4176},{"id":4256,"depth":299,"text":4259},{"id":4299,"depth":299,"text":4302},{"id":4430,"depth":299,"text":4433},{"id":2033,"depth":299,"text":2036},"2025-06-01","Apprenez à créer un serveur Model Context Protocol (MCP) en utilisant Python et l'API Open-Meteo pour fournir des données météorologiques aux modèles de langage comme GPT-4 et Claude.",{"src":2208},{},{"title":24,"description":4633},"F458zeQnEhe_o8Ydhx3dx9iGkSe4WoRy7kzhh_eDBGE",{"id":4639,"title":28,"authors":4640,"badge":4644,"body":4646,"date":6561,"description":6562,"extension":2206,"image":6563,"meta":6564,"navigation":320,"path":29,"seo":6565,"stem":30,"__hash__":6566},"posts_fr/fr/blog/5. mcp-tiny-agents-on-premises.md",[4641],{"name":66,"description":4642,"to":68,"avatar":4643},"Freelance, Serveurs MCP, Développeur Full-Stack, Architecture",{"src":2218},{"label":4645,"color":3189,"variant":74},"MCP, On-Premises",{"type":76,"value":4647,"toc":6544},[4648,4652,4655,4976,4982,4985,4998,5045,5058,5758,6387,6521,6541],[135,4649,4651],{"id":4650},"vue-densemble-de-larchitecture","Vue d'Ensemble de l'Architecture",[79,4653,4654],{},"La beauté des Agents MCP Tiny réside dans leur simplicité architecturale. Qu'ils soient déployés dans le cloud ou on-premises, les composants principaux restent les mêmes : un agent léger, un client MCP et des outils connectés. Voici comment l'architecture complète on-premises se compare aux alternatives cloud :",[281,4656,4658],{"className":283,"code":4657,"language":285,"meta":286,"style":286},"graph TB\n    subgraph \"Infrastructure On-Premises\"\n        subgraph \"Stack IA Local\"\n            Agent[\"Agent Tiny\u003Cbr/>(~50 lignes)\"]\n            LocalLLM[\"LLM Local\u003Cbr/>Ollama/LM Studio\u003Cbr/>Qwen2.5-32B\"]\n            MCPClient[\"Client MCP\u003Cbr/>Gestionnaire d'Outils\"]\n        end\n        \n        subgraph \"Serveurs MCP Locaux\"\n            FileServer[\"Système de Fichiers\u003Cbr/>Serveur MCP\"]\n            WebServer[\"Playwright\u003Cbr/>Serveur MCP\"]\n            BusinessAPI[\"API Métier\u003Cbr/>Serveur MCP\"]\n            DatabaseServer[\"Base de Données\u003Cbr/>Serveur MCP\"]\n        end\n        \n        subgraph \"Couche Matérielle\"\n            GPU[\"GPU/CPU\u003Cbr/>16-140GB VRAM\"]\n            Storage[\"Stockage Modèles\u003Cbr/>GGUF/Safetensors\"]\n        end\n    end\n    \n    subgraph \"Alternative Cloud (Article HF)\"\n        CloudAgent[\"Agent Tiny\u003Cbr/>(Même Code)\"]\n        CloudAPI[\"Nebius/Cohere\u003Cbr/>Qwen2.5-72B\"]\n        CloudMCP[\"Client MCP Cloud\"]\n    end\n    \n    subgraph \"Architecture Hybride\"\n        Router[\"Routeur Intelligent\u003Cbr/>Classification des Données\"]\n        LocalPath[\"Données Sensibles → Local\"]\n        CloudPath[\"Tâches Complexes → Cloud\"]\n    end\n    \n    Agent -->|\"Requêtes d'Outils\"| MCPClient\n    MCPClient -->|\"Appels de Fonctions\"| LocalLLM\n    LocalLLM -->|\"Inférence\"| GPU\n    GPU -->|\"Chargement Modèles\"| Storage\n    \n    MCPClient -->|\"Exécution d'Outils\"| FileServer\n    MCPClient -->|\"Navigation Web\"| WebServer\n    MCPClient -->|\"Logique Métier\"| BusinessAPI\n    MCPClient -->|\"Requêtes de Données\"| DatabaseServer\n    \n    CloudAgent -->|\"Appels API\"| CloudMCP\n    CloudMCP -->|\"Inférence\"| CloudAPI\n    \n    Router -->|\"Décision de Route\"| LocalPath\n    Router -->|\"Décision de Route\"| CloudPath\n    LocalPath -->|\"Exécuter en Local\"| Agent\n    CloudPath -->|\"Exécuter dans le Cloud\"| CloudAgent\n    \n    Agent -.->|\"Boucle While\u003Cbr/>Jusqu'à Completion\"| Agent\n    \n    classDef localInfra stroke:#0277bd,stroke-width:2px\n    classDef cloudInfra stroke:#f57c00,stroke-width:2px\n    classDef hybridInfra stroke:#7b1fa2,stroke-width:2px\n    classDef hardware stroke:#388e3c,stroke-width:2px\n    \n    class Agent,LocalLLM,MCPClient,FileServer,WebServer,BusinessAPI,DatabaseServer localInfra\n    class CloudAgent,CloudAPI,CloudMCP cloudInfra\n    class Router,LocalPath,CloudPath hybridInfra\n    class GPU,Storage hardware\n",[261,4659,4660,4665,4670,4675,4680,4685,4690,4695,4700,4705,4710,4715,4720,4725,4729,4733,4738,4743,4748,4752,4756,4760,4765,4770,4775,4780,4784,4788,4793,4798,4803,4808,4812,4816,4821,4826,4831,4836,4840,4845,4850,4855,4861,4866,4872,4878,4883,4889,4895,4901,4907,4912,4918,4923,4929,4935,4941,4947,4952,4958,4964,4970],{"__ignoreMap":286},[290,4661,4662],{"class":292,"line":293},[290,4663,4664],{},"graph TB\n",[290,4666,4667],{"class":292,"line":299},[290,4668,4669],{},"    subgraph \"Infrastructure On-Premises\"\n",[290,4671,4672],{"class":292,"line":305},[290,4673,4674],{},"        subgraph \"Stack IA Local\"\n",[290,4676,4677],{"class":292,"line":311},[290,4678,4679],{},"            Agent[\"Agent Tiny\u003Cbr/>(~50 lignes)\"]\n",[290,4681,4682],{"class":292,"line":317},[290,4683,4684],{},"            LocalLLM[\"LLM Local\u003Cbr/>Ollama/LM Studio\u003Cbr/>Qwen2.5-32B\"]\n",[290,4686,4687],{"class":292,"line":324},[290,4688,4689],{},"            MCPClient[\"Client MCP\u003Cbr/>Gestionnaire d'Outils\"]\n",[290,4691,4692],{"class":292,"line":330},[290,4693,4694],{},"        end\n",[290,4696,4697],{"class":292,"line":336},[290,4698,4699],{},"        \n",[290,4701,4702],{"class":292,"line":342},[290,4703,4704],{},"        subgraph \"Serveurs MCP Locaux\"\n",[290,4706,4707],{"class":292,"line":347},[290,4708,4709],{},"            FileServer[\"Système de Fichiers\u003Cbr/>Serveur MCP\"]\n",[290,4711,4712],{"class":292,"line":353},[290,4713,4714],{},"            WebServer[\"Playwright\u003Cbr/>Serveur MCP\"]\n",[290,4716,4717],{"class":292,"line":359},[290,4718,4719],{},"            BusinessAPI[\"API Métier\u003Cbr/>Serveur MCP\"]\n",[290,4721,4722],{"class":292,"line":365},[290,4723,4724],{},"            DatabaseServer[\"Base de Données\u003Cbr/>Serveur MCP\"]\n",[290,4726,4727],{"class":292,"line":370},[290,4728,4694],{},[290,4730,4731],{"class":292,"line":376},[290,4732,4699],{},[290,4734,4735],{"class":292,"line":382},[290,4736,4737],{},"        subgraph \"Couche Matérielle\"\n",[290,4739,4740],{"class":292,"line":387},[290,4741,4742],{},"            GPU[\"GPU/CPU\u003Cbr/>16-140GB VRAM\"]\n",[290,4744,4745],{"class":292,"line":393},[290,4746,4747],{},"            Storage[\"Stockage Modèles\u003Cbr/>GGUF/Safetensors\"]\n",[290,4749,4750],{"class":292,"line":398},[290,4751,4694],{},[290,4753,4754],{"class":292,"line":404},[290,4755,1383],{},[290,4757,4758],{"class":292,"line":410},[290,4759,721],{},[290,4761,4762],{"class":292,"line":415},[290,4763,4764],{},"    subgraph \"Alternative Cloud (Article HF)\"\n",[290,4766,4767],{"class":292,"line":421},[290,4768,4769],{},"        CloudAgent[\"Agent Tiny\u003Cbr/>(Même Code)\"]\n",[290,4771,4772],{"class":292,"line":427},[290,4773,4774],{},"        CloudAPI[\"Nebius/Cohere\u003Cbr/>Qwen2.5-72B\"]\n",[290,4776,4777],{"class":292,"line":902},[290,4778,4779],{},"        CloudMCP[\"Client MCP Cloud\"]\n",[290,4781,4782],{"class":292,"line":931},[290,4783,1383],{},[290,4785,4786],{"class":292,"line":975},[290,4787,721],{},[290,4789,4790],{"class":292,"line":1000},[290,4791,4792],{},"    subgraph \"Architecture Hybride\"\n",[290,4794,4795],{"class":292,"line":1020},[290,4796,4797],{},"        Router[\"Routeur Intelligent\u003Cbr/>Classification des Données\"]\n",[290,4799,4800],{"class":292,"line":1026},[290,4801,4802],{},"        LocalPath[\"Données Sensibles → Local\"]\n",[290,4804,4805],{"class":292,"line":1031},[290,4806,4807],{},"        CloudPath[\"Tâches Complexes → Cloud\"]\n",[290,4809,4810],{"class":292,"line":1036},[290,4811,1383],{},[290,4813,4814],{"class":292,"line":1042},[290,4815,721],{},[290,4817,4818],{"class":292,"line":1064},[290,4819,4820],{},"    Agent -->|\"Requêtes d'Outils\"| MCPClient\n",[290,4822,4823],{"class":292,"line":1083},[290,4824,4825],{},"    MCPClient -->|\"Appels de Fonctions\"| LocalLLM\n",[290,4827,4828],{"class":292,"line":1110},[290,4829,4830],{},"    LocalLLM -->|\"Inférence\"| GPU\n",[290,4832,4833],{"class":292,"line":1120},[290,4834,4835],{},"    GPU -->|\"Chargement Modèles\"| Storage\n",[290,4837,4838],{"class":292,"line":1127},[290,4839,721],{},[290,4841,4842],{"class":292,"line":1163},[290,4843,4844],{},"    MCPClient -->|\"Exécution d'Outils\"| FileServer\n",[290,4846,4847],{"class":292,"line":1173},[290,4848,4849],{},"    MCPClient -->|\"Navigation Web\"| WebServer\n",[290,4851,4852],{"class":292,"line":1178},[290,4853,4854],{},"    MCPClient -->|\"Logique Métier\"| BusinessAPI\n",[290,4856,4858],{"class":292,"line":4857},42,[290,4859,4860],{},"    MCPClient -->|\"Requêtes de Données\"| DatabaseServer\n",[290,4862,4864],{"class":292,"line":4863},43,[290,4865,721],{},[290,4867,4869],{"class":292,"line":4868},44,[290,4870,4871],{},"    CloudAgent -->|\"Appels API\"| CloudMCP\n",[290,4873,4875],{"class":292,"line":4874},45,[290,4876,4877],{},"    CloudMCP -->|\"Inférence\"| CloudAPI\n",[290,4879,4881],{"class":292,"line":4880},46,[290,4882,721],{},[290,4884,4886],{"class":292,"line":4885},47,[290,4887,4888],{},"    Router -->|\"Décision de Route\"| LocalPath\n",[290,4890,4892],{"class":292,"line":4891},48,[290,4893,4894],{},"    Router -->|\"Décision de Route\"| CloudPath\n",[290,4896,4898],{"class":292,"line":4897},49,[290,4899,4900],{},"    LocalPath -->|\"Exécuter en Local\"| Agent\n",[290,4902,4904],{"class":292,"line":4903},50,[290,4905,4906],{},"    CloudPath -->|\"Exécuter dans le Cloud\"| CloudAgent\n",[290,4908,4910],{"class":292,"line":4909},51,[290,4911,721],{},[290,4913,4915],{"class":292,"line":4914},52,[290,4916,4917],{},"    Agent -.->|\"Boucle While\u003Cbr/>Jusqu'à Completion\"| Agent\n",[290,4919,4921],{"class":292,"line":4920},53,[290,4922,721],{},[290,4924,4926],{"class":292,"line":4925},54,[290,4927,4928],{},"    classDef localInfra stroke:#0277bd,stroke-width:2px\n",[290,4930,4932],{"class":292,"line":4931},55,[290,4933,4934],{},"    classDef cloudInfra stroke:#f57c00,stroke-width:2px\n",[290,4936,4938],{"class":292,"line":4937},56,[290,4939,4940],{},"    classDef hybridInfra stroke:#7b1fa2,stroke-width:2px\n",[290,4942,4944],{"class":292,"line":4943},57,[290,4945,4946],{},"    classDef hardware stroke:#388e3c,stroke-width:2px\n",[290,4948,4950],{"class":292,"line":4949},58,[290,4951,721],{},[290,4953,4955],{"class":292,"line":4954},59,[290,4956,4957],{},"    class Agent,LocalLLM,MCPClient,FileServer,WebServer,BusinessAPI,DatabaseServer localInfra\n",[290,4959,4961],{"class":292,"line":4960},60,[290,4962,4963],{},"    class CloudAgent,CloudAPI,CloudMCP cloudInfra\n",[290,4965,4967],{"class":292,"line":4966},61,[290,4968,4969],{},"    class Router,LocalPath,CloudPath hybridInfra\n",[290,4971,4973],{"class":292,"line":4972},62,[290,4974,4975],{},"    class GPU,Storage hardware\n",[79,4977,4978,4981],{},[110,4979,4980],{},"Idée Clé"," : Le même code d'agent fonctionne sur tous les modèles de déploiement. La puissance des APIs standardisées signifie que votre investissement dans les outils MCP et la logique d'agent reste portable, que vous choisissiez la commodité du cloud, le contrôle on-premises ou une approche hybride stratégique.",[4983,4984],"hr",{},[102,4986,4988,4992],{"className":4987},[131,132,133],[135,4989,4991],{"id":4990},"le-piège-de-la-commodité-cloud","Le Piège de la Commodité Cloud",[79,4993,4994],{},[82,4995,4996],{"href":145},[110,4997,148],{},[102,4999,5001,5007,5010,5042],{"className":5000},[105],[79,5002,5003,5004],{},"L'implémentation de Hugging Face illustre l'élégance des architectures IA modernes. Avec seulement quelques lignes de TypeScript, vous pouvez créer un agent qui se connecte à plusieurs serveurs MCP (système de fichiers, navigation web via Playwright) et exploite des modèles puissants comme Qwen/Qwen2.5-72B-Instruct. L'idée fondamentale est profonde : ",[110,5005,5006],{},"\"Une fois que vous avez un Client MCP, un Agent n'est littéralement qu'une boucle while au-dessus.\"",[79,5008,5009],{},"Mais cette commodité s'accompagne de dépendances :",[160,5011,5012,5018,5024,5030,5036],{},[163,5013,5014,5017],{},[110,5015,5016],{},"Confidentialité des Données"," : Chaque requête, chaque appel d'outil, chaque contexte métier transite par des APIs externes",[163,5019,5020,5023],{},[110,5021,5022],{},"Imprévisibilité des Coûts"," : La tarification basée sur les tokens peut s'envoler avec des interactions d'agents complexes",[163,5025,5026,5029],{},[110,5027,5028],{},"Contraintes de Latence"," : Les allers-retours réseau ajoutent du délai à chaque étape d'inférence",[163,5031,5032,5035],{},[110,5033,5034],{},"Dépendance au Fournisseur"," : Changer de fournisseur nécessite des modifications de code et une revalidation",[163,5037,5038,5041],{},[110,5039,5040],{},"Problèmes de Conformité"," : Les industries réglementées peuvent interdire l'envoi de données vers des services externes",[79,5043,5044],{},"La question devient : Pouvons-nous maintenir la simplicité des Tiny Agents tout en obtenant un contrôle complet on-premises ?",[102,5046,5048,5052],{"className":5047},[131,132,133],[135,5049,5051],{"id":5050},"anatomie-dun-tiny-agent-local","Anatomie d'un Tiny Agent Local",[79,5053,5054],{},[82,5055,5056],{"href":145},[110,5057,148],{},[102,5059,5061,5064,5070,5073,5105,5108,5114,5117,5123,5126,5150,5153,5215,5218,5224,5227,5555,5568],{"className":5060},[105],[79,5062,5063],{},"La réponse est oui, mais avec des compromis importants. Analysons ce qui change lors du passage du cloud à l'on-premises :",[1612,5065,5067],{"id":5066},"sélection-du-modèle-et-moteur-dinférence",[110,5068,5069],{},"Sélection du Modèle et Moteur d'Inférence",[79,5071,5072],{},"Au lieu d'appeler des APIs externes, nous avons besoin d'inférence locale. Les options se sont considérablement améliorées :",[160,5074,5075,5081,5087,5093,5099],{},[163,5076,5077,5080],{},[110,5078,5079],{},"Ollama"," : Déploiement le plus simple, supporte Qwen2.5, Llama 3.1 et d'autres modèles instruits",[163,5082,5083,5086],{},[110,5084,5085],{},"llama.cpp"," : Exécution directe de modèles avec inférence optimisée",[163,5088,5089,5092],{},[110,5090,5091],{},"LM Studio"," : Interface conviviale avec compatibilité API",[163,5094,5095,5098],{},[110,5096,5097],{},"vLLM"," : Service de niveau production avec endpoints compatibles OpenAI",[163,5100,5101,5104],{},[110,5102,5103],{},"LocalAI"," : Compatibilité complète avec l'API OpenAI pour les modèles locaux",[79,5106,5107],{},"L'idée clé de l'article HF s'applique ici : les LLMs modernes ont un support natif des appels de fonctions. Des modèles comme Qwen2.5-32B-Instruct, Llama 3.1-70B-Instruct, et même des variantes plus petites peuvent gérer efficacement l'utilisation d'outils.",[1612,5109,5111],{"id":5110},"larchitecture-du-serveur-mcp-reste-inchangée",[110,5112,5113],{},"L'Architecture du Serveur MCP Reste Inchangée",[79,5115,5116],{},"C'est ici que brille le protocole MCP. Vos serveurs MCP existants—qu'ils exposent des systèmes de fichiers, des bases de données ou des APIs métier personnalisées—continuent de fonctionner sans modification. L'abstraction du protocole signifie que vos outils restent portables entre les déploiements cloud et on-premises.",[1612,5118,5120],{"id":5119},"implémentation-modifiée-de-lagent",[110,5121,5122],{},"Implémentation Modifiée de l'Agent",[79,5124,5125],{},"La logique centrale de l'agent change à peine. Au lieu de :",[281,5127,5129],{"className":616,"code":5128,"language":618,"meta":286,"style":286},"const client = new InferenceClient(apiKey);\n",[261,5130,5131],{"__ignoreMap":286},[290,5132,5133,5135,5138,5140,5142,5145,5148],{"class":292,"line":293},[290,5134,2991],{"class":631},[290,5136,5137],{"class":691}," client ",[290,5139,2997],{"class":639},[290,5141,754],{"class":639},[290,5143,5144],{"class":705}," InferenceClient",[290,5146,5147],{"class":691},"(apiKey)",[290,5149,716],{"class":639},[79,5151,5152],{},"Vous vous connectez à votre endpoint local :",[281,5154,5156],{"className":616,"code":5155,"language":618,"meta":286,"style":286},"const client = new InferenceClient({\n  baseUrl: \"http://localhost:1234/v1\", // LM Studio\n  apiKey: \"not-needed-for-local\"\n});\n",[261,5157,5158,5174,5193,5207],{"__ignoreMap":286},[290,5159,5160,5162,5164,5166,5168,5170,5172],{"class":292,"line":293},[290,5161,2991],{"class":631},[290,5163,5137],{"class":691},[290,5165,2997],{"class":639},[290,5167,754],{"class":639},[290,5169,5144],{"class":705},[290,5171,652],{"class":691},[290,5173,746],{"class":639},[290,5175,5176,5179,5181,5183,5186,5188,5190],{"class":292,"line":299},[290,5177,5178],{"class":648},"  baseUrl",[290,5180,659],{"class":639},[290,5182,954],{"class":639},[290,5184,5185],{"class":813},"http://localhost:1234/v1",[290,5187,911],{"class":639},[290,5189,665],{"class":639},[290,5191,5192],{"class":625}," // LM Studio\n",[290,5194,5195,5198,5200,5202,5205],{"class":292,"line":305},[290,5196,5197],{"class":648},"  apiKey",[290,5199,659],{"class":639},[290,5201,954],{"class":639},[290,5203,5204],{"class":813},"not-needed-for-local",[290,5206,1017],{"class":639},[290,5208,5209,5211,5213],{"class":292,"line":311},[290,5210,3064],{"class":639},[290,5212,676],{"class":691},[290,5214,716],{"class":639},[79,5216,5217],{},"La boucle while, l'appel d'outils et l'intégration MCP restent identiques. C'est la puissance des APIs standardisées—l'agent ne se soucie pas d'où se produit l'inférence.",[1612,5219,5221],{"id":5220},"la-boucle-while-en-action",[110,5222,5223],{},"La Boucle While en Action",[79,5225,5226],{},"Rappelez-vous l'idée centrale de l'article HF : \"un Agent n'est littéralement qu'une boucle while.\" Voici comment cela se déroule en pratique :",[281,5228,5230],{"className":283,"code":5229,"language":285,"meta":286,"style":286},"flowchart TD\n    Start([\"Requête Utilisateur\u003Cbr/>Obtenir météo et sauvegarder\"])\n    \n    subgraph \"Boucle While du Tiny Agent (On-Premises)\"\n        Initialize[\"Initialiser Agent\u003Cbr/>Charger LLM Local\u003Cbr/>Connecter Serveurs MCP\"]\n        \n        subgraph \"Boucle Principale\"\n            ParseIntent[\"LLM Analyse Intention\u003Cbr/>Local Qwen2.5-32B\"]\n            ToolDecision{\"Outils\u003Cbr/>Nécessaires?\"}\n            \n            subgraph \"Phase 1 d'Exécution\"\n                CallTool[\"Appeler Outil MCP\u003Cbr/>get_weather(lat, lng)\"]\n                ExecuteTool[\"Exécuter Outil\u003Cbr/>Récupérer Données Météo\"]\n                ToolResult[\"Résultat\u003Cbr/>Température: 72°F\"]\n            end\n            \n            FeedResult[\"Alimenter Résultat au LLM\u003Cbr/>Poursuivre Raisonnement\"]\n            \n            subgraph \"Phase 2 d'Exécution\"\n                CallTool2[\"Appeler Autre Outil\u003Cbr/>write_file(weather.txt)\"]\n                ExecuteTool2[\"Exécuter Écriture\u003Cbr/>Sauvegarder Données Météo\"]\n                ToolResult2[\"Fichier Sauvegardé\u003Cbr/>Desktop/weather.txt\"]\n            end\n            \n            Complete{\"Tâche Terminée?\"}\n            Response[\"Générer Réponse\u003Cbr/>Météo sauvegardée avec succès\"]\n        end\n    end\n    \n    End([\"Tâche Accomplie\"])\n    \n    %% Connexions de flux\n    Start --> Initialize\n    Initialize --> ParseIntent\n    ParseIntent --> ToolDecision\n    \n    ToolDecision -->|\"Oui - Besoin Météo\"| CallTool\n    CallTool --> ExecuteTool\n    ExecuteTool --> ToolResult\n    ToolResult --> FeedResult\n    \n    FeedResult --> ToolDecision\n    ToolDecision -->|\"Oui - Besoin Sauvegarde\"| CallTool2\n    CallTool2 --> ExecuteTool2\n    ExecuteTool2 --> ToolResult2\n    ToolResult2 --> FeedResult\n    \n    ToolDecision -->|\"Plus d'Outils\"| Complete\n    Complete -->|\"Oui\"| Response\n    Complete -->|\"Non - Continuer\"| ParseIntent\n    \n    Response --> End\n    \n    %% Annotation idée clé\n    LoopNote[\"Idée Centrale:\u003Cbr/>Agent = Boucle While\u003Cbr/>+ Client MCP\u003Cbr/>+ LLM Local\"]\n    LoopNote -.-> ParseIntent\n    \n    %% Styles\n    classDef agent stroke:#1976d2,stroke-width:2px\n    classDef tool stroke:#388e3c,stroke-width:2px\n    classDef decision stroke:#f57c00,stroke-width:2px\n    classDef insight stroke:#c2185b,stroke-width:2px\n    \n    class Initialize,ParseIntent,FeedResult,Response agent\n    class CallTool,ExecuteTool,ToolResult,CallTool2,ExecuteTool2,ToolResult2 tool\n    class ToolDecision,Complete decision\n    class LoopNote insight\n",[261,5231,5232,5237,5242,5246,5251,5256,5260,5265,5270,5275,5280,5285,5290,5295,5300,5305,5309,5314,5318,5323,5328,5333,5338,5342,5346,5351,5356,5360,5364,5368,5373,5377,5382,5387,5392,5397,5401,5406,5411,5416,5421,5425,5430,5435,5440,5445,5450,5454,5459,5464,5469,5473,5478,5482,5487,5492,5497,5501,5506,5511,5516,5521,5526,5531,5537,5543,5549],{"__ignoreMap":286},[290,5233,5234],{"class":292,"line":293},[290,5235,5236],{},"flowchart TD\n",[290,5238,5239],{"class":292,"line":299},[290,5240,5241],{},"    Start([\"Requête Utilisateur\u003Cbr/>Obtenir météo et sauvegarder\"])\n",[290,5243,5244],{"class":292,"line":305},[290,5245,721],{},[290,5247,5248],{"class":292,"line":311},[290,5249,5250],{},"    subgraph \"Boucle While du Tiny Agent (On-Premises)\"\n",[290,5252,5253],{"class":292,"line":317},[290,5254,5255],{},"        Initialize[\"Initialiser Agent\u003Cbr/>Charger LLM Local\u003Cbr/>Connecter Serveurs MCP\"]\n",[290,5257,5258],{"class":292,"line":324},[290,5259,4699],{},[290,5261,5262],{"class":292,"line":330},[290,5263,5264],{},"        subgraph \"Boucle Principale\"\n",[290,5266,5267],{"class":292,"line":336},[290,5268,5269],{},"            ParseIntent[\"LLM Analyse Intention\u003Cbr/>Local Qwen2.5-32B\"]\n",[290,5271,5272],{"class":292,"line":342},[290,5273,5274],{},"            ToolDecision{\"Outils\u003Cbr/>Nécessaires?\"}\n",[290,5276,5277],{"class":292,"line":347},[290,5278,5279],{},"            \n",[290,5281,5282],{"class":292,"line":353},[290,5283,5284],{},"            subgraph \"Phase 1 d'Exécution\"\n",[290,5286,5287],{"class":292,"line":359},[290,5288,5289],{},"                CallTool[\"Appeler Outil MCP\u003Cbr/>get_weather(lat, lng)\"]\n",[290,5291,5292],{"class":292,"line":365},[290,5293,5294],{},"                ExecuteTool[\"Exécuter Outil\u003Cbr/>Récupérer Données Météo\"]\n",[290,5296,5297],{"class":292,"line":370},[290,5298,5299],{},"                ToolResult[\"Résultat\u003Cbr/>Température: 72°F\"]\n",[290,5301,5302],{"class":292,"line":376},[290,5303,5304],{},"            end\n",[290,5306,5307],{"class":292,"line":382},[290,5308,5279],{},[290,5310,5311],{"class":292,"line":387},[290,5312,5313],{},"            FeedResult[\"Alimenter Résultat au LLM\u003Cbr/>Poursuivre Raisonnement\"]\n",[290,5315,5316],{"class":292,"line":393},[290,5317,5279],{},[290,5319,5320],{"class":292,"line":398},[290,5321,5322],{},"            subgraph \"Phase 2 d'Exécution\"\n",[290,5324,5325],{"class":292,"line":404},[290,5326,5327],{},"                CallTool2[\"Appeler Autre Outil\u003Cbr/>write_file(weather.txt)\"]\n",[290,5329,5330],{"class":292,"line":410},[290,5331,5332],{},"                ExecuteTool2[\"Exécuter Écriture\u003Cbr/>Sauvegarder Données Météo\"]\n",[290,5334,5335],{"class":292,"line":415},[290,5336,5337],{},"                ToolResult2[\"Fichier Sauvegardé\u003Cbr/>Desktop/weather.txt\"]\n",[290,5339,5340],{"class":292,"line":421},[290,5341,5304],{},[290,5343,5344],{"class":292,"line":427},[290,5345,5279],{},[290,5347,5348],{"class":292,"line":902},[290,5349,5350],{},"            Complete{\"Tâche Terminée?\"}\n",[290,5352,5353],{"class":292,"line":931},[290,5354,5355],{},"            Response[\"Générer Réponse\u003Cbr/>Météo sauvegardée avec succès\"]\n",[290,5357,5358],{"class":292,"line":975},[290,5359,4694],{},[290,5361,5362],{"class":292,"line":1000},[290,5363,1383],{},[290,5365,5366],{"class":292,"line":1020},[290,5367,721],{},[290,5369,5370],{"class":292,"line":1026},[290,5371,5372],{},"    End([\"Tâche Accomplie\"])\n",[290,5374,5375],{"class":292,"line":1031},[290,5376,721],{},[290,5378,5379],{"class":292,"line":1036},[290,5380,5381],{},"    %% Connexions de flux\n",[290,5383,5384],{"class":292,"line":1042},[290,5385,5386],{},"    Start --> Initialize\n",[290,5388,5389],{"class":292,"line":1064},[290,5390,5391],{},"    Initialize --> ParseIntent\n",[290,5393,5394],{"class":292,"line":1083},[290,5395,5396],{},"    ParseIntent --> ToolDecision\n",[290,5398,5399],{"class":292,"line":1110},[290,5400,721],{},[290,5402,5403],{"class":292,"line":1120},[290,5404,5405],{},"    ToolDecision -->|\"Oui - Besoin Météo\"| CallTool\n",[290,5407,5408],{"class":292,"line":1127},[290,5409,5410],{},"    CallTool --> ExecuteTool\n",[290,5412,5413],{"class":292,"line":1163},[290,5414,5415],{},"    ExecuteTool --> ToolResult\n",[290,5417,5418],{"class":292,"line":1173},[290,5419,5420],{},"    ToolResult --> FeedResult\n",[290,5422,5423],{"class":292,"line":1178},[290,5424,721],{},[290,5426,5427],{"class":292,"line":4857},[290,5428,5429],{},"    FeedResult --> ToolDecision\n",[290,5431,5432],{"class":292,"line":4863},[290,5433,5434],{},"    ToolDecision -->|\"Oui - Besoin Sauvegarde\"| CallTool2\n",[290,5436,5437],{"class":292,"line":4868},[290,5438,5439],{},"    CallTool2 --> ExecuteTool2\n",[290,5441,5442],{"class":292,"line":4874},[290,5443,5444],{},"    ExecuteTool2 --> ToolResult2\n",[290,5446,5447],{"class":292,"line":4880},[290,5448,5449],{},"    ToolResult2 --> FeedResult\n",[290,5451,5452],{"class":292,"line":4885},[290,5453,721],{},[290,5455,5456],{"class":292,"line":4891},[290,5457,5458],{},"    ToolDecision -->|\"Plus d'Outils\"| Complete\n",[290,5460,5461],{"class":292,"line":4897},[290,5462,5463],{},"    Complete -->|\"Oui\"| Response\n",[290,5465,5466],{"class":292,"line":4903},[290,5467,5468],{},"    Complete -->|\"Non - Continuer\"| ParseIntent\n",[290,5470,5471],{"class":292,"line":4909},[290,5472,721],{},[290,5474,5475],{"class":292,"line":4914},[290,5476,5477],{},"    Response --> End\n",[290,5479,5480],{"class":292,"line":4920},[290,5481,721],{},[290,5483,5484],{"class":292,"line":4925},[290,5485,5486],{},"    %% Annotation idée clé\n",[290,5488,5489],{"class":292,"line":4931},[290,5490,5491],{},"    LoopNote[\"Idée Centrale:\u003Cbr/>Agent = Boucle While\u003Cbr/>+ Client MCP\u003Cbr/>+ LLM Local\"]\n",[290,5493,5494],{"class":292,"line":4937},[290,5495,5496],{},"    LoopNote -.-> ParseIntent\n",[290,5498,5499],{"class":292,"line":4943},[290,5500,721],{},[290,5502,5503],{"class":292,"line":4949},[290,5504,5505],{},"    %% Styles\n",[290,5507,5508],{"class":292,"line":4954},[290,5509,5510],{},"    classDef agent stroke:#1976d2,stroke-width:2px\n",[290,5512,5513],{"class":292,"line":4960},[290,5514,5515],{},"    classDef tool stroke:#388e3c,stroke-width:2px\n",[290,5517,5518],{"class":292,"line":4966},[290,5519,5520],{},"    classDef decision stroke:#f57c00,stroke-width:2px\n",[290,5522,5523],{"class":292,"line":4972},[290,5524,5525],{},"    classDef insight stroke:#c2185b,stroke-width:2px\n",[290,5527,5529],{"class":292,"line":5528},63,[290,5530,721],{},[290,5532,5534],{"class":292,"line":5533},64,[290,5535,5536],{},"    class Initialize,ParseIntent,FeedResult,Response agent\n",[290,5538,5540],{"class":292,"line":5539},65,[290,5541,5542],{},"    class CallTool,ExecuteTool,ToolResult,CallTool2,ExecuteTool2,ToolResult2 tool\n",[290,5544,5546],{"class":292,"line":5545},66,[290,5547,5548],{},"    class ToolDecision,Complete decision\n",[290,5550,5552],{"class":292,"line":5551},67,[290,5553,5554],{},"    class LoopNote insight\n",[102,5556,5558,5562],{"className":5557},[131,132,133],[135,5559,5561],{"id":5560},"défis-dimplémentation","Défis d'Implémentation",[79,5563,5564],{},[82,5565,5566],{"href":145},[110,5567,148],{},[102,5569,5571,5574,5580,5583,5603,5609,5615,5618,5638,5644,5650,5653,5679,5684,5710,5716,5719,5745],{"className":5570},[105],[79,5572,5573],{},"Le passage à l'on-premises n'est pas sans défis. Voici les considérations clés :",[1612,5575,5577],{"id":5576},"exigences-matérielles",[110,5578,5579],{},"Exigences Matérielles",[79,5581,5582],{},"Contrairement aux fournisseurs cloud avec leurs clusters massifs de GPUs, vous êtes limité par le matériel local :",[160,5584,5585,5591,5597],{},[163,5586,5587,5590],{},[110,5588,5589],{},"Mémoire"," : Les modèles 70B nécessitent ~140GB VRAM pour une inférence confortable",[163,5592,5593,5596],{},[110,5594,5595],{},"Modèles Plus Petits"," : Les modèles 7B-13B peuvent fonctionner sur des GPUs grand public avec 16-24GB VRAM",[163,5598,5599,5602],{},[110,5600,5601],{},"Inférence CPU"," : Possible mais significativement plus lente, particulièrement pour l'utilisation complexe d'outils",[79,5604,5605,5608],{},[110,5606,5607],{},"Approche Pratique"," : Commencez avec des modèles quantifiés (format GGUF) qui peuvent fonctionner sur le matériel disponible. Un modèle 32B bien quantifié surpasse souvent un modèle 70B mal configuré.",[1612,5610,5612],{"id":5611},"compromis-de-performance",[110,5613,5614],{},"Compromis de Performance",[79,5616,5617],{},"L'inférence locale introduit une latence que les fournisseurs cloud ont optimisée :",[160,5619,5620,5626,5632],{},[163,5621,5622,5625],{},[110,5623,5624],{},"Latence du Premier Token"," : Les modèles locaux nécessitent un temps d'initialisation",[163,5627,5628,5631],{},[110,5629,5630],{},"Débit"," : Les configurations mono-GPU ne peuvent pas égaler l'inférence distribuée dans le cloud",[163,5633,5634,5637],{},[110,5635,5636],{},"Concurrence"," : Plusieurs sessions d'agents se disputent les mêmes ressources locales",[79,5639,5640,5643],{},[110,5641,5642],{},"Stratégie d'Atténuation"," : Gardez les modèles chargés en mémoire entre les requêtes, utilisez la mise en cache des modèles et envisagez d'exécuter plusieurs petits modèles plutôt qu'un grand.",[1612,5645,5647],{"id":5646},"critères-de-sélection-des-modèles",[110,5648,5649],{},"Critères de Sélection des Modèles",[79,5651,5652],{},"Tous les modèles ne sont pas égaux pour le déploiement on-premises :",[160,5654,5655,5661,5667,5673],{},[163,5656,5657,5660],{},[110,5658,5659],{},"Qualité des Appels de Fonction"," : Testez extensivement avec vos outils MCP spécifiques",[163,5662,5663,5666],{},[110,5664,5665],{},"Longueur de Contexte"," : Des contextes plus longs permettent des conversations d'agents plus sophistiquées",[163,5668,5669,5672],{},[110,5670,5671],{},"Tolérance à la Quantification"," : Certains modèles se dégradent significativement une fois quantifiés",[163,5674,5675,5678],{},[110,5676,5677],{},"Licences"," : Assurez-vous des droits d'utilisation commerciale pour les déploiements en entreprise",[79,5680,5681,1623],{},[110,5682,5683],{},"Modèles Recommandés pour l'On-Premises",[160,5685,5686,5692,5698,5704],{},[163,5687,5688,5691],{},[110,5689,5690],{},"Qwen2.5-32B-Instruct"," : Excellent pour les appels de fonction, exigences matérielles raisonnables",[163,5693,5694,5697],{},[110,5695,5696],{},"Llama 3.1-70B-Instruct"," : Si vous avez le matériel, performances exceptionnelles",[163,5699,5700,5703],{},[110,5701,5702],{},"Mistral-Small-3.1-24B"," : Optimisé spécifiquement pour les appels de fonction",[163,5705,5706,5709],{},[110,5707,5708],{},"Gemma 3 27B"," : Bon équilibre entre capacité et efficacité",[1612,5711,5713],{"id":5712},"complexité-dintégration",[110,5714,5715],{},"Complexité d'Intégration",[79,5717,5718],{},"Les fournisseurs cloud gèrent la compatibilité des APIs, mais les configurations locales nécessitent plus de configuration :",[160,5720,5721,5727,5733,5739],{},[163,5722,5723,5726],{},[110,5724,5725],{},"Passerelle API"," : Assurer des endpoints compatibles avec OpenAI",[163,5728,5729,5732],{},[110,5730,5731],{},"Équilibrage de Charge"," : Distribuer les requêtes entre plusieurs instances de modèles",[163,5734,5735,5738],{},[110,5736,5737],{},"Surveillance"," : Suivi des performances, utilisation des ressources et taux d'erreur",[163,5740,5741,5744],{},[110,5742,5743],{},"Mises à Jour"," : Gestion des mises à jour de modèles et contrôle de version",[102,5746,5748,5752],{"className":5747},[131,132,133],[135,5749,5751],{"id":5750},"cadre-de-décision-entreprise","Cadre de Décision Entreprise",[79,5753,5754],{},[82,5755,5756],{"href":145},[110,5757,148],{},[102,5759,5761,5764,5770,5773,6045,6051,6056,6067,6072,6083,6089,6095,6098,6124,6127,6147,6153,6156,6180,6193],{"className":5760},[105],[79,5762,5763],{},"La décision entre les agents MCP cloud et on-premises n'est pas purement technique—elle est stratégique. Comprendre les compromis est essentiel pour prendre des décisions architecturales éclairées.",[1612,5765,5767],{"id":5766},"comparaison-cloud-vs-on-premises",[110,5768,5769],{},"Comparaison Cloud vs On-Premises",[79,5771,5772],{},"Voici une comparaison complète pour guider votre choix :",[281,5774,5776],{"className":283,"code":5775,"language":285,"meta":286,"style":286},"graph TD\n    subgraph Cloud [\"Agents MCP Cloud\"]\n        CloudAdvantages[\"Avantages\u003Cbr/>• Modèles puissants (70B+)\u003Cbr/>• Calcul illimité\u003Cbr/>• Pas d'investissement matériel\u003Cbr/>• Mise à l'échelle instantanée\u003Cbr/>• Infrastructure gérée\"]\n        \n        CloudRisks[\"Préoccupations de Sécurité\u003Cbr/>• Données hors site\u003Cbr/>• Dépendance fournisseur\u003Cbr/>• Coûts imprévisibles\u003Cbr/>• Défis de conformité\u003Cbr/>• Dépendances API\"]\n        \n        CloudCosts[\"Modèle de Coûts\u003Cbr/>• Paiement par token\u003Cbr/>• 2 000-10 000€/mois\u003Cbr/>• Mise à l'échelle variable\u003Cbr/>• Pas d'investissement initial\"]\n    end\n    \n    subgraph OnPrem [\"Agents MCP On-Premises\"]\n        OnPremAdvantages[\"Bénéfices Sécurité\u003Cbr/>• Souveraineté totale des données\u003Cbr/>• Contrôle total des audits\u003Cbr/>• Conforme aux réglementations\u003Cbr/>• Sans dépendance fournisseur\u003Cbr/>• Fonctionnement hors ligne\"]\n        \n        OnPremChallenges[\"Défis d'Implémentation\u003Cbr/>• Investissement matériel requis\u003Cbr/>• Limites de performance modèles\u003Cbr/>• Complexité opérationnelle\u003Cbr/>• Contraintes d'échelle\u003Cbr/>• Mises à jour manuelles\"]\n        \n        OnPremCosts[\"Structure de Coûts\u003Cbr/>• 10 000-50 000€ initial\u003Cbr/>• Rentabilité 6-18 mois\u003Cbr/>• Coûts opérationnels fixes\u003Cbr/>• Mise à l'échelle prévisible\"]\n    end\n    \n    subgraph Decision [\"Facteurs de Décision\"]\n        DataSensitivity[\"Sensibilité des Données\u003Cbr/>Haute sensibilité → On-Premises\u003Cbr/>Faible sensibilité → Cloud\"]\n        \n        Compliance[\"Exigences de Conformité\u003Cbr/>Réglementation stricte → On-Premises\u003Cbr/>Conformité standard → Cloud\"]\n        \n        TechnicalCapacity[\"Ressources Techniques\u003Cbr/>Équipe IA/ML forte → On-Premises\u003Cbr/>Ressources limitées → Cloud\"]\n        \n        CostModel[\"Préférences de Coûts\u003Cbr/>Coûts prévisibles → On-Premises\u003Cbr/>Coûts variables → Cloud\"]\n    end\n    \n    subgraph Hybrid [\"Architecture Hybride\"]\n        HybridBenefits[\"Combinaison Stratégique\u003Cbr/>• Router données sensibles en local\u003Cbr/>• Utiliser cloud pour tâches complexes\u003Cbr/>• Optimiser coûts dynamiquement\u003Cbr/>• Distribuer risque opérationnel\"]\n    end\n    \n    %% Flux de décision\n    DataSensitivity --> OnPremAdvantages\n    DataSensitivity --> CloudAdvantages\n    \n    Compliance --> OnPremAdvantages\n    Compliance --> CloudAdvantages\n    \n    TechnicalCapacity --> OnPremChallenges\n    TechnicalCapacity --> CloudRisks\n    \n    CostModel --> OnPremCosts\n    CostModel --> CloudCosts\n    \n    %% Connexions hybrides\n    OnPremAdvantages -.-> HybridBenefits\n    CloudAdvantages -.-> HybridBenefits\n    \n    %% Styles\n    classDef cloudStyle stroke:#1976d2,stroke-width:2px\n    classDef onpremStyle stroke:#388e3c,stroke-width:2px\n    classDef decisionStyle stroke:#f57c00,stroke-width:2px\n    classDef hybridStyle stroke:#7b1fa2,stroke-width:2px\n    \n    class Cloud,CloudAdvantages,CloudRisks,CloudCosts cloudStyle\n    class OnPrem,OnPremAdvantages,OnPremChallenges,OnPremCosts onpremStyle\n    class Decision,DataSensitivity,Compliance,TechnicalCapacity,CostModel decisionStyle\n    class Hybrid,HybridBenefits hybridStyle\n",[261,5777,5778,5782,5787,5792,5796,5801,5805,5810,5814,5818,5823,5828,5832,5837,5841,5846,5850,5854,5859,5864,5868,5873,5877,5882,5886,5891,5895,5899,5904,5909,5913,5917,5922,5927,5932,5936,5941,5946,5950,5955,5960,5964,5969,5974,5978,5983,5988,5993,5997,6001,6006,6011,6016,6021,6025,6030,6035,6040],{"__ignoreMap":286},[290,5779,5780],{"class":292,"line":293},[290,5781,2406],{},[290,5783,5784],{"class":292,"line":299},[290,5785,5786],{},"    subgraph Cloud [\"Agents MCP Cloud\"]\n",[290,5788,5789],{"class":292,"line":305},[290,5790,5791],{},"        CloudAdvantages[\"Avantages\u003Cbr/>• Modèles puissants (70B+)\u003Cbr/>• Calcul illimité\u003Cbr/>• Pas d'investissement matériel\u003Cbr/>• Mise à l'échelle instantanée\u003Cbr/>• Infrastructure gérée\"]\n",[290,5793,5794],{"class":292,"line":311},[290,5795,4699],{},[290,5797,5798],{"class":292,"line":317},[290,5799,5800],{},"        CloudRisks[\"Préoccupations de Sécurité\u003Cbr/>• Données hors site\u003Cbr/>• Dépendance fournisseur\u003Cbr/>• Coûts imprévisibles\u003Cbr/>• Défis de conformité\u003Cbr/>• Dépendances API\"]\n",[290,5802,5803],{"class":292,"line":324},[290,5804,4699],{},[290,5806,5807],{"class":292,"line":330},[290,5808,5809],{},"        CloudCosts[\"Modèle de Coûts\u003Cbr/>• Paiement par token\u003Cbr/>• 2 000-10 000€/mois\u003Cbr/>• Mise à l'échelle variable\u003Cbr/>• Pas d'investissement initial\"]\n",[290,5811,5812],{"class":292,"line":336},[290,5813,1383],{},[290,5815,5816],{"class":292,"line":342},[290,5817,721],{},[290,5819,5820],{"class":292,"line":347},[290,5821,5822],{},"    subgraph OnPrem [\"Agents MCP On-Premises\"]\n",[290,5824,5825],{"class":292,"line":353},[290,5826,5827],{},"        OnPremAdvantages[\"Bénéfices Sécurité\u003Cbr/>• Souveraineté totale des données\u003Cbr/>• Contrôle total des audits\u003Cbr/>• Conforme aux réglementations\u003Cbr/>• Sans dépendance fournisseur\u003Cbr/>• Fonctionnement hors ligne\"]\n",[290,5829,5830],{"class":292,"line":359},[290,5831,4699],{},[290,5833,5834],{"class":292,"line":365},[290,5835,5836],{},"        OnPremChallenges[\"Défis d'Implémentation\u003Cbr/>• Investissement matériel requis\u003Cbr/>• Limites de performance modèles\u003Cbr/>• Complexité opérationnelle\u003Cbr/>• Contraintes d'échelle\u003Cbr/>• Mises à jour manuelles\"]\n",[290,5838,5839],{"class":292,"line":370},[290,5840,4699],{},[290,5842,5843],{"class":292,"line":376},[290,5844,5845],{},"        OnPremCosts[\"Structure de Coûts\u003Cbr/>• 10 000-50 000€ initial\u003Cbr/>• Rentabilité 6-18 mois\u003Cbr/>• Coûts opérationnels fixes\u003Cbr/>• Mise à l'échelle prévisible\"]\n",[290,5847,5848],{"class":292,"line":382},[290,5849,1383],{},[290,5851,5852],{"class":292,"line":387},[290,5853,721],{},[290,5855,5856],{"class":292,"line":393},[290,5857,5858],{},"    subgraph Decision [\"Facteurs de Décision\"]\n",[290,5860,5861],{"class":292,"line":398},[290,5862,5863],{},"        DataSensitivity[\"Sensibilité des Données\u003Cbr/>Haute sensibilité → On-Premises\u003Cbr/>Faible sensibilité → Cloud\"]\n",[290,5865,5866],{"class":292,"line":404},[290,5867,4699],{},[290,5869,5870],{"class":292,"line":410},[290,5871,5872],{},"        Compliance[\"Exigences de Conformité\u003Cbr/>Réglementation stricte → On-Premises\u003Cbr/>Conformité standard → Cloud\"]\n",[290,5874,5875],{"class":292,"line":415},[290,5876,4699],{},[290,5878,5879],{"class":292,"line":421},[290,5880,5881],{},"        TechnicalCapacity[\"Ressources Techniques\u003Cbr/>Équipe IA/ML forte → On-Premises\u003Cbr/>Ressources limitées → Cloud\"]\n",[290,5883,5884],{"class":292,"line":427},[290,5885,4699],{},[290,5887,5888],{"class":292,"line":902},[290,5889,5890],{},"        CostModel[\"Préférences de Coûts\u003Cbr/>Coûts prévisibles → On-Premises\u003Cbr/>Coûts variables → Cloud\"]\n",[290,5892,5893],{"class":292,"line":931},[290,5894,1383],{},[290,5896,5897],{"class":292,"line":975},[290,5898,721],{},[290,5900,5901],{"class":292,"line":1000},[290,5902,5903],{},"    subgraph Hybrid [\"Architecture Hybride\"]\n",[290,5905,5906],{"class":292,"line":1020},[290,5907,5908],{},"        HybridBenefits[\"Combinaison Stratégique\u003Cbr/>• Router données sensibles en local\u003Cbr/>• Utiliser cloud pour tâches complexes\u003Cbr/>• Optimiser coûts dynamiquement\u003Cbr/>• Distribuer risque opérationnel\"]\n",[290,5910,5911],{"class":292,"line":1026},[290,5912,1383],{},[290,5914,5915],{"class":292,"line":1031},[290,5916,721],{},[290,5918,5919],{"class":292,"line":1036},[290,5920,5921],{},"    %% Flux de décision\n",[290,5923,5924],{"class":292,"line":1042},[290,5925,5926],{},"    DataSensitivity --> OnPremAdvantages\n",[290,5928,5929],{"class":292,"line":1064},[290,5930,5931],{},"    DataSensitivity --> CloudAdvantages\n",[290,5933,5934],{"class":292,"line":1083},[290,5935,721],{},[290,5937,5938],{"class":292,"line":1110},[290,5939,5940],{},"    Compliance --> OnPremAdvantages\n",[290,5942,5943],{"class":292,"line":1120},[290,5944,5945],{},"    Compliance --> CloudAdvantages\n",[290,5947,5948],{"class":292,"line":1127},[290,5949,721],{},[290,5951,5952],{"class":292,"line":1163},[290,5953,5954],{},"    TechnicalCapacity --> OnPremChallenges\n",[290,5956,5957],{"class":292,"line":1173},[290,5958,5959],{},"    TechnicalCapacity --> CloudRisks\n",[290,5961,5962],{"class":292,"line":1178},[290,5963,721],{},[290,5965,5966],{"class":292,"line":4857},[290,5967,5968],{},"    CostModel --> OnPremCosts\n",[290,5970,5971],{"class":292,"line":4863},[290,5972,5973],{},"    CostModel --> CloudCosts\n",[290,5975,5976],{"class":292,"line":4868},[290,5977,721],{},[290,5979,5980],{"class":292,"line":4874},[290,5981,5982],{},"    %% Connexions hybrides\n",[290,5984,5985],{"class":292,"line":4880},[290,5986,5987],{},"    OnPremAdvantages -.-> HybridBenefits\n",[290,5989,5990],{"class":292,"line":4885},[290,5991,5992],{},"    CloudAdvantages -.-> HybridBenefits\n",[290,5994,5995],{"class":292,"line":4891},[290,5996,721],{},[290,5998,5999],{"class":292,"line":4897},[290,6000,5505],{},[290,6002,6003],{"class":292,"line":4903},[290,6004,6005],{},"    classDef cloudStyle stroke:#1976d2,stroke-width:2px\n",[290,6007,6008],{"class":292,"line":4909},[290,6009,6010],{},"    classDef onpremStyle stroke:#388e3c,stroke-width:2px\n",[290,6012,6013],{"class":292,"line":4914},[290,6014,6015],{},"    classDef decisionStyle stroke:#f57c00,stroke-width:2px\n",[290,6017,6018],{"class":292,"line":4920},[290,6019,6020],{},"    classDef hybridStyle stroke:#7b1fa2,stroke-width:2px\n",[290,6022,6023],{"class":292,"line":4925},[290,6024,721],{},[290,6026,6027],{"class":292,"line":4931},[290,6028,6029],{},"    class Cloud,CloudAdvantages,CloudRisks,CloudCosts cloudStyle\n",[290,6031,6032],{"class":292,"line":4937},[290,6033,6034],{},"    class OnPrem,OnPremAdvantages,OnPremChallenges,OnPremCosts onpremStyle\n",[290,6036,6037],{"class":292,"line":4943},[290,6038,6039],{},"    class Decision,DataSensitivity,Compliance,TechnicalCapacity,CostModel decisionStyle\n",[290,6041,6042],{"class":292,"line":4949},[290,6043,6044],{},"    class Hybrid,HybridBenefits hybridStyle\n",[1612,6046,6048],{"id":6047},"analyse-des-coûts",[110,6049,6050],{},"Analyse des Coûts",[79,6052,6053,1623],{},[110,6054,6055],{},"Coûts Cloud (Estimés)",[160,6057,6058,6061,6064],{},[163,6059,6060],{},"Interactions complexes d'agents : 50-200 tokens par appel d'outil",[163,6062,6063],{},"Usage entreprise : 10,000+ interactions d'agents quotidiennes",[163,6065,6066],{},"Coûts mensuels : $2,000-$10,000+ selon le modèle et l'usage",[79,6068,6069,1623],{},[110,6070,6071],{},"Coûts On-Premises",[160,6073,6074,6077,6080],{},[163,6075,6076],{},"Matériel : $10,000-$50,000 d'investissement initial",[163,6078,6079],{},"Maintenance : Frais opérationnels continus",[163,6081,6082],{},"Point d'équilibre : Généralement 6-18 mois selon l'usage",[79,6084,6085,6088],{},[110,6086,6087],{},"Approche Hybride"," : Utilisez l'on-premises pour les données sensibles, le cloud pour les pics de charge ou les tâches spécialisées.",[1612,6090,6092],{"id":6091},"sécurité-et-conformité",[110,6093,6094],{},"Sécurité et Conformité",[79,6096,6097],{},"L'on-premises offre des avantages significatifs :",[160,6099,6100,6106,6112,6118],{},[163,6101,6102,6105],{},[110,6103,6104],{},"Souveraineté des Données"," : Tout le traitement se fait dans votre infrastructure",[163,6107,6108,6111],{},[110,6109,6110],{},"Pistes d'Audit"," : Visibilité complète sur les actions des agents et les flux de données",[163,6113,6114,6117],{},[110,6115,6116],{},"Conformité"," : Plus facile de respecter GDPR, HIPAA, SOC2",[163,6119,6120,6123],{},[110,6121,6122],{},"Sécurité Personnalisée"," : Intégration avec l'infrastructure de sécurité existante",[79,6125,6126],{},"Mais introduit aussi des responsabilités :",[160,6128,6129,6135,6141],{},[163,6130,6131,6134],{},[110,6132,6133],{},"Sécurité des Modèles"," : S'assurer que les modèles ne sont pas compromis ou biaisés",[163,6136,6137,6140],{},[110,6138,6139],{},"Sécurité de l'Infrastructure"," : Protéger l'infrastructure IA elle-même",[163,6142,6143,6146],{},[110,6144,6145],{},"Contrôle d'Accès"," : Gérer qui peut déployer et modifier les agents",[1612,6148,6150],{"id":6149},"maturité-opérationnelle",[110,6151,6152],{},"Maturité Opérationnelle",[79,6154,6155],{},"L'exécution d'IA on-premises nécessite des capacités organisationnelles :",[160,6157,6158,6164,6169,6175],{},[163,6159,6160,6163],{},[110,6161,6162],{},"DevOps pour l'IA"," : Pipelines CI/CD pour le déploiement des modèles",[163,6165,6166,6168],{},[110,6167,5737],{}," : Compréhension des métriques spécifiques à l'IA et des modes de défaillance",[163,6170,6171,6174],{},[110,6172,6173],{},"Mise à l'Échelle"," : Gestion des ressources à mesure que l'utilisation des agents croît",[163,6176,6177,6179],{},[110,6178,5743],{}," : Maintenir les modèles et l'infrastructure à jour",[102,6181,6183,6187],{"className":6182},[131,132,133],[135,6184,6186],{"id":6185},"stratégie-darchitecture-hybride","Stratégie d'Architecture Hybride",[79,6188,6189],{},[82,6190,6191],{"href":145},[110,6192,148],{},[102,6194,6196,6199,6205,6336,6342,6374],{"className":6195},[105],[79,6197,6198],{},"L'approche la plus pragmatique combine souvent les déploiements cloud et on-premises. Une architecture hybride permet aux organisations d'optimiser à la fois pour la sécurité et la capacité tout en maintenant la flexibilité opérationnelle.",[1612,6200,6202],{"id":6201},"implémentation-du-routage-intelligent",[110,6203,6204],{},"Implémentation du Routage Intelligent",[281,6206,6208],{"className":616,"code":6207,"language":618,"meta":286,"style":286},"const agent = new Agent({\n  // Local pour les opérations sensibles\n  localProvider: \"http://localhost:1234/v1\",\n  localModel: \"qwen2.5-32b-instruct\",\n  \n  // Cloud pour les tâches complexes\n  cloudProvider: \"nebius\",\n  cloudModel: \"Qwen/Qwen2.5-72B-Instruct\",\n  \n  // Routage basé sur la sensibilité des tâches\n  routingStrategy: \"data-classification\"\n});\n",[261,6209,6210,6228,6233,6248,6264,6268,6273,6289,6305,6309,6314,6328],{"__ignoreMap":286},[290,6211,6212,6214,6217,6219,6221,6224,6226],{"class":292,"line":293},[290,6213,2991],{"class":631},[290,6215,6216],{"class":691}," agent ",[290,6218,2997],{"class":639},[290,6220,754],{"class":639},[290,6222,6223],{"class":705}," Agent",[290,6225,652],{"class":691},[290,6227,746],{"class":639},[290,6229,6230],{"class":292,"line":299},[290,6231,6232],{"class":625},"  // Local pour les opérations sensibles\n",[290,6234,6235,6238,6240,6242,6244,6246],{"class":292,"line":305},[290,6236,6237],{"class":648},"  localProvider",[290,6239,659],{"class":639},[290,6241,954],{"class":639},[290,6243,5185],{"class":813},[290,6245,911],{"class":639},[290,6247,820],{"class":639},[290,6249,6250,6253,6255,6257,6260,6262],{"class":292,"line":311},[290,6251,6252],{"class":648},"  localModel",[290,6254,659],{"class":639},[290,6256,954],{"class":639},[290,6258,6259],{"class":813},"qwen2.5-32b-instruct",[290,6261,911],{"class":639},[290,6263,820],{"class":639},[290,6265,6266],{"class":292,"line":317},[290,6267,877],{"class":691},[290,6269,6270],{"class":292,"line":324},[290,6271,6272],{"class":625},"  // Cloud pour les tâches complexes\n",[290,6274,6275,6278,6280,6282,6285,6287],{"class":292,"line":330},[290,6276,6277],{"class":648},"  cloudProvider",[290,6279,659],{"class":639},[290,6281,954],{"class":639},[290,6283,6284],{"class":813},"nebius",[290,6286,911],{"class":639},[290,6288,820],{"class":639},[290,6290,6291,6294,6296,6298,6301,6303],{"class":292,"line":336},[290,6292,6293],{"class":648},"  cloudModel",[290,6295,659],{"class":639},[290,6297,954],{"class":639},[290,6299,6300],{"class":813},"Qwen/Qwen2.5-72B-Instruct",[290,6302,911],{"class":639},[290,6304,820],{"class":639},[290,6306,6307],{"class":292,"line":342},[290,6308,877],{"class":691},[290,6310,6311],{"class":292,"line":347},[290,6312,6313],{"class":625},"  // Routage basé sur la sensibilité des tâches\n",[290,6315,6316,6319,6321,6323,6326],{"class":292,"line":353},[290,6317,6318],{"class":648},"  routingStrategy",[290,6320,659],{"class":639},[290,6322,954],{"class":639},[290,6324,6325],{"class":813},"data-classification",[290,6327,1017],{"class":639},[290,6329,6330,6332,6334],{"class":292,"line":359},[290,6331,3064],{"class":639},[290,6333,676],{"class":691},[290,6335,716],{"class":639},[1612,6337,6339],{"id":6338},"avantages-hybrides",[110,6340,6341],{},"Avantages Hybrides",[160,6343,6344,6350,6356,6362,6368],{},[163,6345,6346,6349],{},[110,6347,6348],{},"Classification des Données"," : Route automatiquement les données sensibles vers le traitement local",[163,6351,6352,6355],{},[110,6353,6354],{},"Optimisation des Performances"," : Utilise les ressources cloud pour les tâches intensives en calcul",[163,6357,6358,6361],{},[110,6359,6360],{},"Gestion des Coûts"," : Équilibre les coûts fixes on-premises avec l'usage variable du cloud",[163,6363,6364,6367],{},[110,6365,6366],{},"Distribution des Risques"," : Évite les points uniques de défaillance dans chaque modèle de déploiement",[163,6369,6370,6373],{},[110,6371,6372],{},"Migration Progressive"," : Commence en local et étend l'usage cloud à mesure que la confiance augmente",[102,6375,6377,6381],{"className":6376},[131,132,133],[135,6378,6380],{"id":6379},"conclusion-et-prochaines-étapes","Conclusion et Prochaines Étapes",[79,6382,6383],{},[82,6384,6385],{"href":145},[110,6386,148],{},[102,6388,6390,6393,6399,6431,6437,6442,6456,6461,6475,6481,6518],{"className":6389},[105],[79,6391,6392],{},"L'exploration des Agents MCP Tiny On-Premises révèle une vérité convaincante : l'élégance du concept d'\"agent en 50 lignes\" de Hugging Face n'est pas diminuée par le déploiement local—elle est améliorée par les avantages de contrôle et de sécurité que fournit l'infrastructure on-premises.",[1612,6394,6396],{"id":6395},"points-clés",[110,6397,6398],{},"Points Clés",[1625,6400,6401,6407,6413,6419,6425],{},[163,6402,6403,6406],{},[110,6404,6405],{},"Faisabilité Technique"," : L'architecture de l'agent reste identique—seul l'endpoint d'inférence change",[163,6408,6409,6412],{},[110,6410,6411],{},"Puissance du Protocole MCP"," : Vos investissements en outils sont entièrement portables entre cloud et on-premises",[163,6414,6415,6418],{},[110,6416,6417],{},"Avantages Stratégiques"," : Les déploiements on-premises offrent souveraineté des données, avantages de conformité et prévisibilité des coûts",[163,6420,6421,6424],{},[110,6422,6423],{},"Réalité d'Implémentation"," : Les contraintes matérielles nécessitent une sélection soigneuse des modèles, mais des solutions capables existent",[163,6426,6427,6430],{},[110,6428,6429],{},"Optimisation Hybride"," : L'approche la plus pratique combine les deux modèles de déploiement selon la sensibilité des données",[1612,6432,6434],{"id":6433},"cadre-de-décision",[110,6435,6436],{},"Cadre de Décision",[79,6438,6439,1623],{},[110,6440,6441],{},"Choisissez l'On-Premises Quand",[160,6443,6444,6447,6450,6453],{},[163,6445,6446],{},"La sensibilité des données est élevée (finance, santé, juridique)",[163,6448,6449],{},"Les exigences de conformité sont strictes (GDPR, HIPAA, SOC2)",[163,6451,6452],{},"Les coûts prévisibles sont préférés aux prix variables",[163,6454,6455],{},"Une équipe technique solide est disponible pour l'implémentation",[79,6457,6458,1623],{},[110,6459,6460],{},"Choisissez le Cloud Quand",[160,6462,6463,6466,6469,6472],{},[163,6464,6465],{},"La mise à l'échelle rapide est essentielle",[163,6467,6468],{},"Les dernières capacités des modèles sont requises",[163,6470,6471],{},"Les ressources techniques sont limitées",[163,6473,6474],{},"Les charges de travail variables rendent l'économie cloud favorable",[1612,6476,6478],{"id":6477},"chemin-dimplémentation-recommandé",[110,6479,6480],{},"Chemin d'Implémentation Recommandé",[1625,6482,6483,6489,6495,6501,6506,6512],{},[163,6484,6485,6488],{},[110,6486,6487],{},"Phase d'Évaluation"," : Évaluez votre sensibilité aux données, besoins de conformité et capacités techniques",[163,6490,6491,6494],{},[110,6492,6493],{},"Déploiement Pilote"," : Commencez avec une petite configuration on-premises utilisant des modèles quantifiés (Qwen2.5-32B)",[163,6496,6497,6500],{},[110,6498,6499],{},"Évaluation des Performances"," : Comparez les performances locales vs. cloud pour vos cas d'usage spécifiques",[163,6502,6503,6505],{},[110,6504,6050],{}," : Calculez les points d'équilibre et le coût total de possession",[163,6507,6508,6511],{},[110,6509,6510],{},"Architecture Hybride"," : Concevez un routage intelligent basé sur la classification des données et la complexité des tâches",[163,6513,6514,6517],{},[110,6515,6516],{},"Mise à l'Échelle Progressive"," : Étendez les modèles réussis tout en maintenant les limites de sécurité",[79,6519,6520],{},"L'avenir de l'IA d'entreprise ne consiste pas à choisir entre la commodité du cloud et le contrôle on-premises—il s'agit d'architecturer des systèmes qui combinent intelligemment les deux approches. Les Agents MCP Tiny rendent cette vision pratique, fournissant la simplicité et la portabilité nécessaires pour des déploiements d'IA durables sur toute infrastructure.",[102,6522,6525,6531],{"className":6523},[2172,6524,2174,2175],"text-end",[79,6526,6527],{},[82,6528,6529],{"href":145},[110,6530,148],{},[102,6532,6534],{"className":6533},[6524],[79,6535,6536],{},[82,6537,6538],{"href":2167},[110,6539,6540],{},"Prêt à explorer les agents IA on-premises ?",[2183,6542,6543],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":286,"searchDepth":299,"depth":299,"links":6545},[6546,6547,6548],{"id":4650,"depth":299,"text":4651},{"id":4990,"depth":299,"text":4991},{"id":5050,"depth":299,"text":5051,"children":6549},[6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560],{"id":5066,"depth":305,"text":5069},{"id":5110,"depth":305,"text":5113},{"id":5119,"depth":305,"text":5122},{"id":5220,"depth":305,"text":5223},{"id":5766,"depth":305,"text":5769},{"id":6047,"depth":305,"text":6050},{"id":6091,"depth":305,"text":6094},{"id":6149,"depth":305,"text":6152},{"id":6395,"depth":305,"text":6398},{"id":6433,"depth":305,"text":6436},{"id":6477,"depth":305,"text":6480},"2025-06-28","Explorer comment exécuter des agents basés sur MCP entièrement on-premises en utilisant des LLMs locaux, en examinant les compromis entre la commodité du cloud et le contrôle local pour les déploiements d'IA en entreprise.",{"src":2208},{},{"title":28,"description":6562},"epMsG1Ni4vE1sze094ppzqcTx_LgZOojqXuq61W9IDg",{"id":6568,"title":32,"authors":6569,"badge":6573,"body":6576,"date":7743,"description":7744,"extension":2206,"image":7745,"meta":7746,"navigation":320,"path":33,"seo":7747,"stem":34,"__hash__":7748},"posts_fr/fr/blog/6. overvibing.md",[6570],{"name":66,"description":6571,"to":68,"avatar":6572},"Freelance, MCP Servers, Développement Full-Stack, Architecture",{"src":2218},{"label":6574,"color":6575,"variant":74},"Développement Agentique, Overvibing","success",{"type":76,"value":6577,"toc":7728},[6578,6594,6600,6606,6789,6804,6807,6833,6848,6858,6873,7024,7039,7075,7080,7103,7118,7124,7195,7201,7243,7256,7259,7268,7274,7508,7524,7539,7571,7586,7636,7651,7687,7702,7716,7725],[102,6579,6581],{"className":6580},[105],[79,6582,6583,6586,6587,3146,6590,6593],{},[110,6584,6585],{},"Bankly",", un système bancaire backend construit en seulement deux jours en utilisant ",[110,6588,6589],{},"Apollo GraphQL",[110,6591,6592],{},"Prisma",". Conçu comme un test technique personnel et une preuve de concept qui démontre comment les flux de travail agentiques et le développement assisté par l'IA peuvent accélérer la livraison de logiciels modernes tout en maintenant la qualité et la structure.",[135,6595,6597],{"id":6596},"chronologie-du-développement",[110,6598,6599],{},"Chronologie du Développement",[102,6601,6603],{"className":6602},[105],[79,6604,6605],{},"Voici la progression complète commit par commit montrant comment l'AWP a permis un développement systématique sans perdre d'élan :",[281,6607,6609],{"className":283,"code":6608,"language":285,"meta":286,"style":286},"---\ntitle: Chronologie du Développement de Bankly - 24-25 Juin 2025 @michaelwybraniec\n---\ngitGraph\n    commit id: \"Diagrammes ER\" tag: \"3.1.2\" type: HIGHLIGHT\n    commit id: \"Modèles Prisma\" tag: \"3.1.1\"\n    commit id: \"Politique AWP → Protocole\" tag: \"9.1\" type: REVERSE\n    commit id: \"BD Sécurisée Transaction\" tag: \"3.3\"\n    commit id: \"Dépendances\" tag: \"1.3\"\n    commit id: \"API GraphQL\" tag: \"4.4\" type: HIGHLIGHT\n    commit id: \"ESLint + Outillage\" tag: \"1.4\"\n    commit id: \"User Stories\" tag: \"5.1\"\n    commit id: \"Producteur Kafka\" tag: \"5.1\" type: HIGHLIGHT\n    commit id: \"Émission d'Événements\" tag: \"5.2\"\n    commit id: \"Étapes Kafka Terminées\" tag: \"5.0\"\n    commit id: \"Procédures AWP\" tag: \"9.2\"\n    branch pre-prod\n    checkout pre-prod\n    commit id: \"Tests Unitaires\" tag: \"8.1\"\n    commit id: \"Docker Compose\" tag: \"10.1\"\n    commit id: \"Release Sémantique\" tag: \"7.4\" type: HIGHLIGHT\n    commit id: \"Winston + Prometheus\" tag: \"10.3\" type: HIGHLIGHT\n    commit id: \"Contrôles Santé\" tag: \"10.3\"\n    commit id: \"Événements d'Audit\" tag: \"6.1\"\n    commit id: \"Actions GitHub\" tag: \"7.4\"\n    commit id: \"Docs Observabilité\" tag: \"10.5\"\n    commit id: \"Structure Projet\" tag: \"11\"\n    checkout main\n    merge pre-prod tag: \"v0.9.0\" type: HIGHLIGHT\n\n%%{init: {\n        \"gitGraph\": {\n            \"titleTopMargin\": 80,\n            \"diagramPadding\": 20\n        }\n    }}%%\n",[261,6610,6611,6616,6621,6625,6630,6635,6640,6645,6650,6655,6660,6665,6670,6675,6680,6685,6690,6695,6700,6705,6710,6715,6720,6725,6730,6735,6740,6745,6750,6755,6759,6764,6769,6774,6779,6784],{"__ignoreMap":286},[290,6612,6613],{"class":292,"line":293},[290,6614,6615],{},"---\n",[290,6617,6618],{"class":292,"line":299},[290,6619,6620],{},"title: Chronologie du Développement de Bankly - 24-25 Juin 2025 @michaelwybraniec\n",[290,6622,6623],{"class":292,"line":305},[290,6624,6615],{},[290,6626,6627],{"class":292,"line":311},[290,6628,6629],{},"gitGraph\n",[290,6631,6632],{"class":292,"line":317},[290,6633,6634],{},"    commit id: \"Diagrammes ER\" tag: \"3.1.2\" type: HIGHLIGHT\n",[290,6636,6637],{"class":292,"line":324},[290,6638,6639],{},"    commit id: \"Modèles Prisma\" tag: \"3.1.1\"\n",[290,6641,6642],{"class":292,"line":330},[290,6643,6644],{},"    commit id: \"Politique AWP → Protocole\" tag: \"9.1\" type: REVERSE\n",[290,6646,6647],{"class":292,"line":336},[290,6648,6649],{},"    commit id: \"BD Sécurisée Transaction\" tag: \"3.3\"\n",[290,6651,6652],{"class":292,"line":342},[290,6653,6654],{},"    commit id: \"Dépendances\" tag: \"1.3\"\n",[290,6656,6657],{"class":292,"line":347},[290,6658,6659],{},"    commit id: \"API GraphQL\" tag: \"4.4\" type: HIGHLIGHT\n",[290,6661,6662],{"class":292,"line":353},[290,6663,6664],{},"    commit id: \"ESLint + Outillage\" tag: \"1.4\"\n",[290,6666,6667],{"class":292,"line":359},[290,6668,6669],{},"    commit id: \"User Stories\" tag: \"5.1\"\n",[290,6671,6672],{"class":292,"line":365},[290,6673,6674],{},"    commit id: \"Producteur Kafka\" tag: \"5.1\" type: HIGHLIGHT\n",[290,6676,6677],{"class":292,"line":370},[290,6678,6679],{},"    commit id: \"Émission d'Événements\" tag: \"5.2\"\n",[290,6681,6682],{"class":292,"line":376},[290,6683,6684],{},"    commit id: \"Étapes Kafka Terminées\" tag: \"5.0\"\n",[290,6686,6687],{"class":292,"line":382},[290,6688,6689],{},"    commit id: \"Procédures AWP\" tag: \"9.2\"\n",[290,6691,6692],{"class":292,"line":387},[290,6693,6694],{},"    branch pre-prod\n",[290,6696,6697],{"class":292,"line":393},[290,6698,6699],{},"    checkout pre-prod\n",[290,6701,6702],{"class":292,"line":398},[290,6703,6704],{},"    commit id: \"Tests Unitaires\" tag: \"8.1\"\n",[290,6706,6707],{"class":292,"line":404},[290,6708,6709],{},"    commit id: \"Docker Compose\" tag: \"10.1\"\n",[290,6711,6712],{"class":292,"line":410},[290,6713,6714],{},"    commit id: \"Release Sémantique\" tag: \"7.4\" type: HIGHLIGHT\n",[290,6716,6717],{"class":292,"line":415},[290,6718,6719],{},"    commit id: \"Winston + Prometheus\" tag: \"10.3\" type: HIGHLIGHT\n",[290,6721,6722],{"class":292,"line":421},[290,6723,6724],{},"    commit id: \"Contrôles Santé\" tag: \"10.3\"\n",[290,6726,6727],{"class":292,"line":427},[290,6728,6729],{},"    commit id: \"Événements d'Audit\" tag: \"6.1\"\n",[290,6731,6732],{"class":292,"line":902},[290,6733,6734],{},"    commit id: \"Actions GitHub\" tag: \"7.4\"\n",[290,6736,6737],{"class":292,"line":931},[290,6738,6739],{},"    commit id: \"Docs Observabilité\" tag: \"10.5\"\n",[290,6741,6742],{"class":292,"line":975},[290,6743,6744],{},"    commit id: \"Structure Projet\" tag: \"11\"\n",[290,6746,6747],{"class":292,"line":1000},[290,6748,6749],{},"    checkout main\n",[290,6751,6752],{"class":292,"line":1020},[290,6753,6754],{},"    merge pre-prod tag: \"v0.9.0\" type: HIGHLIGHT\n",[290,6756,6757],{"class":292,"line":1026},[290,6758,321],{"emptyLinePlaceholder":320},[290,6760,6761],{"class":292,"line":1031},[290,6762,6763],{},"%%{init: {\n",[290,6765,6766],{"class":292,"line":1036},[290,6767,6768],{},"        \"gitGraph\": {\n",[290,6770,6771],{"class":292,"line":1042},[290,6772,6773],{},"            \"titleTopMargin\": 80,\n",[290,6775,6776],{"class":292,"line":1064},[290,6777,6778],{},"            \"diagramPadding\": 20\n",[290,6780,6781],{"class":292,"line":1083},[290,6782,6783],{},"        }\n",[290,6785,6786],{"class":292,"line":1110},[290,6787,6788],{},"    }}%%\n",[102,6790,6792,6798],{"className":6791},[131,132,133],[135,6793,6795],{"id":6794},"vibe-coding",[110,6796,6797],{},"Vibe-Coding",[79,6799,6800],{},[82,6801,6802],{"href":145},[110,6803,148],{},[79,6805,6806],{},"Comment a-t-il été construit ? En utilisant le Vibe-Coding avec la Stratégie de Flux de Travail Agentique.",[102,6808,6810,6816,6830],{"className":6809},[105],[79,6811,6812,6815],{},[110,6813,6814],{},"Le Vibecoding avec Flux de Travail Agentique"," signifie :",[160,6817,6818,6821,6824,6827],{},[163,6819,6820],{},"Travailler dans un état de flux de haute créativité et de rapidité",[163,6822,6823],{},"Laisser les co-pilotes IA gérer les tâches dans un cadre structuré",[163,6825,6826],{},"Éviter l'épuisement cognitif ou le \"over-vibing\" grâce à des limites systématiques",[163,6828,6829],{},"Maintenir la clarté et le contexte tout au long du processus de développement",[79,6831,6832],{},"Le marché du travail évolue, et les ingénieurs doivent s'adapter. L'IA n'est plus optionnelle—c'est un multiplicateur. Mais l'ingénierie à grande échelle avec l'IA nécessite maturité, structure et conscience des risques.",[102,6834,6836,6842],{"className":6835},[131,132,133],[135,6837,6839],{"id":6838},"over-vibing",[110,6840,6841],{},"Over-Vibing",[79,6843,6844],{},[82,6845,6846],{"href":145},[110,6847,148],{},[102,6849,6851],{"className":6850},[105],[79,6852,6853,6854,6857],{},"J'appelle ce risque ",[110,6855,6856],{},"\"over-vibing\"","—un état où l'on pousse trop loin, trop vite, et perd le contexte. Les outils d'IA (en particulier les LLM) souffrent de la dérive du contexte. Les humains aussi. Lorsque vous êtes dans le flux mais perdez de vue l'image globale, la productivité peut rapidement se transformer en dette technique. Pour gérer ce risque, j'ai créé un \"AWP\" qui maintient la structure tout en préservant l'élan créatif.",[102,6859,6861,6867],{"className":6860},[131,132,133],[135,6862,6864],{"id":6863},"awp-protocole-de-flux-de-travail-agentique",[110,6865,6866],{},"AWP : Protocole de Flux de Travail Agentique",[79,6868,6869],{},[82,6870,6871],{"href":145},[110,6872,148],{},[102,6874,6876,6895],{"className":6875},[105],[79,6877,6878,6879,6882,6883,6886,6887,6890,6891,6894],{},"Le secret derrière le développement rapide de Bankly réside dans une méthodologie que j'appelle ",[110,6880,6881],{},"\"Vibecoding avec Flux de Travail Agentique\"",". Cette approche combine des états de flux de haute créativité avec une collaboration IA structurée, évitant les pièges de l'automatisation incontrôlée ou du \"over-vibing\". ",[110,6884,6885],{},"La preuve est dans les commits"," : Bankly a été construit les ",[110,6888,6889],{},"24-25 juin 2025"," en deux jours avec ",[110,6892,6893],{},"plus de 35 commits structurés"," suivant le Protocole de Flux de Travail Agentique (AWP). Chaque commit représente une étape délibérée dans le processus de développement, de la configuration initiale aux fonctionnalités de pré-production.",[281,6896,6898],{"className":283,"code":6897,"language":285,"meta":286,"style":286},"---\ntitle: AWP - Protocole de Flux de Travail Agentique\n---\ngraph TD\n    subgraph Planification\n        A[Définir les Tâches] --> B[Itérer les Tâches]\n    end\n    \n    subgraph Développement\n        C[Revoir la Portée] --> D[Développement]\n        D --> E[Vérifier le Contexte]\n        E --> F[Exécuter les Tests]\n    end\n    \n    subgraph Documentation\n        G[Documentation] --> H[Vérification Finale]\n    end\n    \n    subgraph Contrôle de Version\n        I[Revue Git] --> J[Tâche Suivante]\n    end\n    \n    B --> C\n    F --> G\n    H --> I\n    J --> B\n    E --> C\n",[261,6899,6900,6904,6909,6913,6917,6922,6927,6931,6935,6940,6945,6950,6955,6959,6963,6968,6973,6977,6981,6986,6991,6995,6999,7004,7009,7014,7019],{"__ignoreMap":286},[290,6901,6902],{"class":292,"line":293},[290,6903,6615],{},[290,6905,6906],{"class":292,"line":299},[290,6907,6908],{},"title: AWP - Protocole de Flux de Travail Agentique\n",[290,6910,6911],{"class":292,"line":305},[290,6912,6615],{},[290,6914,6915],{"class":292,"line":311},[290,6916,2406],{},[290,6918,6919],{"class":292,"line":317},[290,6920,6921],{},"    subgraph Planification\n",[290,6923,6924],{"class":292,"line":324},[290,6925,6926],{},"        A[Définir les Tâches] --> B[Itérer les Tâches]\n",[290,6928,6929],{"class":292,"line":330},[290,6930,1383],{},[290,6932,6933],{"class":292,"line":336},[290,6934,721],{},[290,6936,6937],{"class":292,"line":342},[290,6938,6939],{},"    subgraph Développement\n",[290,6941,6942],{"class":292,"line":347},[290,6943,6944],{},"        C[Revoir la Portée] --> D[Développement]\n",[290,6946,6947],{"class":292,"line":353},[290,6948,6949],{},"        D --> E[Vérifier le Contexte]\n",[290,6951,6952],{"class":292,"line":359},[290,6953,6954],{},"        E --> F[Exécuter les Tests]\n",[290,6956,6957],{"class":292,"line":365},[290,6958,1383],{},[290,6960,6961],{"class":292,"line":370},[290,6962,721],{},[290,6964,6965],{"class":292,"line":376},[290,6966,6967],{},"    subgraph Documentation\n",[290,6969,6970],{"class":292,"line":382},[290,6971,6972],{},"        G[Documentation] --> H[Vérification Finale]\n",[290,6974,6975],{"class":292,"line":387},[290,6976,1383],{},[290,6978,6979],{"class":292,"line":393},[290,6980,721],{},[290,6982,6983],{"class":292,"line":398},[290,6984,6985],{},"    subgraph Contrôle de Version\n",[290,6987,6988],{"class":292,"line":404},[290,6989,6990],{},"        I[Revue Git] --> J[Tâche Suivante]\n",[290,6992,6993],{"class":292,"line":410},[290,6994,1383],{},[290,6996,6997],{"class":292,"line":415},[290,6998,721],{},[290,7000,7001],{"class":292,"line":421},[290,7002,7003],{},"    B --> C\n",[290,7005,7006],{"class":292,"line":427},[290,7007,7008],{},"    F --> G\n",[290,7010,7011],{"class":292,"line":902},[290,7012,7013],{},"    H --> I\n",[290,7015,7016],{"class":292,"line":931},[290,7017,7018],{},"    J --> B\n",[290,7020,7021],{"class":292,"line":975},[290,7022,7023],{},"    E --> C\n",[102,7025,7027,7033],{"className":7026},[131,132,133],[135,7028,7030],{"id":7029},"mcp-outils-sldc-agentiques",[110,7031,7032],{},"MCP : Outils SLDC Agentiques",[79,7034,7035],{},[82,7036,7037],{"href":145},[110,7038,148],{},[102,7040,7042,7056,7061],{"className":7041},[105],[79,7043,7044,7047,7048,7051,7052,7055],{},[110,7045,7046],{},"MCP SLDC Agentique"," (Cycle de Développement Logiciel) est un ",[110,7049,7050],{},"protocole open-source"," conçu pour aider les équipes et les agents IA à maintenir la ",[110,7053,7054],{},"clarté, la transparence et le flux"," tout au long du développement.",[79,7057,7058],{},[110,7059,7060],{},"Avantages Clés :",[160,7062,7063,7066,7069,7072],{},[163,7064,7065],{},"Toujours savoir quelle est la prochaine étape",[163,7067,7068],{},"Restaurer le contexte après les pauses ou les réinitialisations",[163,7070,7071],{},"Maintenir la documentation et le code synchronisés",[163,7073,7074],{},"Équilibrer efficacement la collaboration humain-IA",[79,7076,7077],{},[110,7078,7079],{},"Considérations Clés en 2025 :",[102,7081,7083],{"className":7082},[105],[160,7084,7085,7091,7097],{},[163,7086,7087,7090],{},[110,7088,7089],{},"VIBE-CODING"," : Flux créatif productif en développement",[163,7092,7093,7096],{},[110,7094,7095],{},"OVER-VIBING"," : Perte de contrôle du projet due à une automatisation excessive ou à une dérive",[163,7098,7099,7102],{},[110,7100,7101],{},"Collaboration Agentique"," : Attribution de rôles et de responsabilités structurés aux humains et aux IA",[102,7104,7106,7112],{"className":7105},[131,132,133],[135,7107,7109],{"id":7108},"exemples-de-flux-de-travail",[110,7110,7111],{},"Exemples de Flux de Travail",[79,7113,7114],{},[82,7115,7116],{"href":145},[110,7117,148],{},[102,7119,7121],{"className":7120},[105],[79,7122,7123],{},"Voici un diagramme simplifié de la boucle de développement :",[281,7125,7127],{"className":283,"code":7126,"language":285,"meta":286,"style":286},"---\ntitle: SLDC Agentique - Boucle de Développement\n---\nflowchart TD\n    Start([\"Début Étape (ex., 4.2)\"])\n    Code[\"Implémenter Fonctionnalité/Tâche\"]\n    Update[\"mcp:update\u003Cbr/>Mettre à jour README.md & mcp-agentic-sldc.yml\u003Cbr/>Marquer l'étape comme terminée\"]\n    Commit[\"mcp:commit\u003Cbr/>Commit avec message Conventional Commit\"]\n    Next[\"mcp:next\u003Cbr/>Passer à l'étape suivante\"]\n    Review[\"Revoir Progression\u003Cbr/>(Si blocages, les signaler)\"]\n    Done([\"Étape Terminée\"])\n\n    Start --> Code --> Update --> Commit --> Next --> Review --> Done\n    Review -- \"Si pas prêt\" --> Start\n",[261,7128,7129,7133,7138,7142,7146,7151,7156,7161,7166,7171,7176,7181,7185,7190],{"__ignoreMap":286},[290,7130,7131],{"class":292,"line":293},[290,7132,6615],{},[290,7134,7135],{"class":292,"line":299},[290,7136,7137],{},"title: SLDC Agentique - Boucle de Développement\n",[290,7139,7140],{"class":292,"line":305},[290,7141,6615],{},[290,7143,7144],{"class":292,"line":311},[290,7145,5236],{},[290,7147,7148],{"class":292,"line":317},[290,7149,7150],{},"    Start([\"Début Étape (ex., 4.2)\"])\n",[290,7152,7153],{"class":292,"line":324},[290,7154,7155],{},"    Code[\"Implémenter Fonctionnalité/Tâche\"]\n",[290,7157,7158],{"class":292,"line":330},[290,7159,7160],{},"    Update[\"mcp:update\u003Cbr/>Mettre à jour README.md & mcp-agentic-sldc.yml\u003Cbr/>Marquer l'étape comme terminée\"]\n",[290,7162,7163],{"class":292,"line":336},[290,7164,7165],{},"    Commit[\"mcp:commit\u003Cbr/>Commit avec message Conventional Commit\"]\n",[290,7167,7168],{"class":292,"line":342},[290,7169,7170],{},"    Next[\"mcp:next\u003Cbr/>Passer à l'étape suivante\"]\n",[290,7172,7173],{"class":292,"line":347},[290,7174,7175],{},"    Review[\"Revoir Progression\u003Cbr/>(Si blocages, les signaler)\"]\n",[290,7177,7178],{"class":292,"line":353},[290,7179,7180],{},"    Done([\"Étape Terminée\"])\n",[290,7182,7183],{"class":292,"line":359},[290,7184,321],{"emptyLinePlaceholder":320},[290,7186,7187],{"class":292,"line":365},[290,7188,7189],{},"    Start --> Code --> Update --> Commit --> Next --> Review --> Done\n",[290,7191,7192],{"class":292,"line":370},[290,7193,7194],{},"    Review -- \"Si pas prêt\" --> Start\n",[102,7196,7198],{"className":7197},[105],[79,7199,7200],{},"Et comment retrouver le contexte après une pause :",[281,7202,7204],{"className":283,"code":7203,"language":285,"meta":286,"style":286},"---\ntitle: SLDC Agentique - Retrouver le contexte\n---\nflowchart TD\n    Done --> MemoryLoss[\"Perte de Mémoire ?\"]\n    MemoryLoss -- \"Oui\" --> Recall --> Start\n    MemoryLoss -- \"Non\" --> Start\n    Recall[\"Consulter mcp-agentic-sldc.yml\u003Cbr/>Restaurer contexte, voir progression, actions suivantes\"]\n",[261,7205,7206,7210,7215,7219,7223,7228,7233,7238],{"__ignoreMap":286},[290,7207,7208],{"class":292,"line":293},[290,7209,6615],{},[290,7211,7212],{"class":292,"line":299},[290,7213,7214],{},"title: SLDC Agentique - Retrouver le contexte\n",[290,7216,7217],{"class":292,"line":305},[290,7218,6615],{},[290,7220,7221],{"class":292,"line":311},[290,7222,5236],{},[290,7224,7225],{"class":292,"line":317},[290,7226,7227],{},"    Done --> MemoryLoss[\"Perte de Mémoire ?\"]\n",[290,7229,7230],{"class":292,"line":324},[290,7231,7232],{},"    MemoryLoss -- \"Oui\" --> Recall --> Start\n",[290,7234,7235],{"class":292,"line":330},[290,7236,7237],{},"    MemoryLoss -- \"Non\" --> Start\n",[290,7239,7240],{"class":292,"line":336},[290,7241,7242],{},"    Recall[\"Consulter mcp-agentic-sldc.yml\u003Cbr/>Restaurer contexte, voir progression, actions suivantes\"]\n",[102,7244,7246,7250],{"className":7245},[131,132,133],[135,7247,7249],{"id":7248},"prochaines-étapes","Prochaines étapes",[79,7251,7252],{},[82,7253,7254],{"href":145},[110,7255,148],{},[1612,7257,7258],{"id":4215},"MCP",[79,7260,7261],{},[110,7262,7263,7264,7267],{},"Le Fichier ",[261,7265,7266],{},"mcp-agentic-sldc.yml"," : Votre Feuille de Route Vivante",[102,7269,7271],{"className":7270},[105],[79,7272,7273],{},"Comme nous sommes en phase initiale, chaque projet utilisant le SLDC Agentique avec le Protocole de Flux de Travail Agentique devrait inclure un fichier structuré comme cet exemple :",[281,7275,7279],{"className":7276,"code":7277,"language":7278,"meta":286,"style":286},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","author: Michael Wybraniec\ngoal: Construire une API backend moderne pour la banque\noverview:\n  - Configuration\n  - Schéma & Modèles\n  - Auth & Permissions\n  - Tests & Documentation\noutcome: Une API bancaire prête à être étendue, construite avec GraphQL et Prisma\nsteps:\n  - number: 1\n    name: Configurer le projet\n    owner: human\n    done: true\n  - number: 2\n    name: Définir le schéma GraphQL\n    owner: ai\n    done: true\n  - number: 3\n    name: Connecter les modèles Prisma\n    owner: ai\n    done: true\n  - number: 4\n    name: Auth & middleware\n    owner: human\n    done: false\n","yaml",[261,7280,7281,7291,7301,7309,7317,7324,7331,7338,7348,7355,7367,7377,7387,7398,7409,7418,7427,7435,7446,7455,7463,7471,7482,7491,7499],{"__ignoreMap":286},[290,7282,7283,7286,7288],{"class":292,"line":293},[290,7284,7285],{"class":648},"author",[290,7287,659],{"class":639},[290,7289,7290],{"class":813}," Michael Wybraniec\n",[290,7292,7293,7296,7298],{"class":292,"line":299},[290,7294,7295],{"class":648},"goal",[290,7297,659],{"class":639},[290,7299,7300],{"class":813}," Construire une API backend moderne pour la banque\n",[290,7302,7303,7306],{"class":292,"line":305},[290,7304,7305],{"class":648},"overview",[290,7307,7308],{"class":639},":\n",[290,7310,7311,7314],{"class":292,"line":311},[290,7312,7313],{"class":639},"  -",[290,7315,7316],{"class":813}," Configuration\n",[290,7318,7319,7321],{"class":292,"line":317},[290,7320,7313],{"class":639},[290,7322,7323],{"class":813}," Schéma & Modèles\n",[290,7325,7326,7328],{"class":292,"line":324},[290,7327,7313],{"class":639},[290,7329,7330],{"class":813}," Auth & Permissions\n",[290,7332,7333,7335],{"class":292,"line":330},[290,7334,7313],{"class":639},[290,7336,7337],{"class":813}," Tests & Documentation\n",[290,7339,7340,7343,7345],{"class":292,"line":336},[290,7341,7342],{"class":648},"outcome",[290,7344,659],{"class":639},[290,7346,7347],{"class":813}," Une API bancaire prête à être étendue, construite avec GraphQL et Prisma\n",[290,7349,7350,7353],{"class":292,"line":342},[290,7351,7352],{"class":648},"steps",[290,7354,7308],{"class":639},[290,7356,7357,7359,7362,7364],{"class":292,"line":347},[290,7358,7313],{"class":639},[290,7360,7361],{"class":648}," number",[290,7363,659],{"class":639},[290,7365,7366],{"class":1077}," 1\n",[290,7368,7369,7372,7374],{"class":292,"line":353},[290,7370,7371],{"class":648},"    name",[290,7373,659],{"class":639},[290,7375,7376],{"class":813}," Configurer le projet\n",[290,7378,7379,7382,7384],{"class":292,"line":359},[290,7380,7381],{"class":648},"    owner",[290,7383,659],{"class":639},[290,7385,7386],{"class":813}," human\n",[290,7388,7389,7392,7394],{"class":292,"line":365},[290,7390,7391],{"class":648},"    done",[290,7393,659],{"class":639},[290,7395,7397],{"class":7396},"sfNiH"," true\n",[290,7399,7400,7402,7404,7406],{"class":292,"line":370},[290,7401,7313],{"class":639},[290,7403,7361],{"class":648},[290,7405,659],{"class":639},[290,7407,7408],{"class":1077}," 2\n",[290,7410,7411,7413,7415],{"class":292,"line":376},[290,7412,7371],{"class":648},[290,7414,659],{"class":639},[290,7416,7417],{"class":813}," Définir le schéma GraphQL\n",[290,7419,7420,7422,7424],{"class":292,"line":382},[290,7421,7381],{"class":648},[290,7423,659],{"class":639},[290,7425,7426],{"class":813}," ai\n",[290,7428,7429,7431,7433],{"class":292,"line":387},[290,7430,7391],{"class":648},[290,7432,659],{"class":639},[290,7434,7397],{"class":7396},[290,7436,7437,7439,7441,7443],{"class":292,"line":393},[290,7438,7313],{"class":639},[290,7440,7361],{"class":648},[290,7442,659],{"class":639},[290,7444,7445],{"class":1077}," 3\n",[290,7447,7448,7450,7452],{"class":292,"line":398},[290,7449,7371],{"class":648},[290,7451,659],{"class":639},[290,7453,7454],{"class":813}," Connecter les modèles Prisma\n",[290,7456,7457,7459,7461],{"class":292,"line":404},[290,7458,7381],{"class":648},[290,7460,659],{"class":639},[290,7462,7426],{"class":813},[290,7464,7465,7467,7469],{"class":292,"line":410},[290,7466,7391],{"class":648},[290,7468,659],{"class":639},[290,7470,7397],{"class":7396},[290,7472,7473,7475,7477,7479],{"class":292,"line":415},[290,7474,7313],{"class":639},[290,7476,7361],{"class":648},[290,7478,659],{"class":639},[290,7480,7481],{"class":1077}," 4\n",[290,7483,7484,7486,7488],{"class":292,"line":421},[290,7485,7371],{"class":648},[290,7487,659],{"class":639},[290,7489,7490],{"class":813}," Auth & middleware\n",[290,7492,7493,7495,7497],{"class":292,"line":427},[290,7494,7381],{"class":648},[290,7496,659],{"class":639},[290,7498,7386],{"class":813},[290,7500,7501,7503,7505],{"class":292,"line":902},[290,7502,7391],{"class":648},[290,7504,659],{"class":639},[290,7506,7507],{"class":7396}," false\n",[102,7509,7511],{"className":7510},[105],[79,7512,7513,7514,3139,7517,3139,7520,7523],{},"Le YAML définit également des procédures comme ",[261,7515,7516],{},"update",[261,7518,7519],{},"commit",[261,7521,7522],{},"next",", et des règles pour les transferts humain-IA.",[102,7525,7527,7533],{"className":7526},[131,132,133],[1612,7528,7530],{"id":7529},"meilleures-pratiques",[110,7531,7532],{},"Meilleures Pratiques",[79,7534,7535],{},[82,7536,7537],{"href":145},[110,7538,148],{},[102,7540,7542,7545],{"className":7541},[105],[79,7543,7544],{},"Comme le Vibe-Coding est nouveau, ainsi que tous les concepts, vous gardez le contrôle total, que vous le vouliez ou non. Par conséquent, gardez cette liste à l'esprit :",[160,7546,7547,7550,7553,7556,7559,7565,7568],{},[163,7548,7549],{},"Utiliser des commits conventionnels liés à chaque étape",[163,7551,7552],{},"Maintenir README.md et le YAML SLDC toujours à jour",[163,7554,7555],{},"Définir la propriété : Humain vs IA",[163,7557,7558],{},"Permettre un transfert structuré entre agents",[163,7560,7561,7562],{},"Récupérer d'une perte de mémoire avec une seule commande ",[261,7563,7564],{},"check",[163,7566,7567],{},"Maintenir une architecture de code modulaire et testable",[163,7569,7570],{},"Documenter les décisions et compromis au fur et à mesure",[102,7572,7574,7580],{"className":7573},[131,132,133],[1612,7575,7577],{"id":7576},"pourquoi-ça-marche",[110,7578,7579],{},"Pourquoi Ça Marche ?",[79,7581,7582],{},[82,7583,7584],{"href":145},[110,7585,148],{},[102,7587,7589,7596,7629],{"className":7588},[105],[79,7590,7591,7592,7595],{},"Bankly a été complété en ",[110,7593,7594],{},"2 jours"," parce que :",[160,7597,7598,7601,7604,7607,7610,7613,7619],{},[163,7599,7600],{},"La feuille de route était claire et structurée via le protocole AWP",[163,7602,7603],{},"Le travail était modulaire et agentique avec une propriété définie",[163,7605,7606],{},"L'IA gérait les tâches structurées comme le schéma, la génération de modèles et la configuration",[163,7608,7609],{},"L'attention humaine restait sur l'architecture, la logique et la revue",[163,7611,7612],{},"Le contexte n'a jamais été perdu grâce au protocole SLDC",[163,7614,7615,7618],{},[110,7616,7617],{},"35+ commits"," montrent une progression systématique sans dérive fonctionnelle",[163,7620,605,7621,7624,7625,7628],{},[110,7622,7623],{},"Jour 1"," s'est concentré sur les fonctionnalités de base, le ",[110,7626,7627],{},"Jour 2"," sur la préparation à la production",[79,7630,7631,7632,7635],{},"Ce n'est pas juste de la productivité—c'est une ",[110,7633,7634],{},"vélocité durable",". Le système prévient l'épuisement tout en maintenant la qualité et en permettant une itération rapide.",[102,7637,7639,7645],{"className":7638},[131,132,133],[135,7640,7642],{"id":7641},"réflexions-finales",[110,7643,7644],{},"Réflexions Finales",[79,7646,7647],{},[82,7648,7649],{"href":145},[110,7650,148],{},[102,7652,7654,7657,7684],{"className":7653},[105],[79,7655,7656],{},"MCP SLDC Agentique ou mon AWP - Protocole de Flux de Travail Agentique - n'est pas juste un outil—c'est une philosophie pour le développement moderne :",[160,7658,7659,7669,7675,7681],{},[163,7660,7661,7662,7665,7666],{},"Construire ",[110,7663,7664],{},"plus rapidement",", mais rester ",[110,7667,7668],{},"ancré",[163,7670,7671,7672],{},"Collaborer avec l'IA, mais maintenir la ",[110,7673,7674],{},"stratégie et la propriété",[163,7676,7677,7678],{},"Utiliser la clarté et le processus pour ",[110,7679,7680],{},"éviter l'épuisement et la confusion",[163,7682,7683],{},"La structure est la nouvelle vitesse dans un monde assisté par l'IA",[79,7685,7686],{},"Que vous fassiez du Vibe-Coding en solo ou que vous gériez une équipe d'agents, la collaboration structurée est la clé d'une livraison de logiciels durable et de haute qualité.",[102,7688,7690,7696],{"className":7689},[131,132,133],[135,7691,7693],{"id":7692},"participez",[110,7694,7695],{},"Participez !",[79,7697,7698],{},[82,7699,7700],{"href":145},[110,7701,148],{},[102,7703,7705],{"className":7704},[105],[79,7706,7707,7708,7710,7711,200],{},"Contribuez au ",[110,7709,7046],{}," et rejoignez le mouvement vers un développement centré sur l'humain et assisté par l'IA -> ",[82,7712,7715],{"href":7713,"rel":7714},"https://one-front.com/contact",[99],"ici",[102,7717,7719],{"className":7718},[2172,2173,2174,2175],[79,7720,7721],{},[82,7722,7723],{"href":145},[110,7724,148],{},[2183,7726,7727],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":286,"searchDepth":299,"depth":299,"links":7729},[7730,7731,7732,7733,7734,7735,7736,7741,7742],{"id":6596,"depth":299,"text":6599},{"id":6794,"depth":299,"text":6797},{"id":6838,"depth":299,"text":6841},{"id":6863,"depth":299,"text":6866},{"id":7029,"depth":299,"text":7032},{"id":7108,"depth":299,"text":7111},{"id":7248,"depth":299,"text":7249,"children":7737},[7738,7739,7740],{"id":4215,"depth":305,"text":7258},{"id":7529,"depth":305,"text":7532},{"id":7576,"depth":305,"text":7579},{"id":7641,"depth":299,"text":7644},{"id":7692,"depth":299,"text":7695},"2025-06-29","Découvrez comment Bankly, un système bancaire backend, a été construit en seulement deux jours en utilisant Apollo GraphQL, Prisma et le Flux de Travail Agentique - un protocole pour le développement durable assisté par l'IA.",{"src":2208},{},{"title":32,"description":7744},"YK4sakb9zslMRc8p8ii8F05oAMn1YxZECH7H7RpY94E",{"id":7750,"title":36,"authors":7751,"badge":7754,"body":7756,"date":10836,"description":10837,"extension":2206,"image":10838,"meta":10839,"navigation":320,"path":37,"seo":10840,"stem":38,"__hash__":10841},"posts_fr/fr/blog/8. mcp-in-chat-demo.md",[7752],{"name":66,"description":2216,"to":68,"avatar":7753},{"src":2218},{"label":7755,"color":3189,"variant":74},"MCP, E-commerce, Demo",{"type":76,"value":7757,"toc":10786},[7758,7769,7784,7800,7804,7819,7823,7855,7859,7943,7947,7960,7964,8002,8006,8432,8447,8453,8457,8600,8606,8610,8820,8825,8829,9009,9014,9018,9210,9215,9230,9236,9240,9245,9250,9257,9261,9266,9270,9276,9280,9285,9289,9295,9310,9316,9320,9569,9573,9576,9626,9630,9982,9988,10003,10009,10013,10045,10049,10055,10059,10159,10174,10180,10184,10198,10202,10299,10303,10306,10326,10330,10333,10359,10374,10380,10384,10415,10419,10489,10493,10519,10534,10540,10544,10622,10626,10629,10661,10676,10682,10684,10716,10719,10722,10753,10756,10758,10762,10783],[102,7759,7761],{"className":7760},[105],[79,7762,605,7763,7768],{},[82,7764,7767],{"href":7765,"rel":7766},"https://github.com/michaelwybraniec/mcp-in-chat",[99],"projet MCP-in-Chat"," représente une démonstration complète et prête pour la production de comment les serveurs du Protocole de Contexte de Modèle (MCP) peuvent transformer les interactions de chatbots e-commerce. Cet exemple complet montre un système de maintenance et de vente de chaudières qui connecte des chatbots IA externes (Claude, ChatGPT, Cursor) à la logique métier réelle à travers une architecture sécurisée et évolutive. Construit en utilisant la méthodologie du Protocole de Flux de Travail Agentique (AWP), ce projet démontre comment créer des serveurs MCP sophistiqués qui connectent l'IA conversationnelle aux systèmes d'entreprise.",[102,7770,7772,7778],{"className":7771},[131,132,133],[135,7773,7775],{"id":7774},"_1-awp-protocole-de-flux-de-travail-agentique",[110,7776,7777],{},"1. AWP - Protocole de Flux de Travail Agentique",[79,7779,7780],{},[82,7781,7782],{"href":145},[110,7783,148],{},[102,7785,7787],{"className":7786},[105],[79,7788,605,7789,7792,7793,7795,7796,7799],{},[110,7790,7791],{},"Protocole de Flux de Travail Agentique (AWP)"," est une méthodologie de développement agentique créée par ",[110,7794,66],{}," et maintenue par la ",[110,7797,7798],{},"communauté overvibing.com",". Cette approche systématique assure des résultats de développement cohérents et de haute qualité en fournissant des flux de travail structurés qui préviennent la dérive de contexte appelée overvibing et permettent une livraison rapide et fiable de projets tout en évoluant le développement avec l'IA.",[1612,7801,7803],{"id":7802},"vidéo-demo","Vidéo Demo",[102,7805,7807],{"className":7806},[2173],[102,7808,7810],{"style":7809},"padding:95.12% 0 0 0;position:relative;",[7811,7812],"iframe",{"src":7813,"frameBorder":7814,"allow":7815,"referrerPolicy":7816,"style":7817,"title":7818},"https://player.vimeo.com/video/1106052609?badge=0&autopause=0&player_id=0&app_id=58479","0","autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share","strict-origin-when-cross-origin","position:absolute;top:0;left:0;width:100%;height:100%;","Agentic Workflow preventing Overvibing.com - #GreenTokens #MCP #VibeCoding",[1612,7820,7822],{"id":7821},"résultats-dimplémentation","Résultats d'Implémentation",[160,7824,7825,7831,7837,7843,7849],{},[163,7826,7827,7830],{},[110,7828,7829],{},"Calendrier",": 4 heures (incluant les tâches non planifiées)",[163,7832,7833,7836],{},[110,7834,7835],{},"Portée",": 100% des fonctionnalités planifiées implémentées",[163,7838,7839,7842],{},[110,7840,7841],{},"Qualité",": 100% de succès aux tests",[163,7844,7845,7848],{},[110,7846,7847],{},"Documentation",": Complète et compréhensive",[163,7850,7851,7854],{},[110,7852,7853],{},"Prêt pour Demo",": Entièrement fonctionnel et testé",[1612,7856,7858],{"id":7857},"phases-de-développement","Phases de Développement",[1625,7860,7861,7881,7904,7923],{},[163,7862,7863,7866,7867],{},[110,7864,7865],{},"Configuration du Projet et Architecture de Sécurité"," (45 minutes)",[160,7868,7869,7872,7875,7878],{},[163,7870,7871],{},"Initialiser le projet Node.js avec TypeScript",[163,7873,7874],{},"Configurer l'architecture en couches (MCP → API → Services → Base de Données)",[163,7876,7877],{},"Créer des fichiers JSON de données simulées avec contrôles d'accès",[163,7879,7880],{},"Définir les interfaces TypeScript et types de sécurité",[163,7882,7883,7886,7887],{},[110,7884,7885],{},"Développement des Outils MCP Principaux"," (90 minutes)",[160,7888,7889,7892,7895,7898,7901],{},[163,7890,7891],{},"Implémenter l'outil d'information de chaudières avec validation d'API",[163,7893,7894],{},"Implémenter l'outil de planification de maintenance avec contrôles d'accès",[163,7896,7897],{},"Implémenter l'outil d'inventaire avec limitation de débit",[163,7899,7900],{},"Implémenter l'outil d'achat avec validation de transactions",[163,7902,7903],{},"Implémenter l'outil email avec filtrage de contenu",[163,7905,7906,7866,7909],{},[110,7907,7908],{},"Tests et Préparation de Demo",[160,7910,7911,7914,7917,7920],{},[163,7912,7913],{},"Tester le Serveur MCP avec des outils locaux",[163,7915,7916],{},"Créer des instructions de demo pour l'intégration de chatbot",[163,7918,7919],{},"Préparer des flux de conversation d'exemple",[163,7921,7922],{},"Créer README avec instructions de configuration et d'utilisation",[163,7924,7925,7928,7929],{},[110,7926,7927],{},"Intégration de Chatbot Externe"," (60 minutes)",[160,7930,7931,7934,7937,7940],{},[163,7932,7933],{},"Tester le Serveur MCP avec Claude (si disponible)",[163,7935,7936],{},"Tester le Serveur MCP avec ChatGPT (si disponible)",[163,7938,7939],{},"Documenter le processus d'intégration et les résultats",[163,7941,7942],{},"Créer des matériaux de présentation de demo",[1612,7944,7946],{"id":7945},"aperçu-du-projet","Aperçu du Projet",[102,7948,7950,7953],{"className":7949},[105],[79,7951,7952],{},"Serveur MCP de Maintenance de Chaudières",[79,7954,7955,7956,7959],{},"Le projet MCP-in-Chat est une ",[110,7957,7958],{},"démonstration complétée avec succès"," qui montre comment les serveurs MCP peuvent s'intégrer avec des chatbots externes pour fournir une valeur commerciale réelle. Le système gère les services de maintenance de chaudières, les informations client, la gestion d'inventaire et le traitement des achats à travers une interface conversationnelle.",[1612,7961,7963],{"id":7962},"fonctionnalités-clés","Fonctionnalités Clés",[160,7965,7966,7972,7978,7984,7990,7996],{},[163,7967,7968,7971],{},[110,7969,7970],{},"4 Outils MCP",": Information de chaudières, planification de maintenance, traitement d'achat et confirmation par email",[163,7973,7974,7977],{},[110,7975,7976],{},"4 Endpoints API",": Backend RESTful avec authentification et validation",[163,7979,7980,7983],{},[110,7981,7982],{},"8 Services Simulés",": Simulation complète de logique métier avec données réalistes",[163,7985,7986,7989],{},[110,7987,7988],{},"Intégration Externe",": Prêt pour les tests avec Claude, ChatGPT et Cursor IDE",[163,7991,7992,7995],{},[110,7993,7994],{},"100% Couverture de Tests",": Suite de tests complète avec 100% de succès",[163,7997,7998,8001],{},[110,7999,8000],{},"Prêt pour Production",": Middleware de sécurité, limitation de débit et gestion d'erreurs",[1612,8003,8005],{"id":8004},"aperçu-de-larchitecture","Aperçu de l'Architecture",[281,8007,8009],{"className":283,"code":8008,"language":285,"meta":286,"style":286},"---\nheader: MCP-in-Chat System Architecture\nlegend:\n  - color: \"#3B82F6\"\n    text: \"External Systems\"\n  - color: \"#8B5CF6\"\n    text: \"MCP Protocol Layer\"\n  - color: \"#10B981\"\n    text: \"API & Security Layer\"\n  - color: \"#F59E0B\"\n    text: \"Business Services\"\n  - color: \"#EF4444\"\n    text: \"Data Layer\"\n---\ngraph TD\n    subgraph \"External Chatbots\"\n        A[Claude AI]\n        B[ChatGPT]\n        C[Cursor IDE]\n    end\n    \n    subgraph \"MCP Server Layer\"\n        D[MCP Server]\n        E[Boiler Info Tool]\n        F[Maintenance Tool]\n        G[Purchase Tool]\n        H[Email Tool]\n    end\n    \n    subgraph \"Backend API Layer\"\n        I[Express API Server]\n        J[Authentication]\n        K[Validation]\n        L[Rate Limiting]\n    end\n    \n    subgraph \"Business Services\"\n        M[Customer Service]\n        N[Boiler Service]\n        O[Payment Service]\n        P[Email Service]\n    end\n    \n    subgraph \"Mock Data Layer\"\n        Q[Customers JSON]\n        R[Boilers JSON]\n        S[Inventory JSON]\n        T[Orders JSON]\n    end\n    \n    A --> D\n    B --> D\n    C --> D\n    D --> E\n    D --> F\n    D --> G\n    D --> H\n    E --> I\n    F --> I\n    G --> I\n    H --> I\n    I --> J\n    J --> K\n    K --> L\n    L --> M\n    L --> N\n    L --> O\n    L --> P\n    M --> Q\n    N --> R\n    O --> S\n    P --> T\n    \n    classDef external fill:#3B82F6,stroke:#1E40AF,stroke-width:2px,color:#fff\n    classDef mcp fill:#8B5CF6,stroke:#7C3AED,stroke-width:2px,color:#fff\n    classDef api fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff\n    classDef service fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff\n    classDef data fill:#EF4444,stroke:#DC2626,stroke-width:2px,color:#fff\n    \n    class A,B,C external\n    class D,E,F,G,H mcp\n    class I,J,K,L api\n    class M,N,O,P service\n    class Q,R,S,T data\n",[261,8010,8011,8015,8020,8025,8030,8035,8040,8045,8050,8055,8060,8065,8070,8075,8079,8083,8088,8093,8098,8103,8107,8111,8116,8121,8126,8131,8136,8141,8145,8149,8154,8159,8164,8169,8174,8178,8182,8187,8192,8197,8202,8207,8211,8215,8220,8225,8230,8235,8240,8244,8248,8253,8258,8263,8268,8273,8278,8283,8288,8293,8298,8302,8307,8312,8317,8322,8327,8332,8338,8344,8350,8356,8362,8367,8373,8379,8385,8391,8397,8402,8408,8414,8420,8426],{"__ignoreMap":286},[290,8012,8013],{"class":292,"line":293},[290,8014,6615],{},[290,8016,8017],{"class":292,"line":299},[290,8018,8019],{},"header: MCP-in-Chat System Architecture\n",[290,8021,8022],{"class":292,"line":305},[290,8023,8024],{},"legend:\n",[290,8026,8027],{"class":292,"line":311},[290,8028,8029],{},"  - color: \"#3B82F6\"\n",[290,8031,8032],{"class":292,"line":317},[290,8033,8034],{},"    text: \"External Systems\"\n",[290,8036,8037],{"class":292,"line":324},[290,8038,8039],{},"  - color: \"#8B5CF6\"\n",[290,8041,8042],{"class":292,"line":330},[290,8043,8044],{},"    text: \"MCP Protocol Layer\"\n",[290,8046,8047],{"class":292,"line":336},[290,8048,8049],{},"  - color: \"#10B981\"\n",[290,8051,8052],{"class":292,"line":342},[290,8053,8054],{},"    text: \"API & Security Layer\"\n",[290,8056,8057],{"class":292,"line":347},[290,8058,8059],{},"  - color: \"#F59E0B\"\n",[290,8061,8062],{"class":292,"line":353},[290,8063,8064],{},"    text: \"Business Services\"\n",[290,8066,8067],{"class":292,"line":359},[290,8068,8069],{},"  - color: \"#EF4444\"\n",[290,8071,8072],{"class":292,"line":365},[290,8073,8074],{},"    text: \"Data Layer\"\n",[290,8076,8077],{"class":292,"line":370},[290,8078,6615],{},[290,8080,8081],{"class":292,"line":376},[290,8082,2406],{},[290,8084,8085],{"class":292,"line":382},[290,8086,8087],{},"    subgraph \"External Chatbots\"\n",[290,8089,8090],{"class":292,"line":387},[290,8091,8092],{},"        A[Claude AI]\n",[290,8094,8095],{"class":292,"line":393},[290,8096,8097],{},"        B[ChatGPT]\n",[290,8099,8100],{"class":292,"line":398},[290,8101,8102],{},"        C[Cursor IDE]\n",[290,8104,8105],{"class":292,"line":404},[290,8106,1383],{},[290,8108,8109],{"class":292,"line":410},[290,8110,721],{},[290,8112,8113],{"class":292,"line":415},[290,8114,8115],{},"    subgraph \"MCP Server Layer\"\n",[290,8117,8118],{"class":292,"line":421},[290,8119,8120],{},"        D[MCP Server]\n",[290,8122,8123],{"class":292,"line":427},[290,8124,8125],{},"        E[Boiler Info Tool]\n",[290,8127,8128],{"class":292,"line":902},[290,8129,8130],{},"        F[Maintenance Tool]\n",[290,8132,8133],{"class":292,"line":931},[290,8134,8135],{},"        G[Purchase Tool]\n",[290,8137,8138],{"class":292,"line":975},[290,8139,8140],{},"        H[Email Tool]\n",[290,8142,8143],{"class":292,"line":1000},[290,8144,1383],{},[290,8146,8147],{"class":292,"line":1020},[290,8148,721],{},[290,8150,8151],{"class":292,"line":1026},[290,8152,8153],{},"    subgraph \"Backend API Layer\"\n",[290,8155,8156],{"class":292,"line":1031},[290,8157,8158],{},"        I[Express API Server]\n",[290,8160,8161],{"class":292,"line":1036},[290,8162,8163],{},"        J[Authentication]\n",[290,8165,8166],{"class":292,"line":1042},[290,8167,8168],{},"        K[Validation]\n",[290,8170,8171],{"class":292,"line":1064},[290,8172,8173],{},"        L[Rate Limiting]\n",[290,8175,8176],{"class":292,"line":1083},[290,8177,1383],{},[290,8179,8180],{"class":292,"line":1110},[290,8181,721],{},[290,8183,8184],{"class":292,"line":1120},[290,8185,8186],{},"    subgraph \"Business Services\"\n",[290,8188,8189],{"class":292,"line":1127},[290,8190,8191],{},"        M[Customer Service]\n",[290,8193,8194],{"class":292,"line":1163},[290,8195,8196],{},"        N[Boiler Service]\n",[290,8198,8199],{"class":292,"line":1173},[290,8200,8201],{},"        O[Payment Service]\n",[290,8203,8204],{"class":292,"line":1178},[290,8205,8206],{},"        P[Email Service]\n",[290,8208,8209],{"class":292,"line":4857},[290,8210,1383],{},[290,8212,8213],{"class":292,"line":4863},[290,8214,721],{},[290,8216,8217],{"class":292,"line":4868},[290,8218,8219],{},"    subgraph \"Mock Data Layer\"\n",[290,8221,8222],{"class":292,"line":4874},[290,8223,8224],{},"        Q[Customers JSON]\n",[290,8226,8227],{"class":292,"line":4880},[290,8228,8229],{},"        R[Boilers JSON]\n",[290,8231,8232],{"class":292,"line":4885},[290,8233,8234],{},"        S[Inventory JSON]\n",[290,8236,8237],{"class":292,"line":4891},[290,8238,8239],{},"        T[Orders JSON]\n",[290,8241,8242],{"class":292,"line":4897},[290,8243,1383],{},[290,8245,8246],{"class":292,"line":4903},[290,8247,721],{},[290,8249,8250],{"class":292,"line":4909},[290,8251,8252],{},"    A --> D\n",[290,8254,8255],{"class":292,"line":4914},[290,8256,8257],{},"    B --> D\n",[290,8259,8260],{"class":292,"line":4920},[290,8261,8262],{},"    C --> D\n",[290,8264,8265],{"class":292,"line":4925},[290,8266,8267],{},"    D --> E\n",[290,8269,8270],{"class":292,"line":4931},[290,8271,8272],{},"    D --> F\n",[290,8274,8275],{"class":292,"line":4937},[290,8276,8277],{},"    D --> G\n",[290,8279,8280],{"class":292,"line":4943},[290,8281,8282],{},"    D --> H\n",[290,8284,8285],{"class":292,"line":4949},[290,8286,8287],{},"    E --> I\n",[290,8289,8290],{"class":292,"line":4954},[290,8291,8292],{},"    F --> I\n",[290,8294,8295],{"class":292,"line":4960},[290,8296,8297],{},"    G --> I\n",[290,8299,8300],{"class":292,"line":4966},[290,8301,7013],{},[290,8303,8304],{"class":292,"line":4972},[290,8305,8306],{},"    I --> J\n",[290,8308,8309],{"class":292,"line":5528},[290,8310,8311],{},"    J --> K\n",[290,8313,8314],{"class":292,"line":5533},[290,8315,8316],{},"    K --> L\n",[290,8318,8319],{"class":292,"line":5539},[290,8320,8321],{},"    L --> M\n",[290,8323,8324],{"class":292,"line":5545},[290,8325,8326],{},"    L --> N\n",[290,8328,8329],{"class":292,"line":5551},[290,8330,8331],{},"    L --> O\n",[290,8333,8335],{"class":292,"line":8334},68,[290,8336,8337],{},"    L --> P\n",[290,8339,8341],{"class":292,"line":8340},69,[290,8342,8343],{},"    M --> Q\n",[290,8345,8347],{"class":292,"line":8346},70,[290,8348,8349],{},"    N --> R\n",[290,8351,8353],{"class":292,"line":8352},71,[290,8354,8355],{},"    O --> S\n",[290,8357,8359],{"class":292,"line":8358},72,[290,8360,8361],{},"    P --> T\n",[290,8363,8365],{"class":292,"line":8364},73,[290,8366,721],{},[290,8368,8370],{"class":292,"line":8369},74,[290,8371,8372],{},"    classDef external fill:#3B82F6,stroke:#1E40AF,stroke-width:2px,color:#fff\n",[290,8374,8376],{"class":292,"line":8375},75,[290,8377,8378],{},"    classDef mcp fill:#8B5CF6,stroke:#7C3AED,stroke-width:2px,color:#fff\n",[290,8380,8382],{"class":292,"line":8381},76,[290,8383,8384],{},"    classDef api fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff\n",[290,8386,8388],{"class":292,"line":8387},77,[290,8389,8390],{},"    classDef service fill:#F59E0B,stroke:#D97706,stroke-width:2px,color:#fff\n",[290,8392,8394],{"class":292,"line":8393},78,[290,8395,8396],{},"    classDef data fill:#EF4444,stroke:#DC2626,stroke-width:2px,color:#fff\n",[290,8398,8400],{"class":292,"line":8399},79,[290,8401,721],{},[290,8403,8405],{"class":292,"line":8404},80,[290,8406,8407],{},"    class A,B,C external\n",[290,8409,8411],{"class":292,"line":8410},81,[290,8412,8413],{},"    class D,E,F,G,H mcp\n",[290,8415,8417],{"class":292,"line":8416},82,[290,8418,8419],{},"    class I,J,K,L api\n",[290,8421,8423],{"class":292,"line":8422},83,[290,8424,8425],{},"    class M,N,O,P service\n",[290,8427,8429],{"class":292,"line":8428},84,[290,8430,8431],{},"    class Q,R,S,T data\n",[102,8433,8435,8441],{"className":8434},[131,132,133],[135,8436,8438],{"id":8437},"_2-mcp-protocole-de-contexte-de-modèle",[110,8439,8440],{},"2. MCP - Protocole de Contexte de Modèle",[79,8442,8443],{},[82,8444,8445],{"href":145},[110,8446,148],{},[102,8448,8450],{"className":8449},[105],[79,8451,8452],{},"Le serveur MCP expose quatre outils spécialisés qui permettent aux chatbots d'interagir avec le système de maintenance de chaudières. Chaque outil est conçu avec une logique métier spécifique et des contrôles de sécurité.",[1612,8454,8456],{"id":8455},"outil-dinformation-de-chaudières","Outil d'Information de Chaudières",[281,8458,8460],{"className":616,"code":8459,"language":618,"meta":286,"style":286},"// Outil MCP: Obtenir les détails de chaudières du client et informations de garantie\nconst boilerInfoTool = {\n  name: \"boiler-info\",\n  description: \"Obtenir les informations de chaudières du client et détails de garantie\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      customer_id: { type: \"string\" }\n    },\n    required: [\"customer_id\"]\n  }\n}\n",[261,8461,8462,8467,8478,8494,8510,8519,8535,8544,8568,8573,8592,8596],{"__ignoreMap":286},[290,8463,8464],{"class":292,"line":293},[290,8465,8466],{"class":625},"// Outil MCP: Obtenir les détails de chaudières du client et informations de garantie\n",[290,8468,8469,8471,8474,8476],{"class":292,"line":299},[290,8470,2991],{"class":631},[290,8472,8473],{"class":691}," boilerInfoTool ",[290,8475,2997],{"class":639},[290,8477,640],{"class":639},[290,8479,8480,8483,8485,8487,8490,8492],{"class":292,"line":305},[290,8481,8482],{"class":648},"  name",[290,8484,659],{"class":639},[290,8486,954],{"class":639},[290,8488,8489],{"class":813},"boiler-info",[290,8491,911],{"class":639},[290,8493,820],{"class":639},[290,8495,8496,8499,8501,8503,8506,8508],{"class":292,"line":311},[290,8497,8498],{"class":648},"  description",[290,8500,659],{"class":639},[290,8502,954],{"class":639},[290,8504,8505],{"class":813},"Obtenir les informations de chaudières du client et détails de garantie",[290,8507,911],{"class":639},[290,8509,820],{"class":639},[290,8511,8512,8515,8517],{"class":292,"line":317},[290,8513,8514],{"class":648},"  inputSchema",[290,8516,659],{"class":639},[290,8518,640],{"class":639},[290,8520,8521,8524,8526,8528,8531,8533],{"class":292,"line":324},[290,8522,8523],{"class":648},"    type",[290,8525,659],{"class":639},[290,8527,954],{"class":639},[290,8529,8530],{"class":813},"object",[290,8532,911],{"class":639},[290,8534,820],{"class":639},[290,8536,8537,8540,8542],{"class":292,"line":330},[290,8538,8539],{"class":648},"    properties",[290,8541,659],{"class":639},[290,8543,640],{"class":639},[290,8545,8546,8549,8551,8553,8556,8558,8560,8563,8565],{"class":292,"line":336},[290,8547,8548],{"class":648},"      customer_id",[290,8550,659],{"class":639},[290,8552,2963],{"class":639},[290,8554,8555],{"class":648}," type",[290,8557,659],{"class":639},[290,8559,954],{"class":639},[290,8561,8562],{"class":813},"string",[290,8564,911],{"class":639},[290,8566,8567],{"class":639}," }\n",[290,8569,8570],{"class":292,"line":342},[290,8571,8572],{"class":639},"    },\n",[290,8574,8575,8578,8580,8582,8584,8587,8589],{"class":292,"line":347},[290,8576,8577],{"class":648},"    required",[290,8579,659],{"class":639},[290,8581,916],{"class":691},[290,8583,911],{"class":639},[290,8585,8586],{"class":813},"customer_id",[290,8588,911],{"class":639},[290,8590,8591],{"class":691},"]\n",[290,8593,8594],{"class":292,"line":353},[290,8595,872],{"class":639},[290,8597,8598],{"class":292,"line":359},[290,8599,1181],{"class":639},[79,8601,8602,8605],{},[110,8603,8604],{},"Cas d'Usage",": Quand un client demande \"Quel est le statut de garantie de ma chaudière?\", le chatbot peut récupérer des informations détaillées sur son modèle de chaudière spécifique, date d'installation, couverture de garantie et historique de maintenance.",[1612,8607,8609],{"id":8608},"outil-de-planification-de-maintenance","Outil de Planification de Maintenance",[281,8611,8613],{"className":616,"code":8612,"language":618,"meta":286,"style":286},"// Outil MCP: Planifier les services de maintenance avec considération météo\nconst maintenanceTool = {\n  name: \"maintenance\",\n  description: \"Planifier les services de maintenance\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      customer_id: { type: \"string\" },\n      service_type: { type: \"string\", enum: [\"routine\", \"emergency\"] },\n      preferred_date: { type: \"string\" }\n    },\n    required: [\"customer_id\", \"service_type\"]\n  }\n}\n",[261,8614,8615,8620,8631,8646,8661,8669,8683,8691,8712,8762,8783,8787,8812,8816],{"__ignoreMap":286},[290,8616,8617],{"class":292,"line":293},[290,8618,8619],{"class":625},"// Outil MCP: Planifier les services de maintenance avec considération météo\n",[290,8621,8622,8624,8627,8629],{"class":292,"line":299},[290,8623,2991],{"class":631},[290,8625,8626],{"class":691}," maintenanceTool ",[290,8628,2997],{"class":639},[290,8630,640],{"class":639},[290,8632,8633,8635,8637,8639,8642,8644],{"class":292,"line":305},[290,8634,8482],{"class":648},[290,8636,659],{"class":639},[290,8638,954],{"class":639},[290,8640,8641],{"class":813},"maintenance",[290,8643,911],{"class":639},[290,8645,820],{"class":639},[290,8647,8648,8650,8652,8654,8657,8659],{"class":292,"line":311},[290,8649,8498],{"class":648},[290,8651,659],{"class":639},[290,8653,954],{"class":639},[290,8655,8656],{"class":813},"Planifier les services de maintenance",[290,8658,911],{"class":639},[290,8660,820],{"class":639},[290,8662,8663,8665,8667],{"class":292,"line":317},[290,8664,8514],{"class":648},[290,8666,659],{"class":639},[290,8668,640],{"class":639},[290,8670,8671,8673,8675,8677,8679,8681],{"class":292,"line":324},[290,8672,8523],{"class":648},[290,8674,659],{"class":639},[290,8676,954],{"class":639},[290,8678,8530],{"class":813},[290,8680,911],{"class":639},[290,8682,820],{"class":639},[290,8684,8685,8687,8689],{"class":292,"line":330},[290,8686,8539],{"class":648},[290,8688,659],{"class":639},[290,8690,640],{"class":639},[290,8692,8693,8695,8697,8699,8701,8703,8705,8707,8709],{"class":292,"line":336},[290,8694,8548],{"class":648},[290,8696,659],{"class":639},[290,8698,2963],{"class":639},[290,8700,8555],{"class":648},[290,8702,659],{"class":639},[290,8704,954],{"class":639},[290,8706,8562],{"class":813},[290,8708,911],{"class":639},[290,8710,8711],{"class":639}," },\n",[290,8713,8714,8717,8719,8721,8723,8725,8727,8729,8731,8733,8736,8738,8740,8742,8745,8747,8749,8751,8754,8756,8759],{"class":292,"line":342},[290,8715,8716],{"class":648},"      service_type",[290,8718,659],{"class":639},[290,8720,2963],{"class":639},[290,8722,8555],{"class":648},[290,8724,659],{"class":639},[290,8726,954],{"class":639},[290,8728,8562],{"class":813},[290,8730,911],{"class":639},[290,8732,665],{"class":639},[290,8734,8735],{"class":648}," enum",[290,8737,659],{"class":639},[290,8739,916],{"class":691},[290,8741,911],{"class":639},[290,8743,8744],{"class":813},"routine",[290,8746,911],{"class":639},[290,8748,665],{"class":639},[290,8750,954],{"class":639},[290,8752,8753],{"class":813},"emergency",[290,8755,911],{"class":639},[290,8757,8758],{"class":691},"] ",[290,8760,8761],{"class":639},"},\n",[290,8763,8764,8767,8769,8771,8773,8775,8777,8779,8781],{"class":292,"line":347},[290,8765,8766],{"class":648},"      preferred_date",[290,8768,659],{"class":639},[290,8770,2963],{"class":639},[290,8772,8555],{"class":648},[290,8774,659],{"class":639},[290,8776,954],{"class":639},[290,8778,8562],{"class":813},[290,8780,911],{"class":639},[290,8782,8567],{"class":639},[290,8784,8785],{"class":292,"line":353},[290,8786,8572],{"class":639},[290,8788,8789,8791,8793,8795,8797,8799,8801,8803,8805,8808,8810],{"class":292,"line":359},[290,8790,8577],{"class":648},[290,8792,659],{"class":639},[290,8794,916],{"class":691},[290,8796,911],{"class":639},[290,8798,8586],{"class":813},[290,8800,911],{"class":639},[290,8802,665],{"class":639},[290,8804,954],{"class":639},[290,8806,8807],{"class":813},"service_type",[290,8809,911],{"class":639},[290,8811,8591],{"class":691},[290,8813,8814],{"class":292,"line":365},[290,8815,872],{"class":639},[290,8817,8818],{"class":292,"line":370},[290,8819,1181],{"class":639},[79,8821,8822,8824],{},[110,8823,8604],{},": Les clients peuvent demander la planification de maintenance, et le système considère automatiquement les conditions météorologiques, la disponibilité des techniciens et les préférences client pour réserver des rendez-vous optimaux.",[1612,8826,8828],{"id":8827},"outil-de-traitement-dachat","Outil de Traitement d'Achat",[281,8830,8832],{"className":616,"code":8831,"language":618,"meta":286,"style":286},"// Outil MCP: Traiter les commandes d'achat de chaudières\nconst purchaseTool = {\n  name: \"purchase\",\n  description: \"Traiter les commandes d'achat de chaudières\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      customer_id: { type: \"string\" },\n      boiler_model: { type: \"string\" },\n      installation_date: { type: \"string\" }\n    },\n    required: [\"customer_id\", \"boiler_model\"]\n  }\n}\n",[261,8833,8834,8839,8850,8865,8880,8888,8902,8910,8930,8951,8972,8976,9001,9005],{"__ignoreMap":286},[290,8835,8836],{"class":292,"line":293},[290,8837,8838],{"class":625},"// Outil MCP: Traiter les commandes d'achat de chaudières\n",[290,8840,8841,8843,8846,8848],{"class":292,"line":299},[290,8842,2991],{"class":631},[290,8844,8845],{"class":691}," purchaseTool ",[290,8847,2997],{"class":639},[290,8849,640],{"class":639},[290,8851,8852,8854,8856,8858,8861,8863],{"class":292,"line":305},[290,8853,8482],{"class":648},[290,8855,659],{"class":639},[290,8857,954],{"class":639},[290,8859,8860],{"class":813},"purchase",[290,8862,911],{"class":639},[290,8864,820],{"class":639},[290,8866,8867,8869,8871,8873,8876,8878],{"class":292,"line":311},[290,8868,8498],{"class":648},[290,8870,659],{"class":639},[290,8872,954],{"class":639},[290,8874,8875],{"class":813},"Traiter les commandes d'achat de chaudières",[290,8877,911],{"class":639},[290,8879,820],{"class":639},[290,8881,8882,8884,8886],{"class":292,"line":317},[290,8883,8514],{"class":648},[290,8885,659],{"class":639},[290,8887,640],{"class":639},[290,8889,8890,8892,8894,8896,8898,8900],{"class":292,"line":324},[290,8891,8523],{"class":648},[290,8893,659],{"class":639},[290,8895,954],{"class":639},[290,8897,8530],{"class":813},[290,8899,911],{"class":639},[290,8901,820],{"class":639},[290,8903,8904,8906,8908],{"class":292,"line":330},[290,8905,8539],{"class":648},[290,8907,659],{"class":639},[290,8909,640],{"class":639},[290,8911,8912,8914,8916,8918,8920,8922,8924,8926,8928],{"class":292,"line":336},[290,8913,8548],{"class":648},[290,8915,659],{"class":639},[290,8917,2963],{"class":639},[290,8919,8555],{"class":648},[290,8921,659],{"class":639},[290,8923,954],{"class":639},[290,8925,8562],{"class":813},[290,8927,911],{"class":639},[290,8929,8711],{"class":639},[290,8931,8932,8935,8937,8939,8941,8943,8945,8947,8949],{"class":292,"line":342},[290,8933,8934],{"class":648},"      boiler_model",[290,8936,659],{"class":639},[290,8938,2963],{"class":639},[290,8940,8555],{"class":648},[290,8942,659],{"class":639},[290,8944,954],{"class":639},[290,8946,8562],{"class":813},[290,8948,911],{"class":639},[290,8950,8711],{"class":639},[290,8952,8953,8956,8958,8960,8962,8964,8966,8968,8970],{"class":292,"line":347},[290,8954,8955],{"class":648},"      installation_date",[290,8957,659],{"class":639},[290,8959,2963],{"class":639},[290,8961,8555],{"class":648},[290,8963,659],{"class":639},[290,8965,954],{"class":639},[290,8967,8562],{"class":813},[290,8969,911],{"class":639},[290,8971,8567],{"class":639},[290,8973,8974],{"class":292,"line":353},[290,8975,8572],{"class":639},[290,8977,8978,8980,8982,8984,8986,8988,8990,8992,8994,8997,8999],{"class":292,"line":359},[290,8979,8577],{"class":648},[290,8981,659],{"class":639},[290,8983,916],{"class":691},[290,8985,911],{"class":639},[290,8987,8586],{"class":813},[290,8989,911],{"class":639},[290,8991,665],{"class":639},[290,8993,954],{"class":639},[290,8995,8996],{"class":813},"boiler_model",[290,8998,911],{"class":639},[290,9000,8591],{"class":691},[290,9002,9003],{"class":292,"line":365},[290,9004,872],{"class":639},[290,9006,9007],{"class":292,"line":370},[290,9008,1181],{"class":639},[79,9010,9011,9013],{},[110,9012,8604],{},": Quand les clients veulent mettre à niveau leur chaudière, le chatbot peut montrer les modèles disponibles, comparer les spécifications, traiter les paiements et planifier l'installation.",[1612,9015,9017],{"id":9016},"outil-de-confirmation-par-email","Outil de Confirmation par Email",[281,9019,9021],{"className":616,"code":9020,"language":618,"meta":286,"style":286},"// Outil MCP: Envoyer des emails de confirmation\nconst emailTool = {\n  name: \"email\",\n  description: \"Envoyer des emails de confirmation\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      customer_id: { type: \"string\" },\n      email_type: { type: \"string\", enum: [\"maintenance\", \"purchase\", \"reminder\"] }\n    },\n    required: [\"customer_id\", \"email_type\"]\n  }\n}\n",[261,9022,9023,9028,9039,9054,9069,9077,9091,9099,9119,9173,9177,9202,9206],{"__ignoreMap":286},[290,9024,9025],{"class":292,"line":293},[290,9026,9027],{"class":625},"// Outil MCP: Envoyer des emails de confirmation\n",[290,9029,9030,9032,9035,9037],{"class":292,"line":299},[290,9031,2991],{"class":631},[290,9033,9034],{"class":691}," emailTool ",[290,9036,2997],{"class":639},[290,9038,640],{"class":639},[290,9040,9041,9043,9045,9047,9050,9052],{"class":292,"line":305},[290,9042,8482],{"class":648},[290,9044,659],{"class":639},[290,9046,954],{"class":639},[290,9048,9049],{"class":813},"email",[290,9051,911],{"class":639},[290,9053,820],{"class":639},[290,9055,9056,9058,9060,9062,9065,9067],{"class":292,"line":311},[290,9057,8498],{"class":648},[290,9059,659],{"class":639},[290,9061,954],{"class":639},[290,9063,9064],{"class":813},"Envoyer des emails de confirmation",[290,9066,911],{"class":639},[290,9068,820],{"class":639},[290,9070,9071,9073,9075],{"class":292,"line":317},[290,9072,8514],{"class":648},[290,9074,659],{"class":639},[290,9076,640],{"class":639},[290,9078,9079,9081,9083,9085,9087,9089],{"class":292,"line":324},[290,9080,8523],{"class":648},[290,9082,659],{"class":639},[290,9084,954],{"class":639},[290,9086,8530],{"class":813},[290,9088,911],{"class":639},[290,9090,820],{"class":639},[290,9092,9093,9095,9097],{"class":292,"line":330},[290,9094,8539],{"class":648},[290,9096,659],{"class":639},[290,9098,640],{"class":639},[290,9100,9101,9103,9105,9107,9109,9111,9113,9115,9117],{"class":292,"line":336},[290,9102,8548],{"class":648},[290,9104,659],{"class":639},[290,9106,2963],{"class":639},[290,9108,8555],{"class":648},[290,9110,659],{"class":639},[290,9112,954],{"class":639},[290,9114,8562],{"class":813},[290,9116,911],{"class":639},[290,9118,8711],{"class":639},[290,9120,9121,9124,9126,9128,9130,9132,9134,9136,9138,9140,9142,9144,9146,9148,9150,9152,9154,9156,9158,9160,9162,9164,9167,9169,9171],{"class":292,"line":342},[290,9122,9123],{"class":648},"      email_type",[290,9125,659],{"class":639},[290,9127,2963],{"class":639},[290,9129,8555],{"class":648},[290,9131,659],{"class":639},[290,9133,954],{"class":639},[290,9135,8562],{"class":813},[290,9137,911],{"class":639},[290,9139,665],{"class":639},[290,9141,8735],{"class":648},[290,9143,659],{"class":639},[290,9145,916],{"class":691},[290,9147,911],{"class":639},[290,9149,8641],{"class":813},[290,9151,911],{"class":639},[290,9153,665],{"class":639},[290,9155,954],{"class":639},[290,9157,8860],{"class":813},[290,9159,911],{"class":639},[290,9161,665],{"class":639},[290,9163,954],{"class":639},[290,9165,9166],{"class":813},"reminder",[290,9168,911],{"class":639},[290,9170,8758],{"class":691},[290,9172,1181],{"class":639},[290,9174,9175],{"class":292,"line":347},[290,9176,8572],{"class":639},[290,9178,9179,9181,9183,9185,9187,9189,9191,9193,9195,9198,9200],{"class":292,"line":353},[290,9180,8577],{"class":648},[290,9182,659],{"class":639},[290,9184,916],{"class":691},[290,9186,911],{"class":639},[290,9188,8586],{"class":813},[290,9190,911],{"class":639},[290,9192,665],{"class":639},[290,9194,954],{"class":639},[290,9196,9197],{"class":813},"email_type",[290,9199,911],{"class":639},[290,9201,8591],{"class":691},[290,9203,9204],{"class":292,"line":359},[290,9205,872],{"class":639},[290,9207,9208],{"class":292,"line":365},[290,9209,1181],{"class":639},[79,9211,9212,9214],{},[110,9213,8604],{},": Après toute réservation de service ou achat, le système envoie automatiquement des emails de confirmation appropriés avec des détails pertinents et les prochaines étapes.",[102,9216,9218,9224],{"className":9217},[131,132,133],[135,9219,9221],{"id":9220},"_3-scénarios-de-demo-et-flux",[110,9222,9223],{},"3. Scénarios de Demo et Flux",[79,9225,9226],{},[82,9227,9228],{"href":145},[110,9229,148],{},[102,9231,9233],{"className":9232},[105],[79,9234,9235],{},"Le projet MCP-in-Chat inclut des scénarios de demo complets qui montrent les modèles d'utilisation du monde réel et démontrent les capacités du système.",[1612,9237,9239],{"id":9238},"scénario-1-requête-dinformation-de-chaudière","Scénario 1: Requête d'Information de Chaudière",[79,9241,9242,9244],{},[110,9243,1982],{},": \"Quel est le statut de garantie de ma chaudière?\"",[79,9246,9247,659],{},[110,9248,9249],{},"Réponse du Chatbot",[281,9251,9255],{"className":9252,"code":9254,"language":3459},[9253],"language-text","Je vais vérifier les informations de votre chaudière immédiatement.\n\nSelon vos dossiers, vous avez une Worcester Bosch 8000 Style installée le 15 mars 2023. \nVotre garantie est valide jusqu'au 15 mars 2028 (garantie fabricant de 5 ans).\n\nDétails clés:\n- Modèle: Worcester Bosch 8000 Style 30kW\n- Date d'Installation: 15 mars 2023\n- Statut de Garantie: Actif (3 ans restants)\n- Dernier Service: 12 janvier 2024\n- Prochain Service: 12 janvier 2025\n\nVoulez-vous que je planifie votre service annuel ou vérifie s'il y a des réclamations de garantie?\n",[261,9256,9254],{"__ignoreMap":286},[1612,9258,9260],{"id":9259},"scénario-2-planification-de-maintenance","Scénario 2: Planification de Maintenance",[79,9262,9263,9265],{},[110,9264,1982],{},": \"J'ai besoin de planifier la maintenance de ma chaudière\"",[79,9267,9268,659],{},[110,9269,9249],{},[281,9271,9274],{"className":9272,"code":9273,"language":3459},[9253],"Je vais vous aider à planifier la maintenance de votre chaudière. Laissez-moi vérifier votre planning actuel et les créneaux disponibles.\n\nSelon votre localisation et préférences, j'ai trouvé ces rendez-vous disponibles:\n\nSemaine Prochaine:\n- Mardi 21 janvier: 9h00 - 11h00\n- Jeudi 23 janvier: 14h00 - 16h00\n\nLes prévisions météo montrent des conditions claires pour les deux jours. Votre technicien préféré, John Smith (enregistré Gas Safe), est disponible mardi.\n\nJe recommande mardi à 9h00. Le service inclura:\n- Inspection complète du système\n- Vérifications de sécurité\n- Tests d'efficacité\n- Nettoyage des filtres\n\nCoût: £120 (inclut pièces et main d'œuvre)\n\nDois-je réserver ce rendez-vous pour vous?\n",[261,9275,9273],{"__ignoreMap":286},[1612,9277,9279],{"id":9278},"scénario-3-achat-de-mise-à-niveau-de-chaudière","Scénario 3: Achat de Mise à Niveau de Chaudière",[79,9281,9282,9284],{},[110,9283,1982],{},": \"Je veux mettre à niveau ma chaudière vers un modèle plus efficace\"",[79,9286,9287,659],{},[110,9288,9249],{},[281,9290,9293],{"className":9291,"code":9292,"language":3459},[9253],"Excellent choix! Laissez-moi vous montrer les modèles les plus efficaces disponibles et vous aider avec la mise à niveau.\n\nChaudières Haute Efficacité Disponibles:\n\n1. **Worcester Bosch 8000 Style** (Classe A)\n   - Efficacité: 94%\n   - Prix: £2,800\n   - Garantie 10 ans\n   - Thermostat intelligent inclus\n\n2. **Vaillant ecoTEC plus** (Classe A)\n   - Efficacité: 92%\n   - Prix: £2,600\n   - Garantie 7 ans\n   - Design compact\n\n3. **Ideal Logic+** (Classe A)\n   - Efficacité: 90%\n   - Prix: £2,200\n   - Garantie 10 ans\n   - Certifié Quiet Mark\n\nBasé sur votre système actuel, je recommande la Worcester Bosch 8000 Style pour une efficacité et fiabilité maximales.\n\nVoulez-vous que je:\n1. Montre les spécifications détaillées\n2. Vérifie la disponibilité d'installation\n3. Traite l'achat\n4. Compare avec votre chaudière actuelle\n",[261,9294,9292],{"__ignoreMap":286},[102,9296,9298,9304],{"className":9297},[131,132,133],[135,9299,9301],{"id":9300},"_4-spécifications-techniques",[110,9302,9303],{},"4. Spécifications Techniques",[79,9305,9306],{},[82,9307,9308],{"href":145},[110,9309,148],{},[102,9311,9313],{"className":9312},[105],[79,9314,9315],{},"Le projet MCP-in-Chat implémente une architecture sophistiquée en couches qui assure la sécurité, l'évolutivité et la maintenabilité.",[1612,9317,9319],{"id":9318},"architecture-de-sécurité","Architecture de Sécurité",[281,9321,9323],{"className":283,"code":9322,"language":285,"meta":286,"style":286},"---\nheader: MCP Security Flow and Authentication\n---\nsequenceDiagram\n    participant Chatbot as External Chatbot\n    participant MCP as MCP Server\n    participant API as Backend API\n    participant Auth as Authentication\n    participant Service as Business Service\n    participant DB as Mock Database\n    \n    rect rgb(59, 130, 246)\n    note right of Chatbot: External Systems\n    Chatbot->>+MCP: Request with customer_id\n    end\n    \n    rect rgb(139, 92, 246)\n    note right of MCP: MCP Protocol Layer\n    MCP->>+API: API call with validation\n    end\n    \n    rect rgb(16, 185, 129)\n    note right of API: Security & API Layer\n    API->>+Auth: Verify authentication\n    Auth-->>-API: Authentication result\n    end\n    \n    rect rgb(245, 158, 11)\n    note right of Service: Business Logic Layer\n    API->>+Service: Process business logic\n    Service->>+DB: Query with access controls\n    end\n    \n    rect rgb(239, 68, 68)\n    note right of DB: Data Storage Layer\n    DB-->>-Service: Return filtered data\n    end\n    \n    rect rgb(245, 158, 11)\n    note right of Service: Business Logic Layer\n    Service-->>-API: Processed response\n    end\n    \n    rect rgb(16, 185, 129)\n    note right of API: Security & API Layer\n    API-->>-MCP: API response\n    end\n    \n    rect rgb(139, 92, 246)\n    note right of MCP: MCP Protocol Layer\n    MCP-->>-Chatbot: Formatted result\n    end\n    \n    Note over Chatbot,DB: Secure communication flow with\u003Cbr/>authentication at each layer\n",[261,9324,9325,9329,9334,9338,9342,9347,9352,9357,9362,9367,9372,9376,9381,9386,9391,9395,9399,9404,9409,9414,9418,9422,9427,9432,9437,9442,9446,9450,9455,9460,9465,9470,9474,9478,9483,9488,9493,9497,9501,9505,9509,9514,9518,9522,9526,9530,9535,9539,9543,9547,9551,9556,9560,9564],{"__ignoreMap":286},[290,9326,9327],{"class":292,"line":293},[290,9328,6615],{},[290,9330,9331],{"class":292,"line":299},[290,9332,9333],{},"header: MCP Security Flow and Authentication\n",[290,9335,9336],{"class":292,"line":305},[290,9337,6615],{},[290,9339,9340],{"class":292,"line":311},[290,9341,296],{},[290,9343,9344],{"class":292,"line":317},[290,9345,9346],{},"    participant Chatbot as External Chatbot\n",[290,9348,9349],{"class":292,"line":324},[290,9350,9351],{},"    participant MCP as MCP Server\n",[290,9353,9354],{"class":292,"line":330},[290,9355,9356],{},"    participant API as Backend API\n",[290,9358,9359],{"class":292,"line":336},[290,9360,9361],{},"    participant Auth as Authentication\n",[290,9363,9364],{"class":292,"line":342},[290,9365,9366],{},"    participant Service as Business Service\n",[290,9368,9369],{"class":292,"line":347},[290,9370,9371],{},"    participant DB as Mock Database\n",[290,9373,9374],{"class":292,"line":353},[290,9375,721],{},[290,9377,9378],{"class":292,"line":359},[290,9379,9380],{},"    rect rgb(59, 130, 246)\n",[290,9382,9383],{"class":292,"line":365},[290,9384,9385],{},"    note right of Chatbot: External Systems\n",[290,9387,9388],{"class":292,"line":370},[290,9389,9390],{},"    Chatbot->>+MCP: Request with customer_id\n",[290,9392,9393],{"class":292,"line":376},[290,9394,1383],{},[290,9396,9397],{"class":292,"line":382},[290,9398,721],{},[290,9400,9401],{"class":292,"line":387},[290,9402,9403],{},"    rect rgb(139, 92, 246)\n",[290,9405,9406],{"class":292,"line":393},[290,9407,9408],{},"    note right of MCP: MCP Protocol Layer\n",[290,9410,9411],{"class":292,"line":398},[290,9412,9413],{},"    MCP->>+API: API call with validation\n",[290,9415,9416],{"class":292,"line":404},[290,9417,1383],{},[290,9419,9420],{"class":292,"line":410},[290,9421,721],{},[290,9423,9424],{"class":292,"line":415},[290,9425,9426],{},"    rect rgb(16, 185, 129)\n",[290,9428,9429],{"class":292,"line":421},[290,9430,9431],{},"    note right of API: Security & API Layer\n",[290,9433,9434],{"class":292,"line":427},[290,9435,9436],{},"    API->>+Auth: Verify authentication\n",[290,9438,9439],{"class":292,"line":902},[290,9440,9441],{},"    Auth-->>-API: Authentication result\n",[290,9443,9444],{"class":292,"line":931},[290,9445,1383],{},[290,9447,9448],{"class":292,"line":975},[290,9449,721],{},[290,9451,9452],{"class":292,"line":1000},[290,9453,9454],{},"    rect rgb(245, 158, 11)\n",[290,9456,9457],{"class":292,"line":1020},[290,9458,9459],{},"    note right of Service: Business Logic Layer\n",[290,9461,9462],{"class":292,"line":1026},[290,9463,9464],{},"    API->>+Service: Process business logic\n",[290,9466,9467],{"class":292,"line":1031},[290,9468,9469],{},"    Service->>+DB: Query with access controls\n",[290,9471,9472],{"class":292,"line":1036},[290,9473,1383],{},[290,9475,9476],{"class":292,"line":1042},[290,9477,721],{},[290,9479,9480],{"class":292,"line":1064},[290,9481,9482],{},"    rect rgb(239, 68, 68)\n",[290,9484,9485],{"class":292,"line":1083},[290,9486,9487],{},"    note right of DB: Data Storage Layer\n",[290,9489,9490],{"class":292,"line":1110},[290,9491,9492],{},"    DB-->>-Service: Return filtered data\n",[290,9494,9495],{"class":292,"line":1120},[290,9496,1383],{},[290,9498,9499],{"class":292,"line":1127},[290,9500,721],{},[290,9502,9503],{"class":292,"line":1163},[290,9504,9454],{},[290,9506,9507],{"class":292,"line":1173},[290,9508,9459],{},[290,9510,9511],{"class":292,"line":1178},[290,9512,9513],{},"    Service-->>-API: Processed response\n",[290,9515,9516],{"class":292,"line":4857},[290,9517,1383],{},[290,9519,9520],{"class":292,"line":4863},[290,9521,721],{},[290,9523,9524],{"class":292,"line":4868},[290,9525,9426],{},[290,9527,9528],{"class":292,"line":4874},[290,9529,9431],{},[290,9531,9532],{"class":292,"line":4880},[290,9533,9534],{},"    API-->>-MCP: API response\n",[290,9536,9537],{"class":292,"line":4885},[290,9538,1383],{},[290,9540,9541],{"class":292,"line":4891},[290,9542,721],{},[290,9544,9545],{"class":292,"line":4897},[290,9546,9403],{},[290,9548,9549],{"class":292,"line":4903},[290,9550,9408],{},[290,9552,9553],{"class":292,"line":4909},[290,9554,9555],{},"    MCP-->>-Chatbot: Formatted result\n",[290,9557,9558],{"class":292,"line":4914},[290,9559,1383],{},[290,9561,9562],{"class":292,"line":4920},[290,9563,721],{},[290,9565,9566],{"class":292,"line":4925},[290,9567,9568],{},"    Note over Chatbot,DB: Secure communication flow with\u003Cbr/>authentication at each layer\n",[1612,9570,9572],{"id":9571},"implémentation-des-services-simulés","Implémentation des Services Simulés",[79,9574,9575],{},"Le projet inclut 8 services simulés complets qui simulent des opérations métier réelles:",[1625,9577,9578,9584,9590,9596,9602,9608,9614,9620],{},[163,9579,9580,9583],{},[110,9581,9582],{},"Service Client",": Gère les profils clients et préférences",[163,9585,9586,9589],{},[110,9587,9588],{},"Service Chaudières",": Gère les informations de chaudières et données de garantie",[163,9591,9592,9595],{},[110,9593,9594],{},"Service Paiement",": Traite les transactions et validation de paiements",[163,9597,9598,9601],{},[110,9599,9600],{},"Service Email",": Gère la communication et notifications",[163,9603,9604,9607],{},[110,9605,9606],{},"Service Météo",": Fournit les données météo pour la planification",[163,9609,9610,9613],{},[110,9611,9612],{},"Service Garantie",": Gère les informations de garantie et réclamations",[163,9615,9616,9619],{},[110,9617,9618],{},"Service Prédiction IA",": Simule les prédictions de maintenance",[163,9621,9622,9625],{},[110,9623,9624],{},"Service Technicien",": Gère la disponibilité et planification des techniciens",[1612,9627,9629],{"id":9628},"structure-de-couche-de-données","Structure de Couche de Données",[281,9631,9633],{"className":1735,"code":9632,"language":1737,"meta":286,"style":286},"{\n  \"customers\": {\n    \"CUST001\": {\n      \"name\": \"John Smith\",\n      \"email\": \"john.smith@email.com\",\n      \"address\": \"123 Main St, London\",\n      \"phone\": \"+44 20 1234 5678\",\n      \"preferences\": {\n        \"contact_method\": \"email\",\n        \"appointment_time\": \"morning\",\n        \"technician_preference\": \"John Smith\"\n      }\n    }\n  },\n  \"boilers\": {\n    \"BOIL001\": {\n      \"customer_id\": \"CUST001\",\n      \"model\": \"Worcester Bosch 8000 Style\",\n      \"installation_date\": \"2023-03-15\",\n      \"warranty_expiry\": \"2028-03-15\",\n      \"last_service\": \"2024-01-12\",\n      \"next_service_due\": \"2025-01-12\"\n    }\n  }\n}\n",[261,9634,9635,9639,9652,9665,9685,9704,9724,9744,9757,9777,9797,9814,9819,9823,9828,9841,9854,9872,9892,9912,9932,9952,9970,9974,9978],{"__ignoreMap":286},[290,9636,9637],{"class":292,"line":293},[290,9638,746],{"class":639},[290,9640,9641,9643,9646,9648,9650],{"class":292,"line":299},[290,9642,1753],{"class":639},[290,9644,9645],{"class":631},"customers",[290,9647,911],{"class":639},[290,9649,659],{"class":639},[290,9651,640],{"class":639},[290,9653,9654,9656,9659,9661,9663],{"class":292,"line":305},[290,9655,1767],{"class":639},[290,9657,9658],{"class":635},"CUST001",[290,9660,911],{"class":639},[290,9662,659],{"class":639},[290,9664,640],{"class":639},[290,9666,9667,9669,9672,9674,9676,9678,9681,9683],{"class":292,"line":311},[290,9668,905],{"class":639},[290,9670,9671],{"class":1077},"name",[290,9673,911],{"class":639},[290,9675,659],{"class":639},[290,9677,954],{"class":639},[290,9679,9680],{"class":813},"John Smith",[290,9682,911],{"class":639},[290,9684,820],{"class":639},[290,9686,9687,9689,9691,9693,9695,9697,9700,9702],{"class":292,"line":317},[290,9688,905],{"class":639},[290,9690,9049],{"class":1077},[290,9692,911],{"class":639},[290,9694,659],{"class":639},[290,9696,954],{"class":639},[290,9698,9699],{"class":813},"john.smith@email.com",[290,9701,911],{"class":639},[290,9703,820],{"class":639},[290,9705,9706,9708,9711,9713,9715,9717,9720,9722],{"class":292,"line":324},[290,9707,905],{"class":639},[290,9709,9710],{"class":1077},"address",[290,9712,911],{"class":639},[290,9714,659],{"class":639},[290,9716,954],{"class":639},[290,9718,9719],{"class":813},"123 Main St, London",[290,9721,911],{"class":639},[290,9723,820],{"class":639},[290,9725,9726,9728,9731,9733,9735,9737,9740,9742],{"class":292,"line":330},[290,9727,905],{"class":639},[290,9729,9730],{"class":1077},"phone",[290,9732,911],{"class":639},[290,9734,659],{"class":639},[290,9736,954],{"class":639},[290,9738,9739],{"class":813},"+44 20 1234 5678",[290,9741,911],{"class":639},[290,9743,820],{"class":639},[290,9745,9746,9748,9751,9753,9755],{"class":292,"line":336},[290,9747,905],{"class":639},[290,9749,9750],{"class":1077},"preferences",[290,9752,911],{"class":639},[290,9754,659],{"class":639},[290,9756,640],{"class":639},[290,9758,9759,9762,9765,9767,9769,9771,9773,9775],{"class":292,"line":342},[290,9760,9761],{"class":639},"        \"",[290,9763,9764],{"class":648},"contact_method",[290,9766,911],{"class":639},[290,9768,659],{"class":639},[290,9770,954],{"class":639},[290,9772,9049],{"class":813},[290,9774,911],{"class":639},[290,9776,820],{"class":639},[290,9778,9779,9781,9784,9786,9788,9790,9793,9795],{"class":292,"line":347},[290,9780,9761],{"class":639},[290,9782,9783],{"class":648},"appointment_time",[290,9785,911],{"class":639},[290,9787,659],{"class":639},[290,9789,954],{"class":639},[290,9791,9792],{"class":813},"morning",[290,9794,911],{"class":639},[290,9796,820],{"class":639},[290,9798,9799,9801,9804,9806,9808,9810,9812],{"class":292,"line":353},[290,9800,9761],{"class":639},[290,9802,9803],{"class":648},"technician_preference",[290,9805,911],{"class":639},[290,9807,659],{"class":639},[290,9809,954],{"class":639},[290,9811,9680],{"class":813},[290,9813,1017],{"class":639},[290,9815,9816],{"class":292,"line":359},[290,9817,9818],{"class":639},"      }\n",[290,9820,9821],{"class":292,"line":365},[290,9822,767],{"class":639},[290,9824,9825],{"class":292,"line":370},[290,9826,9827],{"class":639},"  },\n",[290,9829,9830,9832,9835,9837,9839],{"class":292,"line":376},[290,9831,1753],{"class":639},[290,9833,9834],{"class":631},"boilers",[290,9836,911],{"class":639},[290,9838,659],{"class":639},[290,9840,640],{"class":639},[290,9842,9843,9845,9848,9850,9852],{"class":292,"line":382},[290,9844,1767],{"class":639},[290,9846,9847],{"class":635},"BOIL001",[290,9849,911],{"class":639},[290,9851,659],{"class":639},[290,9853,640],{"class":639},[290,9855,9856,9858,9860,9862,9864,9866,9868,9870],{"class":292,"line":387},[290,9857,905],{"class":639},[290,9859,8586],{"class":1077},[290,9861,911],{"class":639},[290,9863,659],{"class":639},[290,9865,954],{"class":639},[290,9867,9658],{"class":813},[290,9869,911],{"class":639},[290,9871,820],{"class":639},[290,9873,9874,9876,9879,9881,9883,9885,9888,9890],{"class":292,"line":393},[290,9875,905],{"class":639},[290,9877,9878],{"class":1077},"model",[290,9880,911],{"class":639},[290,9882,659],{"class":639},[290,9884,954],{"class":639},[290,9886,9887],{"class":813},"Worcester Bosch 8000 Style",[290,9889,911],{"class":639},[290,9891,820],{"class":639},[290,9893,9894,9896,9899,9901,9903,9905,9908,9910],{"class":292,"line":398},[290,9895,905],{"class":639},[290,9897,9898],{"class":1077},"installation_date",[290,9900,911],{"class":639},[290,9902,659],{"class":639},[290,9904,954],{"class":639},[290,9906,9907],{"class":813},"2023-03-15",[290,9909,911],{"class":639},[290,9911,820],{"class":639},[290,9913,9914,9916,9919,9921,9923,9925,9928,9930],{"class":292,"line":404},[290,9915,905],{"class":639},[290,9917,9918],{"class":1077},"warranty_expiry",[290,9920,911],{"class":639},[290,9922,659],{"class":639},[290,9924,954],{"class":639},[290,9926,9927],{"class":813},"2028-03-15",[290,9929,911],{"class":639},[290,9931,820],{"class":639},[290,9933,9934,9936,9939,9941,9943,9945,9948,9950],{"class":292,"line":410},[290,9935,905],{"class":639},[290,9937,9938],{"class":1077},"last_service",[290,9940,911],{"class":639},[290,9942,659],{"class":639},[290,9944,954],{"class":639},[290,9946,9947],{"class":813},"2024-01-12",[290,9949,911],{"class":639},[290,9951,820],{"class":639},[290,9953,9954,9956,9959,9961,9963,9965,9968],{"class":292,"line":415},[290,9955,905],{"class":639},[290,9957,9958],{"class":1077},"next_service_due",[290,9960,911],{"class":639},[290,9962,659],{"class":639},[290,9964,954],{"class":639},[290,9966,9967],{"class":813},"2025-01-12",[290,9969,1017],{"class":639},[290,9971,9972],{"class":292,"line":421},[290,9973,767],{"class":639},[290,9975,9976],{"class":292,"line":427},[290,9977,872],{"class":639},[290,9979,9980],{"class":292,"line":902},[290,9981,1181],{"class":639},[79,9983,9984,9987],{},[110,9985,9986],{},"Aperçu de la Structure de Données",": Le système utilise des fichiers JSON pour simuler une vraie base de données, avec des données structurées pour les clients, chaudières, planning de maintenance et commandes. Chaque enregistrement inclut des informations complètes nécessaires pour les interactions du chatbot.",[102,9989,9991,9997],{"className":9990},[131,132,133],[135,9992,9994],{"id":9993},"_5-tests-et-assurance-qualité",[110,9995,9996],{},"5. Tests et Assurance Qualité",[79,9998,9999],{},[82,10000,10001],{"href":145},[110,10002,148],{},[102,10004,10006],{"className":10005},[105],[79,10007,10008],{},"Le projet MCP-in-Chat inclut une suite de tests complète qui assure la fiabilité et la fonctionnalité dans tous les composants.",[1612,10010,10012],{"id":10011},"couverture-de-tests","Couverture de Tests",[160,10014,10015,10021,10027,10033,10039],{},[163,10016,10017,10020],{},[110,10018,10019],{},"Outils MCP",": Tous les 4 outils testés avec divers scénarios d'entrée",[163,10022,10023,10026],{},[110,10024,10025],{},"Endpoints API",": Tests complets d'API REST avec authentification",[163,10028,10029,10032],{},[110,10030,10031],{},"Gestion d'Erreurs",": Validation des réponses d'erreur et cas limites",[163,10034,10035,10038],{},[110,10036,10037],{},"Intégration",": Tests de flux de travail de bout en bout",[163,10040,10041,10044],{},[110,10042,10043],{},"Performance",": Tests de temps de réponse et charge",[1612,10046,10048],{"id":10047},"résumé-des-résultats-de-tests","Résumé des Résultats de Tests",[281,10050,10053],{"className":10051,"code":10052,"language":3459},[9253],"📊 RÉSUMÉ DES TESTS\n============================================================\nTotal des Tests: 5\nRéussis: 5 ✅\nÉchoués: 0 ❌\nTaux de Succès: 100.0%\n\n📋 RÉSULTATS DÉTAILLÉS\n------------------------------------------------------------\n1. boiler-info: ✅ RÉUSSI\n2. maintenance-get: ✅ RÉUSSI\n3. maintenance-schedule: ✅ RÉUSSI\n4. purchase: ✅ RÉUSSI\n5. email: ✅ RÉUSSI\n\n🎉 Tous les tests ont réussi! Les outils MCP fonctionnent correctement.\n",[261,10054,10052],{"__ignoreMap":286},[1612,10056,10058],{"id":10057},"commandes-de-test-rapide","Commandes de Test Rapide",[281,10060,10062],{"className":3325,"code":10061,"language":3327,"meta":286,"style":286},"# Exécuter tous les tests d'outils MCP\nnpm test\n\n# Tester des composants spécifiques\nnpm run test:api          # Tests API backend\nnpm run test:mcp          # Intégration MCP Cursor\nnpm run test:protocol     # Validation protocole MCP\nnpm run test:compiled     # Test version compilée\nnpm run test:connection   # Test connexion\nnpm run test:quick        # Vérification rapide santé\n",[261,10063,10064,10069,10077,10081,10086,10099,10111,10123,10135,10147],{"__ignoreMap":286},[290,10065,10066],{"class":292,"line":293},[290,10067,10068],{"class":625},"# Exécuter tous les tests d'outils MCP\n",[290,10070,10071,10074],{"class":292,"line":299},[290,10072,10073],{"class":635},"npm",[290,10075,10076],{"class":813}," test\n",[290,10078,10079],{"class":292,"line":305},[290,10080,321],{"emptyLinePlaceholder":320},[290,10082,10083],{"class":292,"line":311},[290,10084,10085],{"class":625},"# Tester des composants spécifiques\n",[290,10087,10088,10090,10093,10096],{"class":292,"line":317},[290,10089,10073],{"class":635},[290,10091,10092],{"class":813}," run",[290,10094,10095],{"class":813}," test:api",[290,10097,10098],{"class":625},"          # Tests API backend\n",[290,10100,10101,10103,10105,10108],{"class":292,"line":324},[290,10102,10073],{"class":635},[290,10104,10092],{"class":813},[290,10106,10107],{"class":813}," test:mcp",[290,10109,10110],{"class":625},"          # Intégration MCP Cursor\n",[290,10112,10113,10115,10117,10120],{"class":292,"line":330},[290,10114,10073],{"class":635},[290,10116,10092],{"class":813},[290,10118,10119],{"class":813}," test:protocol",[290,10121,10122],{"class":625},"     # Validation protocole MCP\n",[290,10124,10125,10127,10129,10132],{"class":292,"line":336},[290,10126,10073],{"class":635},[290,10128,10092],{"class":813},[290,10130,10131],{"class":813}," test:compiled",[290,10133,10134],{"class":625},"     # Test version compilée\n",[290,10136,10137,10139,10141,10144],{"class":292,"line":342},[290,10138,10073],{"class":635},[290,10140,10092],{"class":813},[290,10142,10143],{"class":813}," test:connection",[290,10145,10146],{"class":625},"   # Test connexion\n",[290,10148,10149,10151,10153,10156],{"class":292,"line":347},[290,10150,10073],{"class":635},[290,10152,10092],{"class":813},[290,10154,10155],{"class":813}," test:quick",[290,10157,10158],{"class":625},"        # Vérification rapide santé\n",[102,10160,10162,10168],{"className":10161},[131,132,133],[135,10163,10165],{"id":10164},"_6-commencer",[110,10166,10167],{},"6. Commencer",[79,10169,10170],{},[82,10171,10172],{"href":145},[110,10173,148],{},[102,10175,10177],{"className":10176},[105],[79,10178,10179],{},"Le projet MCP-in-Chat est conçu pour être facilement accessible aux développeurs qui veulent comprendre et implémenter des serveurs MCP pour leurs propres cas d'usage.",[1612,10181,10183],{"id":10182},"prérequis","Prérequis",[160,10185,10186,10189,10192,10195],{},[163,10187,10188],{},"Node.js 18+ et npm",[163,10190,10191],{},"Connaissance de TypeScript",[163,10193,10194],{},"Compréhension de base du protocole MCP",[163,10196,10197],{},"Accès aux chatbots externes (Claude, ChatGPT, Cursor)",[1612,10199,10201],{"id":10200},"installation","Installation",[281,10203,10205],{"className":3325,"code":10204,"language":3327,"meta":286,"style":286},"# Cloner le repository\ngit clone https://github.com/michaelwybraniec/mcp-in-chat.git\ncd mcp-in-chat\n\n# Installer les dépendances\nnpm install\n\n# Construire le projet\nnpm run build\n\n# Démarrer le serveur API\nnpm run start:api\n\n# Démarrer le serveur MCP (dans un autre terminal)\nnpm run start:mcp\n",[261,10206,10207,10212,10223,10230,10234,10238,10245,10249,10254,10263,10267,10272,10281,10285,10290],{"__ignoreMap":286},[290,10208,10209],{"class":292,"line":293},[290,10210,10211],{"class":625},"# Cloner le repository\n",[290,10213,10214,10217,10220],{"class":292,"line":299},[290,10215,10216],{"class":635},"git",[290,10218,10219],{"class":813}," clone",[290,10221,10222],{"class":813}," https://github.com/michaelwybraniec/mcp-in-chat.git\n",[290,10224,10225,10227],{"class":292,"line":305},[290,10226,3347],{"class":705},[290,10228,10229],{"class":813}," mcp-in-chat\n",[290,10231,10232],{"class":292,"line":311},[290,10233,321],{"emptyLinePlaceholder":320},[290,10235,10236],{"class":292,"line":317},[290,10237,3398],{"class":625},[290,10239,10240,10242],{"class":292,"line":324},[290,10241,10073],{"class":635},[290,10243,10244],{"class":813}," install\n",[290,10246,10247],{"class":292,"line":330},[290,10248,321],{"emptyLinePlaceholder":320},[290,10250,10251],{"class":292,"line":336},[290,10252,10253],{"class":625},"# Construire le projet\n",[290,10255,10256,10258,10260],{"class":292,"line":342},[290,10257,10073],{"class":635},[290,10259,10092],{"class":813},[290,10261,10262],{"class":813}," build\n",[290,10264,10265],{"class":292,"line":347},[290,10266,321],{"emptyLinePlaceholder":320},[290,10268,10269],{"class":292,"line":353},[290,10270,10271],{"class":625},"# Démarrer le serveur API\n",[290,10273,10274,10276,10278],{"class":292,"line":359},[290,10275,10073],{"class":635},[290,10277,10092],{"class":813},[290,10279,10280],{"class":813}," start:api\n",[290,10282,10283],{"class":292,"line":365},[290,10284,321],{"emptyLinePlaceholder":320},[290,10286,10287],{"class":292,"line":370},[290,10288,10289],{"class":625},"# Démarrer le serveur MCP (dans un autre terminal)\n",[290,10291,10292,10294,10296],{"class":292,"line":376},[290,10293,10073],{"class":635},[290,10295,10092],{"class":813},[290,10297,10298],{"class":813}," start:mcp\n",[1612,10300,10302],{"id":10301},"intégration-avec-chatbots-externes","Intégration avec Chatbots Externes",[79,10304,10305],{},"Le serveur MCP est conçu pour fonctionner avec n'importe quel chatbot compatible MCP:",[1625,10307,10308,10314,10320],{},[163,10309,10310,10313],{},[110,10311,10312],{},"Claude Desktop",": Ajouter le serveur MCP à la configuration de Claude",[163,10315,10316,10319],{},[110,10317,10318],{},"ChatGPT",": Utiliser le serveur MCP comme outil personnalisé",[163,10321,10322,10325],{},[110,10323,10324],{},"Cursor IDE",": Intégrer directement avec l'environnement de développement",[1612,10327,10329],{"id":10328},"personnalisation","Personnalisation",[79,10331,10332],{},"Le projet est conçu pour être facilement personnalisable pour différents domaines métier:",[1625,10334,10335,10341,10347,10353],{},[163,10336,10337,10340],{},[110,10338,10339],{},"Remplacer les Services Simulés",": Connecter aux APIs et bases de données réelles",[163,10342,10343,10346],{},[110,10344,10345],{},"Ajouter de Nouveaux Outils",": Étendre le serveur MCP avec fonctionnalité supplémentaire",[163,10348,10349,10352],{},[110,10350,10351],{},"Modifier la Logique Métier",": Adapter les services pour votre cas d'usage spécifique",[163,10354,10355,10358],{},[110,10356,10357],{},"Améliorer la Sécurité",": Ajouter des couches supplémentaires d'authentification et autorisation",[102,10360,10362,10368],{"className":10361},[131,132,133],[135,10363,10365],{"id":10364},"_7-leçons-apprises",[110,10366,10367],{},"7. Leçons Apprises",[79,10369,10370],{},[82,10371,10372],{"href":145},[110,10373,148],{},[102,10375,10377],{"className":10376},[105],[79,10378,10379],{},"Le projet MCP-in-Chat fournit des insights précieux sur la construction de serveurs MCP prêts pour la production et leur intégration avec des chatbots externes.",[1612,10381,10383],{"id":10382},"facteurs-clés-de-succès","Facteurs Clés de Succès",[1625,10385,10386,10392,10398,10404,10409],{},[163,10387,10388,10391],{},[110,10389,10390],{},"Architecture en Couches",": Séparation claire entre outils MCP, couche API et logique métier",[163,10393,10394,10397],{},[110,10395,10396],{},"Tests Complets",": 100% de couverture de tests assure la fiabilité",[163,10399,10400,10403],{},[110,10401,10402],{},"Sécurité en Premier",": Authentification, validation et limitation de débit dès le début",[163,10405,10406,10408],{},[110,10407,7847],{},": Documentation complète pour une intégration facile",[163,10410,10411,10414],{},[110,10412,10413],{},"Services Simulés",": Simulation de données réaliste pour développement et tests",[1612,10416,10418],{"id":10417},"défis-communs-et-solutions","Défis Communs et Solutions",[1625,10420,10421,10439,10456,10473],{},[163,10422,10423,10426],{},[110,10424,10425],{},"Complexité d'Intégration Externe",[160,10427,10428,10434],{},[163,10429,10430,10433],{},[110,10431,10432],{},"Défi",": Tester avec des chatbots externes peut être difficile",[163,10435,10436,10438],{},[110,10437,2469],{},": Suite de tests locaux complète avec scénarios réalistes",[163,10440,10441,10444],{},[110,10442,10443],{},"Implémentation de Sécurité",[160,10445,10446,10451],{},[163,10447,10448,10450],{},[110,10449,10432],{},": Assurer une communication sécurisée entre composants",[163,10452,10453,10455],{},[110,10454,2469],{},": Sécurité en couches avec authentification à chaque niveau",[163,10457,10458,10461],{},[110,10459,10460],{},"Gestion des Données",[160,10462,10463,10468],{},[163,10464,10465,10467],{},[110,10466,10432],{},": Maintenir un état cohérent entre services",[163,10469,10470,10472],{},[110,10471,2469],{},": Couche de données centralisée avec contrôles d'accès",[163,10474,10475,10477],{},[110,10476,10031],{},[160,10478,10479,10484],{},[163,10480,10481,10483],{},[110,10482,10432],{},": Gestion élégante des erreurs dans les interfaces conversationnelles",[163,10485,10486,10488],{},[110,10487,2469],{},": Réponses d'erreur structurées avec orientation actionnable",[1612,10490,10492],{"id":10491},"considérations-de-performance","Considérations de Performance",[160,10494,10495,10501,10507,10513],{},[163,10496,10497,10500],{},[110,10498,10499],{},"Temps de Réponse",": Les outils MCP doivent répondre en 2-3 secondes",[163,10502,10503,10506],{},[110,10504,10505],{},"Limitation de Débit",": Implémenter des limites de débit appropriées pour prévenir l'abus",[163,10508,10509,10512],{},[110,10510,10511],{},"Cache",": Mettre en cache les données fréquemment accédées pour améliorer les performances",[163,10514,10515,10518],{},[110,10516,10517],{},"Monitoring",": Implémenter logging et monitoring complets",[102,10520,10522,10528],{"className":10521},[131,132,133],[135,10523,10525],{"id":10524},"_8-améliorations-futures",[110,10526,10527],{},"8. Améliorations Futures",[79,10529,10530],{},[82,10531,10532],{"href":145},[110,10533,148],{},[102,10535,10537],{"className":10536},[105],[79,10538,10539],{},"Le projet MCP-in-Chat sert de base pour des implémentations plus sophistiquées de serveurs MCP et fournit une feuille de route pour le développement futur.",[1612,10541,10543],{"id":10542},"améliorations-planifiées","Améliorations Planifiées",[1625,10545,10546,10565,10584,10603],{},[163,10547,10548,10551],{},[110,10549,10550],{},"Intégration de Services Réels",[160,10552,10553,10556,10559,10562],{},[163,10554,10555],{},"Remplacer les services simulés par des APIs réelles",[163,10557,10558],{},"Intégrer avec des passerelles de paiement",[163,10560,10561],{},"Connecter aux bases de données clients",[163,10563,10564],{},"Implémenter des services email réels",[163,10566,10567,10570],{},[110,10568,10569],{},"Fonctionnalités Avancées",[160,10571,10572,10575,10578,10581],{},[163,10573,10574],{},"Support multilingue",[163,10576,10577],{},"Intégration vocale",[163,10579,10580],{},"Intégration d'application mobile",[163,10582,10583],{},"Analyses avancées et rapports",[163,10585,10586,10589],{},[110,10587,10588],{},"Améliorations d'Évolutivité",[160,10590,10591,10594,10597,10600],{},[163,10592,10593],{},"Architecture de microservices",[163,10595,10596],{},"Équilibrage de charge",[163,10598,10599],{},"Optimisation de base de données",[163,10601,10602],{},"Stratégies de cache",[163,10604,10605,10608],{},[110,10606,10607],{},"Améliorations de Sécurité",[160,10609,10610,10613,10616,10619],{},[163,10611,10612],{},"Intégration OAuth 2.0",[163,10614,10615],{},"Contrôle d'accès basé sur les rôles",[163,10617,10618],{},"Logging d'audit",[163,10620,10621],{},"Fonctionnalités de conformité",[1612,10623,10625],{"id":10624},"applications-dindustrie","Applications d'Industrie",[79,10627,10628],{},"L'architecture MCP-in-Chat peut être adaptée pour diverses industries:",[1625,10630,10631,10637,10643,10649,10655],{},[163,10632,10633,10636],{},[110,10634,10635],{},"Santé",": Planification de rendez-vous patients et accès aux dossiers médicaux",[163,10638,10639,10642],{},[110,10640,10641],{},"Finance",": Gestion de comptes et traitement de transactions",[163,10644,10645,10648],{},[110,10646,10647],{},"Éducation",": Inscription aux cours et services étudiants",[163,10650,10651,10654],{},[110,10652,10653],{},"Immobilier",": Recherche de propriétés et gestion de réservations",[163,10656,10657,10660],{},[110,10658,10659],{},"Voyage",": Réservation de vols et gestion d'itinéraires",[102,10662,10664,10670],{"className":10663},[131,132,133],[135,10665,10667],{"id":10666},"_9-conclusion",[110,10668,10669],{},"9. Conclusion",[79,10671,10672],{},[82,10673,10674],{"href":145},[110,10675,148],{},[102,10677,10679],{"className":10678},[105],[79,10680,10681],{},"Le projet MCP-in-Chat démontre le pouvoir et le potentiel des serveurs du Protocole de Contexte de Modèle dans la création de systèmes d'IA conversationnelle sophistiqués. En fournissant un exemple complet et prêt pour la production, il sert à la fois de ressource d'apprentissage et de base pour des implémentations du monde réel.",[1612,10683,6398],{"id":6395},[1625,10685,10686,10692,10698,10704,10710],{},[163,10687,10688,10691],{},[110,10689,10690],{},"Les Serveurs MCP Permettent une Valeur Commerciale Réelle",": Le projet montre comment les serveurs MCP peuvent connecter l'IA conversationnelle aux systèmes d'entreprise",[163,10693,10694,10697],{},[110,10695,10696],{},"Le Développement Systématique Fonctionne",": La méthodologie AWP a assuré un développement cohérent et de haute qualité",[163,10699,10700,10703],{},[110,10701,10702],{},"La Sécurité est Primordiale",": L'architecture de sécurité en couches est essentielle pour les systèmes de production",[163,10705,10706,10709],{},[110,10707,10708],{},"Les Tests sont Critiques",": Les tests complets assurent la fiabilité et la fonctionnalité",[163,10711,10712,10715],{},[110,10713,10714],{},"La Documentation Compte",": La documentation complète permet une adoption et personnalisation faciles",[1612,10717,10718],{"id":7248},"Prochaines Étapes",[79,10720,10721],{},"Pour les développeurs intéressés par les serveurs MCP:",[1625,10723,10724,10735,10741,10747],{},[163,10725,10726,10729,10730,10734],{},[110,10727,10728],{},"Étudier le Code",": Examiner le ",[82,10731,10733],{"href":7765,"rel":10732},[99],"repository MCP-in-Chat"," pour comprendre l'implémentation",[163,10736,10737,10740],{},[110,10738,10739],{},"Exécuter le Demo",": Configurer le projet localement et tester avec des chatbots externes",[163,10742,10743,10746],{},[110,10744,10745],{},"Personnaliser",": Adapter l'architecture pour votre cas d'usage spécifique",[163,10748,10749,10752],{},[110,10750,10751],{},"Contribuer",": Partager les améliorations et améliorations avec la communauté",[79,10754,10755],{},"Le projet MCP-in-Chat représente un pas significatif vers l'avant dans la réalisation des serveurs MCP accessibles et pratiques pour les applications du monde réel. En fournissant un exemple complet et fonctionnel, il réduit la barrière d'entrée pour les développeurs qui veulent intégrer l'IA conversationnelle avec leurs systèmes métier.",[4983,10757],{},[79,10759,10760,659],{},[110,10761,2719],{},[160,10763,10764,10770,10777],{},[163,10765,10766],{},[82,10767,10769],{"href":7765,"rel":10768},[99],"Repository MCP-in-Chat",[163,10771,10772],{},[82,10773,10776],{"href":10774,"rel":10775},"https://modelcontextprotocol.io/",[99],"Documentation du Protocole de Contexte de Modèle",[163,10778,10779],{},[82,10780,7791],{"href":10781,"rel":10782},"https://github.com/michaelwybraniec/mcp-agentic-sldc",[99],[2183,10784,10785],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":286,"searchDepth":299,"depth":299,"links":10787},[10788,10796,10802,10807,10812,10817,10823,10828,10832],{"id":7774,"depth":299,"text":7777,"children":10789},[10790,10791,10792,10793,10794,10795],{"id":7802,"depth":305,"text":7803},{"id":7821,"depth":305,"text":7822},{"id":7857,"depth":305,"text":7858},{"id":7945,"depth":305,"text":7946},{"id":7962,"depth":305,"text":7963},{"id":8004,"depth":305,"text":8005},{"id":8437,"depth":299,"text":8440,"children":10797},[10798,10799,10800,10801],{"id":8455,"depth":305,"text":8456},{"id":8608,"depth":305,"text":8609},{"id":8827,"depth":305,"text":8828},{"id":9016,"depth":305,"text":9017},{"id":9220,"depth":299,"text":9223,"children":10803},[10804,10805,10806],{"id":9238,"depth":305,"text":9239},{"id":9259,"depth":305,"text":9260},{"id":9278,"depth":305,"text":9279},{"id":9300,"depth":299,"text":9303,"children":10808},[10809,10810,10811],{"id":9318,"depth":305,"text":9319},{"id":9571,"depth":305,"text":9572},{"id":9628,"depth":305,"text":9629},{"id":9993,"depth":299,"text":9996,"children":10813},[10814,10815,10816],{"id":10011,"depth":305,"text":10012},{"id":10047,"depth":305,"text":10048},{"id":10057,"depth":305,"text":10058},{"id":10164,"depth":299,"text":10167,"children":10818},[10819,10820,10821,10822],{"id":10182,"depth":305,"text":10183},{"id":10200,"depth":305,"text":10201},{"id":10301,"depth":305,"text":10302},{"id":10328,"depth":305,"text":10329},{"id":10364,"depth":299,"text":10367,"children":10824},[10825,10826,10827],{"id":10382,"depth":305,"text":10383},{"id":10417,"depth":305,"text":10418},{"id":10491,"depth":305,"text":10492},{"id":10524,"depth":299,"text":10527,"children":10829},[10830,10831],{"id":10542,"depth":305,"text":10543},{"id":10624,"depth":305,"text":10625},{"id":10666,"depth":299,"text":10669,"children":10833},[10834,10835],{"id":6395,"depth":305,"text":6398},{"id":7248,"depth":305,"text":10718},"2025-08-06","Une démonstration complète de comment construire un serveur MCP pour l\\'intégration de chatbot e-commerce, avec services de maintenance de chaudières, accès aux données en temps réel et flux de travail automatisés utilisant AWP.",{"src":2208},{},{"title":36,"description":10837},"P8LC4lAwNb3A1h50RgXfwGod9QuANRbeqN8tqrTsmTY",{"id":10843,"title":40,"authors":10844,"badge":10849,"body":10851,"date":11867,"description":11868,"extension":2206,"image":11869,"meta":11871,"navigation":320,"path":41,"seo":11872,"stem":42,"__hash__":11873},"posts_fr/fr/blog/architecture.md",[10845],{"name":66,"description":10846,"to":68,"avatar":10847},"Développement et Architecture Full-Stack",{"src":10848},"https://media.licdn.com/dms/image/v2/D4D03AQFpMfqwhaamwA/profile-displayphoto-shrink_800_800/B4DZbqQSLWH8Ac-/0/1747686860119?e=1753315200&v=beta&t=U9dsnD5qU8FSzW2dKEQXnkRdPl_w1visxvHob18_etc",{"label":10850},"Architecture",{"type":76,"value":10852,"toc":11849},[10853,10858,10875,10886,10901,10905,10914,10940,10943,11106,11110,11114,11122,11268,11272,11281,11402,11406,11412,11589,11593,11597,11602,11697,11701,11715,11719,11810,11814,11840,11846],[10854,10855,10857],"h1",{"id":10856},"introduction-à-larchitecture-moderne-ddd-et-frameworks-full-stack","Introduction à l’Architecture Moderne : DDD et Frameworks Full-Stack",[79,10859,10860,10861,10864,10865,3139,10868,3146,10871,10874],{},"Dans le monde du développement logiciel, le ",[110,10862,10863],{},"Domain-Driven Design (DDD)"," s’impose comme une méthode puissante pour construire des systèmes évolutifs et maintenables. En se concentrant sur le domaine métier, le DDD permet aux développeurs de créer des solutions alignées avec les besoins business. Associé à des frameworks full-stack modernes comme ",[110,10866,10867],{},"Vue.js",[110,10869,10870],{},"Nuxt.js",[110,10872,10873],{},"React",", cet ensemble favorise la création d’applications web robustes, efficaces et hautement interactives.",[79,10876,10877,10878,10881,10882,10885],{},"L’intégration de l’architecture ",[110,10879,10880],{},"Backend-for-Frontend (BFF)"," et des backends modernes en cloud ou ",[110,10883,10884],{},"Node.js"," offre un environnement fluide pour bâtir des applications flexibles et évolutives. Cet article explore comment le DDD, le BFF et les frameworks front-end modernes peuvent collaborer pour concevoir des architectures logicielles de qualité.",[102,10887,10890],{"className":10888},[131,10889,133,132],"space-x-4",[102,10891,10892],{},[79,10893,10894],{},[3221,10895],{"alt":10896,"className":10897,"height":10899,"src":10900},"Architecture BFF",[10898],"rounded-lg",300,"/blog/archi/bff.png",[135,10902,10904],{"id":10903},"les-principes-fondamentaux-du-ddd","Les Principes Fondamentaux du DDD",[79,10906,605,10907,10909,10910,10913],{},[110,10908,10863],{}," est une méthodologie centrée sur le ",[110,10911,10912],{},"domaine métier"," et sa logique. Les principes clés incluent :",[1625,10915,10916,10922,10928,10934],{},[163,10917,10918,10921],{},[110,10919,10920],{},"Langage Ubiquitaire"," – Assurer une compréhension partagée entre développeurs et experts métiers.",[163,10923,10924,10927],{},[110,10925,10926],{},"Contextes Délimités"," – Diviser le système en sous-domaines, chacun avec son propre modèle.",[163,10929,10930,10933],{},[110,10931,10932],{},"Agrégats et Entités"," – Encapsuler les règles et processus métiers dans des entités cohérentes.",[163,10935,10936,10939],{},[110,10937,10938],{},"Objets Valeur"," – Représenter des objets petits et immuables décrivant des aspects métier.",[79,10941,10942],{},"Appliqués correctement, ces principes permettent aux équipes d’aligner leurs choix techniques avec les objectifs métiers pour livrer des logiciels réellement utiles.",[281,10944,10947],{"className":2951,"code":10945,"filename":10946,"language":2953,"meta":286,"style":286},"// Couche Domaine - Exemple d'entité\nexport class Product {\n  constructor(\n    public readonly id: string,\n    public name: string,\n    public price: number\n  ) {}\n\n  changePrice(newPrice: number) {\n    if (newPrice \u003C= 0) throw new Error('Invalid price');\n    this.price = newPrice;\n  }\n}\n","example-ddd.ts",[261,10948,10949,10954,10967,10974,10991,11004,11016,11024,11028,11046,11083,11098,11102],{"__ignoreMap":286},[290,10950,10951],{"class":292,"line":293},[290,10952,10953],{"class":625},"// Couche Domaine - Exemple d'entité\n",[290,10955,10956,10959,10962,10965],{"class":292,"line":299},[290,10957,10958],{"class":698},"export",[290,10960,10961],{"class":631}," class",[290,10963,10964],{"class":635}," Product",[290,10966,640],{"class":639},[290,10968,10969,10972],{"class":292,"line":305},[290,10970,10971],{"class":631},"  constructor",[290,10973,795],{"class":639},[290,10975,10976,10979,10982,10985,10987,10989],{"class":292,"line":311},[290,10977,10978],{"class":631},"    public",[290,10980,10981],{"class":631}," readonly",[290,10983,10984],{"class":655}," id",[290,10986,659],{"class":639},[290,10988,673],{"class":635},[290,10990,820],{"class":639},[290,10992,10993,10995,10998,11000,11002],{"class":292,"line":317},[290,10994,10978],{"class":631},[290,10996,10997],{"class":655}," name",[290,10999,659],{"class":639},[290,11001,673],{"class":635},[290,11003,820],{"class":639},[290,11005,11006,11008,11011,11013],{"class":292,"line":324},[290,11007,10978],{"class":631},[290,11009,11010],{"class":655}," price",[290,11012,659],{"class":639},[290,11014,11015],{"class":635}," number\n",[290,11017,11018,11021],{"class":292,"line":330},[290,11019,11020],{"class":639},"  )",[290,11022,11023],{"class":639}," {}\n",[290,11025,11026],{"class":292,"line":336},[290,11027,321],{"emptyLinePlaceholder":320},[290,11029,11030,11033,11035,11038,11040,11042,11044],{"class":292,"line":342},[290,11031,11032],{"class":648},"  changePrice",[290,11034,652],{"class":639},[290,11036,11037],{"class":655},"newPrice",[290,11039,659],{"class":639},[290,11041,7361],{"class":635},[290,11043,676],{"class":639},[290,11045,640],{"class":639},[290,11047,11048,11050,11052,11054,11057,11060,11062,11065,11067,11070,11072,11074,11077,11079,11081],{"class":292,"line":347},[290,11049,726],{"class":698},[290,11051,729],{"class":648},[290,11053,11037],{"class":691},[290,11055,11056],{"class":639}," \u003C=",[290,11058,11059],{"class":1077}," 0",[290,11061,743],{"class":648},[290,11063,11064],{"class":698},"throw",[290,11066,754],{"class":639},[290,11068,11069],{"class":705}," Error",[290,11071,652],{"class":648},[290,11073,817],{"class":639},[290,11075,11076],{"class":813},"Invalid price",[290,11078,817],{"class":639},[290,11080,676],{"class":648},[290,11082,716],{"class":639},[290,11084,11085,11088,11091,11093,11096],{"class":292,"line":353},[290,11086,11087],{"class":639},"    this.",[290,11089,11090],{"class":691},"price",[290,11092,695],{"class":639},[290,11094,11095],{"class":691}," newPrice",[290,11097,716],{"class":639},[290,11099,11100],{"class":292,"line":359},[290,11101,872],{"class":639},[290,11103,11104],{"class":292,"line":365},[290,11105,1181],{"class":639},[135,11107,11109],{"id":11108},"intégrer-le-ddd-avec-les-frameworks-front-end-vue-nuxt-et-react","Intégrer le DDD avec les Frameworks Front-End : Vue, Nuxt et React",[1612,11111,11113],{"id":11112},"vuejs-nuxtjs-frameworks-progressifs","Vue.js & Nuxt.js : Frameworks Progressifs",[79,11115,11116,11118,11119,11121],{},[110,11117,10867],{}," et son framework serveur ",[110,11120,10870],{}," offrent une expérience de développement riche pour le front-end moderne. En intégrant les principes du DDD, ils permettent de concevoir des interfaces utilisateur réactives, performantes et orientées métier.",[281,11123,11128],{"className":11124,"code":11125,"filename":11126,"language":11127,"meta":286,"style":286},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003Cdiv class=\"card\">\n    \u003Ch2>{{ product.name }}\u003C/h2>\n    \u003Cp>{{ product.price }} USD\u003C/p>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nconst props = defineProps({ product: Object })\n\u003C/script>\n","ProductCard.vue","vue",[261,11129,11130,11141,11161,11181,11198,11207,11215,11219,11231,11260],{"__ignoreMap":286},[290,11131,11132,11135,11138],{"class":292,"line":293},[290,11133,11134],{"class":639},"\u003C",[290,11136,11137],{"class":648},"template",[290,11139,11140],{"class":639},">\n",[290,11142,11143,11146,11148,11150,11152,11154,11157,11159],{"class":292,"line":299},[290,11144,11145],{"class":639},"  \u003C",[290,11147,102],{"class":648},[290,11149,10961],{"class":631},[290,11151,2997],{"class":639},[290,11153,911],{"class":639},[290,11155,11156],{"class":813},"card",[290,11158,911],{"class":639},[290,11160,11140],{"class":639},[290,11162,11163,11166,11168,11171,11174,11177,11179],{"class":292,"line":305},[290,11164,11165],{"class":639},"    \u003C",[290,11167,135],{"class":648},[290,11169,11170],{"class":639},">",[290,11172,11173],{"class":691},"{{ product.name }}",[290,11175,11176],{"class":639},"\u003C/",[290,11178,135],{"class":648},[290,11180,11140],{"class":639},[290,11182,11183,11185,11187,11189,11192,11194,11196],{"class":292,"line":311},[290,11184,11165],{"class":639},[290,11186,79],{"class":648},[290,11188,11170],{"class":639},[290,11190,11191],{"class":691},"{{ product.price }} USD",[290,11193,11176],{"class":639},[290,11195,79],{"class":648},[290,11197,11140],{"class":639},[290,11199,11200,11203,11205],{"class":292,"line":317},[290,11201,11202],{"class":639},"  \u003C/",[290,11204,102],{"class":648},[290,11206,11140],{"class":639},[290,11208,11209,11211,11213],{"class":292,"line":324},[290,11210,11176],{"class":639},[290,11212,11137],{"class":648},[290,11214,11140],{"class":639},[290,11216,11217],{"class":292,"line":330},[290,11218,321],{"emptyLinePlaceholder":320},[290,11220,11221,11223,11226,11229],{"class":292,"line":336},[290,11222,11134],{"class":639},[290,11224,11225],{"class":648},"script",[290,11227,11228],{"class":631}," setup",[290,11230,11140],{"class":639},[290,11232,11233,11235,11238,11240,11243,11245,11247,11250,11252,11255,11257],{"class":292,"line":342},[290,11234,2991],{"class":631},[290,11236,11237],{"class":691}," props ",[290,11239,2997],{"class":639},[290,11241,11242],{"class":705}," defineProps",[290,11244,652],{"class":691},[290,11246,3054],{"class":639},[290,11248,11249],{"class":648}," product",[290,11251,659],{"class":639},[290,11253,11254],{"class":691}," Object ",[290,11256,3064],{"class":639},[290,11258,11259],{"class":691},")\n",[290,11261,11262,11264,11266],{"class":292,"line":347},[290,11263,11176],{"class":639},[290,11265,11225],{"class":648},[290,11267,11140],{"class":639},[1612,11269,11271],{"id":11270},"react-le-framework-basé-sur-les-composants","React : Le Framework Basé sur les Composants",[79,11273,11274,11276,11277,11280],{},[110,11275,10873],{}," est idéal pour concevoir des interfaces modulaires. Grâce à son ",[110,11278,11279],{},"architecture basée sur les composants",", les équipes peuvent créer des modules réutilisables qui incarnent la logique métier, tout en conservant flexibilité et évolutivité.",[281,11282,11287],{"className":11283,"code":11284,"filename":11285,"language":11286,"meta":286,"style":286},"language-jsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","function ProductCard({ product }) {\n  return (\n    \u003Cdiv className=\"card\">\n      \u003Ch2>{product.name}\u003C/h2>\n      \u003Cp>{product.price} USD\u003C/p>\n    \u003C/div>\n  );\n}\n","ProductCard.jsx","jsx",[261,11288,11289,11307,11315,11334,11358,11383,11392,11398],{"__ignoreMap":286},[290,11290,11291,11294,11297,11300,11302,11305],{"class":292,"line":293},[290,11292,11293],{"class":631},"function",[290,11295,11296],{"class":705}," ProductCard",[290,11298,11299],{"class":639},"({",[290,11301,11249],{"class":655},[290,11303,11304],{"class":639}," })",[290,11306,640],{"class":639},[290,11308,11309,11312],{"class":292,"line":299},[290,11310,11311],{"class":698},"  return",[290,11313,11314],{"class":648}," (\n",[290,11316,11317,11319,11321,11324,11326,11328,11330,11332],{"class":292,"line":305},[290,11318,11165],{"class":639},[290,11320,102],{"class":648},[290,11322,11323],{"class":631}," className",[290,11325,2997],{"class":639},[290,11327,911],{"class":639},[290,11329,11156],{"class":813},[290,11331,911],{"class":639},[290,11333,11140],{"class":639},[290,11335,11336,11339,11341,11344,11347,11349,11351,11354,11356],{"class":292,"line":311},[290,11337,11338],{"class":639},"      \u003C",[290,11340,135],{"class":648},[290,11342,11343],{"class":639},">{",[290,11345,11346],{"class":691},"product",[290,11348,200],{"class":639},[290,11350,9671],{"class":691},[290,11352,11353],{"class":639},"}\u003C/",[290,11355,135],{"class":648},[290,11357,11140],{"class":639},[290,11359,11360,11362,11364,11366,11368,11370,11372,11374,11377,11379,11381],{"class":292,"line":317},[290,11361,11338],{"class":639},[290,11363,79],{"class":648},[290,11365,11343],{"class":639},[290,11367,11346],{"class":691},[290,11369,200],{"class":639},[290,11371,11090],{"class":691},[290,11373,3064],{"class":639},[290,11375,11376],{"class":691}," USD",[290,11378,11176],{"class":639},[290,11380,79],{"class":648},[290,11382,11140],{"class":639},[290,11384,11385,11388,11390],{"class":292,"line":324},[290,11386,11387],{"class":639},"    \u003C/",[290,11389,102],{"class":648},[290,11391,11140],{"class":639},[290,11393,11394,11396],{"class":292,"line":330},[290,11395,11020],{"class":648},[290,11397,716],{"class":639},[290,11399,11400],{"class":292,"line":336},[290,11401,1181],{"class":639},[135,11403,11405],{"id":11404},"backend-for-frontend-bff-une-approche-sur-mesure","Backend-for-Frontend (BFF) : Une Approche Sur-Mesure",[79,11407,11408,11411],{},[110,11409,11410],{},"L’architecture BFF"," fait office de couche intermédiaire entre le front-end et le back-end, exposant une API adaptée aux besoins spécifiques du client front-end. Cela permet une récupération de données optimisée et ciblée.",[281,11413,11416],{"className":2951,"code":11414,"filename":11415,"language":2953,"meta":286,"style":286},"// Exemple BFF pour récupérer un produit\nimport express from 'express';\nconst router = express.Router();\n\nrouter.get('/products/:id', async (req, res) => {\n  const data = await fetchProduct(req.params.id);\n  res.json({ name: data.name, price: data.price });\n});\n","bff-handler.ts",[261,11417,11418,11423,11441,11462,11466,11507,11540,11581],{"__ignoreMap":286},[290,11419,11420],{"class":292,"line":293},[290,11421,11422],{"class":625},"// Exemple BFF pour récupérer un produit\n",[290,11424,11425,11427,11430,11432,11434,11437,11439],{"class":292,"line":299},[290,11426,2960],{"class":698},[290,11428,11429],{"class":691}," express ",[290,11431,3098],{"class":698},[290,11433,1151],{"class":639},[290,11435,11436],{"class":813},"express",[290,11438,817],{"class":639},[290,11440,716],{"class":639},[290,11442,11443,11445,11448,11450,11453,11455,11458,11460],{"class":292,"line":305},[290,11444,2991],{"class":631},[290,11446,11447],{"class":691}," router ",[290,11449,2997],{"class":639},[290,11451,11452],{"class":691}," express",[290,11454,200],{"class":639},[290,11456,11457],{"class":705},"Router",[290,11459,760],{"class":691},[290,11461,716],{"class":639},[290,11463,11464],{"class":292,"line":311},[290,11465,321],{"emptyLinePlaceholder":320},[290,11467,11468,11471,11473,11476,11478,11480,11483,11485,11487,11490,11492,11495,11497,11500,11502,11505],{"class":292,"line":317},[290,11469,11470],{"class":691},"router",[290,11472,200],{"class":639},[290,11474,11475],{"class":705},"get",[290,11477,652],{"class":691},[290,11479,817],{"class":639},[290,11481,11482],{"class":813},"/products/:id",[290,11484,817],{"class":639},[290,11486,665],{"class":639},[290,11488,11489],{"class":631}," async",[290,11491,729],{"class":639},[290,11493,11494],{"class":655},"req",[290,11496,665],{"class":639},[290,11498,11499],{"class":655}," res",[290,11501,676],{"class":639},[290,11503,11504],{"class":631}," =>",[290,11506,640],{"class":639},[290,11508,11509,11512,11515,11517,11519,11522,11524,11526,11528,11531,11533,11536,11538],{"class":292,"line":324},[290,11510,11511],{"class":631},"  const",[290,11513,11514],{"class":691}," data",[290,11516,695],{"class":639},[290,11518,699],{"class":698},[290,11520,11521],{"class":705}," fetchProduct",[290,11523,652],{"class":648},[290,11525,11494],{"class":691},[290,11527,200],{"class":639},[290,11529,11530],{"class":691},"params",[290,11532,200],{"class":639},[290,11534,11535],{"class":691},"id",[290,11537,676],{"class":648},[290,11539,716],{"class":639},[290,11541,11542,11545,11547,11549,11551,11553,11555,11557,11559,11561,11563,11565,11567,11569,11571,11573,11575,11577,11579],{"class":292,"line":330},[290,11543,11544],{"class":691},"  res",[290,11546,200],{"class":639},[290,11548,1737],{"class":705},[290,11550,652],{"class":648},[290,11552,3054],{"class":639},[290,11554,10997],{"class":648},[290,11556,659],{"class":639},[290,11558,11514],{"class":691},[290,11560,200],{"class":639},[290,11562,9671],{"class":691},[290,11564,665],{"class":639},[290,11566,11010],{"class":648},[290,11568,659],{"class":639},[290,11570,11514],{"class":691},[290,11572,200],{"class":639},[290,11574,11090],{"class":691},[290,11576,2974],{"class":639},[290,11578,676],{"class":648},[290,11580,716],{"class":639},[290,11582,11583,11585,11587],{"class":292,"line":336},[290,11584,3064],{"class":639},[290,11586,676],{"class":691},[290,11588,716],{"class":639},[135,11590,11592],{"id":11591},"backend-cloud-et-nodejs-des-solutions-flexibles-et-scalables","Backend Cloud et Node.js : Des Solutions Flexibles et Scalables",[1612,11594,11596],{"id":11595},"nodejs-le-backend-javascript","Node.js : Le Backend JavaScript",[79,11598,11599,11601],{},[110,11600,10884],{}," fournit un environnement backend léger et performant, basé sur JavaScript. Il est parfaitement adapté aux applications temps réel et à l’implémentation de logique métier complexe définie selon le DDD.",[281,11603,11606],{"className":2951,"code":11604,"filename":11605,"language":2953,"meta":286,"style":286},"// Exemple de service métier Node.js\nexport function applyDiscount(product, discount) {\n  if (discount > product.price) throw new Error('Discount too high');\n  return product.price - discount;\n}\n","product-service.ts",[261,11607,11608,11613,11636,11676,11693],{"__ignoreMap":286},[290,11609,11610],{"class":292,"line":293},[290,11611,11612],{"class":625},"// Exemple de service métier Node.js\n",[290,11614,11615,11617,11620,11623,11625,11627,11629,11632,11634],{"class":292,"line":299},[290,11616,10958],{"class":698},[290,11618,11619],{"class":631}," function",[290,11621,11622],{"class":705}," applyDiscount",[290,11624,652],{"class":639},[290,11626,11346],{"class":655},[290,11628,665],{"class":639},[290,11630,11631],{"class":655}," discount",[290,11633,676],{"class":639},[290,11635,640],{"class":639},[290,11637,11638,11641,11643,11646,11649,11651,11653,11655,11657,11659,11661,11663,11665,11667,11670,11672,11674],{"class":292,"line":305},[290,11639,11640],{"class":698},"  if",[290,11642,729],{"class":648},[290,11644,11645],{"class":691},"discount",[290,11647,11648],{"class":639}," >",[290,11650,11249],{"class":691},[290,11652,200],{"class":639},[290,11654,11090],{"class":691},[290,11656,743],{"class":648},[290,11658,11064],{"class":698},[290,11660,754],{"class":639},[290,11662,11069],{"class":705},[290,11664,652],{"class":648},[290,11666,817],{"class":639},[290,11668,11669],{"class":813},"Discount too high",[290,11671,817],{"class":639},[290,11673,676],{"class":648},[290,11675,716],{"class":639},[290,11677,11678,11680,11682,11684,11686,11689,11691],{"class":292,"line":311},[290,11679,11311],{"class":698},[290,11681,11249],{"class":691},[290,11683,200],{"class":639},[290,11685,11090],{"class":691},[290,11687,11688],{"class":639}," -",[290,11690,11631],{"class":691},[290,11692,716],{"class":639},[290,11694,11695],{"class":292,"line":317},[290,11696,1181],{"class":639},[1612,11698,11700],{"id":11699},"infrastructure-cloud-évolutivité-et-résilience","Infrastructure Cloud : Évolutivité et Résilience",[79,11702,11703,11704,3139,11707,11710,11711,11714],{},"Utiliser des plateformes cloud comme ",[110,11705,11706],{},"AWS",[110,11708,11709],{},"Google Cloud"," ou ",[110,11712,11713],{},"Azure"," permet une évolutivité sans précédent. Ces services fournissent l’infrastructure nécessaire aux microservices, bases de données et systèmes de stockage compatibles avec le BFF et l’application front-end.",[135,11716,11718],{"id":11717},"configuration-de-tailwind-et-nuxt-ui-pro","Configuration de Tailwind et Nuxt UI Pro",[7352,11720,11722,11729,11772,11776],{"level":11721},"4",[1612,11723,11725,11726],{"id":11724},"étape-1-ajouter-le-module-nuxt-ui-pro-dans-nuxtconfigts","Étape 1 – Ajouter le module Nuxt UI Pro dans ",[261,11727,11728],{},"nuxt.config.ts",[281,11730,11732],{"className":2951,"code":11731,"filename":11728,"language":2953,"meta":286,"style":286},"export default defineNuxtConfig({\n  modules: ['@nuxt/ui-pro']\n})\n",[261,11733,11734,11748,11766],{"__ignoreMap":286},[290,11735,11736,11738,11741,11744,11746],{"class":292,"line":293},[290,11737,10958],{"class":698},[290,11739,11740],{"class":698}," default",[290,11742,11743],{"class":705}," defineNuxtConfig",[290,11745,652],{"class":691},[290,11747,746],{"class":639},[290,11749,11750,11753,11755,11757,11759,11762,11764],{"class":292,"line":299},[290,11751,11752],{"class":648},"  modules",[290,11754,659],{"class":639},[290,11756,916],{"class":691},[290,11758,817],{"class":639},[290,11760,11761],{"class":813},"@nuxt/ui-pro",[290,11763,817],{"class":639},[290,11765,8591],{"class":691},[290,11767,11768,11770],{"class":292,"line":305},[290,11769,3064],{"class":639},[290,11771,11259],{"class":691},[1612,11773,11775],{"id":11774},"étape-2-importer-tailwind-css-et-nuxt-ui-pro-dans-ton-fichier-css","Étape 2 – Importer Tailwind CSS et Nuxt UI Pro dans ton fichier CSS",[281,11777,11782],{"className":11778,"code":11779,"filename":11780,"language":11781,"meta":286,"style":286},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@import \"tailwindcss\";\n@import \"@nuxt/ui-pro\";\n","assets/css/main.css","css",[261,11783,11784,11798],{"__ignoreMap":286},[290,11785,11786,11789,11791,11794,11796],{"class":292,"line":293},[290,11787,11788],{"class":698},"@import",[290,11790,954],{"class":639},[290,11792,11793],{"class":813},"tailwindcss",[290,11795,911],{"class":639},[290,11797,716],{"class":639},[290,11799,11800,11802,11804,11806,11808],{"class":292,"line":299},[290,11801,11788],{"class":698},[290,11803,954],{"class":639},[290,11805,11761],{"class":813},[290,11807,911],{"class":639},[290,11809,716],{"class":639},[135,11811,11813],{"id":11812},"conclusion-construire-des-architectures-modernes-avec-ddd","Conclusion : Construire des Architectures Modernes avec DDD",[79,11815,11816,11817,11820,11821,3139,11824,3146,11827,11829,11830,11833,11834,11710,11837,11839],{},"En adoptant le ",[110,11818,11819],{},"Domain-Driven Design",", en tirant parti de frameworks modernes comme ",[110,11822,11823],{},"Vue",[110,11825,11826],{},"Nuxt",[110,11828,10873],{},", et en intégrant une ",[110,11831,11832],{},"architecture BFF"," avec des backends ",[110,11835,11836],{},"cloud",[110,11838,10884],{},", les développeurs peuvent créer des logiciels à la fois robustes, évolutifs et parfaitement alignés sur les objectifs métier.",[79,11841,11842,11845],{},[110,11843,11844],{},"Bon code à tous !"," 👨‍💻🚀",[2183,11847,11848],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":286,"searchDepth":299,"depth":299,"links":11850},[11851,11852,11856,11857,11861,11866],{"id":10903,"depth":299,"text":10904},{"id":11108,"depth":299,"text":11109,"children":11853},[11854,11855],{"id":11112,"depth":305,"text":11113},{"id":11270,"depth":305,"text":11271},{"id":11404,"depth":299,"text":11405},{"id":11591,"depth":299,"text":11592,"children":11858},[11859,11860],{"id":11595,"depth":305,"text":11596},{"id":11699,"depth":305,"text":11700},{"id":11717,"depth":299,"text":11718,"children":11862},[11863,11865],{"id":11724,"depth":305,"text":11864},"Étape 1 – Ajouter le module Nuxt UI Pro dans nuxt.config.ts",{"id":11774,"depth":305,"text":11775},{"id":11812,"depth":299,"text":11813},"2025-04-20","Explore l’intersection entre l’architecture logicielle moderne, le Domain-Driven Design (DDD) et les frameworks front-end puissants comme Vue, Nuxt et React, soutenus par des backends basés sur le cloud ou Node.js.",{"src":11870},"https://www.hibit.dev/images/posts/2021/ddd_layers.png",{},{"title":40,"description":11868},"Rw4uVNJAxZzI6gY5txEHQv9mB0s6BW84_Dy9Psk2rCc",{"id":11875,"title":44,"authors":11876,"badge":11879,"body":11881,"date":13188,"description":13189,"extension":2206,"image":13190,"meta":13192,"navigation":320,"path":45,"seo":13193,"stem":46,"__hash__":13194},"posts_fr/fr/blog/qa-front.md",[11877],{"name":66,"description":2216,"to":68,"avatar":11878},{"src":2218},{"label":11880,"color":73,"variant":74},"Tests",{"type":76,"value":11882,"toc":13167},[11883,11887,11890,11893,11896,11900,11903,11906,11909,11912,11916,11919,11935,11939,11945,12003,12006,12008,12012,12015,12082,12084,12088,12142,12144,12148,12183,12185,12189,12192,12195,12211,12214,12230,12233,12242,12245,12284,12287,12295,12298,12306,12309,12317,12533,12536,12541,12544,12552,12556,12559,12562,12566,12569,12572,12575,12577,12626,12629,12669,12672,12676,12679,12682,12685,12687,12712,12714,12747,12750,12754,12757,12760,12763,12765,12849,12852,12968,12971,12975,12978,12981,12984,12986,13040,13042,13102,13105,13109,13112,13115,13118,13121,13125,13128,13131,13134,13137,13141,13144,13147,13150,13153,13156,13159,13161,13164],[10854,11884,11886],{"id":11885},"comment-je-combine-laq-classique-et-les-tests-de-lère-ia-pour-les-applications-modernes","Comment je combine l'AQ classique et les tests de l'ère IA pour les applications modernes ?",[79,11888,11889],{},"Aujourd'hui, l'IA n'est plus quelque chose que nous construisons uniquement pour des projets IA — c'est quelque chose que nous utilisons dans presque toutes les applications modernes. Des systèmes de recommandation dans l'e-commerce aux chatbots dans le support client, les composants IA sont partout.",[79,11891,11892],{},"En tant que développeur, j'ai réalisé que ma stratégie de test doit couvrir à la fois l'AQ classique (comme les tests unitaires, les tests d'intégration, la sécurité, les performances) et les défis spécifiques à l'IA (comme la qualité des données, l'équité des modèles, l'explicabilité et la détection de dérive).",[79,11894,11895],{},"Dans cet article, je partage ma checklist QAI personnelle — un guide pratique que j'utilise pour tester les applications qui combinent le logiciel traditionnel avec les fonctionnalités IA. Je vais parcourir les outils et pratiques sur lesquels je m'appuie à travers le frontend, le backend (Node.js, Python, PHP) et les composants d'apprentissage automatique, et expliquer comment je configure l'automatisation, la surveillance et les boucles de rétroaction humaine. 🔥",[135,11897,11899],{"id":11898},"introduction","Introduction",[79,11901,11902],{},"Nous sommes entrés dans une nouvelle ère de développement logiciel où l'IA n'est plus limitée aux projets spécialisés — elle est intégrée dans presque tout ce que nous construisons. Qu'il s'agisse d'une fonction de recherche, d'un moteur de recommandation, d'un chatbot ou d'un tableau de bord prédictif, l'IA devient un élément standard de la pile technologique.",[79,11904,11905],{},"Mais voici le défi auquel j'ai été confronté : les approches d'AQ classiques ne suffisent plus. Les tests unitaires, les tests d'intégration, les vérifications de performance et les audits de sécurité sont toujours essentiels — mais ils ne me disent pas si les données derrière mon modèle dérivent, si mon chatbot donne des réponses biaisées, ou si mes recommandations sont toujours pertinentes.",[79,11907,11908],{},"C'est pourquoi j'ai élaboré une checklist QAI qui aide à tester systématiquement à la fois les couches classiques et les composants IA des applications modernes.",[79,11910,11911],{},"Dans cet article de blog, je vais parcourir comment j'aborde les tests à travers la pile, partager mes outils favoris, et mettre en évidence les étapes supplémentaires que je prends pour m'assurer que mes applications sont fiables, équitables et évolutives à l'ère de l'IA.",[135,11913,11915],{"id":11914},"_1-pourquoi-laq-moderne-a-besoin-à-la-fois-des-tests-classiques-et-ia","1. Pourquoi l'AQ moderne a besoin à la fois des tests classiques et IA",[79,11917,11918],{},"Dans les logiciels d'aujourd'hui, l'IA n'est plus optionnelle ou limitée aux projets spéciaux. Elle fait partie de la recherche, du chat, des recommandations, de la détection de fraude, de la personnalisation, de l'analyse prédictive — dans presque tous les secteurs.",[79,11920,11921,11922,11925,11926,11929,11931,11932],{},"Mais voici le problème que j'ai appris par expérience :",[11923,11924],"br",{},"\n✅ ",[110,11927,11928],{},"L'AQ classique (tests unitaires, d'intégration, E2E, de performance) garantit que l'app fonctionne comme codée.",[11923,11930],{},"\n❌ ",[110,11933,11934],{},"Elle ne garantit PAS que l'IA à l'intérieur se comporte de manière sûre, équitable ou fiable dans le temps.",[1612,11936,11938],{"id":11937},"_12-aq-classique-ce-quelle-détecte","1.2 AQ classique — Ce qu'elle détecte",[79,11940,11941,11942,11944],{},"L'AQ classique est toujours absolument nécessaire.",[11923,11943],{},"\nVoici ce que j'applique dans tous les projets, avec des outils spécifiques :",[160,11946,11947,11960,11970,11983,11993],{},[163,11948,11949,11952],{},[110,11950,11951],{},"Tests unitaires",[160,11953,11954,11957],{},[163,11955,11956],{},"Backend → Jest (Node.js), PyTest (Python), PHPUnit (PHP)",[163,11958,11959],{},"Frontend → Jest + Testing Library (React, Angular, Vue)",[163,11961,11962,11965],{},[110,11963,11964],{},"Tests d'intégration",[160,11966,11967],{},[163,11968,11969],{},"Supertest (APIs Node.js), collections Postman/Newman, pytest-django (APIs Python)",[163,11971,11972,11975],{},[110,11973,11974],{},"Tests E2E",[160,11976,11977,11980],{},[163,11978,11979],{},"Playwright, Cypress (E2E navigateur)",[163,11981,11982],{},"Selenium, Puppeteer (cross-browser, vérifications visuelles)",[163,11984,11985,11988],{},[110,11986,11987],{},"Tests de performance/charge",[160,11989,11990],{},[163,11991,11992],{},"k6, Artillery, Locust (simuler haute charge, tests de stress API)",[163,11994,11995,11998],{},[110,11996,11997],{},"Tests de sécurité",[160,11999,12000],{},[163,12001,12002],{},"OWASP ZAP, Snyk, npm audit, Bandit (scan statique Python)",[79,12004,12005],{},"✅ Exemple : Je teste mon API backend Node.js avec Supertest + Jest pour les réponses correctes et les cas d'échec.",[4983,12007],{},[1612,12009,12011],{"id":12010},"_13-nouveaux-problèmes-daq-introduits-par-lia","1.3 Nouveaux problèmes d'AQ introduits par l'IA",[79,12013,12014],{},"Quand j'ajoute des composants IA🤖 (modèles ML, embeddings, LLMs, moteurs de recommandation), de nouvelles catégories de risques apparaissent :",[160,12016,12017,12030,12043,12056,12069],{},[163,12018,12019,12022],{},[110,12020,12021],{},"Biais et équité",[160,12023,12024,12027],{},[163,12025,12026],{},"Exemple : Recommandations de produits qui favorisent les articles populaires et ignorent les catégories de niche, nuisant aux petits vendeurs.",[163,12028,12029],{},"Outil → IBM AI Fairness 360, Fairlearn",[163,12031,12032,12035],{},[110,12033,12034],{},"Dérive de modèle",[160,12036,12037,12040],{},[163,12038,12039],{},"Exemple : Un modèle de détection de fraude entraîné en 2023 devient inutile en 2025 car les modèles de fraude changent.",[163,12041,12042],{},"Outil → Evidently AI (détection de dérive, tableaux de bord)",[163,12044,12045,12048],{},[110,12046,12047],{},"Explicabilité",[160,12049,12050,12053],{},[163,12051,12052],{},"Exemple : Un chatbot de support client donne des réponses étranges, et personne dans l'équipe ne comprend pourquoi.",[163,12054,12055],{},"Outil → SHAP, LIME, Captum",[163,12057,12058,12061],{},[110,12059,12060],{},"Qualité des données",[160,12062,12063,12066],{},[163,12064,12065],{},"Exemple : Champs manquants dans les données d'entrée causent des prédictions incorrectes du modèle.",[163,12067,12068],{},"Outil → Great Expectations (validation des données)",[163,12070,12071,12074],{},[110,12072,12073],{},"Robustesse adversariale",[160,12075,12076,12079],{},[163,12077,12078],{},"Exemple : Un modèle de vision classe incorrectement une image manipulée.",[163,12080,12081],{},"Outil → Adversarial Robustness Toolbox (ART)",[4983,12083],{},[1612,12085,12087],{"id":12086},"_14-comment-je-combine-laq-classique-avec-qai","1.4 Comment je combine l'AQ classique avec + QAI",[1204,12089,12090,12103],{},[1207,12091,12092],{},[1210,12093,12094,12097,12100],{},[1213,12095,12096],{},"Couche",[1213,12098,12099],{},"AQ classique",[1213,12101,12102],{},"QAI (AQ consciente de l'IA)",[1224,12104,12105],{},[1210,12106,12107,12112,12127],{},[1229,12108,12109,12111],{},[110,12110,2793],{}," (React, Angular, Vue, Next, Nuxt)",[1229,12113,12114,12115,12117,12118,12120,12121,12123,12124,12126],{},"✅ Tests unitaires",[11923,12116],{},"✅ Tests E2E",[11923,12119],{},"✅ Régression visuelle",[11923,12122],{},"✅ Tests d'accessibilité (a11y)",[11923,12125],{},"✅ Tests cross-browser",[1229,12128,12129,12130,12132,12133,12135,12136,12138,12139,12141],{},"⚠️ Cohérence UX du code généré par IA",[11923,12131],{},"⚠️ Détecter les hallucinations (comportement incorrect ou inventé)",[11923,12134],{},"⚠️ Suivre la complexité cachée ou le code inutilisé",[11923,12137],{},"⚠️ Vérifier la justesse des dépendances + versions",[11923,12140],{},"⚠️ Valider le comportement de repli quand les fonctionnalités IA échouent ou donnent des résultats incertains",[4983,12143],{},[1612,12145,12147],{"id":12146},"_15-aq-frontend-classique-toujours-essentielle","1.5 AQ Frontend classique (toujours essentielle)",[160,12149,12150,12155,12160,12165,12171,12177],{},[163,12151,12152,12154],{},[110,12153,11951],{}," → Jest, Vitest, Mocha",[163,12156,12157,12159],{},[110,12158,11964],{}," → React Testing Library, Angular Testing Library",[163,12161,12162,12164],{},[110,12163,11974],{}," → Cypress, Playwright",[163,12166,12167,12170],{},[110,12168,12169],{},"Régression visuelle"," → Percy, Chromatic, Loki",[163,12172,12173,12176],{},[110,12174,12175],{},"Tests d'accessibilité"," → axe-core, Lighthouse",[163,12178,12179,12182],{},[110,12180,12181],{},"Tests cross-browser"," → BrowserStack, Sauce Labs",[4983,12184],{},[1612,12186,12188],{"id":12187},"_16-qai-tests-frontend-conscients-de-lia","1.6 QAI (Tests Frontend conscients de l'IA)",[79,12190,12191],{},"Parce que l'IA aide au codage, nous faisons face à de nouveaux risques :",[79,12193,12194],{},"✅ Vérification de la qualité du code + lisibilité",[160,12196,12197,12204],{},[163,12198,12199,12200,12203],{},"Utiliser ",[110,12201,12202],{},"ESLint, Prettier"," → détecter le code IA désordonné, incohérent",[163,12205,12206,12207,12210],{},"Ajouter des ",[110,12208,12209],{},"vérifications CI"," pour le formatage + linting",[79,12212,12213],{},"✅ Cohérence UI/UX",[160,12215,12216,12223],{},[163,12217,12218,12219,12222],{},"Vérifier si l'UI générée par IA correspond aux ",[110,12220,12221],{},"systèmes de design"," (Storybook aide !)",[163,12224,12225,12226,12229],{},"Utiliser des ",[110,12227,12228],{},"tests de régression visuelle"," pour détecter les dérives de style/mise en page",[79,12231,12232],{},"✅ Validation des hallucinations + logique",[160,12234,12235],{},[163,12236,12237,12238,12241],{},"Écrire des ",[110,12239,12240],{},"tests unitaires/d'intégration"," pour les assistants générés par IA",[79,12243,12244],{},"Exemple :",[281,12246,12250],{"className":12247,"code":12248,"language":12249,"meta":286,"style":286},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Surveiller les assistants trop compliqués :\nconst getUniqueList = arr => [...new Set(arr)];\n","js",[261,12251,12252,12257],{"__ignoreMap":286},[290,12253,12254],{"class":292,"line":293},[290,12255,12256],{"class":625},"// Surveiller les assistants trop compliqués :\n",[290,12258,12259,12261,12264,12266,12269,12271,12273,12276,12279,12282],{"class":292,"line":299},[290,12260,2991],{"class":631},[290,12262,12263],{"class":691}," getUniqueList ",[290,12265,2997],{"class":639},[290,12267,12268],{"class":655}," arr",[290,12270,11504],{"class":631},[290,12272,916],{"class":691},[290,12274,12275],{"class":639},"...new",[290,12277,12278],{"class":705}," Set",[290,12280,12281],{"class":691},"(arr)]",[290,12283,716],{"class":639},[79,12285,12286],{},"✅ Justesse des dépendances + versions",[160,12288,12289,12292],{},[163,12290,12291],{},"Vérifier les versions de bibliothèques et mises à jour",[163,12293,12294],{},"Utiliser npm audit, pnpm audit, Snyk pour repérer les packages non sécurisés ou obsolètes",[79,12296,12297],{},"✅ Détection de complexité cachée / code mort",[160,12299,12300,12303],{},[163,12301,12302],{},"Détecter les imports, vars, fonctions inutilisés",[163,12304,12305],{},"Utiliser webpack, Rollup, ESLint no-unused-vars",[79,12307,12308],{},"✅ Tests de comportement de repli",[160,12310,12311,12314],{},[163,12312,12313],{},"Simuler les échecs et timeouts d'API",[163,12315,12316],{},"Assurer des replis conviviaux\nExemple :",[281,12318,12320],{"className":12247,"code":12319,"language":12249,"meta":286,"style":286},"describe('UI de repli', () => {\n  it('affiche le repli quand l\\'API IA échoue', async () => {\n    server.use(\n      rest.get('/api/ai-endpoint', (req, res, ctx) =>\n        res(ctx.status(500))\n      )\n    );\n    render(\u003CRecommendationWidget />);\n    expect(await screen.findByText('Désolé, recommandations indisponibles')).toBeInTheDocument();\n  });\n});\n",[261,12321,12322,12345,12375,12387,12425,12447,12452,12458,12477,12516,12525],{"__ignoreMap":286},[290,12323,12324,12327,12329,12331,12334,12336,12338,12341,12343],{"class":292,"line":293},[290,12325,12326],{"class":705},"describe",[290,12328,652],{"class":691},[290,12330,817],{"class":639},[290,12332,12333],{"class":813},"UI de repli",[290,12335,817],{"class":639},[290,12337,665],{"class":639},[290,12339,12340],{"class":639}," ()",[290,12342,11504],{"class":631},[290,12344,640],{"class":639},[290,12346,12347,12350,12352,12354,12357,12360,12363,12365,12367,12369,12371,12373],{"class":292,"line":299},[290,12348,12349],{"class":705},"  it",[290,12351,652],{"class":648},[290,12353,817],{"class":639},[290,12355,12356],{"class":813},"affiche le repli quand l",[290,12358,12359],{"class":691},"\\'",[290,12361,12362],{"class":813},"API IA échoue",[290,12364,817],{"class":639},[290,12366,665],{"class":639},[290,12368,11489],{"class":631},[290,12370,12340],{"class":639},[290,12372,11504],{"class":631},[290,12374,640],{"class":639},[290,12376,12377,12380,12382,12385],{"class":292,"line":305},[290,12378,12379],{"class":691},"    server",[290,12381,200],{"class":639},[290,12383,12384],{"class":705},"use",[290,12386,795],{"class":648},[290,12388,12389,12392,12394,12396,12398,12400,12403,12405,12407,12409,12411,12413,12415,12417,12420,12422],{"class":292,"line":311},[290,12390,12391],{"class":691},"      rest",[290,12393,200],{"class":639},[290,12395,11475],{"class":705},[290,12397,652],{"class":648},[290,12399,817],{"class":639},[290,12401,12402],{"class":813},"/api/ai-endpoint",[290,12404,817],{"class":639},[290,12406,665],{"class":639},[290,12408,729],{"class":639},[290,12410,11494],{"class":655},[290,12412,665],{"class":639},[290,12414,11499],{"class":655},[290,12416,665],{"class":639},[290,12418,12419],{"class":655}," ctx",[290,12421,676],{"class":639},[290,12423,12424],{"class":631}," =>\n",[290,12426,12427,12430,12432,12435,12437,12439,12441,12444],{"class":292,"line":317},[290,12428,12429],{"class":705},"        res",[290,12431,652],{"class":648},[290,12433,12434],{"class":691},"ctx",[290,12436,200],{"class":639},[290,12438,1072],{"class":705},[290,12440,652],{"class":648},[290,12442,12443],{"class":1077},"500",[290,12445,12446],{"class":648},"))\n",[290,12448,12449],{"class":292,"line":324},[290,12450,12451],{"class":648},"      )\n",[290,12453,12454,12456],{"class":292,"line":330},[290,12455,835],{"class":648},[290,12457,716],{"class":639},[290,12459,12460,12463,12465,12467,12470,12473,12475],{"class":292,"line":336},[290,12461,12462],{"class":705},"    render",[290,12464,652],{"class":648},[290,12466,11134],{"class":639},[290,12468,12469],{"class":635},"RecommendationWidget",[290,12471,12472],{"class":639}," />",[290,12474,676],{"class":648},[290,12476,716],{"class":639},[290,12478,12479,12482,12484,12487,12490,12492,12495,12497,12499,12502,12504,12507,12509,12512,12514],{"class":292,"line":342},[290,12480,12481],{"class":705},"    expect",[290,12483,652],{"class":648},[290,12485,12486],{"class":698},"await",[290,12488,12489],{"class":691}," screen",[290,12491,200],{"class":639},[290,12493,12494],{"class":705},"findByText",[290,12496,652],{"class":648},[290,12498,817],{"class":639},[290,12500,12501],{"class":813},"Désolé, recommandations indisponibles",[290,12503,817],{"class":639},[290,12505,12506],{"class":648},"))",[290,12508,200],{"class":639},[290,12510,12511],{"class":705},"toBeInTheDocument",[290,12513,760],{"class":648},[290,12515,716],{"class":639},[290,12517,12518,12521,12523],{"class":292,"line":347},[290,12519,12520],{"class":639},"  }",[290,12522,676],{"class":648},[290,12524,716],{"class":639},[290,12526,12527,12529,12531],{"class":292,"line":353},[290,12528,3064],{"class":639},[290,12530,676],{"class":691},[290,12532,716],{"class":639},[79,12534,12535],{},"✅ Vérification sécurité + injection",[160,12537,12538],{},[163,12539,12540],{},"Auditer les interpolations de chaînes générées par IA + gestion HTML",[79,12542,12543],{},"✅ Tests de performance",[160,12545,12546,12549],{},[163,12547,12548],{},"Utiliser Lighthouse, WebPageTest pour détecter les inefficacités",[163,12550,12551],{},"Surveiller le debouncing/throttling manqués",[135,12553,12555],{"id":12554},"_2-aq-frontend-qai","2. AQ Frontend + QAI",[79,12557,12558],{},"Lors de l'utilisation de l'IA dans le développement frontend, plusieurs risques peuvent survenir, et ils doivent être considérés pendant les tests.",[79,12560,12561],{},"Ces risques sont un mélange de problèmes d'AQ classiques et de problèmes spécifiques QAI uniques que les outils IA peuvent introduire :",[1612,12563,12565],{"id":12564},"_211-qualité-du-code-et-lisibilité","2.1.1 Qualité du code et lisibilité",[79,12567,12568],{},"Le code généré par IA pourrait ne pas toujours suivre les meilleures pratiques ou les standards de codage de votre projet, rendant difficile la maintenance ou le débogage futur.",[79,12570,12571],{},"Code incohérent : L'IA pourrait générer du code qui manque de cohérence avec la structure de votre projet.",[79,12573,12574],{},"Nommage de variables peu clair : L'IA pourrait générer des fonctions ou variables avec des noms non descriptifs, rendant le code plus difficile à comprendre.",[79,12576,12244],{},[281,12578,12580],{"className":12247,"code":12579,"language":12249,"meta":286,"style":286},"// Code généré par IA\nfunction f(x, y) {\n  return x * y;\n}\n",[261,12581,12582,12587,12608,12622],{"__ignoreMap":286},[290,12583,12584],{"class":292,"line":293},[290,12585,12586],{"class":625},"// Code généré par IA\n",[290,12588,12589,12591,12594,12596,12599,12601,12604,12606],{"class":292,"line":299},[290,12590,11293],{"class":631},[290,12592,12593],{"class":705}," f",[290,12595,652],{"class":639},[290,12597,12598],{"class":655},"x",[290,12600,665],{"class":639},[290,12602,12603],{"class":655}," y",[290,12605,676],{"class":639},[290,12607,640],{"class":639},[290,12609,12610,12612,12615,12618,12620],{"class":292,"line":305},[290,12611,11311],{"class":698},[290,12613,12614],{"class":691}," x",[290,12616,12617],{"class":639}," *",[290,12619,12603],{"class":691},[290,12621,716],{"class":639},[290,12623,12624],{"class":292,"line":311},[290,12625,1181],{"class":639},[79,12627,12628],{},"Meilleure pratique serait :",[281,12630,12632],{"className":12247,"code":12631,"language":12249,"meta":286,"style":286},"function calculateProduct(x, y) {\n  return x * y;\n}\n",[261,12633,12634,12653,12665],{"__ignoreMap":286},[290,12635,12636,12638,12641,12643,12645,12647,12649,12651],{"class":292,"line":293},[290,12637,11293],{"class":631},[290,12639,12640],{"class":705}," calculateProduct",[290,12642,652],{"class":639},[290,12644,12598],{"class":655},[290,12646,665],{"class":639},[290,12648,12603],{"class":655},[290,12650,676],{"class":639},[290,12652,640],{"class":639},[290,12654,12655,12657,12659,12661,12663],{"class":292,"line":299},[290,12656,11311],{"class":698},[290,12658,12614],{"class":691},[290,12660,12617],{"class":639},[290,12662,12603],{"class":691},[290,12664,716],{"class":639},[290,12666,12667],{"class":292,"line":305},[290,12668,1181],{"class":639},[79,12670,12671],{},"Solution de test QAI : Automatiser les vérifications des conventions de nommage et de cohérence de structure de code en utilisant des linters et formateurs comme ESLint ou Prettier.",[1612,12673,12675],{"id":12674},"_212-uiux-incohérente","2.1.2 UI/UX incohérente",[79,12677,12678],{},"L'IA pourrait générer du code UI qui ne s'aligne pas avec les principes UI/UX désirés, résultant en incohérences ou mauvaise accessibilité.",[79,12680,12681],{},"Incohérences de design : L'IA pourrait ne pas utiliser des systèmes de design cohérents, résultant en couleurs, polices et styles de composants discordants.",[79,12683,12684],{},"Accessibilité : L'IA peut négliger les fonctionnalités d'accessibilité comme les rôles ARIA ou la navigation clavier.",[79,12686,12244],{},[281,12688,12692],{"className":12689,"code":12690,"language":12691,"meta":286,"style":286},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cbutton>Cliquez-moi\u003C/button>\n","html",[261,12693,12694],{"__ignoreMap":286},[290,12695,12696,12698,12701,12703,12706,12708,12710],{"class":292,"line":293},[290,12697,11134],{"class":639},[290,12699,12700],{"class":648},"button",[290,12702,11170],{"class":639},[290,12704,12705],{"class":691},"Cliquez-moi",[290,12707,11176],{"class":639},[290,12709,12700],{"class":648},[290,12711,11140],{"class":639},[79,12713,12628],{},[281,12715,12717],{"className":12689,"code":12716,"language":12691,"meta":286,"style":286},"\u003Cbutton aria-label=\"Soumettre le formulaire\">Cliquez-moi\u003C/button>\n",[261,12718,12719],{"__ignoreMap":286},[290,12720,12721,12723,12725,12728,12730,12732,12735,12737,12739,12741,12743,12745],{"class":292,"line":293},[290,12722,11134],{"class":639},[290,12724,12700],{"class":648},[290,12726,12727],{"class":631}," aria-label",[290,12729,2997],{"class":639},[290,12731,911],{"class":639},[290,12733,12734],{"class":813},"Soumettre le formulaire",[290,12736,911],{"class":639},[290,12738,11170],{"class":639},[290,12740,12705],{"class":691},[290,12742,11176],{"class":639},[290,12744,12700],{"class":648},[290,12746,11140],{"class":639},[79,12748,12749],{},"Solution de test QAI : Utiliser des outils de test d'accessibilité comme axe-core ou Lighthouse pour automatiser la détection des problèmes d'accessibilité et s'assurer que le code généré par IA adhère aux standards d'accessibilité.",[135,12751,12753],{"id":12752},"_213-vulnérabilités-de-sécurité","2.1.3 Vulnérabilités de sécurité",[79,12755,12756],{},"L'IA pourrait involontairement introduire des risques de sécurité en générant du code non sécurisé, particulièrement autour des entrées utilisateur ou appels API.",[79,12758,12759],{},"Vulnérabilités XSS : L'IA peut échouer à nettoyer correctement les entrées utilisateur, exposant votre application au cross-site scripting (XSS).",[79,12761,12762],{},"Appels API non sécurisés : L'IA peut générer des appels API sans HTTPS, exposant les données sensibles à l'interception.",[79,12764,12244],{},[281,12766,12768],{"className":12247,"code":12767,"language":12249,"meta":286,"style":286},"// Appel API non sécurisé généré par IA\nfetch('/api/user', { method: 'POST', body: JSON.stringify(user) })\n  .then(response => response.json());\n",[261,12769,12770,12775,12824],{"__ignoreMap":286},[290,12771,12772],{"class":292,"line":293},[290,12773,12774],{"class":625},"// Appel API non sécurisé généré par IA\n",[290,12776,12777,12780,12782,12784,12787,12789,12791,12793,12795,12797,12799,12802,12804,12806,12809,12811,12813,12815,12817,12820,12822],{"class":292,"line":299},[290,12778,12779],{"class":705},"fetch",[290,12781,652],{"class":691},[290,12783,817],{"class":639},[290,12785,12786],{"class":813},"/api/user",[290,12788,817],{"class":639},[290,12790,665],{"class":639},[290,12792,2963],{"class":639},[290,12794,3057],{"class":648},[290,12796,659],{"class":639},[290,12798,1151],{"class":639},[290,12800,12801],{"class":813},"POST",[290,12803,817],{"class":639},[290,12805,665],{"class":639},[290,12807,12808],{"class":648}," body",[290,12810,659],{"class":639},[290,12812,3044],{"class":691},[290,12814,200],{"class":639},[290,12816,3049],{"class":705},[290,12818,12819],{"class":691},"(user) ",[290,12821,3064],{"class":639},[290,12823,11259],{"class":691},[290,12825,12826,12829,12832,12834,12836,12838,12840,12842,12844,12847],{"class":292,"line":305},[290,12827,12828],{"class":639},"  .",[290,12830,12831],{"class":705},"then",[290,12833,652],{"class":691},[290,12835,1052],{"class":655},[290,12837,11504],{"class":631},[290,12839,1168],{"class":691},[290,12841,200],{"class":639},[290,12843,1737],{"class":705},[290,12845,12846],{"class":691},"())",[290,12848,716],{"class":639},[79,12850,12851],{},"Meilleure pratique :",[281,12853,12855],{"className":12247,"code":12854,"language":12249,"meta":286,"style":286},"fetch('/api/user', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify(user),\n  secure: true\n}).then(response => response.json());\n",[261,12856,12857,12873,12888,12915,12933,12942],{"__ignoreMap":286},[290,12858,12859,12861,12863,12865,12867,12869,12871],{"class":292,"line":293},[290,12860,12779],{"class":705},[290,12862,652],{"class":691},[290,12864,817],{"class":639},[290,12866,12786],{"class":813},[290,12868,817],{"class":639},[290,12870,665],{"class":639},[290,12872,640],{"class":639},[290,12874,12875,12878,12880,12882,12884,12886],{"class":292,"line":299},[290,12876,12877],{"class":648},"  method",[290,12879,659],{"class":639},[290,12881,1151],{"class":639},[290,12883,12801],{"class":813},[290,12885,817],{"class":639},[290,12887,820],{"class":639},[290,12889,12890,12893,12895,12897,12899,12902,12904,12906,12908,12911,12913],{"class":292,"line":305},[290,12891,12892],{"class":648},"  headers",[290,12894,659],{"class":639},[290,12896,2963],{"class":639},[290,12898,1151],{"class":639},[290,12900,12901],{"class":648},"Content-Type",[290,12903,817],{"class":639},[290,12905,659],{"class":639},[290,12907,1151],{"class":639},[290,12909,12910],{"class":813},"application/json",[290,12912,817],{"class":639},[290,12914,8711],{"class":639},[290,12916,12917,12920,12922,12924,12926,12928,12931],{"class":292,"line":311},[290,12918,12919],{"class":648},"  body",[290,12921,659],{"class":639},[290,12923,3044],{"class":691},[290,12925,200],{"class":639},[290,12927,3049],{"class":705},[290,12929,12930],{"class":691},"(user)",[290,12932,820],{"class":639},[290,12934,12935,12938,12940],{"class":292,"line":317},[290,12936,12937],{"class":648},"  secure",[290,12939,659],{"class":639},[290,12941,7397],{"class":7396},[290,12943,12944,12946,12948,12950,12952,12954,12956,12958,12960,12962,12964,12966],{"class":292,"line":324},[290,12945,3064],{"class":639},[290,12947,676],{"class":691},[290,12949,200],{"class":639},[290,12951,12831],{"class":705},[290,12953,652],{"class":691},[290,12955,1052],{"class":655},[290,12957,11504],{"class":631},[290,12959,1168],{"class":691},[290,12961,200],{"class":639},[290,12963,1737],{"class":705},[290,12965,12846],{"class":691},[290,12967,716],{"class":639},[79,12969,12970],{},"Solution de test QAI : Utiliser des outils comme OWASP ZAP ou Snyk pour les audits de sécurité et le scan automatisé de vulnérabilités pour vérifier les risques comme XSS, injection SQL, et plus.",[135,12972,12974],{"id":12973},"_214-problèmes-de-performance","2.1.4 Problèmes de performance",[79,12976,12977],{},"Les outils IA peuvent générer du code qui fonctionne mais n'est pas optimisé pour la performance.",[79,12979,12980],{},"Rendu inefficace : L'IA pourrait échouer à considérer la performance de rendu, résultant en manipulations DOM inutiles ou re-rendus.",[79,12982,12983],{},"Bundles non optimisés : Le code généré par IA peut ne pas tirer parti du lazy loading ou du code splitting, causant des tailles de bundle plus grandes et des temps de chargement plus lents.",[79,12985,12244],{},[281,12987,12989],{"className":12247,"code":12988,"language":12249,"meta":286,"style":286},"// Généré par IA sans debouncing\ninputElement.addEventListener('input', function() {\n  renderResults();\n});\n",[261,12990,12991,12996,13023,13032],{"__ignoreMap":286},[290,12992,12993],{"class":292,"line":293},[290,12994,12995],{"class":625},"// Généré par IA sans debouncing\n",[290,12997,12998,13001,13003,13006,13008,13010,13013,13015,13017,13019,13021],{"class":292,"line":299},[290,12999,13000],{"class":691},"inputElement",[290,13002,200],{"class":639},[290,13004,13005],{"class":705},"addEventListener",[290,13007,652],{"class":691},[290,13009,817],{"class":639},[290,13011,13012],{"class":813},"input",[290,13014,817],{"class":639},[290,13016,665],{"class":639},[290,13018,11619],{"class":631},[290,13020,760],{"class":639},[290,13022,640],{"class":639},[290,13024,13025,13028,13030],{"class":292,"line":305},[290,13026,13027],{"class":705},"  renderResults",[290,13029,760],{"class":648},[290,13031,716],{"class":639},[290,13033,13034,13036,13038],{"class":292,"line":311},[290,13035,3064],{"class":639},[290,13037,676],{"class":691},[290,13039,716],{"class":639},[79,13041,12851],{},[281,13043,13045],{"className":12247,"code":13044,"language":12249,"meta":286,"style":286},"const debouncedRender = debounce(() => renderResults(), 300);\ninputElement.addEventListener('input', debouncedRender);\n",[261,13046,13047,13079],{"__ignoreMap":286},[290,13048,13049,13051,13054,13056,13059,13061,13063,13065,13068,13070,13072,13075,13077],{"class":292,"line":293},[290,13050,2991],{"class":631},[290,13052,13053],{"class":691}," debouncedRender ",[290,13055,2997],{"class":639},[290,13057,13058],{"class":705}," debounce",[290,13060,652],{"class":691},[290,13062,760],{"class":639},[290,13064,11504],{"class":631},[290,13066,13067],{"class":705}," renderResults",[290,13069,760],{"class":691},[290,13071,665],{"class":639},[290,13073,13074],{"class":1077}," 300",[290,13076,676],{"class":691},[290,13078,716],{"class":639},[290,13080,13081,13083,13085,13087,13089,13091,13093,13095,13097,13100],{"class":292,"line":299},[290,13082,13000],{"class":691},[290,13084,200],{"class":639},[290,13086,13005],{"class":705},[290,13088,652],{"class":691},[290,13090,817],{"class":639},[290,13092,13012],{"class":813},[290,13094,817],{"class":639},[290,13096,665],{"class":639},[290,13098,13099],{"class":691}," debouncedRender)",[290,13101,716],{"class":639},[79,13103,13104],{},"Solution de test QAI : Exploiter les outils de performance comme WebPageTest ou Lighthouse pour mesurer les temps de rendu, tailles de bundle et temps de chargement des ressources. Vérifier régulièrement les goulots d'étranglement de performance causés par le code généré par IA.",[1612,13106,13108],{"id":13107},"_215-gestion-des-versions-et-dépendances","2.1.5 Gestion des versions et dépendances",[79,13110,13111],{},"Les outils IA pourraient suggérer des bibliothèques obsolètes ou incompatibles, menant à des problèmes de dépendances.",[79,13113,13114],{},"Bibliothèques obsolètes : L'IA pourrait suggérer des versions obsolètes de bibliothèques ou frameworks, résultant en problèmes de compatibilité.",[79,13116,13117],{},"Conflits de dépendances : Le code généré par IA peut introduire des conflits avec les versions actuelles des bibliothèques dans votre projet.",[79,13119,13120],{},"Solution de test QAI : Utiliser Dependabot ou des outils similaires pour vérifier automatiquement les dépendances obsolètes et conflits de versions. S'assurer que votre package.json est à jour et compatible avec les exigences de votre projet.",[1612,13122,13124],{"id":13123},"_216-comportement-imprévisible-et-manque-de-transparence","2.1.6 Comportement imprévisible et manque de transparence",[79,13126,13127],{},"Le code généré par IA peut parfois mener à un comportement imprévisible dû au manque de contexte ou de transparence dans le processus de génération de code.",[79,13129,13130],{},"Logique cachée : L'IA pourrait introduire des solutions complexes ou non-évidentes qui pourraient mener à des bugs.",[79,13132,13133],{},"Erreurs contextuelles : L'IA peut échouer à saisir le contexte complet du projet, causant des problèmes dans certains scénarios ou cas limites.",[79,13135,13136],{},"Solution de test QAI : Conduire des revues manuelles parallèlement aux tests unitaires pour identifier les cas limites potentiels qui pourraient surgir du code généré par IA. Les frameworks de test automatisés comme Jest, Mocha, ou Cypress peuvent aider à identifier les comportements inattendus.",[1612,13138,13140],{"id":13139},"_221-atténuer-les-risques-de-lia-dans-le-développement-frontend","2.2.1 Atténuer les risques de l'IA dans le développement frontend",[79,13142,13143],{},"Pour réduire ces risques, les développeurs devraient implémenter des stratégies spécifiques, comme :",[79,13145,13146],{},"Revues de code : Le code généré par IA devrait être minutieusement revu par les développeurs pour assurer la qualité et cohérence.",[79,13148,13149],{},"Tests automatisés : Construire des tests unitaires, d'intégration et end-to-end complets pour détecter les problèmes tôt et s'assurer que le frontend se comporte comme attendu.",[79,13151,13152],{},"Tests de performance : Utiliser des outils de performance comme Lighthouse ou WebPageTest pour surveiller continuellement les vitesses de rendu et l'utilisation des ressources.",[79,13154,13155],{},"Audits de sécurité : Utiliser des outils de sécurité automatisés pour détecter les vulnérabilités potentielles dans le code généré par IA.",[79,13157,13158],{},"Vérifications manuelles et automatisées : Utiliser des outils de linting et formatage (ex : ESLint, Prettier) pour appliquer les meilleures pratiques, et exécuter des vérifications d'accessibilité à travers des outils comme axe-core.",[135,13160,3126],{"id":3123},[79,13162,13163],{},"En combinant les pratiques d'AQ frontend traditionnelles avec des stratégies spécifiques QAI, nous pouvons efficacement s'assurer que le développement frontend assisté par IA ne compromet pas la qualité, sécurité, performance ou expérience utilisateur. Il est essentiel d'équilibrer la commodité des outils IA avec des tests et validations soigneux pour assurer des applications frontend robustes et fiables.",[2183,13165,13166],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":286,"searchDepth":299,"depth":299,"links":13168},[13169,13170,13177,13181,13182,13187],{"id":11898,"depth":299,"text":11899},{"id":11914,"depth":299,"text":11915,"children":13171},[13172,13173,13174,13175,13176],{"id":11937,"depth":305,"text":11938},{"id":12010,"depth":305,"text":12011},{"id":12086,"depth":305,"text":12087},{"id":12146,"depth":305,"text":12147},{"id":12187,"depth":305,"text":12188},{"id":12554,"depth":299,"text":12555,"children":13178},[13179,13180],{"id":12564,"depth":305,"text":12565},{"id":12674,"depth":305,"text":12675},{"id":12752,"depth":299,"text":12753},{"id":12973,"depth":299,"text":12974,"children":13183},[13184,13185,13186],{"id":13107,"depth":305,"text":13108},{"id":13123,"depth":305,"text":13124},{"id":13139,"depth":305,"text":13140},{"id":3123,"depth":299,"text":3126},"2025-04-25","Aujourd'hui, l'IA n'est plus limitée aux projets spécialisés — elle est intégrée dans presque tout ce que nous construisons. Qu'il s'agisse d'une fonction de recherche, d'un moteur de recommandation, d'un chatbot ou d'un tableau de bord prédictif, l'IA devient un élément standard de la pile technologique.",{"src":13191},"/blog/testing/thumbnail.png",{},{"title":44,"description":13189},"m9N8QMH5OsbpBlIsdiz5Su1cStAs98p-snDh9f0k7TQ",{"id":13196,"title":48,"authors":13197,"badge":13201,"body":13203,"date":13188,"description":13797,"extension":2206,"image":13798,"meta":13800,"navigation":320,"path":49,"seo":13801,"stem":50,"__hash__":13802},"posts_fr/fr/blog/strategy.md",[13198],{"name":66,"description":13199,"to":68,"avatar":13200},"Développement Full-Stack et Architecture",{"src":10848},{"label":13202},"Stratégie",{"type":76,"value":13204,"toc":13783},[13205,13209,13212,13215,13226,13228,13232,13235,13239,13253,13364,13366,13370,13377,13397,13400,13411,13479,13481,13485,13492,13515,13519,13524,13542,13546,13563,13567,13581,13583,13587,13591,13594,13749,13752,13763,13765,13769,13772,13775,13780],[135,13206,13208],{"id":13207},"paysage-de-complexité","Paysage de complexité",[79,13210,13211],{},"La transformation numérique n'est plus un choix, c'est une nécessité. Dans un paysage technologique en constante évolution, aligner votre stratégie numérique sur les normes mondiales peut déterminer votre avantage concurrentiel.",[79,13213,13214],{},"Cet article explore :",[160,13216,13217,13220,13223],{},[163,13218,13219],{},"✅ Les principes fondamentaux de la consultation IT",[163,13221,13222],{},"✅ La planification stratégique alignée sur les normes mondiales",[163,13224,13225],{},"✅ ONE-FRONT comme cadre de collaboration entre les affaires, les développeurs et les utilisateurs",[4983,13227],{},[135,13229,13231],{"id":13230},"quest-ce-que-la-consultation-it","Qu'est-ce que la consultation IT ?",[79,13233,13234],{},"La consultation IT consiste à conseiller les organisations sur la meilleure façon d'utiliser la technologie de l'information pour atteindre leurs objectifs commerciaux. Il ne s'agit pas seulement de donner des conseils, mais de créer de la valeur stratégique et des résultats mesurables.",[1612,13236,13238],{"id":13237},"activités-principales","Activités principales :",[160,13240,13241,13244,13247,13250],{},[163,13242,13243],{},"Évaluer l'infrastructure actuelle et la maturité numérique",[163,13245,13246],{},"Identifier les lacunes et les opportunités d'optimisation",[163,13248,13249],{},"Définir une feuille de route pour la transformation numérique",[163,13251,13252],{},"Mettre en œuvre des changements technologiques",[281,13254,13257],{"className":2951,"code":13255,"filename":13256,"language":2953,"meta":286,"style":286},"export const DigitalStrategy = {\n  phases: ['Évaluation', 'Stratégie', 'Mise en œuvre', 'Évaluation'],\n  tools: ['Liste de vérification d'audit', 'Tableaux de bord KPI', 'Plans de migration vers le cloud']\n};\n","roadmap.ts",[261,13258,13259,13273,13318,13359],{"__ignoreMap":286},[290,13260,13261,13263,13266,13269,13271],{"class":292,"line":293},[290,13262,10958],{"class":698},[290,13264,13265],{"class":631}," const",[290,13267,13268],{"class":691}," DigitalStrategy ",[290,13270,2997],{"class":639},[290,13272,640],{"class":639},[290,13274,13275,13278,13280,13282,13284,13287,13289,13291,13293,13295,13297,13299,13301,13304,13306,13308,13310,13312,13314,13316],{"class":292,"line":299},[290,13276,13277],{"class":648},"  phases",[290,13279,659],{"class":639},[290,13281,916],{"class":691},[290,13283,817],{"class":639},[290,13285,13286],{"class":813},"Évaluation",[290,13288,817],{"class":639},[290,13290,665],{"class":639},[290,13292,1151],{"class":639},[290,13294,13202],{"class":813},[290,13296,817],{"class":639},[290,13298,665],{"class":639},[290,13300,1151],{"class":639},[290,13302,13303],{"class":813},"Mise en œuvre",[290,13305,817],{"class":639},[290,13307,665],{"class":639},[290,13309,1151],{"class":639},[290,13311,13286],{"class":813},[290,13313,817],{"class":639},[290,13315,926],{"class":691},[290,13317,820],{"class":639},[290,13319,13320,13323,13325,13327,13329,13332,13334,13337,13339,13341,13343,13346,13348,13350,13352,13355,13357],{"class":292,"line":305},[290,13321,13322],{"class":648},"  tools",[290,13324,659],{"class":639},[290,13326,916],{"class":691},[290,13328,817],{"class":639},[290,13330,13331],{"class":813},"Liste de vérification d",[290,13333,817],{"class":639},[290,13335,13336],{"class":691},"audit",[290,13338,817],{"class":639},[290,13340,3139],{"class":813},[290,13342,817],{"class":639},[290,13344,13345],{"class":691},"Tableaux de bord KPI",[290,13347,817],{"class":639},[290,13349,3139],{"class":813},[290,13351,817],{"class":639},[290,13353,13354],{"class":691},"Plans de migration vers le cloud",[290,13356,817],{"class":639},[290,13358,8591],{"class":813},[290,13360,13361],{"class":292,"line":311},[290,13362,13363],{"class":691},"};\n",[4983,13365],{},[135,13367,13369],{"id":13368},"alignement-avec-les-normes-mondiales","Alignement avec les normes mondiales",[79,13371,13372,13373,13376],{},"La consultation professionnelle aligne votre organisation sur des ",[110,13374,13375],{},"normes et des cadres internationaux",", tels que :",[160,13378,13379,13385,13391],{},[163,13380,13381,13384],{},[110,13382,13383],{},"ISO/IEC 27001"," pour la sécurité de l'information",[163,13386,13387,13390],{},[110,13388,13389],{},"ITIL"," pour la gestion des services IT",[163,13392,13393,13396],{},[110,13394,13395],{},"COBIT"," pour la gouvernance",[79,13398,13399],{},"Ces normes garantissent que vos systèmes sont :",[160,13401,13402,13405,13408],{},[163,13403,13404],{},"🔐 Sécurisés",[163,13406,13407],{},"📊 Mesurables",[163,13409,13410],{},"📈 Scalable",[281,13412,13415],{"className":1735,"code":13413,"filename":13414,"language":1737,"meta":286,"style":286},"{\n  \"serviceValueSystem\": true,\n  \"components\": [\"Gouvernance\", \"Gestion des services\", \"Amélioration continue\"]\n}\n","itil-basics.json",[261,13416,13417,13421,13435,13475],{"__ignoreMap":286},[290,13418,13419],{"class":292,"line":293},[290,13420,746],{"class":639},[290,13422,13423,13425,13428,13430,13432],{"class":292,"line":299},[290,13424,1753],{"class":639},[290,13426,13427],{"class":631},"serviceValueSystem",[290,13429,911],{"class":639},[290,13431,659],{"class":639},[290,13433,13434],{"class":639}," true,\n",[290,13436,13437,13439,13442,13444,13446,13448,13450,13453,13455,13457,13459,13462,13464,13466,13468,13471,13473],{"class":292,"line":305},[290,13438,1753],{"class":639},[290,13440,13441],{"class":631},"components",[290,13443,911],{"class":639},[290,13445,659],{"class":639},[290,13447,916],{"class":639},[290,13449,911],{"class":639},[290,13451,13452],{"class":813},"Gouvernance",[290,13454,911],{"class":639},[290,13456,665],{"class":639},[290,13458,954],{"class":639},[290,13460,13461],{"class":813},"Gestion des services",[290,13463,911],{"class":639},[290,13465,665],{"class":639},[290,13467,954],{"class":639},[290,13469,13470],{"class":813},"Amélioration continue",[290,13472,911],{"class":639},[290,13474,8591],{"class":639},[290,13476,13477],{"class":292,"line":311},[290,13478,1181],{"class":639},[4983,13480],{},[135,13482,13484],{"id":13483},"one-front-un-cadre-holistique","ONE-FRONT : Un cadre holistique",[79,13486,13487,13488,13491],{},"ONE-FRONT n'est pas seulement un outil, c'est une ",[110,13489,13490],{},"stratégie collaborative"," où la technologie est alignée autour de trois axes vitaux :",[160,13493,13494,13501,13508],{},[163,13495,13496,13497,13500],{},"🏢 ",[110,13498,13499],{},"Objectifs commerciaux"," : Nous veillons à ce que la technologie soit conçue pour générer de la valeur réelle",[163,13502,13503,13504,13507],{},"👩‍💻 ",[110,13505,13506],{},"Développeurs"," : Nous donnons aux équipes des architectures modulaires et scalables",[163,13509,13510,13511,13514],{},"🙋 ",[110,13512,13513],{},"Utilisateurs"," : Nous centrons le développement autour des retours et des besoins continus",[1612,13516,13518],{"id":13517},"alignement-basé-sur-les-rôles","Alignement basé sur les rôles",[79,13520,13521],{},[110,13522,13523],{},"Affaires",[11156,13525,13528],{"className":13526},[13527],"border-none",[160,13529,13530,13536,13539],{},[163,13531,13532,13533],{},"✅ Comprendre l'",[110,13534,13535],{},"espace du problème",[163,13537,13538],{},"✅ Traduire les besoins en objectifs mesurables",[163,13540,13541],{},"✅ Collaborer pour façonner la feuille de route numérique",[79,13543,13544],{},[110,13545,13506],{},[11156,13547,13549],{"className":13548},[13527],[160,13550,13551,13557,13560],{},[163,13552,13553,13554],{},"✅ Travailler dans des ",[110,13555,13556],{},"contextes délimités",[163,13558,13559],{},"✅ Fournir un logiciel modulaire et testable",[163,13561,13562],{},"✅ Adopter des architectures propres comme DDD et BFF",[79,13564,13565],{},[110,13566,13513],{},[11156,13568,13570],{"className":13569},[13527],[160,13571,13572,13575,13578],{},[163,13573,13574],{},"✅ Fournir des retours continus",[163,13576,13577],{},"✅ Valider les itérations",[163,13579,13580],{},"✅ Créer une culture de co-création",[4983,13582],{},[135,13584,13586],{"id":13585},"la-stratégie-en-pratique","La stratégie en pratique",[1612,13588,13590],{"id":13589},"exemple-conception-dirigée-par-le-domaine-ddd","Exemple : Conception dirigée par le domaine (DDD)",[79,13592,13593],{},"En alignant l'architecture du logiciel sur la logique métier, DDD améliore la scalabilité et la clarté.",[281,13595,13598],{"className":2951,"code":13596,"filename":13597,"language":2953,"meta":286,"style":286},"export class Product {\n  constructor(public id: string, public name: string, private price: number) {}\n\n  applyDiscount(rate: number) {\n    if (rate \u003C 0 || rate > 1) throw new Error('Taux invalide');\n    return this.price * (1 - rate);\n  }\n}\n","Product.ts",[261,13599,13600,13610,13651,13655,13673,13718,13741,13745],{"__ignoreMap":286},[290,13601,13602,13604,13606,13608],{"class":292,"line":293},[290,13603,10958],{"class":698},[290,13605,10961],{"class":631},[290,13607,10964],{"class":635},[290,13609,640],{"class":639},[290,13611,13612,13614,13616,13619,13621,13623,13625,13627,13630,13632,13634,13636,13638,13641,13643,13645,13647,13649],{"class":292,"line":299},[290,13613,10971],{"class":631},[290,13615,652],{"class":639},[290,13617,13618],{"class":631},"public",[290,13620,10984],{"class":655},[290,13622,659],{"class":639},[290,13624,673],{"class":635},[290,13626,665],{"class":639},[290,13628,13629],{"class":631}," public",[290,13631,10997],{"class":655},[290,13633,659],{"class":639},[290,13635,673],{"class":635},[290,13637,665],{"class":639},[290,13639,13640],{"class":631}," private",[290,13642,11010],{"class":655},[290,13644,659],{"class":639},[290,13646,7361],{"class":635},[290,13648,676],{"class":639},[290,13650,11023],{"class":639},[290,13652,13653],{"class":292,"line":305},[290,13654,321],{"emptyLinePlaceholder":320},[290,13656,13657,13660,13662,13665,13667,13669,13671],{"class":292,"line":311},[290,13658,13659],{"class":648},"  applyDiscount",[290,13661,652],{"class":639},[290,13663,13664],{"class":655},"rate",[290,13666,659],{"class":639},[290,13668,7361],{"class":635},[290,13670,676],{"class":639},[290,13672,640],{"class":639},[290,13674,13675,13677,13679,13681,13684,13686,13689,13692,13694,13697,13699,13701,13703,13705,13707,13709,13712,13714,13716],{"class":292,"line":317},[290,13676,726],{"class":698},[290,13678,729],{"class":648},[290,13680,13664],{"class":691},[290,13682,13683],{"class":639}," \u003C",[290,13685,11059],{"class":1077},[290,13687,13688],{"class":639}," ||",[290,13690,13691],{"class":691}," rate",[290,13693,11648],{"class":639},[290,13695,13696],{"class":1077}," 1",[290,13698,743],{"class":648},[290,13700,11064],{"class":698},[290,13702,754],{"class":639},[290,13704,11069],{"class":705},[290,13706,652],{"class":648},[290,13708,817],{"class":639},[290,13710,13711],{"class":813},"Taux invalide",[290,13713,817],{"class":639},[290,13715,676],{"class":648},[290,13717,716],{"class":639},[290,13719,13720,13722,13724,13726,13728,13730,13733,13735,13737,13739],{"class":292,"line":324},[290,13721,851],{"class":698},[290,13723,702],{"class":639},[290,13725,11090],{"class":691},[290,13727,12617],{"class":639},[290,13729,729],{"class":648},[290,13731,13732],{"class":1077},"1",[290,13734,11688],{"class":639},[290,13736,13691],{"class":691},[290,13738,676],{"class":648},[290,13740,716],{"class":639},[290,13742,13743],{"class":292,"line":330},[290,13744,872],{"class":639},[290,13746,13747],{"class":292,"line":336},[290,13748,1181],{"class":639},[79,13750,13751],{},"DDD, lorsqu'il est utilisé dans un cadre full-stack (Nuxt, Node.js, etc.), crée :",[160,13753,13754,13757,13760],{},[163,13755,13756],{},"🔄 Une communication claire entre les développeurs et les entreprises",[163,13758,13759],{},"🧩 Une meilleure maintenabilité",[163,13761,13762],{},"⚙️ Des décisions techniques alignées",[4983,13764],{},[135,13766,13768],{"id":13767},"votre-prochaine-étape","Votre prochaine étape",[79,13770,13771],{},"Que vous soyez une startup ou une entreprise, la consultation stratégique IT peut remodeler votre manière de croître. Avec ONE-FRONT, vous ne construisez pas seulement des logiciels — vous créez de l'alignement.",[79,13773,13774],{},"👉 Laissez la technologie travailler pour les entreprises, les développeurs et les utilisateurs.",[79,13776,13777],{},[110,13778,13779],{},"Prêt à transformer ?",[2183,13781,13782],{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":286,"searchDepth":299,"depth":299,"links":13784},[13785,13786,13789,13790,13793,13796],{"id":13207,"depth":299,"text":13208},{"id":13230,"depth":299,"text":13231,"children":13787},[13788],{"id":13237,"depth":305,"text":13238},{"id":13368,"depth":299,"text":13369},{"id":13483,"depth":299,"text":13484,"children":13791},[13792],{"id":13517,"depth":305,"text":13518},{"id":13585,"depth":299,"text":13586,"children":13794},[13795],{"id":13589,"depth":305,"text":13590},{"id":13767,"depth":299,"text":13768},"Orientation et planification stratégique pour la transformation numérique de votre entreprise, alignée sur les normes mondiales et propulsée par le cadre ONE-FRONT.",{"src":13799},"/blog/strategy/planing.png",{},{"title":48,"description":13797},"CWOFJ23zZ0g1l8FQU1yHHwPq7EYWUZECU137oD8x7Kk",1779118040214]