Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Sep 17, 2025

This PR addresses Issue #8059 by adding support for custom MCP server installation.

Summary

Implements a feature that allows users to add custom MCP servers through the Roo Code marketplace interface, with specific support for the Serena MCP server requested by the issue reporter.

Changes

UI Components

  • Added "Add Custom MCP" button to the marketplace MCP tab
  • Created CustomMcpDialog component for configuring custom MCP servers
  • Included Serena MCP server as an example configuration

Backend Implementation

  • Added addCustomMcpServer message handler in webviewMessageHandler.ts
  • Supports both project-level and global MCP configurations
  • Uses atomic JSON writes with safeWriteJson utility

Testing

  • Comprehensive unit tests for UI components
  • Backend handler tests covering success and error cases
  • All tests passing

Features

  • ✅ User-friendly dialog for adding custom MCP servers
  • ✅ Form validation for required fields (server name, command)
  • ✅ Support for command arguments and environment variables
  • ✅ One-click example configuration for Serena MCP server
  • ✅ Automatic marketplace refresh after adding a server
  • ✅ Support for both workspace and global installations

Testing

All tests pass:

  • Backend tests: src/core/webview/__tests__/webviewMessageHandler.customMcp.spec.ts
  • UI tests: webview-ui/src/components/marketplace/components/__tests__/CustomMcpDialog.spec.tsx

Screenshots

The implementation adds a prominent "Add Custom MCP" button in the MCP tab of the marketplace, which opens a dialog where users can configure their custom MCP servers.

Fixes #8059


Important

Add support for custom MCP server installations with UI and backend changes, including tests for new functionality.

  • UI Components:
    • Add "Add Custom MCP" button to marketplace MCP tab in MarketplaceListView.tsx.
    • Create CustomMcpDialog component for configuring custom MCP servers.
    • Include Serena MCP server as an example configuration in CustomMcpDialog.tsx.
  • Backend Implementation:
    • Add addCustomMcpServer message handler in webviewMessageHandler.ts.
    • Support project-level and global MCP configurations.
    • Use atomic JSON writes with safeWriteJson utility.
  • Testing:
    • Add unit tests for CustomMcpDialog in CustomMcpDialog.spec.tsx.
    • Add backend handler tests in webviewMessageHandler.customMcp.spec.ts.
  • Features:
    • User-friendly dialog for adding custom MCP servers with form validation.
    • Support for command arguments and environment variables.
    • Automatic marketplace refresh after adding a server.
    • Support for both workspace and global installations.

This description was created by Ellipsis for 3894345. You can customize this summary. It will automatically update as commits are pushed.

- Add "Add Custom MCP" button to marketplace MCP tab
- Create CustomMcpDialog component for configuring custom servers
- Include Serena MCP server as example configuration
- Implement backend handler for custom MCP installation
- Add comprehensive tests for the new functionality
- Fix linting issues

Fixes #8059
@roomote roomote bot requested review from cte, jr and mrubens as code owners September 17, 2025 07:56
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request UI/UX UI/UX related or focused labels Sep 17, 2025
const [showSerenaExample, setShowSerenaExample] = useState(false)

const handleSubmit = async () => {
// Validate inputs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider internationalizing the error messages used in validation (e.g., 'Server name is required' and 'Command is required') by using the translation function t(), to ensure consistency with the rest of the UI.

This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 17, 2025
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing my own code is like debugging in a mirror - everything looks backwards but the bugs are still mine.

onSuccess: () => void
}

export function CustomMcpDialog({ onClose, onSuccess }: CustomMcpDialogProps) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider wrapping this dialog component in an error boundary to gracefully handle unexpected errors. Currently, if an error occurs outside the try-catch in handleSubmit, it could crash the UI.

await safeWriteJson(mcpSettingsPath, mcpSettings)

// Refresh MCP connections to load the new server
await mcpHub.refreshAllConnections()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? The success message shows even if refreshAllConnections() fails. Consider wrapping the refresh in a try-catch to handle failures gracefully and provide appropriate user feedback.

return
}
if (!command.trim()) {
setError("Command is required")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command field accepts any input without validation. Could we validate that it's an executable command or at least show a warning about potential security implications of running arbitrary commands?

<Button variant="outline" onClick={onClose} disabled={isSubmitting}>
{t("marketplace:customMcp.cancel")}
</Button>
<Button onClick={handleSubmit} disabled={isSubmitting}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a loading spinner or progress indicator here. Currently users only see the button text change to "Adding..." which might not be enough feedback for slower operations.

placeholder={t("marketplace:customMcp.serverNamePlaceholder")}
disabled={isSubmitting}
/>
{serverName === "" && (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Looking for Serena MCP?" link only appears when serverName is empty. Since Serena was the specific request in the issue, could we make this example more prominent - perhaps always visible at the top of the dialog?

const trimmedLine = line.trim()
if (trimmedLine && trimmedLine.includes("=")) {
const [key, ...valueParts] = trimmedLine.split("=")
envObj[key.trim()] = valueParts.join("=").trim()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good handling of environment variables with multiple equals signs! Consider adding a tooltip or help text to document this behavior for users (e.g., "API_KEY=value=with=equals works correctly").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:XL This PR changes 500-999 lines, ignoring generated files. UI/UX UI/UX related or focused

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add serena to marketplace or provide an entry to add my own mcp server

4 participants