Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions marketplace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Roo Code Marketplace

This directory contains the marketplace configuration files for Roo Code extensions, including MCP servers and custom modes.

## Structure

- `mcps.yml` - Configuration for MCP (Model Context Protocol) servers
- `modes.yml` - Configuration for custom modes

## Adding New MCP Servers

To add a new MCP server to the marketplace, add an entry to `mcps.yml` following this structure:

```yaml
- id: "unique-server-id"
name: "Display Name"
description: "Detailed description of what the MCP server does"
author: "Author Name"
authorUrl: "https://github.com/author"
url: "https://github.com/author/repo"
tags: ["tag1", "tag2", "tag3"]
prerequisites: ["Node.js 18+", "npm"]
content:
- name: "Installation Method Name"
content: |
{
"mcpServers": {
"server-name": {
"command": "npx",
"args": ["package-name"],
"env": {}
}
}
}
parameters: []
prerequisites: ["Node.js 18+"]
```

## Adding New Modes

To add a new custom mode to the marketplace, add an entry to `modes.yml` following this structure:

```yaml
- id: "unique-mode-id"
name: "Mode Display Name"
description: "Description of what the mode does"
author: "Author Name"
authorUrl: "https://github.com/author"
tags: ["tag1", "tag2"]
prerequisites: ["Required MCP Server"]
content: |
name: Mode Name
slug: mode-slug
description: Brief mode description

instructions: |
Detailed instructions for the mode...
```

## Daft.ie MCP Server

The Daft.ie MCP Server has been added to the marketplace as requested in GitHub issue #4756. This server provides:

- Property search functionality for Irish rental market
- Integration with Daft.ie's property database
- Filtering by location, price, property type, and amenities
- Real-time property data and availability

### Installation

The Daft.ie MCP server can be installed via:

1. **NPM Installation** (Recommended)

```bash
npx daft-ie-mcp
```

2. **Local Development**
- Clone the repository from https://github.com/amineremache/daft-ie-mcp
- Build and run locally

### Related Mode

A complementary "Property Search Mode" has also been added to help users effectively utilize the Daft.ie MCP server for property searches and market analysis.

## Contributing

To contribute new marketplace items:

1. Fork the repository
2. Add your item to the appropriate YAML file
3. Test the configuration
4. Submit a pull request

## Validation

All marketplace items should follow the schema defined in `packages/types/src/marketplace.ts` to ensure compatibility with the Roo Code extension.
43 changes: 43 additions & 0 deletions marketplace/mcps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Marketplace MCP Servers Configuration
# This file contains the configuration for MCP servers available in the marketplace

items:
- id: "daft-ie-mcp"
name: "Daft.ie MCP Server"
description: "An MCP server for searching rental properties on Daft.ie, Ireland's largest property website. Search for apartments, houses, and other rental properties with filters for location, price, property type, and more."
author: "amineremache"
authorUrl: "https://github.com/amineremache"
url: "https://github.com/amineremache/daft-ie-mcp"
tags: ["property", "rental", "ireland", "search", "real-estate"]
prerequisites: ["Node.js 18+", "npm or yarn"]
content:
- name: "NPM Installation"
content: |
{
"mcpServers": {
"daft-ie": {
"command": "npx",
"args": ["daft-ie-mcp"],
"env": {}
}
}
}
parameters: []
prerequisites: ["Node.js 18+", "npm"]
- name: "Local Development"
content: |
{
"mcpServers": {
"daft-ie": {
"command": "node",
"args": ["path/to/daft-ie-mcp/dist/index.js"],
"env": {}
}
}
}
parameters:
- name: "Installation Path"
key: "path"
placeholder: "/path/to/daft-ie-mcp"
optional: false
prerequisites: ["Node.js 18+", "Git", "Local clone of the repository"]
43 changes: 43 additions & 0 deletions marketplace/modes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Marketplace Modes Configuration
# This file contains the configuration for custom modes available in the marketplace

items:
- id: "property-search-mode"
name: "Property Search Mode"
description: "A specialized mode for searching and analyzing rental properties using the Daft.ie MCP server. Optimized for property research, market analysis, and rental searches in Ireland."
author: "RooCode Team"
authorUrl: "https://github.com/RooCodeInc"
tags: ["property", "rental", "ireland", "search", "real-estate", "analysis"]
prerequisites: ["Daft.ie MCP Server"]
content: |
name: Property Search Specialist
slug: property-search
description: I am a property search specialist focused on helping you find rental properties in Ireland using Daft.ie. I can search for apartments, houses, and other rental properties with various filters, analyze market trends, and provide detailed property information.

