MCPcopy Create free account
hub / github.com/TanStack/ai / inMemoryMcpSessionStore

Function inMemoryMcpSessionStore

packages/ai-mcp/src/apps/session-store.ts:65–101  ·  view source on GitHub ↗
(
  opts: { ttlMs?: number } = {},
)

Source from the content-addressed store, hash-verified

63 * written, keeping the map bounded to threads active within the TTL window.
64 */
65export function inMemoryMcpSessionStore(
66 opts: { ttlMs?: number } = {},
67): McpSessionStore {
68 const map = new Map<
69 string,
70 { at: number; servers: Record<string, McpServerDescriptor> }
71 >()
72 const ttl = opts.ttlMs ?? 30 * 60_000
73
74 return {
75 async set(threadId, servers) {
76 // Opportunistic sweep: reclaim every expired entry, not just this thread,
77 // so set-but-never-read threads can't accumulate unbounded.
78 const now = Date.now()
79 for (const [id, e] of map) {
80 if (now - e.at > ttl) map.delete(id)
81 }
82 map.set(threadId, { at: now, servers })
83 },
84 async get(threadId, serverId) {
85 const e = map.get(threadId)
86 if (!e || Date.now() - e.at > ttl) {
87 map.delete(threadId)
88 return null
89 }
90 // Sliding TTL: refresh on a successful hit so an actively-used thread
91 // doesn't expire by absolute time mid-session.
92 e.at = Date.now()
93 // serverId omitted (single-server setups): default to the sole server.
94 if (serverId === undefined) {
95 const entries = Object.entries(e.servers)
96 return entries.length === 1 ? (entries[0]?.[1] ?? null) : null
97 }
98 return e.servers[serverId] ?? null
99 },
100 }
101}

Callers 2

Calls

no outgoing calls

Tested by

no test coverage detected