diff --git a/src/commands.ts b/src/commands.ts
index 683e4f08..14cb6d7a 100644
--- a/src/commands.ts
+++ b/src/commands.ts
@@ -108,6 +108,7 @@ export class Commands {
             vscode.commands.executeCommand("coder.open")
           }
         })
+      vscode.commands.executeCommand("coder.refreshWorkspaces")
     } catch (error) {
       vscode.window.showErrorMessage("Failed to authenticate with Coder: " + error)
     }
@@ -122,6 +123,7 @@ export class Commands {
         vscode.commands.executeCommand("coder.login")
       }
     })
+    vscode.commands.executeCommand("coder.refreshWorkspaces")
   }
 
   public async createWorkspace(): Promise<void> {
diff --git a/src/extension.ts b/src/extension.ts
index 931f2995..7345569b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -138,8 +138,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
     commands.navigateToWorkspaceSettings.bind(commands),
   )
   vscode.commands.registerCommand("coder.refreshWorkspaces", () => {
-    myWorkspacesProvider.refresh()
-    allWorkspacesProvider.refresh()
+    myWorkspacesProvider.fetchAndRefresh()
+    allWorkspacesProvider.fetchAndRefresh()
   })
 
   // Since the "onResolveRemoteAuthority:ssh-remote" activation event exists
diff --git a/src/workspacesProvider.ts b/src/workspacesProvider.ts
index 115d3f80..3245b767 100644
--- a/src/workspacesProvider.ts
+++ b/src/workspacesProvider.ts
@@ -13,31 +13,32 @@ export enum WorkspaceQuery {
 
 export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
   private workspaces: WorkspaceTreeItem[] = []
-  private agentMetadata: Record<WorkspaceAgent["id"], AgentMetadataEvent[]> = {}
+  private agentWatchers: Record<WorkspaceAgent["id"], { dispose: () => void; metadata?: AgentMetadataEvent[] }> = {}
 
   constructor(private readonly getWorkspacesQuery: WorkspaceQuery, private readonly storage: Storage) {
-    getWorkspaces({ q: this.getWorkspacesQuery })
-      .then((workspaces) => {
-        const workspacesTreeItem: WorkspaceTreeItem[] = []
-        workspaces.workspaces.forEach((workspace) => {
-          const showMetadata = this.getWorkspacesQuery === WorkspaceQuery.Mine
-          if (showMetadata) {
-            const agents = extractAgents(workspace)
-            agents.forEach((agent) => this.monitorMetadata(agent.id)) // monitor metadata for all agents
-          }
-          const treeItem = new WorkspaceTreeItem(
-            workspace,
-            this.getWorkspacesQuery === WorkspaceQuery.All,
-            showMetadata,
-          )
-          workspacesTreeItem.push(treeItem)
-        })
-        return workspacesTreeItem
-      })
-      .then((workspaces) => {
-        this.workspaces = workspaces
-        this.refresh()
+    this.fetchAndRefresh()
+  }
+
+  // fetchAndRefrehsh fetches new workspaces then re-renders the entire tree.
+  async fetchAndRefresh() {
+    const token = await this.storage.getSessionToken()
+    const workspacesTreeItem: WorkspaceTreeItem[] = []
+    Object.values(this.agentWatchers).forEach((watcher) => watcher.dispose())
+    // If the URL is set then we are logged in.
+    if (this.storage.getURL()) {
+      const resp = await getWorkspaces({ q: this.getWorkspacesQuery })
+      resp.workspaces.forEach((workspace) => {
+        const showMetadata = this.getWorkspacesQuery === WorkspaceQuery.Mine
+        if (showMetadata && token) {
+          const agents = extractAgents(workspace)
+          agents.forEach((agent) => this.monitorMetadata(agent.id, token)) // monitor metadata for all agents
+        }
+        const treeItem = new WorkspaceTreeItem(workspace, this.getWorkspacesQuery === WorkspaceQuery.All, showMetadata)
+        workspacesTreeItem.push(treeItem)
       })
+    }
+    this.workspaces = workspacesTreeItem
+    this.refresh()
   }
 
   private _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | null | void> =
@@ -45,6 +46,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
   readonly onDidChangeTreeData: vscode.Event<vscode.TreeItem | undefined | null | void> =
     this._onDidChangeTreeData.event
 
+  // refresh causes the tree to re-render.  It does not fetch fresh workspaces.
   refresh(item: vscode.TreeItem | undefined | null | void): void {
     this._onDidChangeTreeData.fire(item)
   }
@@ -62,7 +64,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
         )
         return Promise.resolve(agentTreeItems)
       } else if (element instanceof AgentTreeItem) {
-        const savedMetadata = this.agentMetadata[element.agent.id] || []
+        const savedMetadata = this.agentWatchers[element.agent.id]?.metadata || []
         return Promise.resolve(savedMetadata.map((metadata) => new AgentMetadataTreeItem(metadata)))
       }
 
@@ -71,30 +73,39 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
     return Promise.resolve(this.workspaces)
   }
 
-  async monitorMetadata(agentId: WorkspaceAgent["id"]): Promise<void> {
+  // monitorMetadata opens an SSE endpoint to monitor metadata on the specified
+  // agent and registers a disposer that can be used to stop the watch.
+  monitorMetadata(agentId: WorkspaceAgent["id"], token: string): void {
     const agentMetadataURL = new URL(`${this.storage.getURL()}/api/v2/workspaceagents/${agentId}/watch-metadata`)
     const agentMetadataEventSource = new EventSource(agentMetadataURL.toString(), {
       headers: {
-        "Coder-Session-Token": await this.storage.getSessionToken(),
+        "Coder-Session-Token": token,
       },
     })
 
+    this.agentWatchers[agentId] = {
+      dispose: () => {
+        delete this.agentWatchers[agentId]
+        agentMetadataEventSource.close()
+      },
+    }
+
     agentMetadataEventSource.addEventListener("data", (event) => {
       try {
         const dataEvent = JSON.parse(event.data)
         const agentMetadata = AgentMetadataEventSchemaArray.parse(dataEvent)
 
         if (agentMetadata.length === 0) {
-          agentMetadataEventSource.close()
+          this.agentWatchers[agentId].dispose()
         }
 
-        const savedMetadata = this.agentMetadata[agentId]
+        const savedMetadata = this.agentWatchers[agentId].metadata
         if (JSON.stringify(savedMetadata) !== JSON.stringify(agentMetadata)) {
-          this.agentMetadata[agentId] = agentMetadata // overwrite existing metadata
+          this.agentWatchers[agentId].metadata = agentMetadata // overwrite existing metadata
           this.refresh()
         }
       } catch (error) {
-        agentMetadataEventSource.close()
+        this.agentWatchers[agentId].dispose()
       }
     })
   }