instructions: |
You are a property search specialist with access to the Daft.ie MCP server. Your role is to help users find rental properties in Ireland by:

1. **Property Search**: Use the Daft.ie MCP tools to search for rental properties based on user criteria such as:
- Location (county, city, area)
- Price range
- Property type (apartment, house, studio, etc.)
- Number of bedrooms/bathrooms
- Amenities and features

2. **Market Analysis**: Provide insights on:
- Average rental prices in specific areas
- Property availability trends
- Comparison between different locations
- Market recommendations

3. **Property Details**: When users are interested in specific properties, provide:
- Detailed property descriptions
- Photos and virtual tours (if available)
- Contact information for landlords/agents
- Nearby amenities and transport links

4. **Search Optimization**: Help users refine their search criteria to find the best matches for their needs and budget.

Always be helpful, informative, and provide accurate property information. If you cannot find properties matching specific criteria, suggest alternative options or broader search parameters.

Remember to use the Daft.ie MCP server tools effectively to provide real-time property data and search results.
66 changes: 66 additions & 0 deletions scripts/validate-marketplace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env node

const fs = require("fs")
const path = require("path")
const yaml = require("yaml")

// Simple validation script for marketplace files
function validateMarketplaceFiles() {
const marketplaceDir = path.join(__dirname, "..", "marketplace")

console.log("🔍 Validating marketplace files...\n")

// Check mcps.yml
try {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const mcpsContent = fs.readFileSync(mcpsPath, "utf-8")
const mcpsData = yaml.parse(mcpsContent)

console.log("✅ mcps.yml is valid YAML")
console.log(` Found ${mcpsData.items.length} MCP server(s)`)

// Check for Daft.ie MCP
const daftieServer = mcpsData.items.find((item) => item.id === "daft-ie-mcp")
if (daftieServer) {
console.log("✅ Daft.ie MCP Server found")
console.log(` Name: ${daftieServer.name}`)
console.log(` Author: ${daftieServer.author}`)
console.log(` URL: ${daftieServer.url}`)
console.log(` Tags: ${daftieServer.tags.join(", ")}`)
console.log(` Installation methods: ${daftieServer.content.length}`)
} else {
console.log("❌ Daft.ie MCP Server not found")
}
} catch (error) {
console.log("❌ Error validating mcps.yml:", error.message)
}

console.log("")

// Check modes.yml
try {
const modesPath = path.join(marketplaceDir, "modes.yml")
const modesContent = fs.readFileSync(modesPath, "utf-8")
const modesData = yaml.parse(modesContent)

console.log("✅ modes.yml is valid YAML")
console.log(` Found ${modesData.items.length} mode(s)`)

// Check for Property Search mode
const propertyMode = modesData.items.find((item) => item.id === "property-search-mode")
if (propertyMode) {
console.log("✅ Property Search Mode found")
console.log(` Name: ${propertyMode.name}`)
console.log(` Author: ${propertyMode.author}`)
console.log(` Tags: ${propertyMode.tags.join(", ")}`)
} else {
console.log("❌ Property Search Mode not found")
}
} catch (error) {
console.log("❌ Error validating modes.yml:", error.message)
}

console.log("\n🎉 Marketplace validation complete!")
}

validateMarketplaceFiles()
138 changes: 138 additions & 0 deletions src/services/marketplace/__tests__/marketplace-data.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import * as fs from "fs/promises"
import * as path from "path"
import * as yaml from "yaml"
import { modeMarketplaceItemSchema, mcpMarketplaceItemSchema } from "@roo-code/types"

