d275b96bfd
Adds the full MCP setup surface as profile-scoped gateway RPCs so a desktop client (Bot Mode's bot editor, the core Capabilities tab) can add/configure/test/authenticate/remove MCP servers for ANY profile, not just the launch profile: - mcp.servers.list (profile) -> configured servers (transport, auth, oauth_tokens_present, enabled, tool names; no secret values) - mcp.servers.add (profile, name, config|preset, bearer_token?) -> reuses mcp_config._apply_mcp_preset / _save_mcp_server / _save_bearer_auth_token - mcp.servers.set_api_key (profile, name, value, env_var?) -> http auth header template or stdio env ref, via save_env_value - mcp.servers.test (profile, name) -> _probe_single_server + oauth state - mcp.servers.remove (profile, name) - mcp.servers.oauth.start/poll (profile, name[, session_id]) -> mirrors the PROVIDER oauth session/poll model (not the FastAPI dashboard flow): a background worker drives the same interactive machinery 'hermes mcp login' uses, capturing the browser redirect on a local loopback listener. Client opens auth_url via openExternal and polls until status=='approved'. All handlers are profile-scoped via set_hermes_home_override in try/finally (mirrors skills.manage). Shared helpers live in tui_gateway/mcp_rpc_helpers.py and are aliased onto server.py's namespace so the rebound handler bodies (HandlerRegistry.install) can resolve them — a plain def in methods_tools is unreachable post-rebind. Reuses hermes_cli/mcp_config.py throughout; no config logic duplicated; no raw yaml near config.yaml (config-read-guard safe). Tests: tests/tui_gateway/test_mcp_profile_rpcs.py, 8 E2E against real temp HERMES_HOME profiles asserting add/list/set_api_key/remove land in the RIGHT profile's config.yaml and not the launch profile's. 8/8. Registration + live mcp.servers.list verified in an imported gateway. Co-authored-by: Teknium <teknium1@users.noreply.github.com>