From 42567a5305f6200f197f2aed435b1931159050bc Mon Sep 17 00:00:00 2001 From: Blomios Date: Wed, 9 Sep 2026 16:02:05 +0200 Subject: [PATCH] =?UTF-8?q?docs(sdk):=20contrat=20d'exposition=20des=20too?= =?UTF-8?q?ls=20MCP=20par=20les=20plugins=20=E2=80=94=20#293=20(manifest:?= =?UTF-8?q?=20section=20MCP=20Servers=20And=20Agent=20Tools=20=E2=80=94=20?= =?UTF-8?q?contributes.mcpServers=20est=20le=20seul=20canal=20IdeA-native,?= =?UTF-8?q?=20aucun=20registerMcpTool/registerServer=20dans=20activate(ctx?= =?UTF-8?q?),=20r=C3=A8gles=20id/displayName/transport=20stdio/autoStart?= =?UTF-8?q?=20requis=20pour=20la=20r=C3=A9conciliation=20MCP/command=20rel?= =?UTF-8?q?atif=20r=C3=A9solu=20sous=20pluginRoot=20vs=20absolu=20refus?= =?UTF-8?q?=C3=A9=20sans=20allowAbsoluteCommand/cwd=20d=C3=A9faut=20${plug?= =?UTF-8?q?inRoot},=20assignation=20par=20triplet=20pluginId/serverId/tool?= =?UTF-8?q?Name=20devant=20matcher=20tools/list=20du=20serveur,=20example?= =?UTF-8?q?=20manifest=20align=C3=A9=20contributes.skills,=20guidance=20sc?= =?UTF-8?q?ript=20packag=C3=A9=20ex=C3=A9cutable=20vs=20lancement=20via=20?= =?UTF-8?q?binaire=20h=C3=B4te;=20activation-context:=20activate=20n'expos?= =?UTF-8?q?e=20pas=20d'API=20d'enregistrement=20de=20tools=20MCP=20?= =?UTF-8?q?=E2=80=94=20ils=20viennent=20du=20process=20serveur=20stdio=20e?= =?UTF-8?q?xterne=20et=20de=20sa=20r=C3=A9ponse=20tools/list,=20ctx.plugin?= =?UTF-8?q?Root=20officialis=C3=A9=20vs=20import.meta.url;=20project-plugi?= =?UTF-8?q?n-assignments:=20assignation=20r=C3=A9solue=20vers=20serveurs?= =?UTF-8?q?=20manifest=C3=A9s=20autoStart=20uniquement,=20flow=20skill=20?= =?UTF-8?q?=E2=86=92=20serveur=20MCP=20=E2=86=92=20tools=20assign=C3=A9s?= =?UTF-8?q?=20sans=20chemins=20relatifs=20depuis=20le=20Markdown=20servi?= =?UTF-8?q?=20par=20idea=5Fskill=5Fread;=20QA=20verte=20reconfirm=C3=A9e?= =?UTF-8?q?=20par=20Git:=20npm=20run=20check=20=E2=80=94=20build,=20typech?= =?UTF-8?q?eck:examples,=20package:hello-plugin)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/activation-context.md | 11 ++++++ docs/manifest.md | 58 ++++++++++++++++++++++++++++++ docs/project-plugin-assignments.md | 13 +++++++ 3 files changed, 82 insertions(+) diff --git a/docs/activation-context.md b/docs/activation-context.md index 2814981..14ed815 100644 --- a/docs/activation-context.md +++ b/docs/activation-context.md @@ -45,12 +45,23 @@ focused project at invocation/render time. The context never exposes internal IdeA gateways or Tauri commands. Use `ctx.services` and the registration APIs instead. +`activate(ctx)` does not expose an API for registering MCP tools directly. +Agent-callable plugin tools are provided by stdio MCP servers declared in +`idea-plugin.json` under `contributes.mcpServers`. The plugin runtime can +register menu commands and layouts in-process, but MCP tools come from the +external server process and its MCP `tools/list` response. + `pluginRoot` identifies the committed package currently loaded by IdeA. It is not the original source directory or archive path and may change after reinstall. Treat it as read-only, do not persist it, and resolve packaged scripts/assets under it only while the plugin is active. Workspace services remain confined to project-owned paths. +Use `ctx.pluginRoot` as the official way to resolve packaged scripts/assets from +runtime code. `import.meta.url` can still be useful inside a bundle for ordinary +module-relative JavaScript resolution, but it is not the host/plugin contract +for the installed package root. + ## Disposal Push every returned disposable to `ctx.subscriptions`: diff --git a/docs/manifest.md b/docs/manifest.md index b965d1c..892bb96 100644 --- a/docs/manifest.md +++ b/docs/manifest.md @@ -115,6 +115,7 @@ development loop. "capabilities": ["ui", "tooling"], "activationScope": "app", "contributes": { + "skills": [], "menus": [], "menuItems": [], "layouts": [], @@ -247,6 +248,57 @@ Contribution ids are part of the runtime contract: - `services.windows.open({ layoutType })` only accepts a layout type declared by the calling plugin. +## MCP Servers And Agent Tools + +`contributes.mcpServers` is the IdeA-native contract for plugin-provided +agent tools. A plugin does not register individual MCP tools from `activate(ctx)`. +Instead, the plugin ships or references a stdio MCP server process, declares it +in the manifest, and that server advertises its own tools through the MCP +`tools/list` protocol. + +```json +{ + "capabilities": ["mcp"], + "contributes": { + "mcpServers": [ + { + "id": "unity-editor", + "displayName": "Unity Editor Tools", + "command": "scripts/unity-mcp-server.mjs", + "args": [], + "cwd": "${pluginRoot}", + "transport": "stdio", + "autoStart": true + } + ] + } +} +``` + +MCP server contribution rules: + +- `id` is stable within the plugin and is used by project/agent assignments. +- `displayName` is the human-readable server name shown in plugin settings. +- `transport` must currently be `"stdio"`. +- `autoStart: true` is required for IdeA to start the server during plugin MCP + reconciliation. Non-auto-start servers are manifest metadata only today. +- A relative `command` is resolved under the installed plugin package root. +- An absolute `command` is rejected unless `allowAbsoluteCommand: true` is set. + Use this only for an intentional dependency on a host binary. +- `cwd` defaults to `${pluginRoot}` when omitted. + +The tools an agent can call are assigned with the triplet +`pluginId`/`serverId`/`toolName` in project plugin settings. `toolName` must +match a tool name advertised by the MCP server. IdeA does not currently provide +a runtime API such as `ctx.mcp.registerTool()` or `ctx.mcp.registerServer()`. + +For multi-harness workflows, keep `contributes.skills` as instructions and +expose executable behavior through assigned MCP tools. Do not make skill +Markdown depend on filesystem paths relative to the Markdown returned by +`idea_skill_read`; that body is served as read-only content, not mounted as a +working directory. If a skill needs packaged scripts, put the script behind a +manifest-declared MCP server and tell the agent to call the assigned tool. + ## MCP Server Paths `contributes.mcpServers` entries are resolved by the host before starting a @@ -260,6 +312,12 @@ Runtime handlers receive the same installed package location separately as `ctx.pluginRoot`; `ctx.services.tasks.runCommand()` does not perform placeholder substitution, and workspace APIs remain project-confined. +Prefer a packaged executable script for plugin-owned MCP servers, for example +`command: "scripts/unity-mcp-server.mjs"` with an appropriate shebang and file +mode. If the server must be launched through a host executable such as Node, +use an absolute command with `allowAbsoluteCommand: true` and keep plugin-owned +paths in `args`, for example `${pluginRoot}/scripts/unity-mcp-server.mjs`. + ## Validation Use the SDK validator in tests or build tooling: diff --git a/docs/project-plugin-assignments.md b/docs/project-plugin-assignments.md index dae1e9a..d88835f 100644 --- a/docs/project-plugin-assignments.md +++ b/docs/project-plugin-assignments.md @@ -69,6 +69,12 @@ An agent MCP tool reference contains: - `toolName`: the exact tool name advertised by that MCP server. The UI accepts this name as text because a dynamic MCP tool catalogue is not yet available. +IdeA resolves plugin MCP assignments to manifest-declared servers, not to +in-process handlers registered from `activate(ctx)`. A tool assignment is useful +only when the plugin is enabled, runtime-active, the referenced MCP server has +`autoStart: true`, and the server process advertises the named tool through MCP +`tools/list`. + Missing `plugins`, `agents`, `skills`, or `tools` arrays default to empty arrays when IdeA reads the document. Prefer writing them explicitly for clarity and forward-compatible review. @@ -152,3 +158,10 @@ These actions solve different problems: When both package content and assignments changed, reload the plugin first, confirm it is enabled for the project, update the assignments, then relaunch the agent. + +If a plugin skill describes a workflow backed by packaged scripts, prefer this +flow: ship the scripts in the plugin package, expose them through a +manifest-declared MCP server, assign the specific MCP tools to the target agent, +and have the skill instruct the agent to call those tools. Avoid relative paths +from the skill Markdown to packaged scripts; the Markdown served by +`idea_skill_read` is content, not a stable filesystem anchor.