diff --git a/src/pages/compte/mcp.py b/src/pages/compte/mcp.py index cc8018e..236b4e8 100644 --- a/src/pages/compte/mcp.py +++ b/src/pages/compte/mcp.py @@ -45,6 +45,26 @@ def client_instructions(url: str, token: str): title="Claude Code", children=html.Pre(html.Code(claude)), ), + dbc.AccordionItem( + title="Claude.ai / Claude Desktop / mobile", + children=[ + html.P("Aucun jeton à copier : ces applications utilisent OAuth."), + html.Ol( + [ + html.Li( + "Paramètres → Connecteurs → Ajouter un connecteur personnalisé." + ), + html.Li(f"URL du serveur MCP : {url}"), + html.Li( + "Laissez le champ « Client Secret » vide (client public)." + ), + html.Li( + "Connectez-vous avec votre compte colibre, puis « Autoriser »." + ), + ] + ), + ], + ), dbc.AccordionItem( title="Gemini CLI", children=[ @@ -68,8 +88,20 @@ def client_instructions(url: str, token: str): title="ChatGPT", children=[ html.P( - """L'app ChatGPT grand public exige une technique d'authentification plus complexe - qu'un simple jeton. Votez pour cette fonctionnalité si elle peut vous être utile.""" + "ChatGPT utilise aussi OAuth (aucun jeton à copier). Dans les " + "connecteurs, ajoutez un connecteur par URL :" + ), + html.Ol( + [ + html.Li(f"URL du serveur MCP : {url}"), + html.Li( + "Connectez-vous avec colibre, puis autorisez l'accès." + ), + ] + ), + html.P( + "La disponibilité des connecteurs dépend de votre plan ChatGPT.", + className="text-muted", ), ], ), @@ -185,9 +217,10 @@ def layout(**_): [ html.H2("Connecteur MCP"), html.P( - "Générez un jeton pour connecter votre agent IA (Claude, Gemini, " - "Mistral…) aux données colibre via le protocole MCP. Le jeton vaut " - "votre identité : gardez-le secret. Un abonnement actif est requis." + "Les clients en ligne de commande (Claude Code, Gemini, Mistral) se " + "connectent avec un jeton généré ci-dessous. Les applications grand " + "public (Claude.ai, ChatGPT) se connectent par OAuth, sans jeton à " + "copier. Dans tous les cas, un abonnement actif est requis." ), *alerts, html.H4("Générer un jeton", className="mt-3"), diff --git a/tests/mcp/test_account_page.py b/tests/mcp/test_account_page.py index ef854ec..6bfc9d7 100644 --- a/tests/mcp/test_account_page.py +++ b/tests/mcp/test_account_page.py @@ -22,3 +22,32 @@ def test_page_module_registers_and_builds_client_instructions(): assert "https://colibre.fr/_mcp" in text for client_name in ("Claude", "Gemini", "Mistral", "ChatGPT"): assert client_name in text + + +def test_client_instructions_include_oauth_apps(): + from src.app import app # noqa: F401 + from src.pages.compte.mcp import client_instructions + + comp = client_instructions("https://colibre.fr/_mcp", "") + titles = _collect_titles(comp) + assert any("Claude.ai" in t for t in titles) + assert any("ChatGPT" in t for t in titles) + + +def _collect_titles(component): + # Parcourt récursivement les AccordionItem pour collecter leurs `title`. + found = [] + + def walk(node): + title = getattr(node, "title", None) + if isinstance(title, str): + found.append(title) + children = getattr(node, "children", None) + if isinstance(children, (list, tuple)): + for c in children: + walk(c) + elif children is not None: + walk(children) + + walk(component) + return found