Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/agentclientprotocol/typescript-sdk/llms.txt

Use this file to discover all available pages before exploring further.

Sessions are independent conversation contexts in ACP. Each session maintains its own history, state, and configuration, allowing multiple parallel conversations with an agent.

What are Sessions?

A session represents a distinct conversation between a user and an agent. Sessions provide:
  • Independent Context - Each session has its own conversation history
  • Isolated State - Configuration and mode changes don’t affect other sessions
  • Persistent Identity - Sessions can be saved, loaded, and resumed
  • MCP Connections - Each session connects to its own set of MCP servers
Think of sessions like browser tabs - each is independent but part of the same application.

Session Lifecycle

Sessions progress through several states:

Creating Sessions

New Sessions

Create a new session with session/new:
src/acp.ts
const session = await agent.newSession({
  cwd: "/path/to/project",
  mcpServers: [
    {
      type: "stdio",
      command: "npx",
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    }
  ]
});

console.log(session.sessionId); // "session-abc123"
console.log(session.availableModes); // [{ id: "code", name: "Code" }, ...]
The agent returns a unique sessionId that must be included in all subsequent requests for this session.

Session ID Format

src/schema/types.gen.ts
export type SessionId = string;
Session IDs are opaque strings generated by the agent. Clients should treat them as opaque identifiers.

Loading Sessions

Load an existing session to restore conversation history:
src/acp.ts
await agent.loadSession({
  sessionId: "session-abc123",
  mcpServers: [
    // MCP servers to connect
  ]
});

// Agent streams the entire conversation history via session/update notifications
// Client receives each message and tool call in order
Loading sessions requires the agent to advertise loadSession: true in its capabilities.

How Loading Works

  1. Client sends session/load request with existing session ID
  2. Agent restores session state from storage
  3. Agent streams conversation history via session/update notifications
  4. Client rebuilds UI state from the streamed messages
  5. Agent responds when streaming is complete
  6. Session ready for new prompts

Resuming Sessions (Unstable)

Resume a session without replaying history:
src/acp.ts
await agent.unstable_resumeSession({
  sessionId: "session-abc123",
  mcpServers: []
});

// Agent restores context but doesn't stream history
// Useful when client already has the history
This is an unstable feature (unstable_resumeSession) and may change in future versions.

Forking Sessions (Unstable)

Create a new session based on an existing one:
src/acp.ts
const fork = await agent.unstable_forkSession({
  sessionId: "session-abc123",
  mcpServers: []
});

console.log(fork.sessionId); // "session-xyz789" (new ID)

// Fork has same history as original but is now independent
// Changes to fork don't affect original session

Use Cases for Forking

  • Generate Summaries - Fork to create a summary without affecting main conversation
  • Try Alternatives - Fork to explore different approaches in parallel
  • Experimentation - Test agent behavior without modifying original session

Listing Sessions (Unstable)

Query available sessions:
src/acp.ts
const response = await agent.unstable_listSessions({
  cwd: "/path/to/project", // Optional: filter by directory
  cursor: null // Optional: for pagination
});

for (const session of response.sessions) {
  console.log(session.sessionId);
  console.log(session.title);
  console.log(session.lastUpdateTime);
  console.log(session.cwd);
}

// Handle pagination
if (response.cursor) {
  const nextPage = await agent.unstable_listSessions({
    cursor: response.cursor
  });
}

Session State Management

Session Modes

Agents can support different operational modes that affect behavior:
src/acp.ts
// Set the mode for a session
await agent.setSessionMode({
  sessionId: "session-abc123",
  mode: "code" // or "ask", "architect", etc.
});
Modes typically affect:
  • System prompts - Different instructions for the LLM
  • Tool availability - Which tools are accessible
  • Permission behavior - Automatic vs. manual approval
Available modes are returned in NewSessionResponse.availableModes and LoadSessionResponse.availableModes.

Session Configuration

Set configuration options for a session:
src/acp.ts
const response = await agent.setSessionConfigOption({
  sessionId: "session-abc123",
  optionId: "temperature",
  valueId: "high"
});

// Response contains all current configuration
console.log(response.configOptions);

Session Model (Unstable)

Select which LLM to use for a session:
src/acp.ts
await agent.unstable_setSessionModel({
  sessionId: "session-abc123",
  modelId: "claude-opus-4"
});

