Skip to content

feat(client): add long-lived multi-server client that reuses sessions…#419

Open
kulikrch wants to merge 2 commits intolangchain-ai:mainfrom
kulikrch:fix-362-189-long-lived-session-load-mcp-tools
Open

feat(client): add long-lived multi-server client that reuses sessions…#419
kulikrch wants to merge 2 commits intolangchain-ai:mainfrom
kulikrch:fix-362-189-long-lived-session-load-mcp-tools

Conversation

@kulikrch
Copy link

@kulikrch kulikrch commented Feb 18, 2026

Summary

This PR adds a new client class, LongLivedMultiServerMCPClient, to enable long-lived MCP sessions and ensure those sessions are actually reused by high-level APIs.

Problem

Even when a long-lived session was opened, get_tools() could still load tools through load_mcp_tools(session=None, connection=...), which caused tool execution to create fresh sessions instead of using the persistent one.

Changes

  • Added LongLivedMultiServerMCPClient in langchain_mcp_adapters/client.py.
  • Added lifecycle methods:
    • start()
    • stop()
    • __aenter__()
    • __aexit__()
  • Overrode:
    • get_tools() to use self.sessions[server_name] when available.
    • get_prompt() to use persistent sessions when available.
    • get_resources() to use persistent sessions when available (single server and all servers modes).
  • Exported LongLivedMultiServerMCPClient via langchain_mcp_adapters/__init__.py.
  • Added tests in tests/test_client.py to verify persistent-session reuse for:
    • get_tools()
    • get_prompt()
    • get_resources()

Why this fixes it

When a persistent session exists, all three APIs now call loaders with that active ClientSession directly. This avoids per-call session creation and preserves server-side state in long-lived workflows.

Related issues

Testing

Added targeted unit tests for the new behavior.

… for tools/prompts/resources

- add `LongLivedMultiServerMCPClient` inheriting `MultiServerMCPClient`
- support async lifecycle with `start()` / `stop()` and `__aenter__` / `__aexit__`
- override `get_tools()` to pass persistent `ClientSession` into `load_mcp_tools`
- override `get_prompt()` and `get_resources()` to prefer persistent sessions
- export new client from package `__init__`
- add tests validating persistent-session reuse paths

Refs: langchain-ai#362, langchain-ai#189
- refactor LongLivedMultiServerMCPClient session lifecycle to use AsyncExitStack
- ensure partial startup failures close already-opened sessions safely
- centralize server validation via _validate_server_name()
- add _session_for_server() helper to unify persistent/ephemeral session resolution
- keep get_tools() connection-based fallback when no persistent session exists
  to avoid tools bound to closed ephemeral sessions
- update get_prompt() and get_resources() to use shared session-resolution helper
- add tests for persistent-session reuse and partial-start cleanup

Refs: langchain-ai#362, langchain-ai#189
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use interceptors for session/stateful tool calls How to add persistence sessions when working with langgraph

1 participant