feat(mcp): add MCP Server Support #53
No reviewers
Labels
No Label
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sarman/tftsr-devops_investigation#53
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/mcp-server-support"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds full Model Context Protocol (MCP) server management, enabling the AI assistant to discover and call tools from external MCP servers during triage conversations.
What was built
Backend (Rust)
rmcp = "1.7.0"dependency with stdio + Streamable HTTP transportsmcp_servers,mcp_tools,mcp_resourcestables with CHECK constraintssrc/mcp/module: models, store, client, adapter, discovery, commands, transport/{stdio,http}AppState.mcp_connections: Arc<TokioMutex<HashMap<...>>>— live server connections.setup()hook auto-discovers enabled servers at application startupinvoke_handlerexecute_mcp_tool_call: PII scan + mandatorywrite_audit_eventbefore every external tool callauth_valueencrypted at rest (AES-256-GCM); scrubbed from every frontend responseCommand::new()directly (no shell)Frontend
MCPServers.tsxsettings page at/settings/mcptauriCommands.ts:McpServer,McpTool,McpServerStatustypes + 8 typed command wrappersApp.tsx: Plug icon,/settings/mcproute, sidebar nav entryWiki
docs/wiki/MCP-Servers.md(new)docs/wiki/Database.md,IPC-Commands.md,Security-Model.mdupdatedTest plan
cargo clippy -- -D warnings: zero warningsnpx tsc --noEmit: zero errorsAdds full Model Context Protocol (MCP) server management, enabling the AI assistant to discover and call tools from external MCP servers during triage conversations. Backend (Rust): - rmcp 1.7.0 dependency (client + stdio + Streamable HTTP transports) - Migration 018: mcp_servers, mcp_tools, mcp_resources tables with CHECK constraints for transport_type, auth_type, discovery_status - src/mcp/ module: models, store, client, adapter, discovery, commands, transport/{stdio,http} - AppState gains mcp_connections: Arc<TokioMutex<HashMap<...>>> - .setup() hook auto-discovers enabled servers at startup - 8 new Tauri commands wired into invoke_handler - execute_mcp_tool_call: PII scan + mandatory audit_log before execution - Auth values encrypted at rest via integrations::auth::encrypt_token(); scrubbed before any frontend response Frontend: - MCPServers.tsx settings page (/settings/mcp) with server list, status badges, Discover Now, Add/Edit modal, enable/disable toggle - tauriCommands.ts: McpServer, McpTool, McpServerStatus types + 8 cmds - App.tsx: Plug icon, /settings/mcp route, sidebar nav entry Tests (TDD): 15 new tests, all green - 5 migration tests (written before migration, red → green) - 5 store CRUD + encryption tests - 5 adapter sanitization + conversion tests Verification: 185/185 Rust, 94/94 Vitest, clippy -D warnings: 0Automated PR Review could not be completed - LLM analysis failed or produced no output.
Automated PR Review (qwen3-coder-next via liteLLM):\n\nHere's a detailed security, correctness, and best practices review of the provided code changes for the MCP Server Support feature:
✅ 1. Summary
This PR adds robust support for the Model Context Protocol (MCP), enabling the app to integrate external tools via
stdioorHTTPtransports. The implementation is well-structured, with strong separation of concerns (backend Rust modules, frontend React components, and documentation). Key strengths:auth_value, PII scanning, mandatory audit loggingstdio, no shell invocation)Overall assessment: The PR demonstrates high code quality, adherence to security best practices, and solid engineering judgment. Only minor improvements are suggested.
⚠️ 2. Bugs & Correctness Issues
🚫 Critical: Missing
auth_typeField in Schema & Modelsdocs/wiki/Database.md,mcp_serverstable definition does not includeauth_type, yet:MCPServers.tsx) assumesauth_typeis configurable.MCP_SERVER_SUPPORT.mdand docs describe 4 auth types:none,api_key,bearer,oauth2.commands.rsandstore.rslikely useauth_type.Problem: Without
auth_type, auth handling becomes ambiguous or broken.🔧 Fix:
auth_type TEXT NOT NULL DEFAULT 'none' CHECK(auth_type IN ('none','api_key','bearer','oauth2'))tomcp_servers.models.rs,store.rs, and frontend types accordingly.🐞 Stdio Transport: Missing
sh -cBypass Is Not GuaranteedIn
mcp/transport/stdio.rs,rmcp::transport::TokioChildProcess::new()is used, which does not invoke a shell by default—good!However, the documentation in
MCP-Servers.mdsays:But:
store.rsorcommands.rs).rmcpinternally constructs the command string viashell_expand()(unlikely, but not documented), that could reintroduce risk.🔍 Recommendation:
stdio.rsthatcommandis absolute and canonicalized before passing tormcp.test_rejects_relative_path().stdio.rsthat no shell invocation occurs.🚨 Potential Auth Leak in Error Paths
In
mcp/adapter.rs→execute_mcp_tool_call:If
rmcpor your stdio/HTTP client logs errors (e.g.,"Auth failed: Bearer abc..."), theauth_valuecould leak.🔧 Fix:
trace!(),warn!(),log::error!()calls strip auth headers.test_error_does_not_leak_auth.🔐 3. Security Issues
✅ Good Practices Already Implemented
auth_valuestored encrypted with AES-256-GCM (same system as other secrets).list_mcp_servers→auth_value: null.write_audit_event()before tool calls.sh -c) for stdio; absolute path enforced.⚠️ Security Gaps to Address
1. OAuth2 Token Exchange: No CSRF Protection
The
initiate_mcp_oauth()opens a WebView and handles the redirect.But:
stateparameter is mentioned (critical for PKCE/CSRF mitigation).🔧 Fix:
state+code_verifierin session storage.stateon redirect before exchanging the code.2. Missing Rate Limiting / Circuit Breaking for External Calls
discover_mcp_serverorexecute_mcp_tool_call.🔧 Fix:
discovery_timeout_ms,call_timeout_msintransport_config).rmcpcalls withtokio::time::timeout().3. Cascade Delete Without Confirmation
ON DELETE CASCADEon tools/resources.🔧 Fix:
write_audit_event("mcp_server_deleted", ...)that includes deleted tool/resource IDs.deleted_at) if tools are reused.🌟 4. Best Practices
✅ Excellent
cargo clippy -- -D warningsenforced.mcp/submodules).IPC-Commands.md,docs/).CHECK) on enums (transport_type,discovery_status).📝 Suggestions for Improvement
1. Missing API Versioning / Schema Evolution Plan
transport_configis aTEXT(JSON), but no versioning or deprecation strategy.transport_configchanges (e.g.,argsbecomesenv+args)?🔧 Fix:
transport_config_version INTEGER NOT NULL DEFAULT 1.serde_json::Value+#[serde(default)]+ version checks.2. Frontend:
auth_valueType Mismatch RiskIn
src/lib/tauriCommands.ts, the request types (CreateMcpServerRequest) includeauth_value?: string.But if
auth_type = "none", should users be allowed to provideauth_value? Currently, the frontend might let them, and the backend might store an empty string or ignore it.🔧 Fix:
MCPServers.tsx, disableauth_valueinput whenauth_type = "none".auth_value = NULLwhenauth_type = "none".3. Discovery Status Not Resettable
error, there's no way to reset it topendingexcept delete/re-add.🔧 Fix:
update_mcp_serverto setdiscovery_status = 'pending'(e.g., for manual retry).4.
idField: UUID vs. User-FriendlyTEXT PRIMARY KEY. Are they auto-generated UUIDs? Or user-specified?🔧 Fix:
"server-1"that encourage hardcoding).^[a-z0-9-]+$.✅ Final Verdict
auth_typemissing from DB schema✅ Approve with Recommendations
This PR is production-ready with the following changes before merge:
auth_typecolumn to migration 018 and models.stateparameter to OAuth2 flow.Once addressed, this becomes a gold-standard feature PR: secure, well-documented, and thoroughly tested.
Let me know if you'd like PR comment-ready language for these points!\n\n---\nautomated code review
Automated PR Review (qwen3-coder-next via liteLLM):\n\nSummary
This PR adds MCP (Model Context Protocol) server support, including database migrations, backend services, frontend UI, and documentation. The implementation covers server management (CRUD + discovery), two transports (stdio, HTTP), four auth types (none, api_key, bearer, oauth2), encrypted credential storage, audit logging, PII scanning, and integration with the AI tooling pipeline. All automated tests pass, and zero clippy/TSLint errors are reported.
Findings
[WARNING] MCP_SERVER_SUPPORT.md:line 71 — The documentation states that
auth_valueis “Always null in responses (scrubbed server-side)” forlist_mcp_servers, but the IPC-Commands.md example showsauth_value?: stringinMcpServerinterface. This inconsistency could mislead implementers or users about whetherauth_valuemight ever be present in responses.→ Suggested fix: Align the field to
auth_value: null(i.e., remove it entirely) from theMcpServerinterface in IPC-Commands.md, or explicitly clarify that the field is omitted (not null) in all responses.[WARNING] MCP_SERVER_SUPPORT.md:line 237 — The “Adding an MCP Server (UI)” guide states: “For HTTP: typically
{}” fortransport_config. However, for HTTP servers, connection configuration (url) lives on the top-levelurlfield, not intransport_config. This phrasing may confuse users into unnecessarily populatingtransport_configwith irrelevant fields like"url": "...".→ Suggested fix: Clarify that for HTTP transport,
transport_configis always{}(empty JSON), andurlis set separately at the server root level.[SUGGESTION] MCP_SERVER_SUPPORT.md:line 269 — The line
\n\n## Instructions\nat the end of the diff’sMCP_SERVER_SUPPORT.mdfile appears to be an accidental leftover from the PR review prompt template (not part of the intended documentation).→ Suggested fix: Remove the line and everything below it in that file, as it is not relevant to the feature documentation.
[SUGGESTION] docs/wiki/MCP-Servers.md:line 135 — The “Authentication Types” table includes
oauth2, but the table header (line 135) and preceding description list onlyapi_key,bearer, andnone. Thoughoauth2is explained later, its omission from the summary table reduces discoverability.→ Suggested fix: Update the table header to include
oauth2, or add a footnote clarifying its inclusion.Verdict: APPROVE WITH COMMENTS\n\n---\nautomated code review