Replace skaband tools with a sketch.dev MCP client

sketch.dev provides seeing recent sessions and reading a past
session as tool.
diff --git a/claudetool/session_history.go b/claudetool/session_history.go
deleted file mode 100644
index 5351538..0000000
--- a/claudetool/session_history.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package claudetool
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"strings"
-	"time"
-
-	"sketch.dev/llm"
-	"sketch.dev/skabandclient"
-)
-
-// CreateSessionHistoryTools creates the session history tools when skaband is available
-func CreateSessionHistoryTools(skabandClient *skabandclient.SkabandClient, sessionID, currentRepo string) []*llm.Tool {
-	if skabandClient == nil {
-		return nil
-	}
-
-	return []*llm.Tool{
-		listRecentSketchSessionsTool(skabandClient, sessionID, currentRepo),
-		readSketchSessionTool(skabandClient, sessionID),
-	}
-}
-
-func listRecentSketchSessionsTool(client *skabandclient.SkabandClient, sessionID, currentRepo string) *llm.Tool {
-	return &llm.Tool{
-		Name: "list_recent_sketch_sessions",
-		Description: fmt.Sprintf(`Lists recent Sketch sessions%s. Use this tool when the user refers to previous sketch sessions, asks about recent work, or wants to see their session history. This helps you understand what work has been done previously and can provide context for continuing or reviewing past sessions.`, func() string {
-			if currentRepo != "" {
-				return " for the current repository (" + currentRepo + ")"
-			}
-			return ""
-		}()),
-		InputSchema: json.RawMessage(`{
-		"type": "object",
-		"properties": {},
-		"required": []
-	}`),
-		Run: func(ctx context.Context, input json.RawMessage) ([]llm.Content, error) {
-			// Use 60 second timeout for skaband requests
-			ctxWithTimeout, cancel := context.WithTimeout(ctx, 60*time.Second)
-			defer cancel()
-
-			markdownTable, err := client.ListRecentSketchSessionsMarkdown(ctxWithTimeout, currentRepo, sessionID)
-			if err != nil {
-				return nil, fmt.Errorf("failed to list recent sessions: %w", err)
-			}
-
-			// Check if no sessions found (markdown will contain "No sessions found")
-			if strings.Contains(markdownTable, "No sessions found") {
-				return llm.TextContent("No recent sketch sessions found."), nil
-			}
-
-			// Use the markdown table from the server
-			var result strings.Builder
-			result.WriteString("Recent sketch sessions:\n\n")
-			result.WriteString(markdownTable)
-			result.WriteString("\n\nUse the `read_sketch_session` tool with a session ID to see the full conversation history.")
-
-			return llm.TextContent(result.String()), nil
-		},
-	}
-}
-
-func readSketchSessionTool(client *skabandclient.SkabandClient, sessionID string) *llm.Tool {
-	return &llm.Tool{
-		Name:        "read_sketch_session",
-		Description: `Reads the full conversation history of a specific Sketch session. Use this tool when the user mentions a specific sketch session ID, wants to review what was done in a previous session, or needs to understand the context from a past conversation to continue work.`,
-		InputSchema: json.RawMessage(`{
-		"type": "object",
-		"properties": {
-			"session_id": {
-				"type": "string",
-				"description": "The ID of the sketch session to read"
-			}
-		},
-		"required": ["session_id"]
-	}`),
-		Run: func(ctx context.Context, input json.RawMessage) ([]llm.Content, error) {
-			// Use 60 second timeout for skaband requests
-			ctxWithTimeout, cancel := context.WithTimeout(ctx, 60*time.Second)
-			defer cancel()
-
-			var params struct {
-				SessionID string `json:"session_id"`
-			}
-			if err := json.Unmarshal(input, &params); err != nil {
-				return nil, fmt.Errorf("failed to parse input: %w", err)
-			}
-
-			if params.SessionID == "" {
-				return nil, fmt.Errorf("session_id is required")
-			}
-
-			formattedResponse, err := client.ReadSketchSession(ctxWithTimeout, params.SessionID, sessionID)
-			if err != nil {
-				return nil, fmt.Errorf("failed to read session: %w", err)
-			}
-
-			// Server now returns formatted text directly
-			return llm.TextContent(*formattedResponse), nil
-		},
-	}
-}
diff --git a/cmd/sketch/main.go b/cmd/sketch/main.go
index d56fe7a..3ad3e92 100644
--- a/cmd/sketch/main.go
+++ b/cmd/sketch/main.go
@@ -3,6 +3,7 @@
 import (
 	"cmp"
 	"context"
+	"encoding/json"
 	"flag"
 	"fmt"
 	"io"
@@ -23,6 +24,7 @@
 	"sketch.dev/llm"
 	"sketch.dev/llm/gem"
 	"sketch.dev/llm/oai"
+	"sketch.dev/mcp"
 
 	"sketch.dev/browser"
 	"sketch.dev/dockerimg"
@@ -379,6 +381,7 @@
 		if err != nil {
 			return err
 		}
+		flags.mcpServers = append(flags.mcpServers, skabandMcpConfiguration(flags))
 	} else {
 		// When not using skaband, get API key from environment or flag
 		envName := "ANTHROPIC_API_KEY"
@@ -443,6 +446,27 @@
 	return nil
 }
 
