package mcp import ( "bufio" "context" "encoding/json" "fmt" "io" ) // StdioTransport implements the MCP protocol over STDIO using line-delimited JSON-RPC. type StdioTransport struct { server *Server reader io.Reader writer io.Writer } // NewStdioTransport creates a new STDIO transport. func NewStdioTransport(server *Server, r io.Reader, w io.Writer) *StdioTransport { return &StdioTransport{ server: server, reader: r, writer: w, } } // Run starts the STDIO transport, reading line-delimited JSON-RPC from the reader // and writing responses to the writer. func (t *StdioTransport) Run(ctx context.Context) error { scanner := bufio.NewScanner(t.reader) encoder := json.NewEncoder(t.writer) for scanner.Scan() { select { case <-ctx.Done(): return ctx.Err() default: } line := scanner.Bytes() if len(line) == 0 { continue } resp, err := t.server.HandleMessage(ctx, line) if err != nil { t.server.logger.Printf("Error handling message: %v", err) continue } if resp != nil { if err := encoder.Encode(resp); err != nil { return fmt.Errorf("failed to write response: %w", err) } } } if err := scanner.Err(); err != nil { return fmt.Errorf("scanner error: %w", err) } return nil }