Files
IdeA/.ideai/tickets/302/carnet.md

14 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#302 5
kind agent_id
agent a6c6ea12-bfc6-4bdc-8031-324102dfa34d
1788990131498

Carnet #302 - MCP tools plugin non visibles par l'agent cible

Signalement

  • Date: 2026-09-09.
  • Projet utilisateur mentionné: UnitySOundTool.
  • Plugin mentionné: Unity fait par UnityPlugin.
  • Agent cible: Main du projet UnitySOundTool.
  • Tool attendu: unity_detect_project.

Observation capture

  • L'agent répond qu'il voit des workflows Unity côté IdeA (unity-test-runner, unity-project-diagnostics, etc.).
  • Il ne voit pas de tool MCP Unity direct.
  • Une recherche explicite de unity_detect_project dans les tools disponibles/différés retourne 0 tools.
  • Les tools disponibles visibles dans la session concernent surtout IdeA, Sites, document control et hotline, pas Unity Editor.

Hypothèses initiales à vérifier

  • Le plugin expose bien des skills/workflows mais pas de serveur MCP/tool dans son manifeste effectif.
  • Les MCP tools du plugin sont installés mais non ajoutés aux permissions MCP de l'agent ou non propagés à la session lancée.
  • Les tools ont été ajoutés après démarrage et nécessitent restart/reload de l'agent ou du plugin.
  • La source de deferred tools consommée par tool_search ne fusionne pas les MCP tools issus de plugins personnels/projet.
  • Le contexte/capability summary liste les skills Unity mais pas les MCP tools, ce qui suggère une divergence entre capabilities manifestées et tools réellement exposés.

Cadrage Architect

Architect a confirmé que les skills plugin et les MCP tools plugin sont deux flux distincts. Les workflows Unity visibles prouvent seulement que les contributions skills du plugin sont résolues et injectées.

Flux à vérifier:

  1. Manifeste plugin: contributes.mcpServers[], autoStart: true, server.id, command, tools incluant unity_detect_project.
    • crates/domain/src/plugin.rs
    • crates/application/src/plugin/mod.rs
  2. Reconciliation serveur MCP plugin: active_mcp_specs ne démarre que les plugins runtime_active et serveurs auto_start, puis passe les specs au PluginMcpSupervisor.
    • crates/application/src/plugin/mod.rs
    • crates/infrastructure/src/plugin/mod.rs
  3. Affectation agent: l'UI persiste un PluginToolRef { pluginId, serverId, toolName } via plugin_assign_agent_tool dans ProjectPluginSettings, pas dans .ideai/mcp-tool-permissions.json.
    • crates/application/src/project_plugin.rs
    • crates/backend/src/dto.rs
    • frontend/src/features/permissions/McpToolPermissionsPanel.tsx
  4. Session runtime agent: point suspect principal. Le lancement semble matérialiser surtout le serveur MCP idea dans la config runtime ([mcp_servers.idea] / .mcp.json) sans consommer assignments.tools plugin pour ajouter les serveurs MCP Unity au run dir de l'agent.
    • crates/application/src/agent/lifecycle.rs
    • crates/backend/src/lib.rs
  5. Catalogue tool_search / deferred tools: pour OpenAI/direct, tools_for_context semble renvoyer seulement le catalogue MCP IdeA natif filtré par policy, pas les tools métier plugin.
    • crates/backend/src/openai_tools.rs
    • crates/infrastructure/src/orchestrator/mcp/tools.rs

Contrat attendu:

  • Une affectation PluginToolRef à un agent doit avoir un effet runtime vérifiable au prochain démarrage/restart de cet agent.
  • Pour les profils via client MCP (Codex/Claude/OpenCode), matérialiser les serveurs MCP plugin assignés dans la config de session agent avec un nom stable.
  • Pour OpenAI/direct/deferred tools, étendre ToolInvoker::tools_for_context et call ou introduire un provider dédié, sinon tool_search restera aveugle.
  • Ne pas ajouter naïvement ces tools au catalogue MCP IdeA natif tant qu'IdeA n'est pas proxy MCP dynamique.

Responsables

  • DevBackend en premier: propagation affectation plugin -> session runtime / catalogue provider.
  • DevFrontend seulement si l'UI affiche une affectation comme effective alors qu'un restart est requis, permet de cocher un tool dont le plugin/server n'est pas actif, ou mélange catalogue manifeste et disponibilité runtime.
  • QA: reproduction avec plugin MCP minimal ou Unity, vérifier visibilité et appelabilité du tool.

Critères QA proposés

  • Installer/activer un plugin test avec serveur MCP stdio autoStart: true exposant unity_detect_project.
  • Assigner le tool à Main.
  • Redémarrer l'agent si le contrat reste prise en compte au lancement.
  • Chercher explicitement unity_detect_project dans la session Main via tools disponibles/différés.
  • Vérifier tool visible et appelable.
  • Agent sans affectation ne voit pas le tool.
  • Plugin désactivé/serveur en erreur: tool absent ou état clair, pas de faux positif.
  • Permissions MCP natives IdeA continuent de filtrer idea_* sans pollution par PluginToolRef.