+func skabandMcpConfiguration(flags CLIFlags) string {
+	skabandaddr, err := skabandclient.LocalhostToDockerInternal(flags.skabandAddr)
+	if err != nil {
+		skabandaddr = flags.skabandAddr
+	}
+	config := mcp.ServerConfig{
+		Name: "sketchdev",
+		Type: "http",
+		URL:  skabandaddr + "/api/mcp",
+		Headers: map[string]string{
+			"Session-Id": flags.sessionID,
+			"Public-Key": "_sketch_public_key_",
+		},
+	}
+	out, err := json.Marshal(&config)
+	if err != nil {
+		panic("programming error" + err.Error())
+	}
+	return string(out)
+}
+
 // runInContainerMode handles execution inside the Docker container.
 // The inInsideSketch parameter indicates whether we're inside the sketch container
 // with access to outside environment variables.
@@ -483,6 +507,9 @@
 		if err != nil {
 			return err
 		}
+
+		// Add MCP Server for skaband
+		flags.mcpServers = append(flags.mcpServers, skabandMcpConfiguration(flags))
 	}
 
 	return setupAndRunAgent(ctx, flags, antURL, apiKey, pubKey, false, logFile)
diff --git a/loop/agent.go b/loop/agent.go
index 24f3a70..2683cdc 100644
--- a/loop/agent.go
+++ b/loop/agent.go
@@ -1281,16 +1281,24 @@
 
 	convo.Tools = append(convo.Tools, browserTools...)
 
-	// Add session history tools if skaband client is available
-	if a.config.SkabandClient != nil {
-		sessionHistoryTools := claudetool.CreateSessionHistoryTools(a.config.SkabandClient, a.config.SessionID, a.gitOrigin)
-		convo.Tools = append(convo.Tools, sessionHistoryTools...)
-	}
-
 	// Add MCP tools if configured
 	if len(a.config.MCPServers) > 0 {
+
 		slog.InfoContext(ctx, "Initializing MCP connections", "servers", len(a.config.MCPServers))
-		mcpConnections, mcpErrors := a.mcpManager.ConnectToServers(ctx, a.config.MCPServers, 10*time.Second)
+		serverConfigs, parseErrors := mcp.ParseServerConfigs(ctx, a.config.MCPServers)
+
+		// Replace any headers with value _sketch_public_key_ and _sketch_session_id_ with those values.
+		for i := range serverConfigs {
+			if serverConfigs[i].Headers != nil {
+				for key, value := range serverConfigs[i].Headers {
+					// Replace _sketch_public_key_ placeholder
+					if value == "_sketch_public_key_" {
+						serverConfigs[i].Headers[key] = os.Getenv("SKETCH_PUB_KEY")
+					}
+				}
+			}
+		}
+		mcpConnections, mcpErrors := a.mcpManager.ConnectToServerConfigs(ctx, serverConfigs, 10*time.Second, parseErrors)
 
 		if len(mcpErrors) > 0 {
 			for _, err := range mcpErrors {
diff --git a/mcp/client.go b/mcp/client.go
index e87a465..7ea74a6 100644
--- a/mcp/client.go
+++ b/mcp/client.go
@@ -81,17 +81,7 @@
 	return serverConfigs, errors
 }
 
-// ConnectToServers connects to multiple MCP servers in parallel
-func (m *MCPManager) ConnectToServers(ctx context.Context, configs []string, timeout time.Duration) ([]MCPServerConnection, []error) {
-	serverConfigs, parseErrors := ParseServerConfigs(ctx, configs)
-	if len(serverConfigs) == 0 {
-		if len(parseErrors) > 0 {
-			return nil, parseErrors
-		}
-		return nil, nil
-	}
-	return m.ConnectToServerConfigs(ctx, serverConfigs, timeout, parseErrors)
-} // ConnectToServerConfigs connects to multiple parsed MCP server configs in parallel
+// ConnectToServerConfigs connects to multiple parsed MCP server configs in parallel
 func (m *MCPManager) ConnectToServerConfigs(ctx context.Context, serverConfigs []ServerConfig, timeout time.Duration, existingErrors []error) ([]MCPServerConnection, []error) {
 	if len(serverConfigs) == 0 {
 		return nil, existingErrors