mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
feat: add Appium MCP Server documentation and tests
- Add comprehensive test suite for Appium MCP Server configuration - Document MCP server marketplace item structure - Provide guidance for adding new MCP servers to marketplace - Include example configuration for Appium MCP Server Addresses #9479
This commit is contained in:
parent
852e293610
commit
247368c7c6
2 changed files with 519 additions and 0 deletions
211
docs/marketplace-mcp-servers.md
Normal file
211
docs/marketplace-mcp-servers.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
# Adding MCP Servers to the Roo Code Marketplace
|
||||
|
||||
## Overview
|
||||
|
||||
The Roo Code Marketplace provides a centralized location for discovering and installing MCP (Model Context Protocol) servers. This document describes how MCP servers are configured and provides guidance for requesting new servers to be added.
|
||||
|
||||
## MCP Server Configuration Structure
|
||||
|
||||
MCP servers in the marketplace are defined with the following structure:
|
||||
|
||||
```typescript
|
||||
interface McpMarketplaceItem {
|
||||
id: string // Unique identifier for the server
|
||||
name: string // Display name
|
||||
description: string // Brief description of functionality
|
||||
author?: string // Author/organization name
|
||||
authorUrl?: string // Link to author's website or GitHub
|
||||
url: string // Repository URL
|
||||
type: "mcp" // Item type (always "mcp" for servers)
|
||||
tags?: string[] // Searchable tags
|
||||
prerequisites?: string[] // Installation requirements
|
||||
content: string | McpInstallationMethod[] // Server configuration
|
||||
parameters?: McpParameter[] // Configurable parameters
|
||||
}
|
||||
```
|
||||
|
||||
### Basic MCP Server Configuration
|
||||
|
||||
For a simple MCP server that runs via NPX:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "example-mcp",
|
||||
"name": "Example MCP Server",
|
||||
"description": "An example MCP server for demonstration",
|
||||
"url": "https://github.com/example/example-mcp",
|
||||
"type": "mcp",
|
||||
"content": "{\"command\": \"npx\", \"args\": [\"-y\", \"@example/mcp-server\"]}"
|
||||
}
|
||||
```
|
||||
|
||||
### MCP Server with Parameters
|
||||
|
||||
For servers that require configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "configurable-mcp",
|
||||
"name": "Configurable MCP Server",
|
||||
"description": "MCP server with user-configurable options",
|
||||
"url": "https://github.com/example/configurable-mcp",
|
||||
"type": "mcp",
|
||||
"content": "{\"command\": \"npx\", \"args\": [\"-y\", \"@example/mcp-server\"], \"env\": {\"API_KEY\": \"{{API_KEY}}\"}}",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"key": "API_KEY",
|
||||
"placeholder": "Enter your API key",
|
||||
"optional": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Installation Methods
|
||||
|
||||
For servers with different installation options:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "multi-install-mcp",
|
||||
"name": "Multi-Install MCP Server",
|
||||
"description": "MCP server with multiple installation methods",
|
||||
"url": "https://github.com/example/multi-mcp",
|
||||
"type": "mcp",
|
||||
"content": [
|
||||
{
|
||||
"name": "NPX (Recommended)",
|
||||
"content": "{\"command\": \"npx\", \"args\": [\"-y\", \"@example/mcp\"]}"
|
||||
},
|
||||
{
|
||||
"name": "Docker",
|
||||
"content": "{\"command\": \"docker\", \"args\": [\"run\", \"-p\", \"3000:3000\", \"example/mcp:latest\"]}",
|
||||
"prerequisites": ["Docker installed and running"]
|
||||
},
|
||||
{
|
||||
"name": "Global Install",
|
||||
"content": "{\"command\": \"example-mcp\", \"args\": []}",
|
||||
"prerequisites": ["Install globally first: npm install -g @example/mcp"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Example: Appium MCP Server Configuration
|
||||
|
||||
The Appium MCP Server, as requested in issue #9479, would be configured as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "appium-mcp",
|
||||
"name": "Appium MCP Server",
|
||||
"description": "MCP server for Mobile Development and Automation | iOS, Android, Simulator, Emulator, and Real Devices",
|
||||
"author": "Appium Contributors",
|
||||
"authorUrl": "https://github.com/appium",
|
||||
"url": "https://github.com/appium/appium-mcp",
|
||||
"type": "mcp",
|
||||
"tags": ["mobile", "automation", "ios", "android", "testing", "appium"],
|
||||
"prerequisites": [
|
||||
"Node.js 16+ and npm installed",
|
||||
"Appium installed globally or locally",
|
||||
"Platform-specific requirements (Xcode for iOS, Android SDK for Android)"
|
||||
],
|
||||
"content": "{\"command\": \"npx\", \"args\": [\"-y\", \"@appium/mcp-server\"], \"env\": {\"APPIUM_HOST\": \"localhost\", \"APPIUM_PORT\": \"4723\"}}",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Appium Host",
|
||||
"key": "APPIUM_HOST",
|
||||
"placeholder": "localhost",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"name": "Appium Port",
|
||||
"key": "APPIUM_PORT",
|
||||
"placeholder": "4723",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## MCP Server Capabilities
|
||||
|
||||
When documenting an MCP server for the marketplace, include information about its capabilities:
|
||||
|
||||
### Tools
|
||||
|
||||
List the tools/commands the server exposes:
|
||||
|
||||
- `launch_app` - Launch a mobile application
|
||||
- `find_element` - Find UI elements
|
||||
- `take_screenshot` - Capture device screen
|
||||
- etc.
|
||||
|
||||
### Resources
|
||||
|
||||
List the resources available:
|
||||
|
||||
- `device_list` - Available devices
|
||||
- `session_info` - Current session details
|
||||
- etc.
|
||||
|
||||
### Prompts
|
||||
|
||||
List any pre-configured prompts:
|
||||
|
||||
- `test_login_flow` - Automate login testing
|
||||
- `validate_ui_elements` - Check UI consistency
|
||||
- etc.
|
||||
|
||||
## How to Request a New MCP Server
|
||||
|
||||
To request a new MCP server be added to the marketplace:
|
||||
|
||||
1. **Open an Issue**: Create a GitHub issue in the Roo Code repository
|
||||
2. **Provide Information**:
|
||||
- Server name and description
|
||||
- GitHub repository URL
|
||||
- Installation command (NPX, Docker, etc.)
|
||||
- Any required configuration parameters
|
||||
- Prerequisites for installation
|
||||
- List of capabilities (tools, resources, prompts)
|
||||
3. **Include Examples**: Provide example use cases or documentation links
|
||||
4. **Test the Server**: Confirm the server works with the MCP protocol
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
The marketplace items are fetched from a remote API endpoint managed by the Roo Code team. The actual configuration data is stored server-side and retrieved by the extension at runtime.
|
||||
|
||||
### API Endpoints
|
||||
|
||||
- Modes: `https://api.roocode.com/api/marketplace/modes`
|
||||
- MCP Servers: `https://api.roocode.com/api/marketplace/mcps`
|
||||
|
||||
### Local Testing
|
||||
|
||||
For development and testing, you can mock MCP server configurations using the test framework as shown in `src/services/marketplace/__tests__/appium-mcp-server.spec.ts`.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Clear Naming**: Use descriptive, unique IDs and names
|
||||
2. **Comprehensive Descriptions**: Explain what the server does and its use cases
|
||||
3. **Document Prerequisites**: List all requirements for successful installation
|
||||
4. **Provide Parameters**: Allow users to configure server behavior
|
||||
5. **Tag Appropriately**: Use relevant tags for discoverability
|
||||
6. **Test Thoroughly**: Ensure the server configuration works before submission
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Never include sensitive information (API keys, passwords) in the configuration
|
||||
- Use parameter placeholders for user-specific values
|
||||
- Verify server authenticity through official repository URLs
|
||||
- Review server permissions and capabilities before installation
|
||||
|
||||
## Support
|
||||
|
||||
For questions about adding MCP servers to the marketplace:
|
||||
|
||||
- Open a GitHub issue with the "enhancement" label
|
||||
- Join the community discussions
|
||||
- Refer to the MCP protocol documentation
|
||||
308
src/services/marketplace/__tests__/appium-mcp-server.spec.ts
Normal file
308
src/services/marketplace/__tests__/appium-mcp-server.spec.ts
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
// npx vitest services/marketplace/__tests__/appium-mcp-server.spec.ts
|
||||
|
||||
import { SimpleInstaller } from "../SimpleInstaller"
|
||||
import { MarketplaceItem } from "@roo-code/types"
|
||||
import * as fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
import * as vscode from "vscode"
|
||||
import { vi, describe, it, expect, beforeEach } from "vitest"
|
||||
|
||||
// Mock fs module
|
||||
vi.mock("fs/promises")
|
||||
|
||||
// Mock vscode module
|
||||
vi.mock("vscode", () => ({
|
||||
workspace: {
|
||||
workspaceFolders: [
|
||||
{
|
||||
uri: {
|
||||
fsPath: "/test/workspace",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}))
|
||||
|
||||
describe("Appium MCP Server Installation", () => {
|
||||
let installer: SimpleInstaller
|
||||
const mockFs = fs as any
|
||||
const mockContext = {
|
||||
globalStorageUri: { fsPath: "/test/global" },
|
||||
storageUri: { fsPath: "/test/storage" },
|
||||
} as any
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
installer = new SimpleInstaller(mockContext, undefined)
|
||||
// Mock file operations
|
||||
mockFs.access.mockResolvedValue(undefined)
|
||||
mockFs.writeFile.mockResolvedValue(undefined)
|
||||
mockFs.readFile.mockResolvedValue("{}")
|
||||
mockFs.mkdir.mockResolvedValue(undefined)
|
||||
})
|
||||
|
||||
describe("Appium MCP Server Configuration", () => {
|
||||
it("should define Appium MCP Server marketplace item correctly", () => {
|
||||
// This is the expected configuration for Appium MCP Server
|
||||
const appiumMcpItem: MarketplaceItem = {
|
||||
id: "appium-mcp",
|
||||
name: "Appium MCP Server",
|
||||
description:
|
||||
"MCP server for Mobile Development and Automation | iOS, Android, Simulator, Emulator, and Real Devices",
|
||||
author: "Appium Contributors",
|
||||
authorUrl: "https://github.com/appium",
|
||||
url: "https://github.com/appium/appium-mcp",
|
||||
type: "mcp",
|
||||
tags: ["mobile", "automation", "ios", "android", "testing", "appium"],
|
||||
content: JSON.stringify({
|
||||
command: "npx",
|
||||
args: ["-y", "@appium/mcp-server"],
|
||||
env: {
|
||||
APPIUM_HOST: "localhost",
|
||||
APPIUM_PORT: "4723",
|
||||
},
|
||||
}),
|
||||
prerequisites: [
|
||||
"Node.js 16+ and npm installed",
|
||||
"Appium installed globally or locally",
|
||||
"Platform-specific requirements (Xcode for iOS, Android SDK for Android)",
|
||||
],
|
||||
}
|
||||
|
||||
// Validate the structure
|
||||
expect(appiumMcpItem.id).toBe("appium-mcp")
|
||||
expect(appiumMcpItem.type).toBe("mcp")
|
||||
expect(appiumMcpItem.name).toBe("Appium MCP Server")
|
||||
expect(appiumMcpItem.url).toBe("https://github.com/appium/appium-mcp")
|
||||
expect(appiumMcpItem.tags).toContain("mobile")
|
||||
expect(appiumMcpItem.tags).toContain("automation")
|
||||
expect(appiumMcpItem.prerequisites).toBeDefined()
|
||||
expect(appiumMcpItem.prerequisites?.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it("should support alternative Appium MCP installation methods", () => {
|
||||
// Alternative installation method using multiple configurations
|
||||
const appiumMcpWithMethods: MarketplaceItem = {
|
||||
id: "appium-mcp",
|
||||
name: "Appium MCP Server",
|
||||
description: "MCP server for Mobile Development and Automation",
|
||||
url: "https://github.com/appium/appium-mcp",
|
||||
type: "mcp",
|
||||
content: [
|
||||
{
|
||||
name: "Default (NPX)",
|
||||
content: JSON.stringify({
|
||||
command: "npx",
|
||||
args: ["-y", "@appium/mcp-server"],
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Docker",
|
||||
content: JSON.stringify({
|
||||
command: "docker",
|
||||
args: ["run", "-p", "4723:4723", "appium/appium-mcp:latest"],
|
||||
}),
|
||||
prerequisites: ["Docker installed and running"],
|
||||
},
|
||||
{
|
||||
name: "Global NPM Install",
|
||||
content: JSON.stringify({
|
||||
command: "appium-mcp",
|
||||
args: [],
|
||||
}),
|
||||
prerequisites: ["Install globally first: npm install -g @appium/mcp-server"],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// Validate multiple installation methods
|
||||
expect(Array.isArray(appiumMcpWithMethods.content)).toBe(true)
|
||||
if (Array.isArray(appiumMcpWithMethods.content)) {
|
||||
expect(appiumMcpWithMethods.content).toHaveLength(3)
|
||||
expect(appiumMcpWithMethods.content[0].name).toBe("Default (NPX)")
|
||||
expect(appiumMcpWithMethods.content[1].name).toBe("Docker")
|
||||
expect(appiumMcpWithMethods.content[2].name).toBe("Global NPM Install")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("Installing Appium MCP Server", () => {
|
||||
it("should install Appium MCP Server to project configuration", async () => {
|
||||
const appiumMcpItem: MarketplaceItem = {
|
||||
id: "appium-mcp",
|
||||
name: "Appium MCP Server",
|
||||
description: "MCP server for Mobile Development and Automation",
|
||||
url: "https://github.com/appium/appium-mcp",
|
||||
type: "mcp",
|
||||
content: JSON.stringify({
|
||||
command: "npx",
|
||||
args: ["-y", "@appium/mcp-server"],
|
||||
env: {
|
||||
APPIUM_HOST: "localhost",
|
||||
APPIUM_PORT: "4723",
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
// Mock existing MCP configuration
|
||||
mockFs.readFile.mockResolvedValue(
|
||||
JSON.stringify({
|
||||
mcpServers: {
|
||||
"existing-server": {
|
||||
command: "node",
|
||||
args: ["server.js"],
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const result = await installer.installItem(appiumMcpItem, {
|
||||
target: "project",
|
||||
})
|
||||
|
||||
expect(result.filePath).toContain("mcp.json")
|
||||
expect(mockFs.writeFile).toHaveBeenCalled()
|
||||
|
||||
// Verify the written content includes Appium MCP
|
||||
const writtenContent = mockFs.writeFile.mock.calls[0][1]
|
||||
const writtenData = JSON.parse(writtenContent)
|
||||
expect(writtenData.mcpServers["appium-mcp"]).toBeDefined()
|
||||
expect(writtenData.mcpServers["appium-mcp"].command).toBe("npx")
|
||||
expect(writtenData.mcpServers["appium-mcp"].args).toContain("-y")
|
||||
expect(writtenData.mcpServers["appium-mcp"].args).toContain("@appium/mcp-server")
|
||||
expect(writtenData.mcpServers["appium-mcp"].env.APPIUM_HOST).toBe("localhost")
|
||||
expect(writtenData.mcpServers["appium-mcp"].env.APPIUM_PORT).toBe("4723")
|
||||
})
|
||||
|
||||
it("should install Appium MCP Server with parameters", async () => {
|
||||
const appiumMcpItem: MarketplaceItem = {
|
||||
id: "appium-mcp",
|
||||
name: "Appium MCP Server",
|
||||
description: "MCP server for Mobile Development and Automation",
|
||||
url: "https://github.com/appium/appium-mcp",
|
||||
type: "mcp",
|
||||
content: JSON.stringify({
|
||||
command: "npx",
|
||||
args: ["-y", "@appium/mcp-server"],
|
||||
env: {
|
||||
APPIUM_HOST: "{{APPIUM_HOST}}",
|
||||
APPIUM_PORT: "{{APPIUM_PORT}}",
|
||||
PLATFORM_NAME: "{{PLATFORM_NAME}}",
|
||||
},
|
||||
}),
|
||||
parameters: [
|
||||
{
|
||||
name: "Appium Host",
|
||||
key: "APPIUM_HOST",
|
||||
placeholder: "localhost",
|
||||
optional: false,
|
||||
},
|
||||
{
|
||||
name: "Appium Port",
|
||||
key: "APPIUM_PORT",
|
||||
placeholder: "4723",
|
||||
optional: false,
|
||||
},
|
||||
{
|
||||
name: "Platform",
|
||||
key: "PLATFORM_NAME",
|
||||
placeholder: "iOS or Android",
|
||||
optional: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const result = await installer.installItem(appiumMcpItem, {
|
||||
target: "project",
|
||||
parameters: {
|
||||
APPIUM_HOST: "127.0.0.1",
|
||||
APPIUM_PORT: "4444",
|
||||
PLATFORM_NAME: "iOS",
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.filePath).toContain("mcp.json")
|
||||
expect(mockFs.writeFile).toHaveBeenCalled()
|
||||
|
||||
// Verify parameters were properly substituted
|
||||
const writtenContent = mockFs.writeFile.mock.calls[0][1]
|
||||
const writtenData = JSON.parse(writtenContent)
|
||||
expect(writtenData.mcpServers["appium-mcp"].env.APPIUM_HOST).toBe("127.0.0.1")
|
||||
expect(writtenData.mcpServers["appium-mcp"].env.APPIUM_PORT).toBe("4444")
|
||||
expect(writtenData.mcpServers["appium-mcp"].env.PLATFORM_NAME).toBe("iOS")
|
||||
})
|
||||
|
||||
it("should handle Appium MCP Server with multiple capabilities", () => {
|
||||
// Test configuration with advanced Appium capabilities
|
||||
const appiumMcpAdvanced: MarketplaceItem = {
|
||||
id: "appium-mcp",
|
||||
name: "Appium MCP Server",
|
||||
description: "MCP server for Mobile Development and Automation",
|
||||
url: "https://github.com/appium/appium-mcp",
|
||||
type: "mcp",
|
||||
content: JSON.stringify({
|
||||
command: "npx",
|
||||
args: ["-y", "@appium/mcp-server"],
|
||||
env: {
|
||||
APPIUM_HOST: "localhost",
|
||||
APPIUM_PORT: "4723",
|
||||
CAPABILITIES: JSON.stringify({
|
||||
platformName: "iOS",
|
||||
platformVersion: "15.0",
|
||||
deviceName: "iPhone 13",
|
||||
automationName: "XCUITest",
|
||||
app: "/path/to/app.ipa",
|
||||
}),
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
// Parse and validate the capabilities
|
||||
const content = JSON.parse(appiumMcpAdvanced.content as string)
|
||||
const capabilities = JSON.parse(content.env.CAPABILITIES)
|
||||
|
||||
expect(capabilities.platformName).toBe("iOS")
|
||||
expect(capabilities.deviceName).toBe("iPhone 13")
|
||||
expect(capabilities.automationName).toBe("XCUITest")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Appium MCP Server Features", () => {
|
||||
it("should support mobile automation tools and commands", () => {
|
||||
// Define expected Appium MCP capabilities
|
||||
const expectedTools = [
|
||||
"launch_app",
|
||||
"install_app",
|
||||
"uninstall_app",
|
||||
"find_element",
|
||||
"click_element",
|
||||
"send_keys",
|
||||
"swipe",
|
||||
"scroll",
|
||||
"take_screenshot",
|
||||
"get_device_info",
|
||||
"get_orientation",
|
||||
"set_orientation",
|
||||
"start_recording",
|
||||
"stop_recording",
|
||||
"push_file",
|
||||
"pull_file",
|
||||
"get_logs",
|
||||
"execute_script",
|
||||
]
|
||||
|
||||
// This represents what the MCP server should expose
|
||||
const appiumMcpCapabilities = {
|
||||
tools: expectedTools,
|
||||
resources: ["device_list", "app_list", "session_info", "element_tree"],
|
||||
prompts: ["test_login_flow", "validate_ui_elements", "perform_gesture", "capture_performance_metrics"],
|
||||
}
|
||||
|
||||
expect(appiumMcpCapabilities.tools).toContain("launch_app")
|
||||
expect(appiumMcpCapabilities.tools).toContain("find_element")
|
||||
expect(appiumMcpCapabilities.tools).toContain("take_screenshot")
|
||||
expect(appiumMcpCapabilities.resources).toContain("device_list")
|
||||
expect(appiumMcpCapabilities.prompts).toContain("test_login_flow")
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue