diff --git a/arduino/sketches/sketches.go b/arduino/sketches/sketches.go
index d86e0db829b..13c0aa181e6 100644
--- a/arduino/sketches/sketches.go
+++ b/arduino/sketches/sketches.go
@@ -38,6 +38,7 @@ type Metadata struct {
 type BoardMetadata struct {
 	Fqbn string `json:"fqbn,required"`
 	Name string `json:"name,omitempty"`
+	Port string `json:"port,omitepty"`
 }
 
 // NewSketchFromPath loads a sketch from the specified path
diff --git a/cli/board/attach.go b/cli/board/attach.go
index 2721e677b53..0049bcdab22 100644
--- a/cli/board/attach.go
+++ b/cli/board/attach.go
@@ -35,14 +35,14 @@ func initAttachCommand() *cobra.Command {
 		Use:   "attach <port>|<FQBN> [sketchPath]",
 		Short: "Attaches a sketch to a board.",
 		Long:  "Attaches a sketch to a board.",
-		Example: "  " + os.Args[0] + " board attach serial:///dev/tty/ACM0\n" +
-			"  " + os.Args[0] + " board attach serial:///dev/tty/ACM0 HelloWorld\n" +
+		Example: "  " + os.Args[0] + " board attach serial:///dev/ttyACM0\n" +
+			"  " + os.Args[0] + " board attach serial:///dev/ttyACM0 HelloWorld\n" +
 			"  " + os.Args[0] + " board attach arduino:samd:mkr1000",
 		Args: cobra.RangeArgs(1, 2),
 		Run:  runAttachCommand,
 	}
 	attachCommand.Flags().StringVar(&attachFlags.searchTimeout, "timeout", "5s",
-		"The timeout of the search of connected devices, try to high it if your board is not found (e.g. to 10s).")
+		"The connected devices search timeout, raise it if your board doesn't show up (e.g. to 10s).")
 	return attachCommand
 }
 
diff --git a/commands/board/attach.go b/commands/board/attach.go
index fdd80600654..77906062bae 100644
--- a/commands/board/attach.go
+++ b/commands/board/attach.go
@@ -96,6 +96,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachReq, taskCB commands.TaskPr
 		sketch.Metadata.CPU = sketches.BoardMetadata{
 			Fqbn: board.FQBN(),
 			Name: board.Name(),
+			Port: deviceURI.String(),
 		}
 	}
 
diff --git a/commands/upload/upload.go b/commands/upload/upload.go
index 0f77066e97b..c373c9b049f 100644
--- a/commands/upload/upload.go
+++ b/commands/upload/upload.go
@@ -19,6 +19,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"net/url"
 	"os"
 	"path/filepath"
 	"strings"
@@ -53,6 +54,15 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
 
 	// FIXME: make a specification on how a port is specified via command line
 	port := req.GetPort()
+	if port == "" && sketch != nil && sketch.Metadata != nil {
+		deviceURI, err := url.Parse(sketch.Metadata.CPU.Port)
+		if err != nil {
+			return nil, fmt.Errorf("invalid Device URL format: %s", err)
+		}
+		if deviceURI.Scheme == "serial" {
+			port = deviceURI.Host + deviceURI.Path
+		}
+	}
 	if port == "" {
 		return nil, fmt.Errorf("no upload port provided")
 	}