Let MCP servers use env variables; pass along model key for /attach as well
diff --git a/cmd/sketch/main.go b/cmd/sketch/main.go
index 5ca3395..66fa115 100644
--- a/cmd/sketch/main.go
+++ b/cmd/sketch/main.go
@@ -455,8 +455,9 @@
 		Type: "http",
 		URL:  skabandaddr + "/api/mcp",
 		Headers: map[string]string{
-			"Session-Id": flags.sessionID,
-			"Public-Key": "_sketch_public_key_",
+			"Session-Id":     flags.sessionID,
+			"Public-Key":     "env:SKETCH_PUB_KEY",
+			"Session-Secret": "env:SKETCH_MODEL_API_KEY",
 		},
 	}
 	out, err := json.Marshal(&config)
@@ -652,7 +653,8 @@
 			}
 		}
 		if agentConfig.SkabandClient != nil {
-			go agentConfig.SkabandClient.DialAndServeLoop(ctx, flags.sessionID, srv, connectFn)
+			sessionSecret := apiKey
+			go agentConfig.SkabandClient.DialAndServeLoop(ctx, flags.sessionID, sessionSecret, srv, connectFn)
 		}
 	}
 
diff --git a/loop/agent.go b/loop/agent.go
index 2683cdc..f8ee4e8 100644
--- a/loop/agent.go
+++ b/loop/agent.go
@@ -1291,9 +1291,9 @@
 		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")
+					// Replace env placeholders. E.g., "env:FOO" becomes os.Getenv("FOO")
+					if strings.HasPrefix(value, "env:") {
+						serverConfigs[i].Headers[key] = os.Getenv(value[4:])
 					}
 				}
 			}
diff --git a/skabandclient/skabandclient.go b/skabandclient/skabandclient.go
index 3452c55..6e2aef5 100644
--- a/skabandclient/skabandclient.go
+++ b/skabandclient/skabandclient.go
@@ -47,7 +47,7 @@
 	client    *http.Client
 }
 
-func DialAndServe(ctx context.Context, hostURL, sessionID, clientPubKey string, h http.Handler) (err error) {
+func DialAndServe(ctx context.Context, hostURL, sessionID, clientPubKey string, sessionSecret string, h http.Handler) (err error) {
 	// Connect to the server.
 	var conn net.Conn
 	if strings.HasPrefix(hostURL, "https://") {
@@ -84,6 +84,7 @@
 	req.Header.Set("Upgrade", "ska")
 	req.Header.Set("Session-ID", sessionID)
 	req.Header.Set("Public-Key", clientPubKey)
+	req.Header.Set("Session-Secret", sessionSecret)
 
 	if err := req.Write(conn); err != nil {
 		return fmt.Errorf("skabandclient.Dial: write upgrade request: %w", err)
@@ -379,7 +380,7 @@
 }
 
 // DialAndServeLoop is a redial loop around DialAndServe.
-func (c *SkabandClient) DialAndServeLoop(ctx context.Context, sessionID string, srv http.Handler, connectFn func(connected bool)) {
+func (c *SkabandClient) DialAndServeLoop(ctx context.Context, sessionID string, sessionSecret string, srv http.Handler, connectFn func(connected bool)) {
 	skabandAddr := c.addr
 	clientPubKey := c.publicKey
 
@@ -413,7 +414,7 @@
 
 	var lastErrLog time.Time
 	for {
-		if err := DialAndServe(ctx, skabandAddr, sessionID, clientPubKey, skabandHandler); err != nil {
+		if err := DialAndServe(ctx, skabandAddr, sessionID, clientPubKey, sessionSecret, skabandHandler); err != nil {
 			// NOTE: *just* backoff the logging. Backing off dialing
 			// is bad UX. Doing so saves negligible CPU and doing so
 			// without hurting UX requires interrupting the backoff with