feat(mcp): add run_task tool for executing mise tasks#8179
Conversation
Implements the run_task MCP tool that allows AI assistants to execute mise tasks with optional arguments, returning stdout/stderr and exit status.
…t handling Replace spawn_blocking with tokio::process::Command for direct async execution. Simplify output formatting using match expressions and use ErrorData types. Update docs to reflect implemented run_task tool.
- Use spawn() with kill_on_drop(true) to prevent orphaned processes on timeout - Set stdin to Stdio::null() to isolate child from MCP JSON-RPC transport - Add -- separator before task args to prevent flag confusion with mise run - Add install_tool stub with proper schema via ToolRouter - Rewrite e2e tests with full protocol coverage: initialize handshake, tools/list schema validation, run_task success/args/unknown, install_tool stub - Remove hardcoded developer path and unnecessary chmod from test
Summary of ChangesHello @joaommartins, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Model Context Protocol (MCP) integration within Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a run_task tool for the MCP server, allowing AI assistants to execute mise tasks. The implementation is robust, including features like subprocess hardening, timeout support, and integration with schemars for self-describing tools. The e2e tests have been significantly improved to provide comprehensive coverage of the MCP protocol, and the documentation is updated accordingly.
My review focuses on improving code readability in the new run_task implementation. I've suggested refactoring a couple of match statements to use if/else chains, which I believe makes the logic for handling stdout and stderr more explicit and easier to follow.
Overall, this is a solid feature addition that enhances mise's capabilities for AI integration.
There was a problem hiding this comment.
Pull request overview
This PR adds MCP (Model Context Protocol) tool support to mise, enabling AI assistants to execute mise tasks programmatically. The implementation integrates rmcp's #[tool_router] macro system with schemars-derived JSON schemas for self-describing tools, providing a working run_task tool and a stub install_tool tool.
Changes:
- Implemented
run_taskMCP tool with subprocess execution, timeout handling, and comprehensive error reporting - Added
install_toolstub that returns a not-yet-implemented error - Integrated rmcp's tool router system with proper JSON schema generation using schemars
- Rewrote e2e tests with full MCP protocol coverage including initialize, tools/list, and tool execution scenarios
- Updated documentation with detailed parameter descriptions and usage examples
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/cli/mcp.rs | Added tool router integration, implemented run_task with hardened subprocess execution, added install_tool stub, migrated ErrorCode usage to named constants |
| e2e/cli/test_mcp_protocol | Completely rewrote tests with Python script providing comprehensive MCP protocol testing including handshake, tool listing with schema validation, and tool execution scenarios |
| docs/mcp.md | Updated documentation to reflect working run_task tool with parameters, examples, and integration guide; removed stub language |
| Cargo.toml | Added schemars dependency for JSON schema generation |
| Cargo.lock | Updated lockfile with schemars dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jdx
left a comment
There was a problem hiding this comment.
This review was AI-generated.
Overall the implementation is solid — good subprocess hardening (kill_on_drop, stdin(null), NO_COLOR, -- separator) and the #[tool_router] macro integration is clean. A few notes:
test_run_task_with_args doesn't actually test args — it passes "args": [] (empty array) and doesn't verify arguments are forwarded to the task. It would be more useful to pass real args and verify the task receives them.
-- is always inserted even with no args — mise run test-task -- is functionally harmless, but if !args.is_empty() { cmd.arg("--").args(&args) } would be slightly cleaner.
schemars direct dependency may be unnecessary — rmcp already has the schemars feature enabled, and the code imports rmcp::schemars::JsonSchema. Worth checking if the direct schemars = "1" in Cargo.toml can be dropped.
Consider setting MISE_YES=1 on the subprocess — if a task triggers interactive prompts, the subprocess would hang until timeout. stdin(null) helps but MISE_YES=1 would be more defensive.
Minor nits: stderr is placed before stdout in combined output ({stderr}\n{stdout}), which is unconventional but not wrong. The install_tool stub changing from success to error is semantically better.
The ErrorCode cleanup (ErrorCode(400) → ErrorCode::INVALID_REQUEST, etc.) throughout is a nice incidental improvement.
Bump recv timeouts from 10s to 30s for task execution calls to reduce flaky test failures in slower CI environments.
Add explicit match arm for when both stdout and stderr are empty on task failure, returning a descriptive message instead of an empty string.
- Handle empty output on task failure with descriptive message - Only insert `--` separator when args are non-empty - Add MISE_YES=1 to subprocess env to prevent interactive hangs - Drop direct schemars dependency using #[schemars(crate = "rmcp::schemars")] - Fix test_run_task_with_args to pass real args and verify forwarding
|
Thanks for the review! Addressed all feedback in 3f97d2b:
|
### 🚀 Features - **(mcp)** add run_task tool for executing mise tasks by @joaommartins in [#8179](#8179) - **(node)** suggest setting node.flavor if the flavor is not found in mirror by @risu729 in [#8206](#8206) ### 🐛 Bug Fixes - **(java)** sort order for shorthand versions by @roele in [#8197](#8197) - **(node)** migrate env vars to settings by @risu729 in [#8200](#8200) - **(registry)** apply overrides in shims by @risu729 in [#8199](#8199) - migrate MISE_CARGO_BINSTALL_ONLY to settings by @risu729 in [#8202](#8202) ### 📚 Documentation - **(doctor)** fix subcommand in an example by @risu729 in [#8198](#8198) ### 📦 Registry - add github backend for typst by @3w36zj6 in [#8210](#8210) ### Chore - **(test)** disable flaky Forgejo e2e test by @jdx in [#8211](#8211)
## Summary - Add working `run_task` MCP tool that executes mise tasks via subprocess with full stdout/stderr capture - Integrate rmcp's `#[tool_router]` macro system with `schemars`-derived JSON schemas for self-describing tools - Add `install_tool` stub with proper schema (returns not-yet-implemented error) - Harden subprocess execution: `kill_on_drop(true)`, `stdin(null)`, `--` arg separator, timeout support via `task_timeout_duration()` - Update documentation with tool parameters, examples, and integration guide - Rewrite e2e tests with full MCP protocol coverage (initialize, tools/list, run_task success/args/unknown, install_tool stub) ## Test plan - [x] `mise run test:e2e test_mcp_protocol` passes — tests initialize handshake, tool listing with schema validation, task execution (success, with args, unknown task error), and install_tool stub - [x] Manual testing with Claude Desktop or other MCP client --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Summary
run_taskMCP tool that executes mise tasks via subprocess with full stdout/stderr capture#[tool_router]macro system withschemars-derived JSON schemas for self-describing toolsinstall_toolstub with proper schema (returns not-yet-implemented error)kill_on_drop(true),stdin(null),--arg separator, timeout support viatask_timeout_duration()Test plan
mise run test:e2e test_mcp_protocolpasses — tests initialize handshake, tool listing with schema validation, task execution (success, with args, unknown task error), and install_tool stub