mcp-data-platform-v0.35.6
Session Stability Fix
This release fixes a critical session management bug that caused provenance tracking and enrichment deduplication to silently fail after session expiry.
The Problem
When a client reconnects after its session expires (30-min TTL or pod restart), the server previously generated a new random session ID. However, MCP clients like Claude Desktop cache their session ID from the initial handshake and never update it from response headers. This created an infinite replacement cycle:
Client sends Mcp-Session-Id: ABC123
→ store.Get("ABC123") returns nil (expired)
→ server generates new ID: XYZ789
→ client ignores new header, keeps sending ABC123
→ next request: store.Get("ABC123") returns nil again
→ cycle repeats indefinitely
Impact: Every tool call after session expiry was recorded under a different session ID, so provenance.harvest always returned 0 calls. Enrichment dedup (WasSentRecently) also broke since each request appeared to be a fresh session, causing redundant metadata injection on every response.
The Fix
A new reviveSession method recreates the expired session using the client's original ID instead of generating a new one. After revival, the session is stable and all subsequent requests resolve normally.
Client sends Mcp-Session-Id: ABC123
→ store.Get("ABC123") returns nil (expired)
→ reviveSession recreates session with ID ABC123
→ next request: store.Get("ABC123") succeeds
→ provenance and dedup work correctly from here on
Additional Hardening
- Postgres upsert on session create —
INSERT ... ON CONFLICT (id) DO UPDATEeliminates unique constraint violations if two concurrent requests try to revive the same expired session simultaneously - Dead code removal — Removed the now-unused
ReplacedSessionID/WithReplacedSessionIDcontext propagation and theharvestProvenancereplaced-session fallback, which became unreachable after switching to same-ID revival
Changed Files
| File | Change |
|---|---|
pkg/session/handler.go |
New reviveSession method; handleExisting uses same-ID revival; removed ReplacedSessionID infrastructure |
pkg/session/handler_test.go |
6 new/updated tests covering revive stability, timestamps, error paths, and concurrent access |
pkg/session/postgres/store.go |
Create uses upsert to handle race conditions on expired rows |
pkg/middleware/mcp_provenance.go |
Simplified harvestProvenance — no longer checks for replaced session IDs |
pkg/middleware/mcp_provenance_test.go |
Removed session-replacement merge tests (dead code paths) |
Test Coverage
handleExisting: 96.3%reviveSession: 100%harvestProvenance: 100%- All checks pass via
make verify
Installation
Homebrew (macOS)
brew install txn2/tap/mcp-data-platformClaude Code CLI
claude mcp add mcp-data-platform -- mcp-data-platformDocker
docker pull ghcr.io/txn2/mcp-data-platform:v0.35.6Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_0.35.6_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_0.35.6_linux_amd64.tar.gz