Skip to content

Sessions & Working Memory

Sessions provide working memory — temporary context that persists across API calls within a session and can optionally be committed to long-term storage.

How Sessions Work

Session Start
↓
Store working memory (key-value pairs)
↓
Working memory persists across requests
↓
Session End → optionally commit to long-term storage

Session Lifecycle

A session moves through a well-defined lifecycle:

CREATE → USE (read/write working memory) → COMMIT (optional) → EXPIRE/DELETE

1. Create

Sessions are created with a TTL (time-to-live) that determines how long the session stays active. The server auto-creates the target workspace if it does not already exist.

2. Use

During a session, you store and retrieve key-value pairs in working memory. Each API call that uses the session keeps it alive within its TTL window.

3. Commit

Before a session ends, its working memory can be committed to long-term storage. This extracts important information from the session and stores it as permanent memories.

4. Expire or Delete

Sessions expire automatically when their TTL elapses, or they can be deleted explicitly. If auto_commit is enabled (the default), expired sessions are committed before cleanup.

Creating a Session

Python

session = await client.create_session(
ttl_seconds=3600,
workspace_id="my-workspace"
)
print(f"Session ID: {session.id}")

TypeScript

const { session, briefing } = await client.createSession({
workspaceId: "my-workspace",
ttlSeconds: 3600,
briefing: true, // Get briefing on session start
});

Session Options

ParameterDefaultDescription
session_idauto-generatedClient-provided session ID
workspace_id_defaultWorkspace to bind the session to
ttl_seconds3600Session TTL (60 to 86400 seconds)
context_id_defaultContext within the workspace
working_memorynullInitial key-value pairs to populate
briefingfalseInclude a briefing with relevant memories on start
auto_committrueAuto-commit working memory on session end

Working Memory

Working memory is a key-value store scoped to a session. Values are JSON-serializable and persist across API calls for the session’s lifetime.

Python

# Store working memory
await client.set_context(
session.id,
"current_task",
{"description": "Debugging auth", "file": "auth.py"}
)
# Retrieve working memory
context = await client.get_context(session.id, ["current_task"])

TypeScript

// Store working memory
await client.setWorkingMemory(session.id, "current_task", {
description: "Debugging auth",
file: "auth.py",
});
// Retrieve working memory
const memory = await client.getWorkingMemory(session.id, "current_task");

Working Memory TTL

Individual working memory entries can have their own TTL that overrides the session TTL:

# This entry expires in 5 minutes, even if the session lasts an hour
await client.set_context(
session.id,
"temp_calculation",
{"result": 42},
ttl_seconds=300
)

MCP Tools

When using via MCP server (Claude Code, Claude Desktop), use the session tools:

// memory_session_start — Start a session
{ "workspace_id": "my-project", "ttl_seconds": 3600 }
// memory_session_status — Check session status
{}
// memory_session_commit — Commit working memory to long-term storage
{ "importance_threshold": 0.5 }
// memory_session_end — End session
{ "commit": true }

Session TTL and Touch/Extend

Sessions have a fixed TTL set at creation time. To keep a session alive beyond its original TTL, use the touch/extend mechanism:

# Extend session by another hour (default)
await client.touch_session(session.id)
# Extend by a specific duration
await client.touch_session(session.id, extend_seconds=7200)

The touch operation adds the specified seconds to the current expiration time. The maximum extension per call is 86400 seconds (24 hours).

Committing Sessions

Committing extracts important working memory items and stores them as permanent memories.

Explicit Commit

result = await client.commit_session(
session_id,
min_importance=0.5,
deduplicate=True
)
print(f"Created {result['memories_created']} long-term memories")

The commit response includes details about what was extracted:

FieldDescription
memories_extractedTotal memories extracted from session
memories_deduplicatedNumber of duplicates removed
memories_createdNumber of new memories created
breakdownMemory count by category
extraction_time_msTime taken for extraction

Commit Options

OptionDefaultDescription
min_importance0.5Minimum importance threshold for extraction
deduplicatetrueRemove duplicate memories during extraction
categoriesallSpecific category names to extract
max_memories50Maximum memories to extract per commit

Auto-Commit on Session End

When auto_commit is enabled (the default), sessions are automatically committed when they expire. This ensures working memory is not lost even if the client disconnects:

# Auto-commit is on by default
session = await client.create_session(ttl_seconds=3600)
# Working memory is stored during the session
await client.set_context(session.id, "decision", {
"choice": "Use PostgreSQL for persistence",
"reason": "Need ACID guarantees"
})
# When the session expires, working memory is committed automatically

End a Session

await client.delete_session(session.id)

Session Briefings

Briefings provide a summary of recent activity and relevant context when starting a new session. Request a briefing at session creation time or separately:

# Briefing at session creation
session_response = await client.create_session(
ttl_seconds=3600,
briefing=True,
briefing_options={"lookback_hours": 24, "detail_level": "overview"}
)
briefing = session_response.briefing
# Standalone briefing
briefing = await client.get_briefing(lookback_hours=24)
print(briefing.recent_activity_summary)

A briefing includes:

SectionDescription
workspace_summaryTotal memories, recent activity counts
recent_activityRecent session summaries and key decisions
open_threadsOngoing topics that may need attention
contradictions_detectedMemories with contradictory relationships
memoriesRelevant memories for the new session
const briefing = await client.getBriefing(24, true);
console.log(briefing.recent_activity_summary);
console.log(briefing.open_threads);

Practical Patterns

Agent Task Tracking

# Start of task
await client.set_context(session.id, "task", {
"goal": "Fix authentication bug",
"files_modified": [],
"decisions": []
})
# During work
task = await client.get_context(session.id, ["task"])
task["files_modified"].append("auth.py")
await client.set_context(session.id, "task", task)
# End of task — commit learnings
await client.commit_session(session.id)

Claude Code Sessions

The MCP server’s session tools are designed for Claude Code workflows:

  1. memory_session_start — Initialize at session start
  2. memory_remember — Store decisions and learnings during work
  3. memory_session_end with commit: true — Persist working memory at session end

Multi-Turn Conversations

Sessions keep context across multiple API calls without re-fetching:

session = await client.create_session(ttl_seconds=7200)
# Turn 1
await client.set_context(session.id, "user_name", "Alice")
await client.set_context(session.id, "topic", "Python debugging")
# Turn 2 (different API call, same session)
name = await client.get_context(session.id, ["user_name"])
# Returns "Alice" — context preserved

Structured Session Memory

For complex sessions, organize working memory into semantic sections:

# Store context about the current task
await client.set_context(session.id, "context", [
"Working on payment service refactoring",
"Using FastAPI with SQLAlchemy"
])
# Track decisions made during the session
await client.set_context(session.id, "decisions", [
"Use circuit breaker pattern for external API calls",
"Switch from REST to gRPC for inter-service communication"
])
# Record errors encountered
await client.set_context(session.id, "errors", [
"ConnectionPool exhaustion under load — fixed by increasing pool size"
])