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.