Skip to content

fix(mcp): resolve active session from store for mem_save instead of manual-save fallback#449

Merged
Alan-TheGentleman merged 1 commit into
mainfrom
fix/mcp-session-active-386
May 29, 2026
Merged

fix(mcp): resolve active session from store for mem_save instead of manual-save fallback#449
Alan-TheGentleman merged 1 commit into
mainfrom
fix/mcp-session-active-386

Conversation

@Alan-TheGentleman
Copy link
Copy Markdown
Collaborator

Summary

Closes #386mem_save (and prompt/summary/passive saves) without an explicit session_id fell back to manual-save-{project} even when a real UUID session was active, leaving UUID sessions at observation_count: 0.

Root cause

engram serve (HTTP) and engram mcp (stdio) are separate processes sharing only the on-disk SQLite store. The SessionStart hook registers the UUID session via POST /sessions (HTTP process), so any in-process state in the MCP process stays empty in the real flow.

Change

  • New store method MostRecentActiveSession(project) — resolves the most-recent un-ended session from the shared sessions table (ended_at IS NULL, excludes manual-save%, ORDER BY started_at DESC).
  • New resolveFallbackSessionID helper wired into the 4 MCP fallback sites; falls back to manual-save-{project} only when no active session exists or the query errors (fail-safe).

Test plan

TDD red→green. Covers the real repro (session created as POST /sessions does → mem_save with no session_id lands in the UUID session), plus no-active-session fallback, multi-session recency, ended-session skip, manual-save% exclusion, project scoping. go test -race ./internal/mcp/... clean; go build ./... clean.

Notes

Passed adversarial review (cross-process correctness, fail-safe, determinism verified). Non-blocking follow-up: a sessions(project, ended_at) index if session volume grows.

@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label May 29, 2026
Copilot AI review requested due to automatic review settings May 29, 2026 12:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes MCP write tools (mem_save, prompt/summary/passive capture) defaulting to manual-save-{project} even when a real UUID session is active in the shared SQLite store, by resolving the most-recent active session directly from persisted sessions rows.

Changes:

  • Add Store.MostRecentActiveSession(project) to select the latest un-ended, non-manual-save% session for a project.
  • Wire a new resolveFallbackSessionID helper into MCP write-tool fallback paths so implicit writes prefer the persisted active UUID session.
  • Add store- and MCP-level tests covering active-session resolution, ended-session exclusion, recency ordering, and preserved manual-save fallback.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
internal/store/store.go Adds MostRecentActiveSession query for cross-process active session resolution.
internal/store/store_test.go Adds unit tests validating active-session selection rules and project scoping.
internal/mcp/mcp.go Uses store-backed fallback session resolution for write tools when session_id is omitted.
internal/mcp/mcp_test.go Adds regression tests reproducing issue #386 and verifying new fallback behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/mcp/mcp.go
Comment on lines +2710 to +2714
func resolveFallbackSessionID(s *store.Store, project string) string {
if s != nil {
if id, ok, err := s.MostRecentActiveSession(project); err == nil && ok {
return id
}
@Alan-TheGentleman Alan-TheGentleman merged commit 841507f into main May 29, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mcp): mem_save falls back to manual-save-{project} despite active session, leaving UUID sessions empty

2 participants