-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Summary
Add a child process transport that spawns and manages MCP server subprocesses, communicating via their stdin/stdout.
Motivation
Essential for the MCP Client (#89) to connect to servers that run as separate processes. This is the primary way MCP clients (like Claude Desktop) communicate with servers.
Proposed Implementation
Reuse existing StdioTransport internally:
use tokio::process::Command;
pub struct ChildProcessTransport {
child: Child,
stdio: StdioTransport, // Reuse existing!
}
impl ChildProcessTransport {
pub async fn spawn(command: Command) -> Result<Self, TransportError> {
let mut child = command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let stdin = child.stdin.take().unwrap();
let stdout = child.stdout.take().unwrap();
Ok(Self {
child,
stdio: StdioTransport::from_streams(stdin, stdout),
})
}
pub async fn kill(&mut self) -> Result<(), Error> {
self.child.kill().await
}
pub fn id(&self) -> Option<u32> {
self.child.id()
}
}
impl Transport for ChildProcessTransport {
// Delegate to self.stdio
}Features
- Spawn MCP servers as child processes
- Proper cleanup on drop (kill zombie processes)
- Access to stderr for debugging
- Process ID tracking
- Graceful shutdown support
Code Reuse
| Existing | Reuse |
|---|---|
StdioTransport |
Core read/write logic |
Transport trait |
Interface |
| JSON-RPC framing | Message handling |
Acceptance Criteria
- Spawn child processes with piped stdio
- Implement
Transporttrait (delegating toStdioTransport) - Proper process cleanup on drop
- Stderr capture/logging option
- Graceful shutdown with timeout
- Example usage with MCP Client
References
- rmcp child process: https://github.com/modelcontextprotocol/rust-sdk/blob/main/crates/rmcp/src/transport/child_process.rs
- Depends on: feat: Add MCP Client implementation #89 (MCP Client)
Metadata
Metadata
Assignees
Labels
No labels