Skip to content

feat: add session-scoped MCP support with same-turn tool refresh#4435

Closed
terakael wants to merge 2 commits into
anomalyco:devfrom
terakael:dev
Closed

feat: add session-scoped MCP support with same-turn tool refresh#4435
terakael wants to merge 2 commits into
anomalyco:devfrom
terakael:dev

Conversation

@terakael

@terakael terakael commented Nov 18, 2025

Copy link
Copy Markdown
Contributor

Add Session-Scoped MCP Support + Same-Turn Tool Refresh

Summary

Adds session-scoped MCP loading and event-driven tool refresh to enable:

  1. Same-turn usage - MCPs loaded mid-turn are immediately available without requiring the user to type "continue"
  2. Agent-driven loading - Agent can decide when to load MCPs based on user requests, not explicit mentions
  3. Session isolation - Subagents load temporary MCPs that auto-dispose without polluting parent context

Implementation

MCP state is now split between instance-scoped (shared, persistent) and session-scoped (isolated, ephemeral). When a session-scoped MCP loads, it publishes an event that triggers tool refresh mid-turn, allowing immediate use. Session disposal automatically cleans up associated MCPs.

The API surface adds addSessionScoped() and disposeSession() to the MCP module, with a new REST endpoint for session-scoped loading. Event-driven tool refresh replaces the previous turn-boundary limitation.

- Add session-scoped MCP API (addSessionScoped, disposeSession)
- Implement event-driven tool refresh for same-turn MCP usage
- Add automatic cleanup when sessions are removed
- Fix dynamic loading to ignore enabled flag
- Add comprehensive test suite (5 new tests)

Enables subagents to load temporary MCPs that auto-dispose without
polluting parent contexts. MCPs loaded mid-turn are immediately
available without requiring 'continue'.

All tests passing (197 total). Fully backward compatible.
@rekram1-node

rekram1-node commented Nov 18, 2025

Copy link
Copy Markdown
Collaborator

@terakael

from guidelines:

Avoid having verbose LLM generated PR descriptions

☹️

@rekram1-node

Copy link
Copy Markdown
Collaborator

If you can rewrite your description I can review but that's a bigger description than there is code almost haha

@terakael

Copy link
Copy Markdown
Contributor Author

Fair enough! I've changed the PR description to be much easier to read.

- Extract registerMCP() helper to eliminate duplication in add() and addSessionScoped()
- Extract retrieveToolsFromClients() helper to eliminate duplicate tool retrieval
- Move enabled flag check to state init (only place it's needed for config loading)
- Consolidate create/createDynamic/createInternal into single create() function
- Add TUI sync listeners for mcp.server.added/removed events
- Update test comments for clarity

Reduces code duplication by ~86 lines while maintaining all existing behavior.
All 197 tests passing.
@rekram1-node

Copy link
Copy Markdown
Collaborator

im not sure i follow, what problem are you trying to solve here

@terakael

terakael commented Nov 18, 2025

Copy link
Copy Markdown
Contributor Author

The background for this is that I have a plugin that lazy-loads MCP servers when the agent thinks it needs them (so I can start up OpenCode, say "check my calendar", and the agent will see there's a calendar MCP server and then load it in real time and then use it).

The reason for this PR is because I was having an issue where the tools were being loaded once per turn, so when I said "check my calendar" the agent would load the MCP server, but the tools wouldn't be available (so I'd have to say "continue" etc to have it start its next turn with the tools available).

I just checked the main branch again and it seems like I'm not having this issue anymore - the tools are all loading in the same turn. Looks like my main issue was actually fixed in v1.0.69 with the agent loop refactor!

The other parts (session-based MCP servers) are so we can do things like spawning a sub-agent with its own MCP server without polluting the parent agent context. I guess it's premature optimization for now though - so long as my plugin loads MCP servers on demand I think it's sufficient.

I think we can close this PR - sorry for the trouble and thanks for your time!

@terakael terakael closed this Nov 19, 2025
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.

2 participants