describe("Marketplace Data Validation", () => {
const marketplaceDir = path.join(__dirname, "../../../../marketplace")

describe("MCP Servers Configuration", () => {
it("should have valid mcps.yml file", async () => {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const content = await fs.readFile(mcpsPath, "utf-8")
const data = yaml.parse(content)

expect(data).toHaveProperty("items")
expect(Array.isArray(data.items)).toBe(true)
})

it("should validate all MCP items against schema", async () => {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const content = await fs.readFile(mcpsPath, "utf-8")
const data = yaml.parse(content)

for (const item of data.items) {
expect(() => mcpMarketplaceItemSchema.parse(item)).not.toThrow()
}
})

it("should contain Daft.ie MCP server", async () => {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const content = await fs.readFile(mcpsPath, "utf-8")
const data = yaml.parse(content)

const daftieServer = data.items.find((item: any) => item.id === "daft-ie-mcp")
expect(daftieServer).toBeDefined()
expect(daftieServer.name).toBe("Daft.ie MCP Server")
expect(daftieServer.author).toBe("amineremache")
expect(daftieServer.url).toBe("https://github.com/amineremache/daft-ie-mcp")
expect(daftieServer.tags).toContain("ireland")
expect(daftieServer.tags).toContain("rental")
expect(daftieServer.tags).toContain("property")
})

it("should have valid installation methods for Daft.ie MCP", async () => {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const content = await fs.readFile(mcpsPath, "utf-8")
const data = yaml.parse(content)

const daftieServer = data.items.find((item: any) => item.id === "daft-ie-mcp")
expect(daftieServer.content).toBeDefined()
expect(Array.isArray(daftieServer.content)).toBe(true)
expect(daftieServer.content.length).toBeGreaterThan(0)

// Check NPM installation method
const npmMethod = daftieServer.content.find((method: any) => method.name === "NPM Installation")
expect(npmMethod).toBeDefined()
expect(npmMethod.content).toContain("daft-ie")
expect(npmMethod.content).toContain("npx")

// Check local development method
const localMethod = daftieServer.content.find((method: any) => method.name === "Local Development")
expect(localMethod).toBeDefined()
expect(localMethod.parameters).toBeDefined()
expect(localMethod.parameters.length).toBeGreaterThan(0)
})
})

describe("Modes Configuration", () => {
it("should have valid modes.yml file", async () => {
const modesPath = path.join(marketplaceDir, "modes.yml")
const content = await fs.readFile(modesPath, "utf-8")
const data = yaml.parse(content)

expect(data).toHaveProperty("items")
expect(Array.isArray(data.items)).toBe(true)
})

it("should validate all mode items against schema", async () => {
const modesPath = path.join(marketplaceDir, "modes.yml")
const content = await fs.readFile(modesPath, "utf-8")
const data = yaml.parse(content)

for (const item of data.items) {
expect(() => modeMarketplaceItemSchema.parse(item)).not.toThrow()
}
})

it("should contain Property Search mode", async () => {
const modesPath = path.join(marketplaceDir, "modes.yml")
const content = await fs.readFile(modesPath, "utf-8")
const data = yaml.parse(content)

const propertyMode = data.items.find((item: any) => item.id === "property-search-mode")
expect(propertyMode).toBeDefined()
expect(propertyMode.name).toBe("Property Search Mode")
expect(propertyMode.tags).toContain("property")
expect(propertyMode.tags).toContain("rental")
expect(propertyMode.tags).toContain("ireland")
expect(propertyMode.prerequisites).toContain("Daft.ie MCP Server")
})

it("should have valid mode content structure", async () => {
const modesPath = path.join(marketplaceDir, "modes.yml")
const content = await fs.readFile(modesPath, "utf-8")
const data = yaml.parse(content)

const propertyMode = data.items.find((item: any) => item.id === "property-search-mode")
expect(propertyMode.content).toBeDefined()
expect(propertyMode.content).toContain("name:")
expect(propertyMode.content).toContain("slug:")
expect(propertyMode.content).toContain("description:")
expect(propertyMode.content).toContain("instructions:")
})
})

describe("Cross-references", () => {
it("should have matching tags between related MCP and mode", async () => {
const mcpsPath = path.join(marketplaceDir, "mcps.yml")
const modesPath = path.join(marketplaceDir, "modes.yml")

const mcpsContent = await fs.readFile(mcpsPath, "utf-8")
const modesContent = await fs.readFile(modesPath, "utf-8")

const mcpsData = yaml.parse(mcpsContent)
const modesData = yaml.parse(modesContent)

const daftieServer = mcpsData.items.find((item: any) => item.id === "daft-ie-mcp")
const propertyMode = modesData.items.find((item: any) => item.id === "property-search-mode")

// Check that they share common tags
const commonTags = ["property", "rental", "ireland"]
for (const tag of commonTags) {
expect(daftieServer.tags).toContain(tag)
expect(propertyMode.tags).toContain(tag)
}
})
})
})