feat(mcp): add MCP server mode for subagent composition#126
Merged
spachava753 merged 13 commits intomainfrom Jan 10, 2026
Merged
feat(mcp): add MCP server mode for subagent composition#126spachava753 merged 13 commits intomainfrom
spachava753 merged 13 commits intomainfrom
Conversation
This specification defines MCP Server Mode, a feature enabling CPE to be exposed as an MCP server for agent composition. The design addresses context window pressure from accumulating tools by allowing focused subagents to handle tool orchestration behind a simple interface. The specification covers: - Motivation for subagent patterns including context management, parallel execution, and separation of concerns between planning and execution - Configuration schema with one subagent per config file for simplicity and version control - CLI interface via `cpe mcp serve --config` with stdio transport - Execution model where subagents inherit parent context (CWD, environment) - Structured output support via optional JSON schemas and final_answer tool - Conversation persistence with subagent traces annotated in .cpeconvo - Example configurations for review, coding, and documentation workflows - Detailed implementation task breakdown with dependencies and testing criteria The design intentionally omits retry logic, recursion guards, and complex orchestration in favor of transparency and debuggability for the initial implementation.
Extend the configuration schema to support defining subagents that can be exposed as MCP tools. This is the foundation for MCP server mode, which allows CPE to run as an MCP server exposing a single focused subagent. The SubagentConfig struct captures the essential identity of a subagent: its name and description (both required), plus an optional path to a JSON schema file for structured output. Validation ensures the output schema file exists and contains valid JSON when specified.
This implements the MCP server transport layer for CPE, allowing it to be run as an MCP server that exposes a configured subagent as a tool. The `cpe mcp serve` command starts a server that communicates via stdio transport, enabling CPE to be composed as a subagent within other MCP-compliant environments. The server validates that a subagent is configured and handles graceful shutdown on context cancellation. Closes Task 2 and Task 3 from the MCP server mode spec.
Implements tool registration for the MCP server mode, allowing the configured subagent to be exposed as an MCP tool that clients can discover and invoke. The tool is registered with the name and description from the subagent config, and uses a typed input schema with `prompt` (required) and `inputs` (optional file paths). When `outputSchemaPath` is configured, the JSON schema is loaded, validated, and set as the tool's output schema. Invalid schema files (missing or malformed JSON) cause server startup to fail with a clear error message. The tool handler is a placeholder that returns a not-implemented error; actual subagent execution will be added in a subsequent task.
When the MCP server receives a tool call, it now executes the configured subagent using the same patterns as the root command. The server accepts a `SubagentExecutor` function that handles config resolution, system prompt loading, generator creation, and generation. The input processing logic that converts file paths and URLs into gai.Blocks has been extracted from `cmd/root.go` into `agent.BuildUserBlocks` so it can be shared with subagent execution. A new `commands.ExecuteSubagent` function provides a simpler single-turn generation interface without conversation state management. The `baseURLOverride` parameter was removed from `CreateToolCapableGenerator` since custom URLs can be set directly on the model config before calling the function.
Add support for structured output in MCP server mode subagents. When a subagent configuration includes an outputSchemaPath, the system registers a final_answer tool with the specified JSON schema as its input schema. The tool uses a nil callback which causes gai.ToolGenerator to terminate execution immediately when called, and the tool call parameters are extracted and returned as the structured JSON result. The output schema is loaded and validated at server startup to ensure invalid schema files cause immediate failures rather than runtime errors. This aligns with the Task 4 spec requirement for startup validation. Closes Task 6 of the MCP Server Mode specification.
Update Task 6 to reflect actual files modified during implementation. Remove Task 9 (CLI wiring) as it was completed as part of earlier tasks. Mark Task 8 (logging notifications) as optional. Renumber remaining tasks and update their dependencies accordingly.
Subagent invocations now save their execution traces to the shared .cpeconvo database, enabling conversation history and debugging for MCP server mode. Each invocation generates a unique 8-character run ID and labels all messages with the format "subagent:<name>:<run_id>" in the title field. This allows subagent traces to be distinguished from parent agent entries when viewing conversation history. The persistence is non-blocking—storage errors are logged to stderr but do not fail the subagent execution, prioritizing the primary tool response over observability.
Task 7 now reflects actual implementation: storage init in cmd/mcp.go, persistence logic in commands/subagent.go with saveSubagentTrace(). Task 9 (E2E integration) now depends on Task 7 since persistence is part of the complete execution flow.
Add example subagent configurations demonstrating both supported patterns: a thinking-focused reviewer subagent with structured JSON output, and a code mode subagent with filesystem access for making changes. Create comprehensive documentation covering subagent authoring, configuration reference, structured output via final_answer, troubleshooting, and usage patterns for composing subagents with parent CPE sessions. Closes task #9 in MCP server mode spec.
This implements Task #10 of the MCP server mode spec, adding comprehensive error handling to ensure subagent execution failures are surfaced clearly to MCP clients rather than crashing the server process. The server now recovers from panics in tool call handlers and returns them as structured MCP error responses. Input validation rejects empty prompts early. Context cancellation is checked at blocking points to respect timeouts and cancellation requests. Error messages include actionable context like file paths, model references, and subagent names to aid debugging.
MCP server mode uses stdio transport where stdout must contain only JSON-RPC messages. The streaming printer was writing response text to stdout, corrupting the protocol and causing parse errors. Remove the streaming printer entirely and add a disablePrinting parameter to CreateToolCapableGenerator. MCP server mode passes true to suppress stdout output while interactive CLI retains response printing. Consolidate MCP server mode documentation into README.md and AGENTS.md, removing the separate docs/subagents.md file. Mark Task 11 (documentation) as complete in the spec. Fix code generation for tools with multiline descriptions by splitting on newlines and prefixing each line with a comment marker.
67f6635 to
3247927
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements MCP Server Mode, enabling CPE to be exposed as an MCP server. This allows composition of AI agents where CPE subagents can be invoked as tools from parent agents, supporting patterns like context management, parallel execution, and focused task delegation.
Motivation
As agent environments accumulate more MCP servers and tools, context windows become crowded, leading to:
Subagents address this by aggregating tools behind a simpler interface. The parent agent invokes a single subagent tool instead of orchestrating many tools directly, saving context space and reducing complexity. Additionally, subagents enable "parallel intelligence" where multiple focused agents can execute concurrently.
MCP server mode was chosen over a simple CLI wrapper because:
Features
cpe mcp servecommand: Starts CPE as a long-lived MCP server over stdiosubagentconfig block withname,description, and optionaloutputSchemaPathoutputSchemaPathis set, subagent uses afinal_answertool to return validated JSONdefaults.codeMode.cpeconvowith unique run IDsUsage
Create a subagent config:
Start as MCP server:
Configure parent to use subagent:
Files Changed
cmd/mcp.go: Newmcp servecommand implementationinternal/mcp/server.go: MCP server with tool registration and stdio transportinternal/commands/subagent.go: Subagent execution logic with final_answer supportinternal/config/: Extended config schema for subagent definitioninternal/agent/input.go: Refactored input processing (extracted from cmd/root.go)examples/subagent/: Example configs, prompts, and schemasdocs/specs/mcp_server_mode.md: Full specification documentCloses #112