claudetool/browse: block port 80 access in browser tools
Prevents agents from attempting to browse to port 80, which is reserved
for the Sketch server itself. This is a common source of confusion.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sf481df655a16903ek
diff --git a/claudetool/browse/browse.go b/claudetool/browse/browse.go
index 9c2cca1..dfb963e 100644
--- a/claudetool/browse/browse.go
+++ b/claudetool/browse/browse.go
@@ -8,6 +8,7 @@
"fmt"
"log"
"net/http"
+ "net/url"
"os"
"path/filepath"
"strings"
@@ -148,7 +149,19 @@
type navigateInput struct {
URL string `json:"url"`
Timeout string `json:"timeout,omitempty"`
-} // NewNavigateTool creates a tool for navigating to URLs
+}
+
+// isPort80 reports whether urlStr definitely uses port 80.
+func isPort80(urlStr string) bool {
+ parsedURL, err := url.Parse(urlStr)
+ if err != nil {
+ return false
+ }
+ port := parsedURL.Port()
+ return port == "80" || (port == "" && parsedURL.Scheme == "http")
+}
+
+// NewNavigateTool creates a tool for navigating to URLs
func (b *BrowseTools) NewNavigateTool() *llm.Tool {
return &llm.Tool{
Name: "browser_navigate",
@@ -177,6 +190,10 @@
return llm.TextContent(errorResponse(fmt.Errorf("invalid input: %w", err))), nil
}
+ if isPort80(input.URL) {
+ return llm.TextContent(errorResponse(fmt.Errorf("port 80 is not the port you're looking for--it is the main sketch server"))), nil
+ }
+
browserCtx, err := b.GetBrowserContext()
if err != nil {
return llm.TextContent(errorResponse(err)), nil