--- issueRef: "#302" version: 5 updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} updatedAt: 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____`. - 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.