Implémentation DevBackend — 2026-09-09

Cause confirmée:

  • ProjectPluginSettings.assignments.tools était correctement persisté dans .ideai/project-plugins.json par MutateAgentPluginTool.
  • Le launcher partageait le resolver des skills plugin, mais ne consommait jamais les PluginToolRef; les configs de session ne contenaient donc que le serveur MCP natif idea.

Correctif:

  • ProjectPluginResolver::assigned_mcp_servers projette les affectations de l'agent en specs stdio uniquement lorsque le plugin est activé pour le projet, runtime-active, installé, et que le serveur assigné est autoStart.
  • Les variables ${pluginRoot} et ${appDataDir} sont résolues comme dans la réconciliation globale des serveurs plugin; les serveurs sont dédupliqués par (pluginId, serverId).
  • Nom de session stable et sans collision: idea_plugin__<plugin-id encodé>__<server-id encodé>.
  • Au lancement/restart, le launcher matérialise les serveurs pertinents dans:
    • Claude: .mcp.json, puis enabledMcpjsonServers dans .claude/settings.local.json;
    • Codex: .codex/config.toml sous mcp_servers;
    • OpenCode local/cloud: bloc mcp dans opencode.json.
  • Un restart interne sans McpRuntime conserve le wiring réel idea déjà écrit et ne réconcilie que les entrées plugin gérées. Les entrées plugin devenues obsolètes sont retirées.
  • Les racines cwd/commande des serveurs assignés sont ajoutées en lecture au plan Landlock quand un plan existe, pour que le processus plugin puisse réellement lire son package.
  • Aucun changement dans .ideai/mcp-tool-permissions.json ni dans le catalogue natif idea_*.

Fichiers modifiés:

  • crates/domain/src/plugin.rs
  • crates/application/src/project_plugin.rs
  • crates/application/src/agent/lifecycle.rs
  • crates/backend/src/lib.rs
  • .ideai/tickets/302/carnet.md

Chemin OpenAI/direct/deferred:

  • Le symptôme Main/Codex n'utilise pas AppOpenAiToolInvoker::tools_for_context: Codex consomme son client MCP natif et son tool_search découvre les serveurs déclarés dans le CODEX_HOME isolé.
  • OpenAiCompatibleSession, en revanche, continue à ne recevoir que les tools locaux idea_*. Le superviseur plugin actuel ne possède pas de client JSON-RPC (tools/list/tools/call), seulement des handles de processus; rendre les tools métier plugin appelables par ce chemin nécessite un provider/client MCP dédié. Ce gap ne bloque pas la correction du cas signalé et n'a pas été contourné en polluant le catalogue natif.

Tests et vérifications exécutés:

  • cargo test -p application --lib — 178 passés.
  • cargo test -p application --test agent_lifecycle — 111 passés.
  • cargo test -p domain plugin --lib — 7 passés.
  • cargo check -p backend — OK.
  • cargo check -p app-tauri — OK.
  • cargo fmt --all puis git diff --check — OK.

Tests ciblés ajoutés:

  • matérialisation d'un serveur assigné dans les trois formats Claude/Codex/OpenCode;
  • conservation du wiring idea réel lors d'un restart interne et suppression des entrées plugin obsolètes;
  • stabilité et absence de collision du nom MCP client;
  • conservation des clés/tables Codex non gérées lors de la réconciliation.

Validation QA — 2026-09-09

Verdict: VERT.

Inspection:

  • Diff relu sur crates/application/src/project_plugin.rs, crates/application/src/agent/lifecycle.rs, crates/domain/src/plugin.rs, crates/backend/src/lib.rs.
  • Le correctif ne modifie pas .ideai/mcp-tool-permissions.json et ne projette pas les tools plugin dans le catalogue natif idea_*; il matérialise des serveurs MCP plugin assignés dans les configs de session Claude/Codex/OpenCode.
  • Gap OpenAiCompatibleSession: confirmé comme non bloquant pour le symptôme utilisateur décrit, car le cas Main/Codex passe par client MCP natif et CODEX_HOME isolé. À suivre séparément si un profil OpenAI/direct doit appeler directement les MCP tools plugin.

Couverture QA ajoutée:

  • project_plugin::tests::assigned_mcp_servers_project_assigned_active_autostart_server_only
    • vérifie qu'un PluginToolRef assigné produit un PluginMcpServerSpec unique, avec nom stable idea_plugin__..., substitution ${pluginRoot} / ${appDataDir}, commande relative résolue sous le package plugin, env/cwd corrects.
  • project_plugin::tests::assigned_mcp_servers_omits_unassigned_disabled_and_non_autostart_servers
    • vérifie l'absence quand le serveur n'est pas assigné, quand le plugin est désactivé au niveau projet, quand il est désactivé globalement, ou quand le serveur assigné n'est pas autoStart.

