Skip to content

feat: Add Child Process transport #90

@avrabe

Description

@avrabe

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 Transport trait (delegating to StdioTransport)
  • Proper process cleanup on drop
  • Stderr capture/logging option
  • Graceful shutdown with timeout
  • Example usage with MCP Client

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions