feat: inject per-user MCP servers into ACP sessions#345
Closed
Reese-max wants to merge 7 commits into
Closed
Conversation
… sessions
When a user adds MCP servers via /mcp-add, the servers are now automatically
injected into ACP session/new and session/load calls. This completes the
"UI management → runtime activation" loop.
Changes:
- config.rs: add McpServerEntry struct + read_mcp_profile() + mcp_profiles_dir config
- connection.rs: session_new/session_load accept mcp_servers parameter + cfg(unix) guards
- pool.rs: get_or_create passes mcp_servers through + saturating_duration_since fix
- discord.rs: mcp_servers_for_user() reads profile dir, message handler injects
- main.rs: handler gets mcp_profiles_dir
Verified: all 4 backends (Claude, Copilot, Gemini, Codex) accept the unified
[{name, type:"http", url, headers:[]}] format. E2E tested with Claude ACP.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- mcp_servers_for_user() now async with spawn_blocking (no blocking I/O on Tokio) - Log level downgraded info → debug (avoid per-message log spam) - Non-object MCP profile entries skipped with warning (validation) - kill_on_drop(true) added to ACP child spawn (Windows cleanup) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
All PRs must reference a prior Discord discussion to ensure community alignment before implementation. Please edit the PR description to include a link like: This PR will be automatically closed in 3 days if the link is not added. |
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem does this solve?
Users can manage MCP servers via Discord slash commands such as
/mcp-add,/mcp-remove, and/mcp-list, but those profile entries are never injected into ACP sessions. The profile JSON is written, but the backend session still starts withoutmcpServers, so/mcp-addis a dead-end UI.This change closes the loop from Discord MCP profile management to runtime MCP activation.
At a Glance
Prior Art
OpenClaw
OpenClaw merges MCP config from bundle defaults plus global config and injects it at session/runtime creation. For CLI backends it relies on backend-specific config/CLI arg injection such as
--mcp-config, not ACPsession/new.Relevant difference:
Hermes Agent
Hermes supports
mcp_serverson ACP session creation, but tools are registered into a process-wide registry rather than isolated per Discord user/session.Relevant difference:
Comparison
/new-sessionProposed Solution
McpServerEntryandread_mcp_profile()insrc/config.rsto read{mcp_profiles_dir}/{user_id}.json.session_new()/session_load()insrc/acp/connection.rsto acceptmcp_serversand send them through ACP.SessionPool::get_or_create()insrc/acp/pool.rsto threadmcp_serversinto new or resumed sessions.src/discord.rs, resolve the calling user's MCP profile and inject it into message handling and session-creating slash commands.&[]so health/status flows do not depend on user MCP state.Profile JSON stays in the existing Discord-managed format:
{ "discord_user_id": "844236700611379200", "mcpServers": { "mempalace": { "type": "http", "url": "http://127.0.0.1:18793/mcp", "headers": [] } }, "enabled": true }Converted at runtime to ACP format:
[ { "name": "mempalace", "type": "http", "url": "http://127.0.0.1:18793/mcp", "headers": [] } ]Why this approach?
mcpServerson session creation.mcp_profiles_dir.~/.claude*, Copilot config files, or other local machine state.Alternatives Considered
Backend-specific config file mutation.
Rejected because it is fragile, backend-specific, and risks overwriting user-managed config.
Global singleton MCP registry.
Rejected because OpenAB is a shared Discord bot process and would leak one user's MCP tools into another user's sessions.
In-session hot reload.
Deferred because the current ACP/session model is simpler and the UX is already covered by “next session” plus
/new-session.Validation
Current branch validation:
cargo checkcargo build --releasecargo test(42 passed, 0 failed)cargo fmt --checkbat/ local profile / runtime script filesPreviously validated during the implementation session:
session/new(mcpServers)-> tool discovery ->mempalace_search/mcp-addUX updated to note that changes apply on next session and/new-sessioncan apply immediatelyNotes
This PR branch also includes a small follow-up cleanup to remove dead-code warnings in the model picker path so the branch stays warning-free during review.