Commandes exécutées et résultats:

  • cargo test -p application --lib assigned_mcp_servers
    • OK: 2 passed; 0 failed; 178 filtered out.
  • cargo test -p application --lib plugin_server
    • OK: 5 passed; 0 failed; 175 filtered out.
  • cargo test -p application --lib
    • OK: 180 passed; 0 failed.
  • cargo test -p application --test agent_lifecycle
    • OK: 111 passed; 0 failed.
  • cargo test -p domain plugin --lib
    • OK: 7 passed; 0 failed.
  • cargo check -p backend
    • OK: Finished dev profile.
  • cargo check -p app-tauri
    • OK: Finished dev profile.
  • cargo fmt --all -- --check
    • OK après formatage des tests QA ajoutés.
  • git diff --check
    • OK.

Tentatives remplacées:

  • Deux commandes cargo test avec plusieurs filtres positionnels ont échoué sur erreur d'usage Cargo (unexpected argument ...). Elles ont été remplacées par cargo test -p application --lib, cargo test -p application --lib plugin_server et cargo test -p application --test agent_lifecycle, toutes vertes.

Conclusion:

  • Serveur MCP plugin assigné: injecté au lancement/restart dans les formats client visés avec un nom stable et sans collision.
  • Serveur non assigné/désactivé/non-autoStart: non injecté.
  • Serveur MCP natif idea: conservé, y compris au restart interne sans runtime, et non pollué par les entrées plugin.
  • Aucun finding bloquant.

Topologie Git — 2026-09-09

QA reconfirmée par Git avant commit (exécution réelle):

  • rustup run stable cargo fmt --all -- --check — OK.
  • git diff --check — OK.
  • cargo test -p application --lib — 180/180.
  • cargo test -p application --test agent_lifecycle — 111/111.
  • cargo test -p domain plugin --lib — 7/7.
  • cargo check -p backend — OK.
  • cargo check -p app-tauri — OK.

Commit du correctif (4 fichiers uniquement, bookkeeping exclu):

  • Branche: fix/302-plugin-mcp-tools-not-visible.
  • Commit: 78b379a — fix(application,domain,backend): les serveurs MCP des plugins assignés atteignent la session de l'agent — #302.
  • Fichiers: crates/domain/src/plugin.rs, crates/application/src/project_plugin.rs, crates/application/src/agent/lifecycle.rs, crates/backend/src/lib.rs.
  • Exclus (hors périmètre, restés en worktree): .ideai/tickets/296/*, .ideai/tickets/299-302/*, counter.json, index.json, .ideai/attachments/, scripts/.

Merge local:

  • develop ← merge --no-ff de fix/302-plugin-mcp-tools-not-visible → commit 9e9498b.
  • develop n'avait pas divergé depuis la création de la branche (fast-path, contenu identique à 78b379a).
  • Branche fix/302-plugin-mcp-tools-not-visible conservée (convention du dépôt, pas de suppression).
  • Aucune action distante (aucun push; develop reste en avance locale sur origin/develop).

Restants hors topologie:

  • Gap OpenAiCompatibleSession/tools_for_context (tools plugin non appelables en direct) — ticket séparé à ouvrir si besoin.
  • Validation live du symptôme UnitySOundTool depuis l'app installée: nécessite un rebuild AppImage (commit dédié + tag vx.y.z selon convention, incrément y sur develop).

Rebuild AppImage — 2026-09-09

Rebuild exécuté par Main depuis develop @ 9e9498b (incluant le merge #302):

  • Commandes: npm --prefix frontend run build OK, puis depuis crates/app-tauri: mkdir -p /tmp/idea-cargo-home && CARGO_HOME=/tmp/idea-cargo-home APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage OK.
  • Artefact: target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage, 119699960 octets, sha256 d016aab3b643bab61a1ab864a4b5f5e5ab57ff1c493f12d1002918efa5c08c33 (vérifié par Git).

Traçabilité Git:

  • Commit dédié --allow-empty (l'artefact vit sous target/ gitignoré): 3911ce1 sur develop — chore(appimage): rebuild AppImage develop — commit dédié v0.44.0 #302.
  • Tag annoté v0.44.0 posé sur 3911ce1 (convention respectée: y incrémenté pour un rebuild committé sur develop, v0.43.0 -> v0.44.0).
  • Bookkeeping carnet/index/counter et fichiers hors périmètre exclus, restés en worktree. Aucun push.

Restant après rebuild:

  • Validation live UnitySOundTool depuis l'app installée (v0.44.0): unity_detect_project visible et appelable par Main après restart de l'agent, agent sans affectation ne voit pas le tool.