feat: MCP tool channel for composable TaskSet → Harness#1090
feat: MCP tool channel for composable TaskSet → Harness#1090
Conversation
| f"TaskSet provides MCP servers {list(mcp_servers)} but " | ||
| f"harness {type(self.harness).__name__} does not implement " | ||
| f"format_mcp_config" | ||
| ) |
There was a problem hiding this comment.
Contradictory None semantics in format_mcp_config contract
Medium Severity
The format_mcp_config docstring documents None as a valid return value meaning "the harness handles MCP servers through other means (e.g. by regenerating its run_command)." However, ComposableEnv.post_sandbox_setup treats a None return as an error and raises NotImplementedError. A harness subclass that follows the documented contract and returns None to signal alternative handling will crash at runtime. The None return is overloaded with two incompatible meanings: "not implemented" (base class default) and "handled differently" (documented subclass use case).
Additional Locations (1)
| f"harness {type(self.harness).__name__} does not implement " | ||
| f"format_mcp_config" | ||
| ) | ||
| await self.upload_content(sandbox_id, mcp_config, "/task/mcp_config.json") |
There was a problem hiding this comment.
Missing parent directory creation for MCP config upload
Medium Severity
The MCP config is uploaded to the hardcoded path /task/mcp_config.json without ensuring the /task directory exists. The existing code (step 2) only creates parent directories for instruction_path and system_prompt_path. If instruction_path is customized to a non-/task path (it's configurable on Harness), the /task directory won't be created, and the upload will fail. The /task path for MCP config needs to be included in the mkdir -p set, or have its own directory creation.
| """ | ||
|
|
||
| command: list[str] | ||
| env_vars: dict[str, str] | None = None |
There was a problem hiding this comment.
Documentation not updated for new MCP functionality
Low Severity
This PR adds user-facing MCPServerSpec, TaskSet.get_mcp_servers(), Harness.format_mcp_config(), and Harness.mcp_servers — all part of the composable architecture already documented in docs/environments.md (lines 889–892) and docs/reference.md. None of these additions are reflected in the documentation. Per project rules, PRs that add or modify core user-facing functionality described in docs/ must update the relevant documentation.
Additional Locations (1)
Triggered by project rule: BugBot Instructions
TaskSets can now declare MCP servers via get_mcp_servers(), enabling tasks to bring their own tools (e.g. web search, code execution) without requiring fork-specific agent modifications. - MCPServerSpec dataclass: command, env_vars, files - TaskSet.get_mcp_servers() -> dict[str, MCPServerSpec] - Harness.format_mcp_config() hook for agent-native config generation - ComposableEnv uploads MCP server files and wires configs at setup This enables future tasksets (DeepDive, BrowseComp) to ship MCP servers that any harness can connect to via the standard protocol. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
If a taskset declares MCP servers but the harness doesn't implement format_mcp_config, fail hard instead of silently dropping tools. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The taskset handles getting server scripts into the sandbox via its own setup() method, docker image, or install script. MCPServerSpec only needs command and env_vars. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8939667 to
9b9d228
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 4 total unresolved issues (including 3 from previous reviews).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| harness handles MCP servers through other means (e.g. by | ||
| regenerating its run_command). | ||
| """ | ||
| return None |
There was a problem hiding this comment.
Conflicting None semantics between docstring and caller
High Severity
The format_mcp_config docstring documents None as a valid return value meaning "the harness handles MCP servers through other means (e.g. by regenerating its run_command)." However, ComposableEnv.post_sandbox_setup treats any None return as an error and raises NotImplementedError. A harness subclass that intentionally returns None per the documented contract will crash. There's no way to distinguish "not overridden" from "handled through other means" since both return None.


Summary
This enables tasksets to bring their own tools via the MCP standard protocol, without requiring fork-specific agent modifications. The harness stays generic — it just connects whatever MCP servers the task provides.
Motivation
Environments like DeepDive and BrowseComp need task-specific tools (web search via Serper/Exa, web fetch). Currently these are baked into a custom OpenCode fork as built-in TypeScript tools. With this change, a DeepDive taskset can ship a Python MCP server wrapping the Serper API, and any harness (OpenCode, Claude Code, etc.) can connect to it.
Design
mcpJSON section, Claude Code's--mcp-serverflags, etc.)get_mcp_servers()defaults to empty dictNext steps
format_mcp_config()in the OpenCode harness (research-environments PR)Test plan
🤖 Generated with Claude Code
Note
Medium Risk
Changes the
ComposableEnvsandbox setup sequence to inject task-provided MCP server configuration, which can break existing harnesses if tasks start declaring MCP servers without a correspondingformat_mcp_configimplementation.Overview
Adds a new TaskSet→Harness “MCP tool server” channel so tasks can declare MCP servers and have the environment pass them to the agent.
This introduces
MCPServerSpecplus aTaskSet.get_mcp_servers()hook, extendsHarnesswithmcp_serversand an overridableformat_mcp_config()method, and updatesComposableEnv.post_sandbox_setup()to call the hook, require a harness config formatter, and upload the generated config to/task/mcp_config.jsonbefore installing the agent.Written by Cursor Bugbot for commit 9b9d228. This will update automatically on new commits. Configure here.