Processing Prompts

Once a session is created, send prompts to the agent:
src/acp.ts
const response = await agent.prompt({
  sessionId: "session-abc123",
  messages: [
    {
      role: "user",
      content: {
        type: "text",
        text: "Help me fix the bug in utils.ts"
      }
    }
  ]
});

console.log(response.stopReason); // "endTurn", "cancelled", etc.

Prompt Lifecycle

Receiving Updates

Clients receive real-time updates via notifications:
class MyClient implements Client {
  async sessionUpdate(params: SessionNotification) {
    console.log("Session ID:", params.sessionId);
    
    if (params.content) {
      // Message chunk
      console.log("Content:", params.content);
    }
    
    if (params.toolCallUpdate) {
      // Tool call progress
      console.log("Tool call:", params.toolCallUpdate);
    }
    
    if (params.currentModeUpdate) {
      // Mode changed
      console.log("New mode:", params.currentModeUpdate);
    }
  }
}

Cancelling Operations

Cancel an ongoing prompt:
src/acp.ts
await agent.cancel({
  sessionId: "session-abc123"
});

// Agent should:
// 1. Stop all LLM requests
// 2. Abort tool call invocations  
// 3. Send any pending updates
// 4. Respond with stopReason: "cancelled"
The agent may send additional session/update notifications before responding with the cancelled status.

Session Persistence

Agents are responsible for persisting session state:
class MyAgent implements Agent {
  private sessions = new Map<string, SessionState>();
  
  async newSession(params) {
    const sessionId = crypto.randomUUID();
    const state = {
      id: sessionId,
      cwd: params.cwd,
      messages: [],
      mode: "code"
    };
    
    this.sessions.set(sessionId, state);
    await this.saveToDatabase(state);
    
    return { sessionId, availableModes: [...] };
  }
  
  async loadSession(params) {
    const state = await this.loadFromDatabase(params.sessionId);
    this.sessions.set(params.sessionId, state);
    
    // Stream history to client
    for (const message of state.messages) {
      await this.connection.sessionUpdate({
        sessionId: params.sessionId,
        content: message.content
      });
    }
    
    return { availableModes: [...] };
  }
}

Best Practices

Always validate that session IDs exist and are accessible:
async prompt(params: PromptRequest) {
  if (!this.sessions.has(params.sessionId)) {
    throw RequestError.invalidParams(
      { sessionId: params.sessionId },
      "Session not found"
    );
  }
  // Process prompt
}
Every session-related operation requires the session ID:
// ✅ Correct
await agent.prompt({ sessionId, messages: [...] });
await connection.sessionUpdate({ sessionId, content: {...} });

// ❌ Wrong - missing sessionId
await agent.prompt({ messages: [...] });
When loading sessions, batch updates to avoid overwhelming the client:
// Send updates in chunks
const CHUNK_SIZE = 10;
for (let i = 0; i < messages.length; i += CHUNK_SIZE) {
  const chunk = messages.slice(i, i + CHUNK_SIZE);
  for (const msg of chunk) {
    await connection.sessionUpdate({...});
  }
  // Small delay between chunks
  await new Promise(resolve => setTimeout(resolve, 10));
}
Clean up resources when sessions end:
connection.signal.addEventListener('abort', () => {
  // Clean up all active sessions
  for (const [id, session] of this.sessions) {
    session.mcpConnections.forEach(conn => conn.close());
    this.sessions.delete(id);
  }
});

Session Information

Sessions include metadata for organization:
interface SessionInfo {
  sessionId: string;
  title: string | null;
  lastUpdateTime: string; // ISO 8601
  cwd: string;
}

MCP Server Connections

Each session can connect to MCP servers for additional tools:
const session = await agent.newSession({
  cwd: "/project",
  mcpServers: [
    {
      type: "stdio",
      command: "npx",
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    },
    {
      type: "sse",
      url: "https://api.example.com/mcp"
    }
  ]
});
MCP servers are connected at session creation/load and provide tools and resources to the agent.

Learn More

Protocol Overview

Understanding the ACP specification

Connections

Establishing agent-client connections

Session Setup

Full specification for session operations

Prompt Turn

How prompts are processed in sessions

Build docs developers (and LLMs) love