npm.io
0.3.0 • Published 1 month ago

@tmcp/session-manager

Licence
MIT
Version
0.3.0
Deps
1
Size
28 kB
Vulns
0
Weekly
0
Stars
203

@tmcp/session-manager

Session management for TMCP (TypeScript Model Context Protocol) transport implementations. This package provides the base classes and in-memory implementations for both streaming session coordination and session metadata persistence.

Installation

pnpm add @tmcp/session-manager

Overview

Session management is split into three concerns:

  • Stream session managers handle the storage of long-lived streaming connections (SSE/HTTP) and the fan-out of notifications back to the right session.
  • Info session managers persist metadata that MCP transports need across requests, such as client capabilities, client info, requested log level, and resource subscriptions.
  • Subscription managers route MCP 2026-07-28 per-request change notifications to long-lived subscriptions/listen streams.

Together they manage:

  • Session Creation: Establishing new client sessions with stream controllers
  • Session Deletion: Cleaning up disconnected sessions and metadata
  • Session Queries: Checking whether a given session is still attached
  • Message Delivery: Sending messages to specific sessions or everyone
  • Client Metadata: Persisting capabilities, clientInfo, and log level between requests
  • Resource Subscriptions: Tracking which sessions subscribed to which URIs
  • Per-Request Subscriptions: Acknowledging, filtering, ordering, and closing sessionless notification streams

Usage

In-Memory Session Managers (Default)

The package ships with InMemoryStreamSessionManager and InMemoryInfoSessionManager. Together they are suitable for single-server deployments or tests:

import {
	InMemoryStreamSessionManager,
	InMemoryInfoSessionManager,
} from '@tmcp/session-manager';

const sessionManagers = {
	streams: new InMemoryStreamSessionManager(),
	info: new InMemoryInfoSessionManager(),
};

InMemorySubscriptionManager is the default for transports that support the per-request protocol. It preserves JSON-RPC ID types, buffers changes until acknowledgement completes, and serializes delivery per subscription.

Custom Session Managers

You can implement your own managers by extending the base classes that ship with this package.

Stream session manager
import { StreamSessionManager } from '@tmcp/session-manager';

class CustomStreamSessionManager extends StreamSessionManager {
	create(id, controller) {
		// Persist the ReadableStream controller for later notifications
	}

	delete(id) {
		// Clean up the controller and any associated timers
	}

	async has(id) {
		// Return whether a controller for the session exists
	}

	send(sessions, data) {
		// Fan out the payload to the targeted sessions (or everyone if sessions is undefined)
	}
}
Info session manager
import { InfoSessionManager } from '@tmcp/session-manager';

class CustomInfoSessionManager extends InfoSessionManager {
	async getClientInfo(id) {
		// Return the last clientInfo payload for the session
	}

	setClientInfo(id, info) {
		// Persist clientInfo for later requests
	}

	async getClientCapabilities(id) {
		// Retrieve cached client capabilities
	}

	setClientCapabilities(id, capabilities) {
		// Persist the negotiated capabilities
	}

	async getLogLevel(id) {
		// Return the log level requested by the client
	}

	setLogLevel(id, level) {
		// Store the latest log level
	}

	async getSubscriptions(uri) {
		// Return all session ids subscribed to the URI
	}

	addSubscription(id, uri) {
		// Track that the session subscribed to the URI
	}

	removeSubscription(id, uri) {
		// Stop tracking this resource subscription
	}

	delete(id) {
		// Remove all metadata for the session (client info, capabilities, subscriptions, etc.)
	}
}

API

SubscriptionManager (Abstract Base Class)

Transport-owned manager for subscriptions/listen registrations.

  • create(subscription, callbacks) – atomically register { id, origin, filters } and acknowledge before delivering buffered changes
  • send(notification) – route one change to every matching registration
  • close(id, origin, reason) – close one registration without conflating numeric and string IDs
  • closeAll(origin?, reason?) – close all registrations, optionally for one transport origin

Only the descriptor is suitable for persistence. Callback functions remain on the instance serving the response stream; distributed implementations should use pub/sub only to fan notifications out to that instance. Registration and closure stay local to the process that owns the response stream.

StreamSessionManager (Abstract Base Class)

Responsible for creating and managing streaming controllers.

  • create(id, controller) – register a session and associate its stream controller
  • delete(id) – remove the controller and clean up resources
  • has(id) – resolve to true when a controller for the session exists
  • send(sessions, data) – push a payload to selected sessions (or everyone when sessions is undefined)
InfoSessionManager (Abstract Base Class)

Stores session metadata that needs to survive across HTTP requests or reconnects.

  • getClientInfo(id) / setClientInfo(id, info)
  • getClientCapabilities(id) / setClientCapabilities(id, capabilities)
  • getLogLevel(id) / setLogLevel(id, level)
  • getSubscriptions(uri) – return all session IDs that subscribed to a resource
  • addSubscription(id, uri) – record a new resource subscription
  • removeSubscription(id, uri) – remove one resource subscription
  • delete(id) – remove all metadata for a session when it disconnects
InMemoryStreamSessionManager & InMemoryInfoSessionManager

Concrete in-memory implementations that cover both responsibilities. Combine them when configuring a transport:

import { HttpTransport } from '@tmcp/transport-http';
import { SseTransport } from '@tmcp/transport-sse';
import {
	InMemoryStreamSessionManager,
	InMemoryInfoSessionManager,
} from '@tmcp/session-manager';

const sessionManagers = {
	streams: new InMemoryStreamSessionManager(),
	info: new InMemoryInfoSessionManager(),
};

const httpTransport = new HttpTransport(server, {
	sessionManager: sessionManagers,
});
const sseTransport = new SseTransport(server, {
	sessionManager: sessionManagers,
});

License

MIT

Keywords